cedric pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=1cc23d4ff26ade2e58b575e295fb1ef4fc937a13

commit 1cc23d4ff26ade2e58b575e295fb1ef4fc937a13
Author: Wonguk Jeong <[email protected]>
Date:   Sun Jul 6 19:58:47 2014 +0200

    evas: jpeg loader - support flip, transpose, transverse
    
    Summary:
    Previously, jpeg image loader support rotation (90°, 180°, 270°) only.
    this patch is about supporting flip(vertical, horizontal), transpose, 
transverse
    
    @feature
    
    Test Plan: I'm going to make tests in src/tests
    
    Reviewers: cedric, raster, jpeg
    
    CC: seoz, cedric
    
    Differential Revision: https://phab.enlightenment.org/D1126
    
    Signed-off-by: Cedric BAIL <[email protected]>
---
 src/lib/evas/Evas_Loader.h                         |   2 +
 src/lib/evas/common/evas_image_load.c              |   6 +-
 src/lib/evas/include/evas_common_private.h         |   1 +
 .../evas/loaders/jpeg/evas_image_load_jpeg.c       | 328 +++++++++++++--------
 4 files changed, 219 insertions(+), 118 deletions(-)

diff --git a/src/lib/evas/Evas_Loader.h b/src/lib/evas/Evas_Loader.h
index 74d6835..6a28550 100644
--- a/src/lib/evas/Evas_Loader.h
+++ b/src/lib/evas/Evas_Loader.h
@@ -193,6 +193,8 @@ struct _Evas_Image_Property
    struct {
       unsigned char l, r, t, b; /**< Specify the dimensions of duplicated 
pixels borders for OpenGL compressed textures, set by the loader. @since 1.11 */
    } borders;
+
+   Eina_Bool     flipped;
 };
 
 struct _Evas_Image_Animated
diff --git a/src/lib/evas/common/evas_image_load.c 
b/src/lib/evas/common/evas_image_load.c
index 6158e0b..e57bb61 100644
--- a/src/lib/evas/common/evas_image_load.c
+++ b/src/lib/evas/common/evas_image_load.c
@@ -231,9 +231,8 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, 
int *error)
              ie->flags.alpha = property.alpha;
              if (property.cspaces)
                ie->cspaces = property.cspaces;
-            if (ie->load_opts.orientation &&
-                ie->load_opts.degree != 0)
-              ie->flags.rotated = EINA_TRUE;
+             ie->flags.rotated = property.rotated;
+             ie->flags.flipped = property.flipped;
              r = EINA_FALSE;
           }
         else
@@ -416,6 +415,7 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
    property.h = ie->h;
    property.scale = ie->scale;
    property.rotated = ie->flags.rotated;
+   property.flipped = ie->flags.flipped;
    property.premul = EINA_FALSE;
    property.alpha_sparse = EINA_FALSE;
    property.cspace = ie->space;
diff --git a/src/lib/evas/include/evas_common_private.h 
b/src/lib/evas/include/evas_common_private.h
index b1cc92e..b79cf43 100644
--- a/src/lib/evas/include/evas_common_private.h
+++ b/src/lib/evas/include/evas_common_private.h
@@ -532,6 +532,7 @@ struct _Image_Entry_Flags
    Eina_Bool given_mmap    : 1;
 
    Eina_Bool updated_data  : 1;
+   Eina_Bool flipped       : 1;
 };
 
 struct _Image_Entry_Frame
diff --git a/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c 
b/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c
index 0ec2c85..c0047a3 100644
--- a/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c
+++ b/src/modules/evas/loaders/jpeg/evas_image_load_jpeg.c
@@ -37,8 +37,9 @@ static void _JPEGFatalErrorHandler(j_common_ptr cinfo);
 static void _JPEGErrorHandler(j_common_ptr cinfo);
 static void _JPEGErrorHandler2(j_common_ptr cinfo, int msg_level);
 static Eina_Bool _get_next_app0(unsigned char *map, size_t fsize, size_t 
*position);
-static Eina_Bool _get_orientation_app1(unsigned char *map, size_t fsize, 
size_t *position, int *orientation);
-static int _get_orientation(void *map, size_t length);
+static Eina_Bool _get_orientation_app1(unsigned char *map, size_t fsize, 
size_t *position,
+                                       int *orientation, Eina_Bool *flipped);
+static int _get_orientation(void *map, size_t length, Eina_Bool *flipped);
 
 #if 0 /* not used at the moment */
 static int evas_image_load_file_data_jpeg_alpha_internal(Image_Entry *ie, FILE 
*f) EINA_ARG_NONNULL(1, 2);
@@ -218,7 +219,8 @@ _get_next_app0(unsigned char *map, size_t fsize, size_t 
*position)
  */
 
 static Eina_Bool
-_get_orientation_app1(unsigned char *map, size_t fsize, size_t *position, int 
*orientation_res)
+_get_orientation_app1(unsigned char *map, size_t fsize, size_t *position,
+                      int *orientation_res, Eina_Bool *flipped)
 {
    unsigned char *app1_head, *buf;
    unsigned char orientation[2];
@@ -279,20 +281,37 @@ _get_orientation_app1(unsigned char *map, size_t fsize, 
size_t *position, int *o
              switch (direction)
                {
                 case 3:
+                  *orientation_res = 180;
+                  *flipped = EINA_FALSE;
+                  return EINA_TRUE;
                 case 4:
-                   *orientation_res = 180;
-                   return EINA_TRUE;
+                  *orientation_res = 180;
+                  *flipped = EINA_TRUE;
+                  return EINA_TRUE;
                 case 6:
+                  *orientation_res = 90;
+                  *flipped = EINA_FALSE;
+                  return EINA_TRUE;
                 case 7:
-                   *orientation_res = 90;
-                   return EINA_TRUE;
+                  *orientation_res = 90;
+                  *flipped = EINA_TRUE;
+                  return EINA_TRUE;
                 case 5:
+                  *orientation_res = 270;
+                  *flipped = EINA_TRUE;
+                  return EINA_TRUE;
                 case 8:
-                   *orientation_res = 270;
-                   return EINA_TRUE;
+                  *orientation_res = 270;
+                  *flipped = EINA_FALSE;
+                  return EINA_TRUE;
+                case 2:
+                  *orientation_res = 0;
+                  *flipped = EINA_TRUE;
+                  return EINA_TRUE;
                 default:
-                   *orientation_res = 0;
-                   return EINA_TRUE;
+                  *orientation_res = 0;
+                  *flipped = EINA_FALSE;
+                  return EINA_TRUE;
                }
           }
         else
@@ -302,13 +321,15 @@ _get_orientation_app1(unsigned char *map, size_t fsize, 
size_t *position, int *o
 }
 
 static int
-_get_orientation(void *map, size_t length)
+_get_orientation(void *map, size_t length, Eina_Bool *flipped)
 {
    unsigned char *buf;
    size_t position = 0;
    int orientation = -1;
    Eina_Bool res = EINA_FALSE;
 
+   *flipped = EINA_FALSE;
+
    /* open file and get 22 byte frome file */
    if (!map) return 0;
    /* 1. read 22byte */
@@ -326,7 +347,7 @@ _get_orientation(void *map, size_t length)
           }
         else if (!memcmp(buf + position, App1, sizeof (App1)))
           {
-             res = _get_orientation_app1(map, length, &position, &orientation);
+             res = _get_orientation_app1(map, length, &position, &orientation, 
flipped);
              if (!res) break;
              if (orientation != -1) return orientation;
           }
@@ -335,10 +356,69 @@ _get_orientation(void *map, size_t length)
    return 0;
 }
 
+static void
+_rotate_region(unsigned int *r_x, unsigned int *r_y, unsigned int *r_w, 
unsigned int *r_h,
+               unsigned int x, unsigned int y, unsigned int w, unsigned int h,
+               unsigned int output_w, unsigned int output_h,
+               int degree, Eina_Bool flipped)
+{
+   switch (degree)
+     {
+      case 90:
+        if (flipped)
+          {
+             *r_x = output_w - (y + h);
+             *r_y = output_h - (x + w);
+             *r_w = h;
+             *r_h = w;
+          }
+        else
+          {
+             *r_x = y;
+             *r_y = output_h - (x + y);
+             *r_w = h;
+             *r_h = w;
+          }
+        break;
+      case 180:
+        if (flipped)
+          {
+             *r_y = output_h - (y + h);
+          }
+        else
+          {
+             *r_x = output_w - (x + w);
+             *r_y = output_h - (y + h);
+          }
+        break;
+      case 270:
+        if (flipped)
+          {
+             *r_x = y;
+             *r_y = x;
+             *r_w = h;
+             *r_h = w;
+          }
+        else
+          {
+             *r_x = output_w - (y + h);
+             *r_y = x;
+             *r_w = h;
+             *r_h = w;
+          }
+        break;
+      default:
+        if (flipped)
+           *r_x = output_w - (x + w);
+        break;
+     }
+}
+
 static Eina_Bool
 evas_image_load_file_head_jpeg_internal(unsigned int *w, unsigned int *h,
                                         unsigned char *scale,
                                         unsigned char *rotated,
+                                        Eina_Bool *flipped,
                                         Evas_Image_Load_Opts *opts,
                                         void *map, size_t length,
                                         int *error)
@@ -388,8 +468,8 @@ evas_image_load_file_head_jpeg_internal(unsigned int *w, 
unsigned int *h,
    /* rotation decoding */
    if (opts->orientation)
      {
-        degree = _get_orientation(map, length);
-        if (degree != 0)
+        degree = _get_orientation(map, length, flipped);
+        if (degree != 0 || *flipped)
           {
              opts->degree = degree;
             *rotated = EINA_TRUE;
@@ -522,29 +602,9 @@ evas_image_load_file_head_jpeg_internal(unsigned int *w, 
unsigned int *h,
              load_region_w = opts->region.w;
              load_region_h = opts->region.h;
 
-             switch (degree)
-               {
-                case 90:
-                   opts->region.x = load_region_y;
-                   opts->region.y = *h - (load_region_x + load_region_w);
-                   opts->region.w = load_region_h;
-                   opts->region.h = load_region_w;
-                   break;
-                case 180:
-                   opts->region.x = *w - (load_region_x+ load_region_w);
-                   opts->region.y = *h - (load_region_y + load_region_h);
-
-                   break;
-                case 270:
-                   opts->region.x = *w - (load_region_y + load_region_h);
-                   opts->region.y = load_region_x;
-                   opts->region.w = load_region_h;
-                   opts->region.h = load_region_w;
-                   break;
-                default:
-                   break;
-               }
-
+             _rotate_region(&opts->region.x, &opts->region.y, &opts->region.w, 
&opts->region.h,
+                            load_region_x, load_region_y, load_region_w, 
load_region_h,
+                            *w, *h, degree, *flipped);
           }
         RECTS_CLIP_TO_RECT(opts->region.x, opts->region.y,
                            opts->region.w, opts->region.h,
@@ -592,6 +652,88 @@ get_time(void)
 }
 */
 
+static void
+_rotate_180(DATA32 *data, int w, int h)
+{
+   DATA32 *p1, *p2;
+   DATA32 pt;
+   int x;
+
+   p1 = data;
+   p2 = data + (h * w) - 1;
+   for (x = (w * h) / 2; --x >= 0;)
+     {
+        pt = *p1;
+        *p1 = *p2;
+        *p2 = pt;
+        p1++;
+        p2--;
+     }
+}
+
+static void
+_flip_horizontal(DATA32 *data, int w, int h)
+{
+   DATA32 *p1, *p2;
+   DATA32 pt;
+   int x, y;
+
+   for (y = 0; y < h; y++)
+     {
+        p1 = data + (y * w);
+        p2 = data + ((y + 1) * w) - 1;
+        for (x = 0; x < (w >> 1); x++)
+          {
+             pt = *p1;
+             *p1 = *p2;
+             *p2 = pt;
+             p1++;
+             p2--;
+          }
+     }
+}
+
+static void
+_flip_vertical(DATA32 *data, int w, int h)
+{
+   DATA32 *p1, *p2;
+   DATA32 pt;
+   int x, y;
+
+   for (y = 0; y < (h >> 1); y++)
+     {
+        p1 = data + (y * w);
+        p2 = data + ((h - 1 - y) * w);
+        for (x = 0; x < w; x++)
+          {
+             pt = *p1;
+             *p1 = *p2;
+             *p2 = pt;
+             p1++;
+             p2++;
+          }
+     }
+}
+
+static void
+_rotate_change_wh(DATA32 *to, DATA32 *from,
+                  int w, int h,
+                  int dx, int dy)
+{
+   int x, y;
+
+   for (x = h; --x >= 0;)
+     {
+        for (y = w; --y >= 0;)
+          {
+             *to = *from;
+             from++;
+             to += dy;
+          }
+        to += dx;
+     }
+}
+
 static Eina_Bool
 evas_image_load_file_data_jpeg_internal(Evas_Image_Load_Opts *opts,
                                         Evas_Image_Property *prop,
@@ -705,29 +847,9 @@ 
evas_image_load_file_data_jpeg_internal(Evas_Image_Load_Opts *opts,
              load_region_w = opts->region.w;
              load_region_h = opts->region.h;
 
-             switch (degree)
-               {
-                case 90:
-                   opts->region.x = load_region_y;
-                   opts->region.y = h - (load_region_x + load_region_w);
-                   opts->region.w = load_region_h;
-                   opts->region.h = load_region_w;
-                   break;
-                case 180:
-                   opts->region.x = w - (load_region_x+ load_region_w);
-                   opts->region.y = h - (load_region_y + load_region_h);
-
-                   break;
-                case 270:
-                   opts->region.x = w - (load_region_y + load_region_h);
-                   opts->region.y = load_region_x;
-                   opts->region.w = load_region_h;
-                   opts->region.h = load_region_w;
-                   break;
-                default:
-                   break;
-               }
-
+             _rotate_region(&opts->region.x, &opts->region.y, &opts->region.w, 
&opts->region.h,
+                            load_region_x, load_region_y, load_region_w, 
load_region_h,
+                            w, h, degree, prop->flipped);
           }
 #ifdef BUILD_LOADER_JPEG_REGION
         cinfo.region_x = opts->region.x;
@@ -1076,61 +1198,36 @@ done:
 
    if (prop->rotated)
      {
-        DATA32 *data1, *data2, *to, *from;
-        int lx, ly, lw, lh, hw;
+        DATA32 *to;
+        int hw;
 
-        lw = w;
-        lh = h;
-        hw = lw * lh;
+        hw = w * h;
+        to = pixels;
 
-        data1 = pixels;
-
-        if (degree == 180)
+        switch (degree)
           {
-             DATA32 tmpd;
-
-             data2 = data1 + (lh * lw) -1;
-             for (lx = (lw * lh) / 2; --lx >= 0;)
-               {
-                  tmpd = *data1;
-                  *data1 = *data2;
-                  *data2 = tmpd;
-                  data1++;
-                  data2--;
-               }
-          }
-        else
-          {
-             data2 = NULL;
-             to = NULL;
-             if (ptr_rotate) data2 = ptr_rotate;
-
-             if (degree == 90)
-               {
-                  to = data1 + lh - 1;
-                  hw = -hw - 1;
-               }
-             else if (degree == 270)
-               {
-                  to = data1 + hw - lh;
-                  lh = -lh;
-                  hw = hw + 1;
-               }
-
-             if (to)
-               {
-                  from = data2;
-                  for (lx = h; --lx >= 0;)
-                    {
-                       for (ly = w; --ly >= 0;)
-                         {
-                            *to = *from;
-                            from++;
-                            to += lh;
-                         }
-                       to += hw;
-                    }
-               }
+           case 90:
+             if (prop->flipped)
+               _rotate_change_wh(to + hw - 1, ptr_rotate, w, h, hw - 1, -h);
+             else
+               _rotate_change_wh(to + h - 1, ptr_rotate, w, h, -hw - 1, h);
+             break;
+           case 180:
+             if (prop->flipped)
+               _flip_vertical(to, w, h);
+             else
+               _rotate_180(to, w, h);
+             break;
+           case 270:
+             if (prop->flipped)
+               _rotate_change_wh(to, ptr_rotate, w, h, -hw + 1, h);
+             else
+               _rotate_change_wh(to + hw - h, ptr_rotate, w, h, hw + 1, -h);
+             break;
+           default:
+             if (prop->flipped)
+               _flip_horizontal(to, w, h);
+             break;
           }
         if (ptr_rotate)
           {
@@ -1317,8 +1414,9 @@ evas_image_load_file_head_jpeg(void *loader_data,
      }
 
    val = evas_image_load_file_head_jpeg_internal(&prop->w, &prop->h,
-                                                &prop->scale, &prop->rotated,
-                                                opts,
+                                                 &prop->scale, &prop->rotated,
+                                                 &prop->flipped,
+                                                 opts,
                                                  map, eina_file_size_get(f),
                                                  error);
 

-- 


Reply via email to