emile: fix region load for jpeg image with orientation different set.

Summary:
If you try to load the jpeg image with an orientation mode defined
using elm_photocam, you can see the broken image(in canse of 90 degree)
or even segmentation fault can happen (in case of 180,270 degree)

@fix

Test Plan: photocam menu on elementary_test

Reviewers: Hermet, cedric

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D2593

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
jiin.moon 2015-06-03 10:57:27 +02:00 committed by Cedric BAIL
parent 0c729faf68
commit 63a12d7d26
2 changed files with 148 additions and 34 deletions

View File

@ -1048,7 +1048,7 @@ _rotate_region(unsigned int *r_x, unsigned int *r_y,
else
{
*r_x = y;
*r_y = output_h - (x + y);
*r_y = output_h - (x + w);
*r_w = h;
*r_h = w;
}
@ -2124,7 +2124,7 @@ done:
uint16_t *to16;
int hw;
hw = w * h;
hw = ie_w * ie_h;
to = pixels;
to8 = pixels;
to16 = pixels;
@ -2135,23 +2135,23 @@ done:
if (prop->cspace == EMILE_COLORSPACE_GRY8)
{
if (prop->flipped)
_rotate_change_wh8(to8 + hw - 1, ptrg_rotate, w, h, hw - 1, -h);
_rotate_change_wh8(to8 + hw - 1, ptrg_rotate, ie_w, ie_h, hw - 1, -ie_h);
else
_rotate_change_wh8(to8 + h - 1, ptrg_rotate, w, h, -hw - 1, h);
_rotate_change_wh8(to8 + ie_h - 1, ptrg_rotate, ie_w, ie_h, -hw - 1, ie_h);
}
else if (prop->cspace == EMILE_COLORSPACE_AGRY88)
{
if (prop->flipped)
_rotate_change_wh16(to16 + hw - 1, ptrag_rotate, w, h, hw - 1, -h);
_rotate_change_wh16(to16 + hw - 1, ptrag_rotate, ie_w, ie_h, hw - 1, -ie_h);
else
_rotate_change_wh16(to16 + h - 1, ptrag_rotate, w, h, -hw - 1, h);
_rotate_change_wh16(to16 + ie_h - 1, ptrag_rotate, ie_w, ie_h, -hw - 1, ie_h);
}
else
{
if (prop->flipped)
_rotate_change_wh(to + hw - 1, ptr_rotate, w, h, hw - 1, -h);
_rotate_change_wh(to + hw - 1, ptr_rotate, ie_w, ie_h, hw - 1, -ie_h);
else
_rotate_change_wh(to + h - 1, ptr_rotate, w, h, -hw - 1, h);
_rotate_change_wh(to + ie_h - 1, ptr_rotate, ie_w, ie_h, -hw - 1, ie_h);
}
break;
@ -2159,23 +2159,23 @@ done:
if (prop->cspace == EMILE_COLORSPACE_GRY8)
{
if (prop->flipped)
_flip_vertical8(to8, w, h);
_flip_vertical8(to8, ie_w, ie_h);
else
_rotate8_180(to8, w, h);
_rotate8_180(to8, ie_w, ie_h);
}
else if (prop->cspace == EMILE_COLORSPACE_AGRY88)
{
if (prop->flipped)
_flip_vertical16(to16, w, h);
_flip_vertical16(to16, ie_w, ie_h);
else
_rotate16_180(to16, w, h);
_rotate16_180(to16, ie_w, ie_h);
}
else
{
if (prop->flipped)
_flip_vertical(to, w, h);
_flip_vertical(to, ie_w, ie_h);
else
_rotate_180(to, w, h);
_rotate_180(to, ie_w, ie_h);
}
break;
@ -2183,23 +2183,23 @@ done:
if (prop->cspace == EMILE_COLORSPACE_GRY8)
{
if (prop->flipped)
_rotate_change_wh8(to8, ptrg_rotate, w, h, -hw + 1, h);
_rotate_change_wh8(to8, ptrg_rotate, ie_w, ie_h, -hw + 1, ie_h);
else
_rotate_change_wh8(to8 + hw - h, ptrg_rotate, w, h, hw + 1, -h);
_rotate_change_wh8(to8 + hw - ie_h, ptrg_rotate, ie_w, ie_h, hw + 1, -ie_h);
}
else if (prop->cspace == EMILE_COLORSPACE_AGRY88)
{
if (prop->flipped)
_rotate_change_wh16(to16, ptrag_rotate, w, h, -hw + 1, h);
else
_rotate_change_wh16(to16 + hw - h, ptrag_rotate, w, h, hw + 1, -h);
_rotate_change_wh16(to16 + hw - ie_h, ptrag_rotate, ie_w, ie_h, hw + 1, -ie_h);
}
else
{
if (prop->flipped)
_rotate_change_wh(to, ptr_rotate, w, h, -hw + 1, h);
_rotate_change_wh(to, ptr_rotate, ie_w, ie_h, -hw + 1, ie_h);
else
_rotate_change_wh(to + hw - h, ptr_rotate, w, h, hw + 1, -h);
_rotate_change_wh(to + hw - ie_h, ptr_rotate, ie_w, ie_h, hw + 1, -ie_h);
}
break;
@ -2207,11 +2207,11 @@ done:
if (prop->flipped)
{
if (prop->cspace == EMILE_COLORSPACE_GRY8)
_flip_horizontal8(to8, w, h);
_flip_horizontal8(to8, ie_w, ie_h);
else if (prop->cspace == EMILE_COLORSPACE_AGRY88)
_flip_horizontal16(to16, w, h);
_flip_horizontal16(to16, ie_w, ie_h);
else
_flip_horizontal(to, w, h);
_flip_horizontal(to, ie_w, ie_h);
}
break;
}

View File

@ -100,11 +100,13 @@ START_TEST(evas_object_image_loader)
}
END_TEST
typedef struct _orientation_Test_Res {
typedef struct _Orientation_Test_Res Orientation_Test_Res;
struct _Orientation_Test_Res {
const char *img;
const char *desc;
Evas_Image_Orient orient;
int (*compare_func)(const uint32_t *d1, const uint32_t *d2, int w2, int h2);
} Orientation_Test_Res;
};
typedef struct _orient_Test {
Evas_Image_Orient orient;
@ -247,16 +249,16 @@ START_TEST(evas_object_image_loader_orientation)
{
Evas *e = _setup_evas();
Evas_Object *orig, *rot;
Orientation_Test_Res res[] = {
{TESTS_IMG_DIR"/Light_exif.jpg", "Original", _compare_img},
{TESTS_IMG_DIR"/Light_exif_flip_h.jpg", "Flip horizontally", _compare_img_flip_h},
{TESTS_IMG_DIR"/Light_exif_180.jpg", "Rotate 180° CW", _compare_img_180},
{TESTS_IMG_DIR"/Light_exif_flip_v.jpg", "Flip vertically", _compare_img_flip_v},
{TESTS_IMG_DIR"/Light_exif_transpose.jpg", "Transpose", _compare_img_transpose},
{TESTS_IMG_DIR"/Light_exif_90.jpg", "Rotate 90° CW", _compare_img_90},
{TESTS_IMG_DIR"/Light_exif_transverse.jpg", "Transverse", _compare_img_transverse},
{TESTS_IMG_DIR"/Light_exif_270.jpg", "Rotate 90° CCW", _compare_img_270},
{NULL, NULL, NULL}
static const Orientation_Test_Res res[] = {
{ TESTS_IMG_DIR"/Light_exif.jpg", "Original", EVAS_IMAGE_ORIENT_NONE, _compare_img },
{ TESTS_IMG_DIR"/Light_exif_flip_h.jpg", "Flip horizontally", EVAS_IMAGE_FLIP_HORIZONTAL, _compare_img_flip_h },
{ TESTS_IMG_DIR"/Light_exif_180.jpg", "Rotate 180° CW", EVAS_IMAGE_ORIENT_180, _compare_img_180 },
{ TESTS_IMG_DIR"/Light_exif_flip_v.jpg", "Flip vertically", EVAS_IMAGE_FLIP_VERTICAL, _compare_img_flip_v },
{ TESTS_IMG_DIR"/Light_exif_transpose.jpg", "Transpose", EVAS_IMAGE_FLIP_TRANSPOSE, _compare_img_transpose },
{ TESTS_IMG_DIR"/Light_exif_90.jpg", "Rotate 90° CW", EVAS_IMAGE_ORIENT_90, _compare_img_90 },
{ TESTS_IMG_DIR"/Light_exif_transverse.jpg", "Transverse", EVAS_IMAGE_FLIP_TRANSVERSE, _compare_img_transverse },
{ TESTS_IMG_DIR"/Light_exif_270.jpg", "Rotate 90° CCW", EVAS_IMAGE_ORIENT_270, _compare_img_270 },
{ NULL, NULL, EVAS_IMAGE_ORIENT_NONE, NULL }
};
int w, h, r_w, r_h;
const uint32_t *d, *r_d;
@ -528,6 +530,117 @@ START_TEST(evas_object_image_buggy)
}
END_TEST
static void check_rotate_region(Evas_Image_Orient orientation, int *r_x, int *r_y, int *r_w, int *r_h, int w, int h)
{
int tmp;
switch (orientation)
{
case EVAS_IMAGE_FLIP_HORIZONTAL:
*r_x = w - *r_w;
break;
case EVAS_IMAGE_FLIP_VERTICAL:
*r_y = h - *r_h;
break;
case EVAS_IMAGE_ORIENT_180:
*r_x = w - *r_w;
*r_y = h - *r_h;
break;
case EVAS_IMAGE_ORIENT_90:
tmp = *r_x;
*r_x = w - (*r_y + *r_h);
*r_y = tmp;
tmp = *r_w;
*r_w = *r_h;
*r_h = tmp;
break;
case EVAS_IMAGE_ORIENT_270:
tmp = *r_y;
*r_y = h - (*r_x + *r_w);
*r_x = tmp;
tmp = *r_w;
*r_w = *r_h;
*r_h = tmp;
break;
case EVAS_IMAGE_FLIP_TRANSPOSE:
tmp = *r_x;
*r_x = *r_y;
*r_y = tmp;
tmp = *r_w;
*r_w = *r_h;
*r_h = tmp;
break;
case EVAS_IMAGE_FLIP_TRANSVERSE:
tmp = *r_x;
*r_x = w - (*r_y + *r_h);
*r_y = h - (tmp + *r_w);
tmp = *r_w;
*r_w = *r_h;
*r_h = tmp;
break;
case EVAS_IMAGE_ORIENT_0:
break;
}
}
START_TEST(evas_object_image_partially_load_orientation)
{
static const Orientation_Test_Res res[] = {
{ TESTS_IMG_DIR"/Light_exif.jpg", "Original", EVAS_IMAGE_ORIENT_NONE, _compare_img },
{ TESTS_IMG_DIR"/Light_exif_flip_h.jpg", "Flip horizontally", EVAS_IMAGE_FLIP_HORIZONTAL, _compare_img_flip_h },
{ TESTS_IMG_DIR"/Light_exif_180.jpg", "Rotate 180° CW", EVAS_IMAGE_ORIENT_180, _compare_img_180 },
{ TESTS_IMG_DIR"/Light_exif_flip_v.jpg", "Flip vertically", EVAS_IMAGE_FLIP_VERTICAL, _compare_img_flip_v },
{ TESTS_IMG_DIR"/Light_exif_transpose.jpg", "Transpose", EVAS_IMAGE_FLIP_TRANSPOSE, _compare_img_transpose },
{ TESTS_IMG_DIR"/Light_exif_90.jpg", "Rotate 90° CW", EVAS_IMAGE_ORIENT_90, _compare_img_90 },
{ TESTS_IMG_DIR"/Light_exif_transverse.jpg", "Transverse", EVAS_IMAGE_FLIP_TRANSVERSE, _compare_img_transverse },
{ TESTS_IMG_DIR"/Light_exif_270.jpg", "Rotate 90° CCW", EVAS_IMAGE_ORIENT_270, _compare_img_270 },
{ NULL, NULL, EVAS_IMAGE_ORIENT_NONE, NULL }
};
Evas *e = _setup_evas();
Evas_Object *orig, *rot;
int x, y, w, h, r_w, r_h;
int region_x, region_y, region_w, region_h;
const uint32_t *d, *r_d;
int i;
orig = evas_object_image_add(e);
evas_object_image_file_set(orig, TESTS_IMG_DIR"/Light.jpg", NULL);
fail_if(evas_object_image_load_error_get(orig) != EVAS_LOAD_ERROR_NONE);
evas_object_image_size_get(orig, &w, &h);
x = 0; y = 0; w = w / 2; h = h / 2;;
evas_object_image_load_region_set(orig, x, y, w, h);
evas_object_image_size_get(orig, &w, &h);
d = evas_object_image_data_get(orig, EINA_FALSE);
for (i = 0; res[i].img; i++)
{
region_x = x;
region_y = y;
region_w = w;
region_h = h;
rot = evas_object_image_add(e);
evas_object_image_load_orientation_set(rot, EINA_TRUE);
evas_object_image_file_set(rot, res[i].img, NULL);
fail_if(evas_object_image_load_error_get(rot) != EVAS_LOAD_ERROR_NONE);
evas_object_image_size_get(rot, &r_w, &r_h);
check_rotate_region(res[i].orient, &region_x, &region_y, &region_w, &region_h, r_w, r_h);
evas_object_image_load_region_set(rot, region_x, region_y, region_w, region_h);
evas_object_image_size_get(rot, &r_w, &r_h);
fail_if(w * h != r_w * r_h);
r_d = evas_object_image_data_get(rot, EINA_FALSE);
fail_if(res[i].compare_func(d, r_d, r_w, r_h),
"Image orientation partially load test failed: exif orientation flag: %s\n", res[i].desc);
evas_object_del(rot);
}
evas_object_del(orig);
evas_free(e);
evas_shutdown();
}
END_TEST
void evas_test_image_object(TCase *tc)
{
tcase_add_test(tc, evas_object_image_loader);
@ -540,4 +653,5 @@ void evas_test_image_object(TCase *tc)
tcase_add_test(tc, evas_object_image_all_loader_data);
tcase_add_test(tc, evas_object_image_buggy);
#endif
tcase_add_test(tc, evas_object_image_partially_load_orientation);
}