double CompareScreenshot(const u8 *pixels, int w, int h, int stride, const std::string screenshotFilename, std::string &error) { u32 *pixels32 = (u32 *) pixels; // We assume the bitmap is the specified size, not including whatever stride. u32 *reference = (u32 *) calloc(w * h, sizeof(u32)); FILE *bmp = fopen(screenshotFilename.c_str(), "rb"); if (bmp) { // The bitmap header is 14 + 40 bytes. We could validate it but the test would fail either way. fseek(bmp, 14 + 40, SEEK_SET); fread(reference, sizeof(u32), w * h, bmp); fclose(bmp); } else { error = "Unable to read screenshot: " + screenshotFilename; free(reference); return -1.0f; } u32 errors = 0; for (int y = 0; y < h; ++y) { for (int x = 0; x < w; ++x) errors += ComparePixel(pixels32[y * stride + x], reference[y * w + x]); } free(reference); return (double) errors / (double) (w * h); }
void FillWorker(unsigned long x, unsigned long y, char color, char oldColor) { SetPixel(x, y, color); if (ComparePixel(x, y-1, oldColor)) { FillWorker(x, y-1, color, oldColor); } if (ComparePixel(x, y+1, oldColor)) { FillWorker(x, y+1, color, oldColor); } if (ComparePixel(x-1, y, oldColor)) { FillWorker(x-1, y, color, oldColor); } if (ComparePixel(x+1, y, oldColor)) { FillWorker(x+1, y, color, oldColor); } }
static float FindPixel(ImgType s1, int r1, int c1, ImgType s2, int *pr2, int *pc2, int BLOCK_SIZEX, int BLOCK_SIZEY, int SEARCH_SIZEX, int SEARCH_SIZEY, int OFFSET_X, int OFFSET_Y, int NORMALIZE) { int r2=(*pr2) + OFFSET_Y, c2=(*pc2) + OFFSET_X; float best = 999999999999.0f, current, central=0; float worst = 0; int i, j; int delx = SEARCH_SIZEX; int dely = SEARCH_SIZEY; for (i = -dely+OFFSET_Y; i <= dely+OFFSET_Y; i++) { for (j = -delx+OFFSET_X; j <= delx+OFFSET_X; j++) { int r1d = (*pr2)+i; int c1d = (*pc2)+j; if (c1 + BLOCK_SIZEX < IMG_W && c1 - BLOCK_SIZEX >= 0 && r1 + BLOCK_SIZEY < IMG_H && r1 - BLOCK_SIZEY >= 0 && c1d + BLOCK_SIZEX < IMG_W && c1d - BLOCK_SIZEX >= 0 && r1d + BLOCK_SIZEY < IMG_H && r1d - BLOCK_SIZEY >= 0) { current = ComparePixel(s1,r1,c1,s2,r1d,c1d,BLOCK_SIZEX,BLOCK_SIZEY,NORMALIZE); if (i==0 && j==0) { central = current; } if (current<best || (current==best && i==0 && j==0)) { r2 = (*pr2)+i; c2 = (*pc2)+j; best = current; } if (current > worst) { worst = current; } } } } *pr2 = r2; *pc2 = c2; float safe = 10; return (fabs(worst-best)+safe)/(best+safe); }