forked from enlightenment/efl
Eet: fix decoding of embedded ETC images
Typos, lack of NULL check, excessive sizeof(type) not matching the object type, no border set, etc... This all lead to a crash and then no render (with an error message and then without...). This also simplifies the implicit loading of ETC1 as ETC2 when supported by the driver. @fix
This commit is contained in:
parent
e586b9debc
commit
cc5cccc511
|
@ -357,14 +357,14 @@ eet_data_image_jpeg_header_decode(const void *data,
|
|||
bin = eina_binbuf_manage_new(data, size, EINA_TRUE);
|
||||
if (!bin) return 0;
|
||||
|
||||
memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
|
||||
memset(&opts, 0, sizeof (opts));
|
||||
|
||||
image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error);
|
||||
if (!image) goto on_error;
|
||||
|
||||
memset(&prop, 0, sizeof (prop));
|
||||
|
||||
if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
|
||||
if (!emile_image_head(image, &prop, sizeof (prop), &error))
|
||||
goto on_error;
|
||||
|
||||
*w = prop.w;
|
||||
|
@ -410,7 +410,7 @@ eet_data_image_jpeg_rgb_decode(const void *data,
|
|||
bin = eina_binbuf_manage_new(data, size, EINA_TRUE);
|
||||
if (!bin) return 0;
|
||||
|
||||
memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
|
||||
memset(&opts, 0, sizeof (opts));
|
||||
opts.region.x = src_x;
|
||||
opts.region.y = src_y;
|
||||
opts.region.w = w;
|
||||
|
@ -421,12 +421,12 @@ eet_data_image_jpeg_rgb_decode(const void *data,
|
|||
|
||||
memset(&prop, 0, sizeof (prop));
|
||||
|
||||
if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
|
||||
if (!emile_image_head(image, &prop, sizeof (prop), &error))
|
||||
goto on_error;
|
||||
|
||||
prop.cspace = cspace;
|
||||
|
||||
if (!emile_image_data(image, &prop, sizeof (Emile_Image_Property), d, &error))
|
||||
if (!emile_image_data(image, &prop, sizeof (prop), d, &error))
|
||||
goto on_error;
|
||||
|
||||
r = 1;
|
||||
|
@ -464,7 +464,7 @@ eet_data_image_jpeg_alpha_decode(const void *data,
|
|||
bin = eina_binbuf_manage_new(data, size, EINA_TRUE);
|
||||
if (!bin) return 0;
|
||||
|
||||
memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
|
||||
memset(&opts, 0, sizeof (opts));
|
||||
opts.region.x = src_x;
|
||||
opts.region.y = src_y;
|
||||
opts.region.w = w;
|
||||
|
@ -475,7 +475,7 @@ eet_data_image_jpeg_alpha_decode(const void *data,
|
|||
|
||||
memset(&prop, 0, sizeof (prop));
|
||||
|
||||
if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
|
||||
if (!emile_image_head(image, &prop, sizeof (prop), &error))
|
||||
goto on_error;
|
||||
|
||||
remember = tmp = malloc(sizeof (unsigned char) * w * h);
|
||||
|
@ -484,7 +484,7 @@ eet_data_image_jpeg_alpha_decode(const void *data,
|
|||
// Alpha should always be encoded as GRY8
|
||||
prop.cspace = EMILE_COLORSPACE_GRY8;
|
||||
|
||||
if (!emile_image_data(image, &prop, sizeof (Emile_Image_Property), tmp, &error))
|
||||
if (!emile_image_data(image, &prop, sizeof (prop), tmp, &error))
|
||||
goto on_error;
|
||||
|
||||
if (cspace == EMILE_COLORSPACE_AGRY88)
|
||||
|
@ -584,6 +584,7 @@ eet_data_image_etc2_decode(const void *data,
|
|||
Emile_Image *image;
|
||||
Eina_Binbuf *bin;
|
||||
Emile_Image_Load_Error error;
|
||||
Eina_Bool found = EINA_FALSE;
|
||||
int i;
|
||||
int r = 0;
|
||||
|
||||
|
@ -593,7 +594,7 @@ eet_data_image_etc2_decode(const void *data,
|
|||
bin = eina_binbuf_manage_new(data, length, EINA_TRUE);
|
||||
if (!bin) return 0;
|
||||
|
||||
memset(&opts, 0, sizeof (Emile_Image_Load_Opts));
|
||||
memset(&opts, 0, sizeof (opts));
|
||||
opts.region.x = dst_x;
|
||||
opts.region.y = dst_y;
|
||||
opts.region.w = dst_w;
|
||||
|
@ -604,12 +605,20 @@ eet_data_image_etc2_decode(const void *data,
|
|||
|
||||
memset(&prop, 0, sizeof (prop));
|
||||
|
||||
if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error))
|
||||
if (!emile_image_head(image, &prop, sizeof (prop), &error))
|
||||
goto on_error;
|
||||
|
||||
for (i = 0; prop.cspaces[i] != EMILE_COLORSPACE_ARGB8888; i++)
|
||||
if (prop.cspaces)
|
||||
{
|
||||
if (prop.cspaces[i] == cspace) break;
|
||||
for (i = 0; prop.cspaces[i] != EMILE_COLORSPACE_ARGB8888; i++)
|
||||
{
|
||||
if (prop.cspaces[i] == cspace)
|
||||
{
|
||||
found = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) goto on_error;
|
||||
}
|
||||
|
||||
switch (cspace)
|
||||
|
@ -619,7 +628,7 @@ eet_data_image_etc2_decode(const void *data,
|
|||
if (alpha != EINA_FALSE) goto on_error;
|
||||
break;
|
||||
case EMILE_COLORSPACE_RGB8_ETC2:
|
||||
if (lossy != EET_IMAGE_ETC2_RGB) goto on_error;
|
||||
if ((lossy != EET_IMAGE_ETC2_RGB) && (lossy != EET_IMAGE_ETC1)) goto on_error;
|
||||
if (alpha != EINA_FALSE) goto on_error;
|
||||
break;
|
||||
case EMILE_COLORSPACE_RGBA8_ETC2_EAC:
|
||||
|
@ -638,7 +647,7 @@ eet_data_image_etc2_decode(const void *data,
|
|||
|
||||
prop.cspace = cspace;
|
||||
|
||||
if (!emile_image_data(image, &prop, sizeof (Emile_Image_Load_Opts), p, &error))
|
||||
if (!emile_image_data(image, &prop, sizeof (prop), p, &error))
|
||||
goto on_error;
|
||||
|
||||
// TODO: Add support for more unpremultiplied modes (ETC2)
|
||||
|
@ -648,6 +657,7 @@ eet_data_image_etc2_decode(const void *data,
|
|||
r = 1;
|
||||
|
||||
on_error:
|
||||
ERR("Failed to decode image inside Eet");
|
||||
emile_image_close(image);
|
||||
eina_binbuf_free(bin);
|
||||
|
||||
|
@ -1641,6 +1651,7 @@ eet_data_image_encode(const void *data,
|
|||
|
||||
static const Eet_Colorspace _eet_etc1_colorspace[] = {
|
||||
EET_COLORSPACE_ETC1,
|
||||
EET_COLORSPACE_RGB8_ETC2,
|
||||
EET_COLORSPACE_ARGB8888
|
||||
};
|
||||
|
||||
|
@ -2201,9 +2212,8 @@ eet_data_image_decode_to_cspace_surface_cipher(const void *data,
|
|||
}
|
||||
else
|
||||
{
|
||||
if ((cspaces != EET_COLORSPACE_ARGB8888) ||
|
||||
(cspace == EET_COLORSPACE_ARGB8888 &&
|
||||
w * 4 > row_stride))
|
||||
if ((cspace != EET_COLORSPACE_ARGB8888) ||
|
||||
((cspace == EET_COLORSPACE_ARGB8888) && (w * 4 > row_stride)))
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -177,27 +177,28 @@ _roundup(int val, int rup)
|
|||
|
||||
/* TGV Handling */
|
||||
|
||||
static const Emile_Colorspace cspaces_etc1[2] = {
|
||||
static const Emile_Colorspace cspaces_etc1[] = {
|
||||
EMILE_COLORSPACE_ETC1,
|
||||
EMILE_COLORSPACE_ARGB8888
|
||||
};
|
||||
|
||||
static const Emile_Colorspace cspaces_rgb8_etc2[2] = {
|
||||
EMILE_COLORSPACE_RGB8_ETC2,
|
||||
EMILE_COLORSPACE_ARGB8888
|
||||
};
|
||||
|
||||
static const Emile_Colorspace cspaces_rgba8_etc2_eac[2] = {
|
||||
static const Emile_Colorspace cspaces_rgb8_etc2[] = {
|
||||
EMILE_COLORSPACE_RGB8_ETC2,
|
||||
EMILE_COLORSPACE_ARGB8888
|
||||
};
|
||||
|
||||
static const Emile_Colorspace cspaces_rgba8_etc2_eac[] = {
|
||||
EMILE_COLORSPACE_RGBA8_ETC2_EAC,
|
||||
EMILE_COLORSPACE_ARGB8888
|
||||
};
|
||||
|
||||
static const Emile_Colorspace cspaces_etc1_alpha[2] = {
|
||||
static const Emile_Colorspace cspaces_etc1_alpha[] = {
|
||||
EMILE_COLORSPACE_ETC1_ALPHA,
|
||||
EMILE_COLORSPACE_ARGB8888
|
||||
};
|
||||
|
||||
static const Emile_Colorspace cspaces_agry[3] = {
|
||||
static const Emile_Colorspace cspaces_gry[] = {
|
||||
EMILE_COLORSPACE_GRY8,
|
||||
EMILE_COLORSPACE_AGRY88,
|
||||
EMILE_COLORSPACE_ARGB8888
|
||||
|
@ -1414,7 +1415,7 @@ _emile_jpeg_head(Emile_Image *image,
|
|||
if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
|
||||
{
|
||||
/* We do handle GRY8 and AGRY88 (with FF for alpha) colorspace as an output for JPEG */
|
||||
prop->cspaces = cspaces_agry;
|
||||
prop->cspaces = cspaces_gry;
|
||||
}
|
||||
|
||||
/* rotation decoding */
|
||||
|
|
|
@ -215,7 +215,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
|
|||
goto load_error;
|
||||
}
|
||||
|
||||
memset(&property, 0, sizeof (Evas_Image_Property));
|
||||
memset(&property, 0, sizeof (property));
|
||||
if (evas_image_load_func->file_head(ie->loader_data, &property,
|
||||
error) &&
|
||||
(*error == EVAS_LOAD_ERROR_NONE))
|
||||
|
@ -412,7 +412,7 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
|
|||
|
||||
if (!ie->f) return EVAS_LOAD_ERROR_DOES_NOT_EXIST;
|
||||
|
||||
memset(&property, 0, sizeof (Evas_Image_Property));
|
||||
memset(&property, 0, sizeof (property));
|
||||
property.w = ie->w;
|
||||
property.h = ie->h;
|
||||
property.scale = ie->scale;
|
||||
|
|
|
@ -64,8 +64,17 @@ _evas_image_load_return_error(int err, int *error)
|
|||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
static const Evas_Colorspace cspaces_etc1[2] = {
|
||||
static int
|
||||
_roundup(int val, int rup)
|
||||
{
|
||||
if (val >= 0 && rup > 0)
|
||||
return (val + rup - 1) - ((val + rup - 1) % rup);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const Evas_Colorspace cspaces_etc1[] = {
|
||||
EVAS_COLORSPACE_ETC1,
|
||||
EVAS_COLORSPACE_RGB8_ETC2,
|
||||
EVAS_COLORSPACE_ARGB8888
|
||||
};
|
||||
|
||||
|
@ -93,6 +102,7 @@ evas_image_load_file_head_eet(void *loader_data,
|
|||
int a, compression, quality;
|
||||
Eet_Image_Encoding lossy;
|
||||
const Eet_Colorspace *cspaces = NULL;
|
||||
Eina_Bool border_set = EINA_FALSE;
|
||||
int ok;
|
||||
|
||||
ok = eet_data_image_header_read(loader->ef, loader->key,
|
||||
|
@ -113,21 +123,25 @@ evas_image_load_file_head_eet(void *loader_data,
|
|||
if (cspaces[i] == EET_COLORSPACE_ETC1)
|
||||
{
|
||||
prop->cspaces = cspaces_etc1;
|
||||
border_set = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
else if (cspaces[i] == EET_COLORSPACE_ETC1_ALPHA)
|
||||
{
|
||||
prop->cspaces = cspaces_etc1_alpha;
|
||||
border_set = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
else if (cspaces[i] == EET_COLORSPACE_RGB8_ETC2)
|
||||
{
|
||||
prop->cspaces = cspaces_etc2_rgb;
|
||||
border_set = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
else if (cspaces[i] == EET_COLORSPACE_RGBA8_ETC2_EAC)
|
||||
{
|
||||
prop->cspaces = cspaces_etc2_rgba;
|
||||
border_set = EINA_TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -135,6 +149,13 @@ evas_image_load_file_head_eet(void *loader_data,
|
|||
}
|
||||
|
||||
prop->alpha = !!a;
|
||||
if (border_set)
|
||||
{
|
||||
prop->borders.l = 1;
|
||||
prop->borders.t = 1;
|
||||
prop->borders.r = _roundup(prop->w + 2, 4) - prop->w - 1;
|
||||
prop->borders.b = _roundup(prop->h + 2, 4) - prop->h - 1;
|
||||
}
|
||||
*error = EVAS_LOAD_ERROR_NONE;
|
||||
|
||||
return EINA_TRUE;
|
||||
|
|
|
@ -77,7 +77,7 @@ evas_image_load_file_head_jpeg(void *loader_data,
|
|||
Eina_Bool ret;
|
||||
|
||||
ret = emile_image_head(loader->image,
|
||||
prop, sizeof (Emile_Image_Property),
|
||||
prop, sizeof (*prop),
|
||||
&image_error);
|
||||
*error = image_error;
|
||||
|
||||
|
@ -95,7 +95,7 @@ evas_image_load_file_data_jpeg(void *loader_data,
|
|||
Eina_Bool ret;
|
||||
|
||||
ret = emile_image_data(loader->image,
|
||||
prop, sizeof (Emile_Image_Property),
|
||||
prop, sizeof (*prop),
|
||||
pixels,
|
||||
&image_error);
|
||||
*error = image_error;
|
||||
|
|
|
@ -77,7 +77,7 @@ evas_image_load_file_head_tgv(void *loader_data,
|
|||
Eina_Bool ret;
|
||||
|
||||
ret = emile_image_head(loader->image,
|
||||
prop, sizeof (Emile_Image_Property),
|
||||
prop, sizeof (*prop),
|
||||
&image_error);
|
||||
*error = image_error;
|
||||
|
||||
|
@ -95,7 +95,7 @@ evas_image_load_file_data_tgv(void *loader_data,
|
|||
Eina_Bool ret;
|
||||
|
||||
ret = emile_image_data(loader->image,
|
||||
prop, sizeof (Emile_Image_Property),
|
||||
prop, sizeof (*prop),
|
||||
pixels,
|
||||
&image_error);
|
||||
*error = image_error;
|
||||
|
|
Loading…
Reference in New Issue