fix recent png loader break with etc1 support that broke interlaced imgs

this fixes the png loader code to use png_read_row properly with the
number of passes needed to load aninterlaced image as well as handling
this right with scale ratio scaledown set.
This commit is contained in:
Carsten Haitzler 2014-04-15 17:56:07 +09:00
parent 0cc713b765
commit 9e100627a7
1 changed files with 50 additions and 16 deletions

View File

@ -218,9 +218,9 @@ evas_image_load_file_data_png(void *loader_data,
unsigned int pack_offset; unsigned int pack_offset;
int w, h; int w, h;
int bit_depth, color_type, interlace_type; int bit_depth, color_type, interlace_type;
char hasa; char hasa, passes;
int i, j; int i, j, p, k;
int scale_ratio = 1, image_w = 0; int scale_ratio = 1, image_w = 0, image_h = 0;
Eina_Bool r = EINA_FALSE; Eina_Bool r = EINA_FALSE;
opts = loader->opts; opts = loader->opts;
@ -278,6 +278,7 @@ evas_image_load_file_data_png(void *loader_data,
(png_uint_32 *) (&h32), &bit_depth, &color_type, (png_uint_32 *) (&h32), &bit_depth, &color_type,
&interlace_type, NULL, NULL); &interlace_type, NULL, NULL);
image_w = w32; image_w = w32;
image_h = h32;
if (opts->scale_down_by > 1) if (opts->scale_down_by > 1)
{ {
scale_ratio = opts->scale_down_by; scale_ratio = opts->scale_down_by;
@ -348,34 +349,67 @@ evas_image_load_file_data_png(void *loader_data,
default: abort(); default: abort();
} }
passes = png_set_interlace_handling(png_ptr);
/* we read image line by line if scale down was set */ /* we read image line by line if scale down was set */
if (scale_ratio == 1) if (scale_ratio == 1)
{
for (p = 0; p < passes; p++)
{ {
for (i = 0; i < h; i++) for (i = 0; i < h; i++)
png_read_row(png_ptr, surface + (i * w * pack_offset), NULL); png_read_row(png_ptr, surface + (i * w * pack_offset), NULL);
}
png_read_end(png_ptr, info_ptr); png_read_end(png_ptr, info_ptr);
} }
else else
{ {
unsigned char *src_ptr, *dst_ptr; unsigned char *src_ptr, *dst_ptr;
tmp_line = (unsigned char *) alloca(image_w * pack_offset);
dst_ptr = surface; dst_ptr = surface;
if (passes == 1)
{
tmp_line = (unsigned char *) alloca(image_w * pack_offset);
for (i = 0; i < h; i++) for (i = 0; i < h; i++)
{ {
png_read_row(png_ptr, tmp_line, NULL); png_read_row(png_ptr, tmp_line, NULL);
src_ptr = tmp_line; src_ptr = tmp_line;
for (j = 0; j < w; j++) for (j = 0; j < w; j++)
{ {
*dst_ptr = *src_ptr; for (k = 0; k < (int)pack_offset; k++)
dst_ptr[k] = src_ptr[k];
dst_ptr += pack_offset; dst_ptr += pack_offset;
src_ptr += scale_ratio * pack_offset; src_ptr += scale_ratio * pack_offset;
} }
for (j = 0; j < (scale_ratio - 1); j++) for (j = 0; j < (scale_ratio - 1); j++)
{
png_read_row(png_ptr, tmp_line, NULL); png_read_row(png_ptr, tmp_line, NULL);
} }
} }
else
{
unsigned char *pixels2 = malloc(image_w * image_h * pack_offset);
if (pixels2)
{
for (p = 0; p < passes; p++)
{
for (i = 0; i < image_h; i++)
png_read_row(png_ptr, pixels2 + (i * image_w * pack_offset), NULL);
}
for (i = 0; i < h; i++)
{
src_ptr = pixels2 + (i * scale_ratio * image_w * pack_offset);
for (j = 0; j < w; j++)
{
for (k = 0; k < (int)pack_offset; k++)
dst_ptr[k] = src_ptr[k];
src_ptr += scale_ratio * pack_offset;
dst_ptr += pack_offset;
}
}
free(pixels2);
}
}
} }
prop->premul = EINA_TRUE; prop->premul = EINA_TRUE;