Suite: replace the compare method

Instead of using ImageMagick, we now use an internal function.
This commit is contained in:
Daniel Zaoui 2018-05-14 11:57:49 +03:00
parent 53a52a3419
commit f56ee0dfac
4 changed files with 145 additions and 122 deletions

View File

@ -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;
}
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;
fprintf(stderr, "could not load image '%s'. error string is \"%s\"\n",
filename, evas_load_error_str(err));
return NULL;
}
#define _DIGEST_SIZE 20
static Eina_Bool
_is_equal(const char *filename1, const char *filename2)
{
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;
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);
return !memcmp(res1, res2, _DIGEST_SIZE);
ecore_evas_free(ee);
return ex_img;
}
static void
_image_save(Exactness_Image *ex_img, const char *output)
{
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;

View File

@ -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;

View File

@ -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
*

View File

@ -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);
}