forked from enlightenment/efl
evas - ico loader - detect probable p0ng entry in ico file
ico files were defined to have bmp's in each key - in fact a subset of them. unbenknownst to yours truly, vista now allows them to also be pngs and thus the ico loader rejects them as corrupt. at least detect it and complain right now
This commit is contained in:
parent
dee1640d0f
commit
10405ffc41
|
@ -554,246 +554,227 @@ evas_image_load_file_data_ico(void *loader_data,
|
||||||
|
|
||||||
// read bmp header time... let's do some checking
|
// read bmp header time... let's do some checking
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // headersize - dont care
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // headersize - dont care
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // width
|
if (dword != 40) // must be 40 if bmp entry - if not, something else
|
||||||
if (dword > 0)
|
|
||||||
{
|
{
|
||||||
if ((int)dword != w)
|
ERR("ICO at %i offset, size %i in %s is not a standard ico bmp "
|
||||||
{
|
" file entry. It may be PNG (new as of Vista - not in original spec)",
|
||||||
w = dword;
|
(int)position, (int)chosen.bmsize,
|
||||||
diff_size = 1;
|
eina_file_filename_get(f));
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // height
|
|
||||||
if (dword > 0)
|
|
||||||
{
|
|
||||||
if ((int)dword != (h * 2))
|
|
||||||
{
|
|
||||||
h = dword / 2;
|
|
||||||
diff_size = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (diff_size)
|
|
||||||
{
|
|
||||||
ERR("Broken ICO file: %s - "
|
|
||||||
" Reporting size of %ix%i in index, but bitmap is %ix%i. "
|
|
||||||
" May be expanded or cropped.",
|
|
||||||
eina_file_filename_get(f), prop->w, prop->h, w, h);
|
|
||||||
}
|
|
||||||
if (!read_ushort(map, fsize, &position, &word)) goto close_file; // planes
|
|
||||||
//planes2 = word;
|
|
||||||
if (!read_ushort(map, fsize, &position, &word)) goto close_file; // bitcount
|
|
||||||
bitcount = word;
|
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // compression
|
|
||||||
//compression = dword;
|
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // imagesize
|
|
||||||
//imagesize = dword;
|
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // z pixels per m
|
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // y pizels per m
|
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors used
|
|
||||||
//colorsused = dword;
|
|
||||||
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors important
|
|
||||||
//colorsimportant = dword;
|
|
||||||
|
|
||||||
surface = pixels;
|
|
||||||
memset(surface, 0, prop->w * prop->h * 4);
|
|
||||||
|
|
||||||
if (!((bitcount == 1) || (bitcount == 4) || (bitcount == 8) ||
|
|
||||||
(bitcount == 24) || (bitcount == 32)))
|
|
||||||
goto close_file;
|
|
||||||
if (bitcount <= 8)
|
|
||||||
{
|
|
||||||
cols2 = 1 << bitcount;
|
|
||||||
if (cols == 0) cols = cols2;
|
|
||||||
if (cols > cols2) cols = cols2;
|
|
||||||
if (cols > 256) cols = 256;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cols = 0;
|
|
||||||
if (bitcount > 8) cols = 0;
|
|
||||||
|
|
||||||
pal = alloca(256 * 4);
|
|
||||||
for (i = 0; i < cols; i++)
|
|
||||||
{
|
{
|
||||||
unsigned char a, r, g, b;
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // width
|
||||||
|
if (dword > 0)
|
||||||
if (!read_uchar(map, fsize, &position, &b)) goto close_file;
|
|
||||||
if (!read_uchar(map, fsize, &position, &g)) goto close_file;
|
|
||||||
if (!read_uchar(map, fsize, &position, &r)) goto close_file;
|
|
||||||
if (!read_uchar(map, fsize, &position, &a)) goto close_file;
|
|
||||||
a = 0xff;
|
|
||||||
pal[i] = ARGB_JOIN(a, r, g, b);
|
|
||||||
}
|
|
||||||
stride = ((w + 31) / 32);
|
|
||||||
maskbuf = alloca(stride * h);
|
|
||||||
pixbuf = alloca(stride * 32 * 4); // more than enough
|
|
||||||
if (bitcount == 1)
|
|
||||||
{
|
|
||||||
pstride = stride * 4;
|
|
||||||
for (i = 0; i < h; i++)
|
|
||||||
{
|
{
|
||||||
pix = surface + (i * w);
|
if ((int)dword != w)
|
||||||
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
|
||||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
|
||||||
p = pixbuf;
|
|
||||||
if (i >= h) continue;
|
|
||||||
for (j = 0; j < w; j++)
|
|
||||||
{
|
{
|
||||||
if (j >= w) break;
|
w = dword;
|
||||||
if ((j & 0x7) == 0x0)
|
diff_size = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // height
|
||||||
|
if (dword > 0)
|
||||||
|
{
|
||||||
|
if ((int)dword != (h * 2))
|
||||||
|
{
|
||||||
|
h = dword / 2;
|
||||||
|
diff_size = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (diff_size)
|
||||||
|
{
|
||||||
|
ERR("Broken ICO file: %s - "
|
||||||
|
" Reporting size of %ix%i in index, but bitmap is %ix%i. "
|
||||||
|
" May be expanded or cropped.",
|
||||||
|
eina_file_filename_get(f), prop->w, prop->h, w, h);
|
||||||
|
}
|
||||||
|
if (!read_ushort(map, fsize, &position, &word)) goto close_file; // planes
|
||||||
|
//planes2 = word;
|
||||||
|
if (!read_ushort(map, fsize, &position, &word)) goto close_file; // bitcount
|
||||||
|
bitcount = word;
|
||||||
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // compression
|
||||||
|
//compression = dword;
|
||||||
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // imagesize
|
||||||
|
//imagesize = dword;
|
||||||
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // z pixels per m
|
||||||
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // y pizels per m
|
||||||
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors used
|
||||||
|
//colorsused = dword;
|
||||||
|
if (!read_uint(map, fsize, &position, &dword)) goto close_file; // colors important
|
||||||
|
//colorsimportant = dword;
|
||||||
|
|
||||||
|
surface = pixels;
|
||||||
|
memset(surface, 0, prop->w * prop->h * 4);
|
||||||
|
|
||||||
|
if (!((bitcount == 1) || (bitcount == 4) || (bitcount == 8) ||
|
||||||
|
(bitcount == 24) || (bitcount == 32)))
|
||||||
|
goto close_file;
|
||||||
|
if (bitcount <= 8)
|
||||||
|
{
|
||||||
|
cols2 = 1 << bitcount;
|
||||||
|
if (cols == 0) cols = cols2;
|
||||||
|
if (cols > cols2) cols = cols2;
|
||||||
|
if (cols > 256) cols = 256;
|
||||||
|
}
|
||||||
|
else cols = 0;
|
||||||
|
if (bitcount > 8) cols = 0;
|
||||||
|
|
||||||
|
pal = alloca(256 * 4);
|
||||||
|
for (i = 0; i < cols; i++)
|
||||||
|
{
|
||||||
|
unsigned char a, r, g, b;
|
||||||
|
|
||||||
|
if (!read_uchar(map, fsize, &position, &b)) goto close_file;
|
||||||
|
if (!read_uchar(map, fsize, &position, &g)) goto close_file;
|
||||||
|
if (!read_uchar(map, fsize, &position, &r)) goto close_file;
|
||||||
|
if (!read_uchar(map, fsize, &position, &a)) goto close_file;
|
||||||
|
a = 0xff;
|
||||||
|
pal[i] = ARGB_JOIN(a, r, g, b);
|
||||||
|
}
|
||||||
|
stride = ((w + 31) / 32);
|
||||||
|
maskbuf = alloca(stride * h);
|
||||||
|
pixbuf = alloca(stride * 32 * 4); // more than enough
|
||||||
|
if (bitcount == 1)
|
||||||
|
{
|
||||||
|
pstride = stride * 4;
|
||||||
|
for (i = 0; i < h; i++)
|
||||||
|
{
|
||||||
|
pix = surface + (i * w);
|
||||||
|
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
||||||
|
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||||
|
p = pixbuf;
|
||||||
|
if (i >= h) continue;
|
||||||
|
for (j = 0; j < w; j++)
|
||||||
{
|
{
|
||||||
*pix = pal[*p >> 7];
|
if (j >= w) break;
|
||||||
|
if ((j & 0x7) == 0x0) *pix = pal[*p >> 7];
|
||||||
|
else if ((j & 0x7) == 0x1) *pix = pal[(*p >> 6) & 0x1];
|
||||||
|
else if ((j & 0x7) == 0x2) *pix = pal[(*p >> 5) & 0x1];
|
||||||
|
else if ((j & 0x7) == 0x3) *pix = pal[(*p >> 4) & 0x1];
|
||||||
|
else if ((j & 0x7) == 0x4) *pix = pal[(*p >> 3) & 0x1];
|
||||||
|
else if ((j & 0x7) == 0x5) *pix = pal[(*p >> 2) & 0x1];
|
||||||
|
else if ((j & 0x7) == 0x6) *pix = pal[(*p >> 1) & 0x1];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pix = pal[*p & 0x1];
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
pix++;
|
||||||
}
|
}
|
||||||
else if ((j & 0x7) == 0x1)
|
}
|
||||||
|
}
|
||||||
|
else if (bitcount == 4)
|
||||||
|
{
|
||||||
|
pstride = ((w + 7) / 8) * 4;
|
||||||
|
for (i = 0; i < h; i++)
|
||||||
|
{
|
||||||
|
pix = surface + (i * w);
|
||||||
|
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
||||||
|
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||||
|
p = pixbuf;
|
||||||
|
if (i >= h) continue;
|
||||||
|
for (j = 0; j < w; j++)
|
||||||
{
|
{
|
||||||
*pix = pal[(*p >> 6) & 0x1];
|
if (j >= w) break;
|
||||||
|
if ((j & 0x1) == 0x1)
|
||||||
|
{
|
||||||
|
*pix = pal[*p & 0x0f];
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*pix = pal[*p >> 4];
|
||||||
|
}
|
||||||
|
pix++;
|
||||||
}
|
}
|
||||||
else if ((j & 0x7) == 0x2)
|
}
|
||||||
|
}
|
||||||
|
else if (bitcount == 8)
|
||||||
|
{
|
||||||
|
pstride = ((w + 3) / 4) * 4;
|
||||||
|
for (i = 0; i < h; i++)
|
||||||
|
{
|
||||||
|
pix = surface + (i * w);
|
||||||
|
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
||||||
|
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||||
|
p = pixbuf;
|
||||||
|
if (i >= h) continue;
|
||||||
|
for (j = 0; j < w; j++)
|
||||||
{
|
{
|
||||||
*pix = pal[(*p >> 5) & 0x1];
|
if (j >= w) break;
|
||||||
}
|
*pix = pal[*p];
|
||||||
else if ((j & 0x7) == 0x3)
|
|
||||||
{
|
|
||||||
*pix = pal[(*p >> 4) & 0x1];
|
|
||||||
}
|
|
||||||
else if ((j & 0x7) == 0x4)
|
|
||||||
{
|
|
||||||
*pix = pal[(*p >> 3) & 0x1];
|
|
||||||
}
|
|
||||||
else if ((j & 0x7) == 0x5)
|
|
||||||
{
|
|
||||||
*pix = pal[(*p >> 2) & 0x1];
|
|
||||||
}
|
|
||||||
else if ((j & 0x7) == 0x6)
|
|
||||||
{
|
|
||||||
*pix = pal[(*p >> 1) & 0x1];
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
*pix = pal[*p & 0x1];
|
|
||||||
p++;
|
p++;
|
||||||
|
pix++;
|
||||||
}
|
}
|
||||||
pix++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
else if (bitcount == 24)
|
||||||
else if (bitcount == 4)
|
|
||||||
{
|
|
||||||
pstride = ((w + 7) / 8) * 4;
|
|
||||||
for (i = 0; i < h; i++)
|
|
||||||
{
|
{
|
||||||
pix = surface + (i * w);
|
pstride = w * 3;
|
||||||
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
for (i = 0; i < h; i++)
|
||||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
|
||||||
p = pixbuf;
|
|
||||||
if (i >= h) continue;
|
|
||||||
for (j = 0; j < w; j++)
|
|
||||||
{
|
{
|
||||||
if (j >= w) break;
|
pix = surface + (i * w);
|
||||||
if ((j & 0x1) == 0x1)
|
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
||||||
|
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||||
|
p = pixbuf;
|
||||||
|
if (i >= h) continue;
|
||||||
|
for (j = 0; j < w; j++)
|
||||||
{
|
{
|
||||||
*pix = pal[*p & 0x0f];
|
unsigned char a, r, g, b;
|
||||||
p++;
|
|
||||||
|
if (j >= w) break;
|
||||||
|
b = p[0]; g = p[1]; r = p[2];
|
||||||
|
p += 3;
|
||||||
|
a = 0xff;
|
||||||
|
*pix = ARGB_JOIN(a, r, g, b);
|
||||||
|
pix++;
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
}
|
||||||
|
else if (bitcount == 32)
|
||||||
|
{
|
||||||
|
pstride = w * 4;
|
||||||
|
for (i = 0; i < h; i++)
|
||||||
|
{
|
||||||
|
pix = surface + (i * w);
|
||||||
|
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
||||||
|
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
||||||
|
p = pixbuf;
|
||||||
|
if (i >= h) continue;
|
||||||
|
for (j = 0; j < w; j++)
|
||||||
{
|
{
|
||||||
*pix = pal[*p >> 4];
|
unsigned char a, r, g, b;
|
||||||
|
|
||||||
|
if (j >= w) break;
|
||||||
|
b = p[0]; g = p[1]; r = p[2]; a = p[3];
|
||||||
|
p += 4;
|
||||||
|
if (a) none_zero_alpha = 1;
|
||||||
|
*pix = ARGB_JOIN(a, r, g, b);
|
||||||
|
pix++;
|
||||||
}
|
}
|
||||||
pix++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!none_zero_alpha)
|
||||||
else if (bitcount == 8)
|
|
||||||
{
|
|
||||||
pstride = ((w + 3) / 4) * 4;
|
|
||||||
for (i = 0; i < h; i++)
|
|
||||||
{
|
{
|
||||||
pix = surface + (i * w);
|
if (!read_mem(map, fsize, &position, maskbuf, stride * 4 * h)) goto close_file;
|
||||||
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
// apply mask
|
||||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
pix = surface;
|
||||||
p = pixbuf;
|
for (i = 0; i < h; i++)
|
||||||
if (i >= h) continue;
|
|
||||||
for (j = 0; j < w; j++)
|
|
||||||
{
|
{
|
||||||
if (j >= w) break;
|
unsigned char *m;
|
||||||
*pix = pal[*p];
|
|
||||||
p++;
|
|
||||||
pix++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (bitcount == 24)
|
|
||||||
{
|
|
||||||
pstride = w * 3;
|
|
||||||
for (i = 0; i < h; i++)
|
|
||||||
{
|
|
||||||
pix = surface + (i * w);
|
|
||||||
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
|
||||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
|
||||||
p = pixbuf;
|
|
||||||
if (i >= h) continue;
|
|
||||||
for (j = 0; j < w; j++)
|
|
||||||
{
|
|
||||||
unsigned char a, r, g, b;
|
|
||||||
|
|
||||||
if (j >= w) break;
|
pix = surface + (i * w);
|
||||||
b = p[0];
|
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
||||||
g = p[1];
|
m = maskbuf + (stride * i * 4);
|
||||||
r = p[2];
|
if (i >= h) continue;
|
||||||
p += 3;
|
for (j = 0; j < w; j++)
|
||||||
a = 0xff;
|
{
|
||||||
*pix = ARGB_JOIN(a, r, g, b);
|
if (j >= w) break;
|
||||||
pix++;
|
if (*m & (1 << (7 - (j & 0x7)))) *pix = 0;
|
||||||
}
|
else A_VAL(pix) = 0xff;
|
||||||
}
|
if ((j & 0x7) == 0x7) m++;
|
||||||
}
|
pix++;
|
||||||
else if (bitcount == 32)
|
}
|
||||||
{
|
|
||||||
pstride = w * 4;
|
|
||||||
for (i = 0; i < h; i++)
|
|
||||||
{
|
|
||||||
pix = surface + (i * w);
|
|
||||||
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
|
||||||
if (!read_mem(map, fsize, &position, pixbuf, pstride)) goto close_file;
|
|
||||||
p = pixbuf;
|
|
||||||
if (i >= h) continue;
|
|
||||||
for (j = 0; j < w; j++)
|
|
||||||
{
|
|
||||||
unsigned char a, r, g, b;
|
|
||||||
|
|
||||||
if (j >= w) break;
|
|
||||||
b = p[0];
|
|
||||||
g = p[1];
|
|
||||||
r = p[2];
|
|
||||||
a = p[3];
|
|
||||||
p += 4;
|
|
||||||
if (a) none_zero_alpha = 1;
|
|
||||||
*pix = ARGB_JOIN(a, r, g, b);
|
|
||||||
pix++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!none_zero_alpha)
|
|
||||||
{
|
|
||||||
if (!read_mem(map, fsize, &position, maskbuf, stride * 4 * h)) goto close_file;
|
|
||||||
// apply mask
|
|
||||||
pix = surface;
|
|
||||||
for (i = 0; i < h; i++)
|
|
||||||
{
|
|
||||||
unsigned char *m;
|
|
||||||
|
|
||||||
pix = surface + (i * w);
|
|
||||||
if (!right_way_up) pix = surface + ((h - 1 - i) * w);
|
|
||||||
m = maskbuf + (stride * i * 4);
|
|
||||||
if (i >= h) continue;
|
|
||||||
for (j = 0; j < w; j++)
|
|
||||||
{
|
|
||||||
if (j >= w) break;
|
|
||||||
if (*m & (1 << (7 - (j & 0x7))))
|
|
||||||
A_VAL(pix) = 0x00;
|
|
||||||
else
|
|
||||||
A_VAL(pix) = 0xff;
|
|
||||||
if ((j & 0x7) == 0x7) m++;
|
|
||||||
pix++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue