|
| 1 | +#include <stdio.h> |
| 2 | +#include <stdint.h> |
| 3 | + |
| 4 | +#define BYTE uint8_t |
| 5 | +#define DWORD uint32_t |
| 6 | + |
| 7 | +#ifdef _WIN64 |
| 8 | + #define EXPORT __declspec(dllexport) |
| 9 | + #define CALL_TYPE __stdcall |
| 10 | +#elif _WIN32 |
| 11 | + #define EXPORT __declspec(dllexport) |
| 12 | + #define CALL_TYPE __stdcall |
| 13 | +#elif linux |
| 14 | + #define EXPORT |
| 15 | + #define CALL_TYPE |
| 16 | +#endif |
| 17 | + |
| 18 | +#ifdef __cplusplus |
| 19 | +extern "C" { // only need to export C interface if |
| 20 | + // used by C++ source code |
| 21 | +#endif |
| 22 | + |
| 23 | +// On linux use: |
| 24 | +// gcc -c -Werror -fpic img_murphy.c |
| 25 | +// gcc -shared -o img_murphy.so img_murphy.o |
| 26 | +// On windows, create a solution |
| 27 | + |
| 28 | +//hint: h_x1, h_y1, h_x2, h_y2 |
| 29 | +EXPORT int CALL_TYPE find(BYTE* search_for, int for_width, int for_height, BYTE* search_in, int in_width, int in_height, int *best_x, int *best_y, BYTE* mask) |
| 30 | +{ |
| 31 | + int x0, y0, x1, y1; |
| 32 | + |
| 33 | + int in_ptr, for_ptr; |
| 34 | + |
| 35 | + int right_gap, right_limit; |
| 36 | + int bottom_limit; |
| 37 | + int matches, mismatches, best_match; |
| 38 | + int diff, half_for_height; |
| 39 | + |
| 40 | + int xx, yy; |
| 41 | + BYTE mask_val; |
| 42 | + |
| 43 | + right_limit = in_width - for_width; |
| 44 | + right_gap = right_limit; |
| 45 | + bottom_limit = in_height - for_height; |
| 46 | + half_for_height = 2; |
| 47 | + |
| 48 | + in_ptr = 0; |
| 49 | + for_ptr = 0; |
| 50 | + best_match = -1; |
| 51 | + |
| 52 | + xx = *best_x; |
| 53 | + yy = *best_y; |
| 54 | + if( xx < 0 ) { |
| 55 | + xx = -xx; |
| 56 | + right_limit = xx + 1; |
| 57 | + } |
| 58 | + if( yy < 0 ) { |
| 59 | + yy = -yy; |
| 60 | + bottom_limit = yy + 1; |
| 61 | + } |
| 62 | + //printf("Search starts at %i %i ends at %i %i with mask %i\n", xx, yy, right_limit, bottom_limit, mask); |
| 63 | + |
| 64 | + for( y0 = yy; y0 <= bottom_limit; y0++ ) { |
| 65 | + for( x0 = xx; x0 <= right_limit; x0++ ) { |
| 66 | + in_ptr = (y0 * in_width) + x0; |
| 67 | + for_ptr = 0; |
| 68 | + matches = 0; |
| 69 | + mismatches = 0; |
| 70 | + for( y1 = 0; y1 < for_height; y1++ ) { |
| 71 | + for( x1 = 0; x1 < for_width; x1++ ) { |
| 72 | + if( mask == NULL) { |
| 73 | + diff = (search_in[in_ptr++] - search_for[for_ptr++]) & 0xfff; |
| 74 | + } else { |
| 75 | + mask_val = mask[for_ptr]; |
| 76 | + if(mask_val == 0) { |
| 77 | + diff = (search_in[in_ptr++] - search_for[for_ptr++]) & 0xfff; |
| 78 | + } else { |
| 79 | + in_ptr++; |
| 80 | + for_ptr++; |
| 81 | + diff = 0; |
| 82 | + } |
| 83 | + } |
| 84 | + if( diff < 2 ) { |
| 85 | + matches++; |
| 86 | + } else { |
| 87 | + mismatches++; |
| 88 | + if( mismatches > matches && y1 > half_for_height ) |
| 89 | + break; |
| 90 | + } |
| 91 | + } |
| 92 | + if( mismatches > matches && y1 > half_for_height ) |
| 93 | + break; |
| 94 | + in_ptr += right_gap; |
| 95 | + } |
| 96 | + |
| 97 | + if( matches > best_match ) { |
| 98 | + best_match = matches; |
| 99 | + *best_x = x0; |
| 100 | + *best_y = y0; |
| 101 | + } |
| 102 | + } |
| 103 | + } |
| 104 | + |
| 105 | + return best_match; |
| 106 | + |
| 107 | +} |
| 108 | + |
| 109 | +#ifdef __cplusplus |
| 110 | +} |
| 111 | +#endif |
0 commit comments