png: prototype colormap load 87/175387/7
authorJaeun Choi <jaeun12.choi@samsung.com>
Thu, 10 May 2018 09:23:58 +0000 (18:23 +0900)
committerGerrit Code Review <gerrit@review.ap-northeast-2.compute.internal>
Mon, 22 Oct 2018 09:40:53 +0000 (09:40 +0000)
Change-Id: I8588e855a00b54ac3766c97fdc4565f47b104b65

12 files changed:
src/lib/efl/interfaces/efl_gfx_types.eot
src/lib/emile/emile_image.h
src/lib/evas/Evas_Loader.h
src/lib/evas/cache/evas_cache_image.c
src/lib/evas/canvas/evas_image_private.h
src/lib/evas/canvas/evas_object_image.c
src/lib/evas/common/evas_image_data.c
src/lib/evas/common/evas_image_load.c
src/lib/evas/common/evas_image_main.c
src/lib/evas/include/evas_common_private.h
src/modules/evas/engines/gl_generic/evas_engine.c
src/modules/evas/image_loaders/png/evas_image_load_png.c

index 8f8292c..d883a46 100644 (file)
@@ -20,7 +20,8 @@ enum Efl.Gfx.Colorspace {
   rgba_s3tc_dxt2 = 15,  [[DirectDraw DXT2 format with premultiplied RGBA. Not supported by OpenGL itself. @since 1.11.]]
   rgba_s3tc_dxt3 = 16,  [[OpenGL COMPRESSED_RGBA_S3TC_DXT3_EXT format with RGBA. @since 1.11.]]
   rgba_s3tc_dxt4 = 17,  [[DirectDraw DXT4 format with premultiplied RGBA. Not supported by OpenGL itself. @since 1.11.]]
-  rgba_s3tc_dxt5 = 18   [[OpenGL COMPRESSED_RGBA_S3TC_DXT5_EXT format with RGBA. @since 1.11.]]
+  rgba_s3tc_dxt5 = 18,  [[OpenGL COMPRESSED_RGBA_S3TC_DXT5_EXT format with RGBA. @since 1.11.]]
+  palette
 }
 
 enum Efl.Gfx.Render_Op {
index 3c1c6f2..b39dc11 100644 (file)
@@ -168,11 +168,21 @@ struct _Emile_Image_Property
     unsigned char l, r, t, b;
   } borders;
 
+  struct
+    {
+       unsigned char red;
+       unsigned char green;
+       unsigned char blue;
+       unsigned char alpha;
+    } palette[256];
+
   const Emile_Colorspace *cspaces;
   Emile_Colorspace cspace;
 
   Emile_Image_Encoding encoding;
 
+  int num_palette;
+
   unsigned int w;
   unsigned int h;
   unsigned int row_stride;
@@ -220,6 +230,7 @@ struct _Emile_Image_Load_Opts
   int scale_down_by;
 
   Eina_Bool orientation;
+  Eina_Bool can_load_colormap;
 };
 
 // FIXME: should we set region at load time, instead of head time
index 5dbbab9..1788f05 100644 (file)
@@ -184,6 +184,7 @@ typedef Efl_Gfx_Colorspace Evas_Colorspace; /**< Colorspaces for pixel data supp
 #define EVAS_COLORSPACE_RGBA_S3TC_DXT3 EFL_GFX_COLORSPACE_RGBA_S3TC_DXT3
 #define EVAS_COLORSPACE_RGBA_S3TC_DXT4 EFL_GFX_COLORSPACE_RGBA_S3TC_DXT4
 #define EVAS_COLORSPACE_RGBA_S3TC_DXT5 EFL_GFX_COLORSPACE_RGBA_S3TC_DXT5
+#define EVAS_COLORSPACE_PALETTE EFL_GFX_COLORSPACE_PALETTE
 
 struct _Evas_Image_Load_Func
 {
index 3c42443..1971bdb 100644 (file)
@@ -687,6 +687,7 @@ static const Evas_Image_Load_Opts prevent = {
       0,
       0,
 
+      EINA_FALSE,
       EINA_FALSE
    },
    EINA_FALSE
@@ -704,7 +705,8 @@ _evas_cache_image_loadopts_append(char *hkey, Evas_Image_Load_Opts **plo)
            (EINA_DBL_EQ(lo->emile.dpi, 0.0)) &&
            ((lo->emile.w == 0) || (lo->emile.h == 0)) &&
            ((lo->emile.region.w == 0) || (lo->emile.region.h == 0)) &&
-           (lo->emile.orientation == 0)
+           (lo->emile.orientation == 0) &&
+           (lo->emile.can_load_colormap == 0)
        ))
      {
         *plo = (Evas_Image_Load_Opts*) &prevent;
@@ -743,6 +745,27 @@ _evas_cache_image_loadopts_append(char *hkey, Evas_Image_Load_Opts **plo)
              hkey[offset] = 'o';
              offset += 1;
           }
+        else
+          {
+             hkey[offset] = '/';
+             offset += 1;
+             hkey[offset] = 'x';
+             offset += 1;
+          }
+        if (lo->emile.can_load_colormap)
+          {
+             hkey[offset] = '/';
+             offset += 1;
+             hkey[offset] = 'o';
+             offset += 1;
+          }
+        else
+          {
+             hkey[offset] = '/';
+             offset += 1;
+             hkey[offset] = 'x';
+             offset += 1;
+          }
      }
    hkey[offset] = '\0';
 
index 94d5726..9ba1303 100755 (executable)
@@ -48,6 +48,7 @@ struct _Evas_Object_Image_Load_Opts
       int scale_hint;
    } scale_load;
    Eina_Bool  orientation : 1;
+   Eina_Bool  can_load_colormap : 1;
 };
 
 struct _Evas_Object_Image_Pixels
index cf6c7b5..dfc24ab 100755 (executable)
@@ -222,7 +222,15 @@ _efl_canvas_image_internal_efl_object_constructor(Eo *eo_obj, Evas_Image_Data *o
    o->prev = eina_cow_alloc(evas_object_image_state_cow);
    o->proxy_src_clip = EINA_TRUE;
 
+   if (!strcmp(obj->layer->evas->engine.module->definition->name, "wayland_egl"))
+     {
+        EINA_COW_LOAD_OPTS_WRITE_BEGIN(o, low)
+           low->can_load_colormap = EINA_TRUE;
+        EINA_COW_LOAD_OPTS_WRITE_END(o, low)
+     }
+
    cspace = ENFN->image_colorspace_get(ENC, o->engine_data);
+
    if (cspace != o->cur->cspace)
      {
         EINA_COW_IMAGE_STATE_WRITE_BEGIN(o, state_write)
@@ -301,6 +309,7 @@ _evas_image_init_set(const Eina_File *f, const char *key,
    lo->emile.scale_load.scale_hint = o->load_opts->scale_load.scale_hint;
    lo->emile.orientation = o->load_opts->orientation;
    lo->emile.degree = 0;
+   lo->emile.can_load_colormap = o->load_opts->can_load_colormap;
    lo->skip_head = o->skip_head;
 }
 
@@ -1176,6 +1185,7 @@ _evas_image_load(Evas_Object *eo_obj, Evas_Object_Protected_Data *obj, Evas_Imag
    lo.emile.scale_load.scale_hint = o->load_opts->scale_load.scale_hint;
    lo.emile.orientation = o->load_opts->orientation;
    lo.emile.degree = 0;
+   lo.emile.can_load_colormap = o->load_opts->can_load_colormap;
    lo.skip_head = o->skip_head;
    o->engine_data = ENFN->image_mmap(ENC, o->cur->f, o->cur->key, &o->load_error, &lo);
 
index ad348f4..910edb4 100644 (file)
@@ -170,6 +170,7 @@ evas_common_rgba_image_colorspace_set(Image_Entry* ie, Evas_Colorspace cspace)
       case EVAS_COLORSPACE_ARGB8888:
       case EVAS_COLORSPACE_AGRY88:
       case EVAS_COLORSPACE_GRY8:
+      case EVAS_COLORSPACE_PALETTE:
         // all good
         break;
       case EVAS_COLORSPACE_ETC1:
index 7d4ca66..2d29aeb 100644 (file)
@@ -178,6 +178,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
 {
    Evas_Image_Load_Func *evas_image_load_func = NULL;
    Eina_Bool r = EINA_TRUE;
+   int i;
 
    if (!evas_module_load(em)) goto load_error;
    evas_image_load_func = em->functions;
@@ -226,6 +227,24 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
              if (property.cspaces) ie->cspaces = property.cspaces;
              ie->flags.rotated = property.rotated;
              ie->flags.flipped = property.flipped;
+             ie->num_palette = property.num_palette;
+
+             for (i = 0; i < ie->num_palette; i++)
+               {
+                  ie->palette[i].red = property.palette[i].red;
+                  ie->palette[i].green = property.palette[i].green;
+                  ie->palette[i].blue = property.palette[i].blue;
+                  ie->palette[i].alpha = property.palette[i].alpha;
+#if 0
+                  ERR("[%d] %d %d %d %d", i,
+                      ie->palette[i].red,
+                      ie->palette[i].green,
+                      ie->palette[i].blue,
+                      ie->palette[i].alpha
+                     );
+#endif
+               }
+
              r = EINA_FALSE;
           }
         else
index f99e76a..012cb96 100644 (file)
@@ -109,6 +109,7 @@ _evas_common_rgba_image_surface_size(unsigned int w, unsigned int h,
 
    switch (cspace)
      {
+      case EVAS_COLORSPACE_PALETTE:
       case EVAS_COLORSPACE_GRY8: siz = w * h * sizeof(DATA8); break;
       case EVAS_COLORSPACE_AGRY88: siz = w * h * sizeof(DATA16); break;
       case EVAS_COLORSPACE_RGBA8_ETC2_EAC:
index c666fb3..2598bbe 100755 (executable)
@@ -656,6 +656,14 @@ struct _Image_Entry
         Evas_Image_Load_Func *loader;
      } info;
 
+   struct
+     {
+        DATA8 red;
+        DATA8 green;
+        DATA8 blue;
+        DATA8 alpha;
+     } palette[256];
+
    SLK(lock);
    SLK(lock_cancel);
 
@@ -673,6 +681,7 @@ struct _Image_Entry
    int                    connect_num;
    int                    channel;
    int                    load_error;
+   int                    num_palette;
 };
 
 struct _Engine_Image_Entry
index a8c3859..60ca877 100755 (executable)
@@ -332,6 +332,7 @@ eng_image_colorspace_set(void *engine, void *image, Evas_Colorspace cspace)
    evas_gl_common_image_alloc_ensure(im);
    switch (cspace)
      {
+      case EVAS_COLORSPACE_PALETTE:
       case EVAS_COLORSPACE_ARGB8888:
          evas_cache_image_colorspace(&im->im->cache_entry, cspace);
          if (im->cs.data)
index e7ac88b..8df0dcf 100644 (file)
@@ -93,8 +93,11 @@ evas_image_load_file_head_png(void *loader_data,
    png_infop info_ptr = NULL;
    png_uint_32 w32, h32;
    int bit_depth, color_type, interlace_type;
+   int num_trans;
    volatile char hasa;
    volatile Eina_Bool r = EINA_FALSE;
+   png_colorp palette;
+   png_bytep trans;
 
    opts = loader->opts;
    f = loader->f;
@@ -204,6 +207,32 @@ evas_image_load_file_head_png(void *loader_data,
       case PNG_COLOR_TYPE_GRAY:
          if (!hasa) prop->cspaces = cspace_grey;
          break;
+      case PNG_COLOR_TYPE_PALETTE:
+         if (!opts->emile.can_load_colormap) break;
+         if (png_get_PLTE(png_ptr, info_ptr, &palette, &prop->num_palette)
+             != PNG_INFO_PLTE)
+           {
+              *error = EVAS_LOAD_ERROR_GENERIC;
+              goto close_file;
+           }
+         int i;
+         for (i = 0; i < prop->num_palette; i++)
+           {
+              prop->palette[i].red = palette[i].red;
+              prop->palette[i].green = palette[i].green;
+              prop->palette[i].blue = palette[i].blue;
+              prop->palette[i].alpha = 0xff;
+           }
+         if (png_get_tRNS(png_ptr, info_ptr, &trans, &num_trans, NULL)
+             == PNG_INFO_tRNS)
+           {
+              for (i = 0; i < num_trans; i++)
+                {
+                   prop->palette[i].alpha = trans[i];
+                }
+           }
+
+         break;
      }
    if (hasa) prop->alpha = 1;
 
@@ -325,7 +354,8 @@ evas_image_load_file_data_png(void *loader_data,
      }
 
    surface = pixels;
-   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS))
+   if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)
+       && !((color_type == PNG_COLOR_TYPE_PALETTE) && opts->emile.can_load_colormap))
      {
         /* expand transparency entry -> alpha channel if present */
         png_set_tRNS_to_alpha(png_ptr);
@@ -337,7 +367,8 @@ evas_image_load_file_data_png(void *loader_data,
 
    /* Prep for transformations...  ultimately we want ARGB */
    /* expand palette -> RGB if necessary */
-   if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr);
+   if ((color_type == PNG_COLOR_TYPE_PALETTE) && !opts->emile.can_load_colormap)
+     png_set_palette_to_rgb(png_ptr);
    /* expand gray (w/reduced bits) -> 8-bit RGB if necessary */
    if ((color_type == PNG_COLOR_TYPE_GRAY) ||
        (color_type == PNG_COLOR_TYPE_GRAY_ALPHA))
@@ -378,9 +409,13 @@ evas_image_load_file_data_png(void *loader_data,
          pack_offset = sizeof(DATA16);
          break;
       case EVAS_COLORSPACE_GRY8: pack_offset = sizeof(DATA8); break;
+      case EVAS_COLORSPACE_PALETTE: break;
       default: abort();
      }
 
+   if ((color_type == PNG_COLOR_TYPE_PALETTE) && opts->emile.can_load_colormap)
+     pack_offset = sizeof(DATA8);
+
    passes = png_set_interlace_handling(png_ptr);
    
    /* we read image line by line if scale down was set */