cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=63a12d7d26f53b22b7794eb61897de930614bac7

commit 63a12d7d26f53b22b7794eb61897de930614bac7
Author: jiin.moon <jiin.m...@samsung.com>
Date:   Wed Jun 3 10:57:27 2015 +0200

    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 <ced...@osg.samsung.com>
---
 src/lib/emile/emile_image.c      |  44 ++++++-------
 src/tests/evas/evas_test_image.c | 138 +++++++++++++++++++++++++++++++++++----
 2 files changed, 148 insertions(+), 34 deletions(-)

diff --git a/src/lib/emile/emile_image.c b/src/lib/emile/emile_image.c
index 018745c..dc1bed2 100644
--- a/src/lib/emile/emile_image.c
+++ b/src/lib/emile/emile_image.c
@@ -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;
           }
diff --git a/src/tests/evas/evas_test_image.c b/src/tests/evas/evas_test_image.c
index ca7a0cb..cfb0f94 100644
--- a/src/tests/evas/evas_test_image.c
+++ b/src/tests/evas/evas_test_image.c
@@ -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);
 }

-- 


Reply via email to