From: Jiyoun Park <jy0703.park@samsung.com>

Subject: Re: [E-devel] [Patch] Implement scale down decoding feature of bmp loader

I implement scale down decoding feature of bmp loader using down sample algorithm.
Desktop have low risk to go wrong memory problem during big image decoding, 
but mobile device is different.

Raster said it is life (meet memory problem during big image decoding),
and it is enough to return decoding fail.

But I think it seems a bit harsh, because 2 or 3 bmp image (5000X5000 size: for example) 
can cause application close because of memory lack.   



SVN revision: 64163
This commit is contained in:
Jiyoun Park 2011-10-19 06:36:28 +00:00 committed by Carsten Haitzler
parent eca175dbe5
commit a1e7fa3103
1 changed files with 507 additions and 199 deletions

View File

@ -8,6 +8,8 @@
# include <Evil.h>
#endif
#include <math.h>
#include "evas_common.h"
#include "evas_private.h"
@ -259,7 +261,14 @@ evas_image_load_file_head_bmp(Image_Entry *ie, const char *file, const char *key
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
/* It is not bad idea that bmp loader support scale down decoding
* because of memory issue in mobile world.*/
if (ie->load_opts.scale_down_by > 1)
{
w /= ie->load_opts.scale_down_by;
h /= ie->load_opts.scale_down_by;
}
if (bit_count < 16)
{
if ((palette_size < 0) || (palette_size > 256)) pal_num = 256;
@ -345,7 +354,14 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
int fsize = 0;
unsigned int bmpsize;
unsigned short res1, res2;
/* for scale decoding */
unsigned int *scale_surface = NULL, *scale_pix = NULL;
int scale_ratio = 1, image_w = 0, image_h = 0;
int row_size = 0; /* Row size is rounded up to a multiple of 4bytes */
int read_line = 0; /* total read line */
f = fopen(file, "rb");
if (!f)
{
@ -533,20 +549,40 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
/* It is not bad idea that bmp loader support scale down decoding
* because of memory issue in mobile world. */
if (ie->load_opts.scale_down_by > 1)
scale_ratio = ie->load_opts.scale_down_by;
image_w = w;
image_h = h;
if (scale_ratio > 1)
{
w /= scale_ratio;
h /= scale_ratio;
if ((w < 1) || (h < 1) )
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
}
if ((w != (int)ie->w) || (h != (int)ie->h))
{
*error = EVAS_LOAD_ERROR_GENERIC;
goto close_file;
}
evas_cache_image_surface_alloc(ie, w, h);
evas_cache_image_surface_alloc(ie, ie->w, ie->h);
surface = evas_cache_image_pixels(ie);
if (!surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
row_size = ceil((double)(image_w * bit_count) / 32) * 4;
if (bit_count < 16)
{
unsigned int i;
@ -580,25 +616,52 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
pal[i] = ARGB_JOIN(a, r, g, b);
}
fseek(f, offset, SEEK_SET);
buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
if ((scale_ratio == 1) || (comp !=0))
buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
else
{
scale_surface = malloc(image_w * sizeof(DATA32)); //for one line decoding
if (!scale_surface)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
buffer = malloc(row_size); // scale down is usually set because of memory issue, so read line by line
}
if (!buffer)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
buffer_end = buffer + image_size;
if ((scale_ratio == 1) || (comp !=0))
buffer_end = buffer + image_size;
else
buffer_end = buffer + row_size;
p = buffer;
if (fread(buffer, image_size, 1, f) != 1) goto close_file;
if ((scale_ratio == 1) || (comp !=0))
{
if (fread(buffer, image_size, 1, f) != 1) goto close_file;
}
else
{
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
}
if (bit_count == 1)
{
if (comp == 0) // no compression
{
pix = surface;
for (y = 0; y < h; y++)
{
if (!right_way_up) pix = surface + ((h - 1 - y) * w);
for (x = 0; x < w; x++)
if (scale_ratio > 1) pix = scale_surface; // one line decoding
for (x = 0; x < image_w; x++)
{
if ((x & 0x7) == 0x0)
{
@ -636,10 +699,34 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
if (p >= buffer_end) break;
pix++;
}
if ((x & 0x7) != 0) p++;
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
if (!right_way_up) scale_pix = surface + ((h - 1 - y) * w);
else scale_pix = surface + (y * w);
pix = scale_surface;
for (x = 0; x < w; x++)
{
*scale_pix = *pix;
scale_pix ++;
pix += scale_ratio;
}
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
if ((x & 0x7) != 0) p++;
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
}
else
@ -653,7 +740,8 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
for (y = 0; y < h; y++)
{
if (!right_way_up) pix = surface + ((h - 1 - y) * w);
for (x = 0; x < w; x++)
if (scale_ratio > 1) pix = scale_surface; // one line decoding
for (x = 0; x < image_w; x++)
{
if ((x & 0x1) == 0x1)
{
@ -667,116 +755,184 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
if (p >= buffer_end) break;
pix++;
}
if ((x & 0x1) != 0) p++;
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
if (!right_way_up) scale_pix = surface + ((h - 1 - y) * w);
else scale_pix = surface + (y * w);
pix = scale_surface;
for (x = 0; x < w; x++)
{
*scale_pix = *pix;
scale_pix ++;
pix += scale_ratio;
}
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
if ((x & 0x1) != 0) p++;
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
}
else if (comp == 2) // rle 4bit/pixel
{
int count = 0, done = 0, wpad;
int scale_x = 0, scale_y = 0;
Eina_Bool scale_down_line = EINA_TRUE;
pix = surface;
if (!right_way_up) pix = surface + ((h - 1 - y) * w);
wpad = ((w + 1) / 2) * 2;
wpad = ((image_w + 1) / 2) * 2;
while (p < buffer_end)
{
if (p[0])
{
if ((x + p[0]) <= wpad)
{
unsigned int col1 = pal[p[1] >> 4];
unsigned int col2 = pal[p[1] & 0xf];
count = p[0] / 2;
while (count > 0)
if (scale_down_line)
{
if ((x + p[0]) <= wpad)
{
if (x < w)
unsigned int col1 = pal[p[1] >> 4];
unsigned int col2 = pal[p[1] & 0xf];
count = p[0] / 2;
while (count > 0)
{
pix[0] = col1;
if (x < w)
{
if (((x % scale_ratio) == 0) && (scale_x < w))
{
*pix = col1;
pix++;
scale_x++;
}
x++;
}
if (x < w)
{
if (((x % scale_ratio) == 0) && (scale_x < w))
{
*pix = col2;
pix++;
scale_x++;
}
x++;
}
count--;
}
if (p[0] & 0x1)
{
if (((x % scale_ratio) == 0) && (scale_x < w))
{
*pix = col1;
pix++;
scale_x++;
}
x++;
}
if (x < w)
{
pix[1] = col2;
x++;
}
pix += 2;
count--;
}
if (p[0] & 0x1)
{
*pix = col1;
x++;
pix++;
}
}
}
p += 2;
}
else
{
switch (p[1])
{
case 0: // EOL
x = 0;
y++;
if (!right_way_up)
pix = surface + ((h - 1 - y) * w);
else
pix = surface + (y * w);
if (y >= h)
{
p = buffer_end;
}
p += 2;
break;
case 1: // EOB
p = buffer_end;
break;
case 2: // DELTA
x += p[2];
y += p[3];
if ((x >= w) || (y >= h))
{
p = buffer_end;
}
if (!right_way_up)
pix = surface + x + ((h - 1 - y) * w);
else
pix = surface + x + (y * w);
p += 4;
break;
default:
count = p[1];
if (((p + count) > buffer_end) ||
((x + count) > w))
{
p = buffer_end;
break;
}
p += 2;
done = count;
count /= 2;
while (count > 0)
{
pix[0] = pal[*p >> 4];
pix[1] = pal[*p & 0xf];
pix += 2;
p++;
count--;
}
x += done;
if (done & 0x1)
{
*pix = pal[*p >> 4];
p++;
}
if ((done & 0x3) == 0x1)
p += 2;
else if ((done & 0x3) == 0x2)
p += 1;
break;
case 0: // EOL
x = 0;
scale_x = 0;
y++;
if ((y % scale_ratio) == 0)
{
scale_y++;
scale_down_line = EINA_TRUE;
if (!right_way_up)
pix = surface + ((h - 1 - scale_y) * w);
else
pix = surface + (scale_y * w);
}
else
scale_down_line = EINA_FALSE;
if (scale_y >= h)
{
p = buffer_end;
}
p += 2;
break;
case 1: // EOB
p = buffer_end;
break;
case 2: // DELTA
x += p[2];
y += p[3];
scale_x = x / scale_ratio;
scale_y = y / scale_ratio;
if ((scale_x >= w) || (scale_y >= h))
{
p = buffer_end;
}
if (!right_way_up)
pix = surface + scale_x + ((h - 1 - scale_y) * w);
else
pix = surface + scale_x + (scale_y * w);
p += 4;
break;
default:
count = p[1];
if (((p + count) > buffer_end) ||
((x + count) > w))
{
p = buffer_end;
break;
}
p += 2;
done = count;
count /= 2;
while (count > 0)
{
if (((x % scale_ratio) == 0) && (scale_x < w))
{
*pix = pal[*p >> 4];
pix++;
scale_x++;
}
x++;
if (((x % scale_ratio) == 0) && (scale_x < w))
{
*pix = pal[*p & 0xf];
pix++;
scale_x++;
}
x++;
p++;
count--;
}
if (done & 0x1)
{
if (((x % scale_ratio) == 0) && (scale_x < w))
{
*pix = pal[*p >> 4];
scale_x++;
}
x++;
p++;
}
if ((done & 0x3) == 0x1)
p += 2;
else if ((done & 0x3) == 0x2)
p += 1;
break;
}
}
}
@ -795,93 +951,131 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
for (x = 0; x < w; x++)
{
*pix = pal[*p];
p++;
p += scale_ratio;
if (p >= buffer_end) break;
pix++;
}
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
}
else if (comp == 1) // rle 8bit/pixel
{
int count = 0, done = 0;
int scale_x = 0, scale_y = 0;
Eina_Bool scale_down_line = EINA_TRUE;
pix = surface;
if (!right_way_up) pix = surface + ((h - 1 - y) * w);
while (p < buffer_end)
{
if (p[0])
{
if ((x + p[0]) <= w)
{
unsigned int col = pal[p[1]];
count = p[0];
while (count > 0)
if (scale_down_line)
{
if ((x + p[0]) <= image_w)
{
*pix = col;
pix++;
count--;
unsigned int col = pal[p[1]];
count = p[0];
while (count > 0)
{
if (((x % scale_ratio) == 0) && (scale_x < w))
{
*pix = col;
pix++;
scale_x ++;
}
x++;
count--;
}
}
x += p[0];
}
}
p += 2;
}
else
{
switch (p[1])
{
case 0: // EOL
x = 0;
y++;
if (!right_way_up)
pix = surface + ((h - 1 - y) * w);
else
pix = surface + (y * w);
if (y >= h)
{
p = buffer_end;
}
p += 2;
break;
case 1: // EOB
p = buffer_end;
break;
case 2: // DELTA
x += p[2];
y += p[3];
if ((x >= w) || (y >= h))
{
p = buffer_end;
}
if (!right_way_up)
pix = surface + x + ((h - 1 - y) * w);
else
pix = surface + x + (y * w);
p += 4;
break;
default:
count = p[1];
if (((p + count) > buffer_end) ||
((x + count) > w))
{
p = buffer_end;
break;
}
p += 2;
done = count;
while (count > 0)
{
*pix = pal[*p];
pix++;
p++;
count--;
}
x += done;
if (done & 0x1) p++;
break;
case 0: // EOL
x = 0;
scale_x = 0;
y++;
if ((y % scale_ratio) == 0)
{
scale_y++;
scale_down_line = EINA_TRUE;
if (!right_way_up)
pix = surface + ((h - 1 - scale_y) * w);
else
pix = surface + (scale_y * w);
}
else
scale_down_line = EINA_FALSE;
if (scale_y >= h)
{
p = buffer_end;
}
p += 2;
break;
case 1: // EOB
p = buffer_end;
break;
case 2: // DELTA
x += p[2];
y += p[3];
scale_x = x / scale_ratio;
scale_y = y / scale_ratio;
if ((scale_x >= w) || (scale_y >= h))
{
p = buffer_end;
}
if (!right_way_up)
pix = surface + scale_x + ((h - 1 - scale_y) * w);
else
pix = surface + scale_x + (scale_y * w);
p += 4;
break;
default:
count = p[1];
if (((p + count) > buffer_end) ||
((x + count) > image_w))
{
p = buffer_end;
break;
}
p += 2;
done = count;
while (count > 0)
{
if (((x % scale_ratio) == 0) && (scale_x < w))
{
*pix = pal[*p];
pix++;
scale_x ++;
}
p++;
x++;
count--;
}
if (done & 0x1) p++;
break;
}
}
}
@ -895,19 +1089,33 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
if (comp == 0) // no compression
{
fseek(f, offset, SEEK_SET);
buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
if (scale_ratio == 1)
buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
else
buffer = malloc(row_size); // scale down is usually set because of memory issue, so read line by line
if (!buffer)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
buffer_end = buffer + image_size;
if (scale_ratio == 1)
buffer_end = buffer + image_size;
else
buffer_end = buffer + row_size;
p = buffer;
if (fread(buffer, image_size, 1, f) != 1) goto close_file;
if (scale_ratio == 1)
{
if (fread(buffer, image_size, 1, f) != 1) goto close_file;
}
else
{
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
}
if (bit_count == 16)
{
unsigned short tmp;
pix = surface;
for (y = 0; y < h; y++)
{
@ -920,13 +1128,28 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
g = (tmp >> 2) & 0xf8; g |= g >> 5;
b = (tmp << 3) & 0xf8; b |= b >> 5;
*pix = ARGB_JOIN(0xff, r, g, b);
p += 2;
p += 2 * scale_ratio;
if (p >= buffer_end) break;
pix++;
}
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
}
else if (bit_count == 24)
@ -941,13 +1164,26 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
g = p[1];
r = p[2];
*pix = ARGB_JOIN(0xff, r, g, b);
p += 3;
p += 3 * scale_ratio;
if (p >= buffer_end) break;
pix++;
}
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
}
else if (bit_count == 32)
@ -966,13 +1202,27 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
if (a) none_zero_alpha = 1;
if (!hasa) a = 0xff;
*pix = ARGB_JOIN(a, r, g, b);
p += 4;
p += 4 * scale_ratio;
if (p >= buffer_end) break;
pix++;
}
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
if (!none_zero_alpha)
{
@ -996,21 +1246,37 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
if (!read_uint(f, &bmask)) goto close_file;
fseek(f, offset, SEEK_SET);
buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
if (scale_ratio == 1)
buffer = malloc(image_size + 8); // add 8 for padding to avoid checks
else
buffer = malloc(row_size); // scale down is usually set because of memory issue, so read line by line
if (!buffer)
{
*error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto close_file;
}
buffer_end = buffer + image_size;
if (scale_ratio == 1)
buffer_end = buffer + image_size;
else
buffer_end = buffer + row_size;
p = buffer;
if (fread(buffer, image_size, 1, f) != 1) goto close_file;
if (scale_ratio == 1)
{
if (fread(buffer, image_size, 1, f) != 1) goto close_file;
}
else
{
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
}
if ((bit_count == 16) &&
(rmask == 0xf800) && (gmask == 0x07e0) && (bmask == 0x001f)
)
{
unsigned short tmp;
pix = surface;
for (y = 0; y < h; y++)
{
@ -1023,13 +1289,27 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
g = (tmp >> 3) & 0xfc; g |= g >> 6;
b = (tmp << 3) & 0xf8; b |= b >> 5;
*pix = ARGB_JOIN(0xff, r, g, b);
p += 2;
p += 2 * scale_ratio;
if (p >= buffer_end) break;
pix++;
}
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
}
else if ((bit_count == 16) &&
@ -1037,7 +1317,6 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
)
{
unsigned short tmp;
pix = surface;
for (y = 0; y < h; y++)
{
@ -1050,13 +1329,26 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
g = (tmp >> 2) & 0xf8; g |= g >> 5;
b = (tmp << 3) & 0xf8; b |= b >> 5;
*pix = ARGB_JOIN(0xff, r, g, b);
p += 2;
p += 2 * scale_ratio;
if (p >= buffer_end) break;
pix++;
}
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
}
else if (bit_count == 32)
@ -1073,13 +1365,27 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
a = p[3];
if (!hasa) a = 0xff;
*pix = ARGB_JOIN(a, r, g, b);
p += 4;
p += 4 * scale_ratio;
if (p >= buffer_end) break;
pix++;
}
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
if (scale_ratio > 1)
{
read_line += scale_ratio;
if (read_line >= image_h) break;
fseek(f, row_size * (scale_ratio - 1), SEEK_CUR);
if (fread(buffer, row_size, 1, f) != 1) goto close_file;
p = buffer;
buffer_end = buffer + row_size;
}
else
{
fix = (int)(((unsigned long)p) & 0x3);
if (fix > 0) p += 4 - fix; // align row read
if (p >= buffer_end) break;
}
}
}
else
@ -1100,6 +1406,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
goto close_file;
if (buffer) free(buffer);
if (scale_surface) free(scale_surface);
fclose(f);
evas_common_image_premul(ie);
@ -1108,6 +1415,7 @@ evas_image_load_file_data_bmp(Image_Entry *ie, const char *file, const char *key
close_file:
if (buffer) free(buffer);
if (scale_surface) free(scale_surface);
fclose(f);
return EINA_FALSE;
}