diff --git a/src/bin/exactness.c b/src/bin/exactness.c index 8211fe7..87606f1 100644 --- a/src/bin/exactness.c +++ b/src/bin/exactness.c @@ -220,79 +220,72 @@ _scheduler_run() while (_job_consume()); } -static Eina_Bool -_file_sha1_get(const char *filename, unsigned char *result) +static Exactness_Image * +_image_load(const char *filename) { - Eina_File *f = NULL; - const char *key = "0123456789abcde"; - int key_len = strlen(key); - unsigned int size = 0; - Eina_Binbuf *buf = NULL; - void *data = NULL; + int w, h; + Evas_Load_Error err; + Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL); + Eo *e = ecore_evas_get(ee); - f = eina_file_open(filename, EINA_FALSE); - if (!f) goto false; - size = eina_file_size_get(f); - if (size < 1) goto false; - data = eina_file_map_all(f, EINA_FILE_POPULATE); - if (!data) goto false; - - buf = eina_binbuf_manage_new(data, size, EINA_TRUE); - if (!buf) + Eo *img = evas_object_image_add(e); + evas_object_image_file_set(img, filename, NULL); + err = evas_object_image_load_error_get(img); + if (err != EVAS_LOAD_ERROR_NONE) { - fprintf(stderr, "Could not create Binary Buffer"); - goto false; + fprintf(stderr, "could not load image '%s'. error string is \"%s\"\n", + filename, evas_load_error_str(err)); + return NULL; } - if (!emile_binbuf_hmac_sha1(key, key_len, buf, result)) - { - fprintf(stderr, "Cannot generate sha1 for image"); - goto false; - } - eina_binbuf_free(buf); - eina_file_close(f); - return EINA_TRUE; -false: - if (buf) eina_binbuf_free(buf); - if (f) eina_file_close(f); - return EINA_FALSE; + Exactness_Image *ex_img = malloc(sizeof(*ex_img)); + int len; + evas_object_image_size_get(img, &w, &h); + ex_img->w = w; + ex_img->h = h; + len = w * h * 4; + ex_img->pixels = malloc(len); + memcpy(ex_img->pixels, evas_object_image_data_get(img, EINA_FALSE), len); + + ecore_evas_free(ee); + return ex_img; } -#define _DIGEST_SIZE 20 -static Eina_Bool -_is_equal(const char *filename1, const char *filename2) +static void +_image_save(Exactness_Image *ex_img, const char *output) { - unsigned char res1[_DIGEST_SIZE], res2[_DIGEST_SIZE]; - if (!_file_sha1_get(filename1, res1)) - return EINA_FALSE; - if (!_file_sha1_get(filename2, res2)) - return EINA_FALSE; - - return !memcmp(res1, res2, _DIGEST_SIZE); + Ecore_Evas *ee; + Eo *e, *img; + ee = ecore_evas_new(NULL, 0, 0, 100, 100, NULL); + e = ecore_evas_get(ee); + img = evas_object_image_add(e); + evas_object_image_size_set(img, ex_img->w, ex_img->h); + evas_object_image_data_set(img, ex_img->pixels); + evas_object_image_save(img, output, NULL, NULL); + ecore_evas_free(ee); } static void _file_compare(const char *orig_dir, const char *ent_name) { char filename1[EXACTNESS_PATH_MAX], filename2[EXACTNESS_PATH_MAX]; + Exactness_Image *img1, *img2, *imgO = NULL; snprintf(filename1, EXACTNESS_PATH_MAX, "%s/%s", orig_dir, ent_name); snprintf(filename2, EXACTNESS_PATH_MAX, "%s/%s/%s", _dest_dir, CURRENT_SUBDIR, ent_name); - if (!_is_equal(filename1, filename2)) + + img1 = _image_load(filename1); + img2 = _image_load(filename2); + + if (exactness_image_compare(img1, img2, &imgO)) { char buf[EXACTNESS_PATH_MAX]; + snprintf(buf, EXACTNESS_PATH_MAX, "%s/%s/comp_%s", _dest_dir, CURRENT_SUBDIR, ent_name); + _image_save(imgO, buf); _compare_errors = eina_list_append(_compare_errors, strdup(ent_name)); - - /* FIXME: Clean up. */ - snprintf(buf, EXACTNESS_PATH_MAX, - "compare '%s' '%s' '%s/%s/comp_%s'", - filename1, filename2, - _dest_dir, - CURRENT_SUBDIR, ent_name); - if (system(buf)) - { - fprintf(stderr, "Failed image comparing '%s'\n", ent_name); - } } + exactness_image_free(img1); + exactness_image_free(img2); + exactness_image_free(imgO); } static void @@ -326,7 +319,7 @@ _exu_imgs_unpack(const char *exu_path, const char *dir, const char *ent_name) static void _run_test_compare(const List_Entry *ent) { - char path[EXACTNESS_PATH_MAX]; + char path[2*EXACTNESS_PATH_MAX]; char origdir[EXACTNESS_PATH_MAX]; const char *base_dir; Eina_List *itr; diff --git a/src/bin/inspect.c b/src/bin/inspect.c index a41ab53..0846536 100644 --- a/src/bin/inspect.c +++ b/src/bin/inspect.c @@ -203,69 +203,6 @@ _are_images_different(Exactness_Image *e_img1, Exactness_Image *e_img2) return EINA_FALSE; } -static Exactness_Image * -_pixels_compare(Exactness_Image *img1, Exactness_Image *img2, Eina_Bool *has_diff) -{ - Exactness_Image *imgO = malloc(sizeof(*imgO)); - unsigned int w, h; - int *pxs1, *pxs2, *pxsO; - unsigned int w1 = img1 ? img1->w : 0, h1 = img1 ? img1->h : 0; - unsigned int w2 = img2 ? img2->w : 0, h2 = img2 ? img2->h : 0; - imgO->w = MAX(w1, w2); - imgO->h = MAX(h1, h2); - if (has_diff) *has_diff = EINA_FALSE; - if (!imgO->w || !imgO->h) - { - free(imgO); - return NULL; - } - imgO->pixels = malloc(imgO->w * imgO->h * 4); - - pxs1 = img1 ? img1->pixels : NULL; - pxs2 = img2 ? img2->pixels : NULL; - pxsO = imgO->pixels; - - for (w = 0; w < imgO->w; w++) - { - for (h = 0; h < imgO->h; h++) - { - Eina_Bool valid1 = img1 ? w <= w1 && h <= h1 : EINA_FALSE; - Eina_Bool valid2 = img2 ? w <= w2 && h <= h2 : EINA_FALSE; - int px1 = valid1 ? pxs1[h * w1 + w] : 0; - int px2 = valid2 ? pxs2[h * w2 + w] : 0; - int r1 = (px1 & 0x00FF0000) >> 16; - int r2 = (px2 & 0x00FF0000) >> 16; - int g1 = (px1 & 0x0000FF00) >> 8; - int g2 = (px2 & 0x0000FF00) >> 8; - int b1 = (px1 & 0x000000FF); - int b2 = (px2 & 0x000000FF); - int new_r, new_g, new_b; - if (valid1 || valid2) - { - if (px1 != px2) - { - new_r = 0xFF; - new_g = ((g1 + g2) >> 1) >> 2; - new_b = ((b1 + b2) >> 1) >> 2; - if (has_diff) *has_diff = EINA_TRUE; - } - else - { - new_r = (((r1 + r2) >> 1) >> 2) + 0xC0; - new_g = (((g1 + g2) >> 1) >> 2) + 0xC0; - new_b = (((b1 + b2) >> 1) >> 2) + 0xC0; - } - } - else - { - new_r = new_g = new_b = 0x0; - } - pxsO[h * imgO->w + w] = 0xFF000000 | new_r << 16 | new_g << 8 | new_b; - } - } - return imgO; -} - static Eina_Bool _are_objs_different(Exactness_Object *e_obj1, Exactness_Object *e_obj2, Eina_Bool check_objs) { @@ -497,7 +434,8 @@ _scn_content_get(void *data, Evas_Object *gl, const char *part) int shot2_no = _unit_shot_no_get(unit2, v2); Exactness_Image *ex_img1 = shot1_no != -1 ? eina_list_nth(unit1->imgs, shot1_no) : NULL; Exactness_Image *ex_img2 = shot2_no != -1 ? eina_list_nth(unit2->imgs, shot2_no) : NULL; - Exactness_Image *ex_imgO = _pixels_compare(ex_img1, ex_img2, NULL); + Exactness_Image *ex_imgO = NULL; + exactness_image_compare(ex_img1, ex_img2, &ex_imgO); if (ex_imgO) { @@ -570,7 +508,8 @@ _img_content_get(void *data, Evas_Object *gl, const char *part) _Compare_Item_Data *vv = data; Exactness_Image *ex_img1 = vv->p1; Exactness_Image *ex_img2 = vv->p2; - Exactness_Image *ex_imgO = _pixels_compare(ex_img1, ex_img2, NULL); + Exactness_Image *ex_imgO = NULL; + exactness_image_compare(ex_img1, ex_img2, &ex_imgO); evas_object_image_size_set(evas_img, ex_imgO->w, ex_imgO->h); evas_object_image_data_set(evas_img, ex_imgO->pixels); @@ -1329,12 +1268,11 @@ main(int argc, char *argv[]) if (!strcmp(ext, ".png")) { - Eina_Bool has_diff = EINA_FALSE; Exactness_Image *ex_img1 = eina_list_data_get(unit1->imgs); Exactness_Image *ex_img2 = eina_list_data_get(unit2->imgs); - Exactness_Image *ex_imgO = _pixels_compare(ex_img1, ex_img2, &has_diff); + Exactness_Image *ex_imgO = NULL; - if (has_diff) + if (exactness_image_compare(ex_img1, ex_img2, &ex_imgO)) { Ecore_Evas *ee; Eo *e, *img; diff --git a/src/lib/Exactness.h b/src/lib/Exactness.h index 621afa7..d31f38e 100644 --- a/src/lib/Exactness.h +++ b/src/lib/Exactness.h @@ -214,6 +214,25 @@ EAPI Exactness_Unit *exactness_unit_file_read(const char *filename); */ EAPI Eina_Bool exactness_unit_file_write(Exactness_Unit *unit, const char *filename); +/** + * @brief Compare two images + * + * @param img1 first image + * @param img2 second image + * @param imgO pointer for the diff image. Can be NULL + * + * @return EINA_TRUE if the images are different, EINA_FALSE otherwise + */ +EAPI Eina_Bool exactness_image_compare(Exactness_Image *img1, Exactness_Image *img2, Exactness_Image **imgO); + +/** + * @brief Free the given image + * + * @param img the image + * + */ +EAPI void exactness_image_free(Exactness_Image *img); + /** * @brief Read a legacy file and convert it to an unit * diff --git a/src/lib/unit.c b/src/lib/unit.c index 4f29d75..f1142e3 100644 --- a/src/lib/unit.c +++ b/src/lib/unit.c @@ -318,3 +318,76 @@ exactness_unit_file_write(Exactness_Unit *unit, const char *filename) return EINA_TRUE; } +EAPI Eina_Bool +exactness_image_compare(Exactness_Image *img1, Exactness_Image *img2, Exactness_Image **imgO) +{ + unsigned int w, h; + int *pxs1, *pxs2, *pxsO = NULL; + unsigned int w1 = img1 ? img1->w : 0, h1 = img1 ? img1->h : 0; + unsigned int w2 = img2 ? img2->w : 0, h2 = img2 ? img2->h : 0; + unsigned int wO = MAX(w1, w2); + unsigned int hO = MAX(h1, h2); + Eina_Bool ret = EINA_FALSE; + if (imgO) *imgO = NULL; + if (!wO || !hO) return EINA_FALSE; + + pxs1 = img1 ? img1->pixels : NULL; + pxs2 = img2 ? img2->pixels : NULL; + if (imgO) pxsO = malloc(wO * hO * 4); + + for (w = 0; w < wO; w++) + { + for (h = 0; h < hO; h++) + { + Eina_Bool valid1 = img1 ? w <= w1 && h <= h1 : EINA_FALSE; + Eina_Bool valid2 = img2 ? w <= w2 && h <= h2 : EINA_FALSE; + int px1 = valid1 ? pxs1[h * w1 + w] : 0; + int px2 = valid2 ? pxs2[h * w2 + w] : 0; + int r1 = (px1 & 0x00FF0000) >> 16; + int r2 = (px2 & 0x00FF0000) >> 16; + int g1 = (px1 & 0x0000FF00) >> 8; + int g2 = (px2 & 0x0000FF00) >> 8; + int b1 = (px1 & 0x000000FF); + int b2 = (px2 & 0x000000FF); + int new_r, new_g, new_b; + if (valid1 || valid2) + { + if (px1 != px2) + { + new_r = 0xFF; + new_g = ((g1 + g2) >> 1) >> 2; + new_b = ((b1 + b2) >> 1) >> 2; + ret = EINA_TRUE; + } + else + { + new_r = (((r1 + r2) >> 1) >> 2) + 0xC0; + new_g = (((g1 + g2) >> 1) >> 2) + 0xC0; + new_b = (((b1 + b2) >> 1) >> 2) + 0xC0; + } + } + else + { + new_r = new_g = new_b = 0x0; + } + if (pxsO) pxsO[h * wO + w] = 0xFF000000 | new_r << 16 | new_g << 8 | new_b; + } + } + if (imgO) + { + Exactness_Image *imgR = calloc(1, sizeof(Exactness_Image)); + *imgO = imgR; + imgR->w = wO; + imgR->h = hO; + imgR->pixels = pxsO; + } + return ret; +} + +EAPI void exactness_image_free(Exactness_Image *img) +{ + if (!img) return; + free(img->pixels); + free(img); +} +