From: Jiyoun Park <jy0703.park@samsung.com>
authorraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 19 Oct 2011 09:04:34 +0000 (09:04 +0000)
committerraster <raster@7cbeb6ba-43b4-40fd-8cce-4c39aea84d33>
Wed, 19 Oct 2011 09:04:34 +0000 (09:04 +0000)
Subject: [E-devel] [Patch] Add scale down decoding feature to evas png loader

I add scale down decoding feature to evas png loader. 5515X3986 size png image need 80~90M memory,
but scale down(scale num=2) option can reduce memory to 25~30M.

I use down sample method for scale down.
(there is more efficient algorithm for scale down, I'll add this to my
todo list)

git-svn-id: http://svn.enlightenment.org/svn/e/trunk/evas@64170 7cbeb6ba-43b4-40fd-8cce-4c39aea84d33

src/modules/loaders/png/evas_image_load_png.c

index c4a907a..a1480ae 100644 (file)
@@ -107,8 +107,21 @@ evas_image_load_file_head_png(Image_Entry *ie, const char *file, const char *key
          *error = EVAS_LOAD_ERROR_GENERIC;
        goto close_file;
      }
-   ie->w = (int) w32;
-   ie->h = (int) h32;
+   if (ie->load_opts.scale_down_by > 1)
+     {
+        ie->w = (int) w32 / ie->load_opts.scale_down_by;
+        ie->h = (int) h32 / ie->load_opts.scale_down_by;
+        if ((ie->w < 1) || (ie->h < 1))
+          {
+             *error = EVAS_LOAD_ERROR_GENERIC;
+             goto close_file;
+          }
+     }
+   else
+     {
+        ie->w = (int) w32;
+        ie->h = (int) h32;
+     }
    if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS)) hasa = 1;
    if (color_type == PNG_COLOR_TYPE_RGB_ALPHA) hasa = 1;
    if (color_type == PNG_COLOR_TYPE_GRAY_ALPHA) hasa = 1;
@@ -137,7 +150,10 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
    unsigned char buf[PNG_BYTES_TO_CHECK];
    unsigned char **lines;
    char hasa;
-   int i;
+   int i, j;
+   int scale_ratio = 1, image_w = 0;
+   unsigned char *tmp_line;
+   DATA32 *src_ptr, *dst_ptr;
 
    hasa = 0;
    f = E_FOPEN(file, "rb");
@@ -184,6 +200,13 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
    png_get_IHDR(png_ptr, info_ptr, (png_uint_32 *) (&w32),
                (png_uint_32 *) (&h32), &bit_depth, &color_type,
                &interlace_type, NULL, NULL);
+   image_w = w32;
+   if (ie->load_opts.scale_down_by > 1)
+     {
+        scale_ratio = ie->load_opts.scale_down_by;
+        w32 /= scale_ratio;
+        h32 /= scale_ratio;
+     }
    evas_cache_image_surface_alloc(ie, w32, h32);
    surface = (unsigned char *) evas_cache_image_pixels(ie);
    if (!surface)
@@ -231,12 +254,37 @@ evas_image_load_file_data_png(Image_Entry *ie, const char *file, const char *key
    png_set_bgr(png_ptr);
    if (!hasa) png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
 #endif
-   lines = (unsigned char **) alloca(h * sizeof(unsigned char *));
 
-   for (i = 0; i < h; i++)
-     lines[i] = surface + (i * w * sizeof(DATA32));
-   png_read_image(png_ptr, lines);
-   png_read_end(png_ptr, info_ptr);
+   /* we read image line by line if scale down was set */
+   if (scale_ratio == 1)
+     {
+        lines = (unsigned char **) alloca(h * sizeof(unsigned char *));
+        for (i = 0; i < h; i++)
+          lines[i] = surface + (i * w * sizeof(DATA32));
+        png_read_image(png_ptr, lines);
+        png_read_end(png_ptr, info_ptr);
+     }
+   else
+     {
+        tmp_line = (unsigned char *) alloca(image_w * sizeof(DATA32));
+        dst_ptr = (DATA32 *)surface;
+        for (i = 0; i < h; i++)
+          {
+             png_read_row(png_ptr, tmp_line, NULL);
+             src_ptr = (DATA32 *)tmp_line;
+             for (j = 0; j < w; j++)
+               {
+                  *dst_ptr = *src_ptr;
+                  dst_ptr++;
+                  src_ptr += scale_ratio;
+               }
+             for (j = 0; j < (scale_ratio - 1); j++)
+               {
+                  png_read_row(png_ptr, tmp_line, NULL);
+               }
+          }
+     }
+
    png_destroy_read_struct(&png_ptr, &info_ptr, NULL);
    E_FCLOSE(f);
    evas_common_image_premul(ie);