From 0028add9c642352115ba1f2a1117598e77d6859c Mon Sep 17 00:00:00 2001 From: Jiyoun Park Date: Wed, 19 Oct 2011 09:04:34 +0000 Subject: [PATCH] From: Jiyoun Park 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) SVN revision: 64170 --- .../modules/loaders/png/evas_image_load_png.c | 64 ++++++++++++++++--- 1 file changed, 56 insertions(+), 8 deletions(-) diff --git a/legacy/evas/src/modules/loaders/png/evas_image_load_png.c b/legacy/evas/src/modules/loaders/png/evas_image_load_png.c index c4a907a27a..a1480ae4bf 100644 --- a/legacy/evas/src/modules/loaders/png/evas_image_load_png.c +++ b/legacy/evas/src/modules/loaders/png/evas_image_load_png.c @@ -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);