summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2015-10-29 15:30:16 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2015-10-29 17:58:34 +0900
commitcc5cccc511a3823bf328772e7b7ef9cfa852af54 (patch)
tree7915a73f3f1cbde7d5eef594b440bb7065385aba
parente586b9debc22ff3257d9405cf0ed0ebf8cf919b8 (diff)
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
-rw-r--r--src/lib/eet/eet_image.c44
-rw-r--r--src/lib/emile/emile_image.c13
-rw-r--r--src/lib/evas/common/evas_image_load.c4
-rw-r--r--src/modules/evas/image_loaders/eet/evas_image_load_eet.c23
-rw-r--r--src/modules/evas/image_loaders/jpeg/evas_image_load_jpeg.c4
-rw-r--r--src/modules/evas/image_loaders/tgv/evas_image_load_tgv.c4
6 files changed, 62 insertions, 30 deletions
diff --git a/src/lib/eet/eet_image.c b/src/lib/eet/eet_image.c
index c8ce81b1d3..95b9ee21de 100644
--- a/src/lib/eet/eet_image.c
+++ b/src/lib/eet/eet_image.c
@@ -357,14 +357,14 @@ eet_data_image_jpeg_header_decode(const void *data,
357 bin = eina_binbuf_manage_new(data, size, EINA_TRUE); 357 bin = eina_binbuf_manage_new(data, size, EINA_TRUE);
358 if (!bin) return 0; 358 if (!bin) return 0;
359 359
360 memset(&opts, 0, sizeof (Emile_Image_Load_Opts)); 360 memset(&opts, 0, sizeof (opts));
361 361
362 image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error); 362 image = emile_image_jpeg_memory_open(bin, &opts, NULL, &error);
363 if (!image) goto on_error; 363 if (!image) goto on_error;
364 364
365 memset(&prop, 0, sizeof (prop)); 365 memset(&prop, 0, sizeof (prop));
366 366
367 if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error)) 367 if (!emile_image_head(image, &prop, sizeof (prop), &error))
368 goto on_error; 368 goto on_error;
369 369
370 *w = prop.w; 370 *w = prop.w;
@@ -410,7 +410,7 @@ eet_data_image_jpeg_rgb_decode(const void *data,
410 bin = eina_binbuf_manage_new(data, size, EINA_TRUE); 410 bin = eina_binbuf_manage_new(data, size, EINA_TRUE);
411 if (!bin) return 0; 411 if (!bin) return 0;
412 412
413 memset(&opts, 0, sizeof (Emile_Image_Load_Opts)); 413 memset(&opts, 0, sizeof (opts));
414 opts.region.x = src_x; 414 opts.region.x = src_x;
415 opts.region.y = src_y; 415 opts.region.y = src_y;
416 opts.region.w = w; 416 opts.region.w = w;
@@ -421,12 +421,12 @@ eet_data_image_jpeg_rgb_decode(const void *data,
421 421
422 memset(&prop, 0, sizeof (prop)); 422 memset(&prop, 0, sizeof (prop));
423 423
424 if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error)) 424 if (!emile_image_head(image, &prop, sizeof (prop), &error))
425 goto on_error; 425 goto on_error;
426 426
427 prop.cspace = cspace; 427 prop.cspace = cspace;
428 428
429 if (!emile_image_data(image, &prop, sizeof (Emile_Image_Property), d, &error)) 429 if (!emile_image_data(image, &prop, sizeof (prop), d, &error))
430 goto on_error; 430 goto on_error;
431 431
432 r = 1; 432 r = 1;
@@ -464,7 +464,7 @@ eet_data_image_jpeg_alpha_decode(const void *data,
464 bin = eina_binbuf_manage_new(data, size, EINA_TRUE); 464 bin = eina_binbuf_manage_new(data, size, EINA_TRUE);
465 if (!bin) return 0; 465 if (!bin) return 0;
466 466
467 memset(&opts, 0, sizeof (Emile_Image_Load_Opts)); 467 memset(&opts, 0, sizeof (opts));
468 opts.region.x = src_x; 468 opts.region.x = src_x;
469 opts.region.y = src_y; 469 opts.region.y = src_y;
470 opts.region.w = w; 470 opts.region.w = w;
@@ -475,7 +475,7 @@ eet_data_image_jpeg_alpha_decode(const void *data,
475 475
476 memset(&prop, 0, sizeof (prop)); 476 memset(&prop, 0, sizeof (prop));
477 477
478 if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error)) 478 if (!emile_image_head(image, &prop, sizeof (prop), &error))
479 goto on_error; 479 goto on_error;
480 480
481 remember = tmp = malloc(sizeof (unsigned char) * w * h); 481 remember = tmp = malloc(sizeof (unsigned char) * w * h);
@@ -484,7 +484,7 @@ eet_data_image_jpeg_alpha_decode(const void *data,
484 // Alpha should always be encoded as GRY8 484 // Alpha should always be encoded as GRY8
485 prop.cspace = EMILE_COLORSPACE_GRY8; 485 prop.cspace = EMILE_COLORSPACE_GRY8;
486 486
487 if (!emile_image_data(image, &prop, sizeof (Emile_Image_Property), tmp, &error)) 487 if (!emile_image_data(image, &prop, sizeof (prop), tmp, &error))
488 goto on_error; 488 goto on_error;
489 489
490 if (cspace == EMILE_COLORSPACE_AGRY88) 490 if (cspace == EMILE_COLORSPACE_AGRY88)
@@ -584,6 +584,7 @@ eet_data_image_etc2_decode(const void *data,
584 Emile_Image *image; 584 Emile_Image *image;
585 Eina_Binbuf *bin; 585 Eina_Binbuf *bin;
586 Emile_Image_Load_Error error; 586 Emile_Image_Load_Error error;
587 Eina_Bool found = EINA_FALSE;
587 int i; 588 int i;
588 int r = 0; 589 int r = 0;
589 590
@@ -593,7 +594,7 @@ eet_data_image_etc2_decode(const void *data,
593 bin = eina_binbuf_manage_new(data, length, EINA_TRUE); 594 bin = eina_binbuf_manage_new(data, length, EINA_TRUE);
594 if (!bin) return 0; 595 if (!bin) return 0;
595 596
596 memset(&opts, 0, sizeof (Emile_Image_Load_Opts)); 597 memset(&opts, 0, sizeof (opts));
597 opts.region.x = dst_x; 598 opts.region.x = dst_x;
598 opts.region.y = dst_y; 599 opts.region.y = dst_y;
599 opts.region.w = dst_w; 600 opts.region.w = dst_w;
@@ -604,12 +605,20 @@ eet_data_image_etc2_decode(const void *data,
604 605
605 memset(&prop, 0, sizeof (prop)); 606 memset(&prop, 0, sizeof (prop));
606 607
607 if (!emile_image_head(image, &prop, sizeof (Emile_Image_Property), &error)) 608 if (!emile_image_head(image, &prop, sizeof (prop), &error))
608 goto on_error; 609 goto on_error;
609 610
610 for (i = 0; prop.cspaces[i] != EMILE_COLORSPACE_ARGB8888; i++) 611 if (prop.cspaces)
611 { 612 {
612 if (prop.cspaces[i] == cspace) break; 613 for (i = 0; prop.cspaces[i] != EMILE_COLORSPACE_ARGB8888; i++)
614 {
615 if (prop.cspaces[i] == cspace)
616 {
617 found = EINA_TRUE;
618 break;
619 }
620 }
621 if (!found) goto on_error;
613 } 622 }
614 623
615 switch (cspace) 624 switch (cspace)
@@ -619,7 +628,7 @@ eet_data_image_etc2_decode(const void *data,
619 if (alpha != EINA_FALSE) goto on_error; 628 if (alpha != EINA_FALSE) goto on_error;
620 break; 629 break;
621 case EMILE_COLORSPACE_RGB8_ETC2: 630 case EMILE_COLORSPACE_RGB8_ETC2:
622 if (lossy != EET_IMAGE_ETC2_RGB) goto on_error; 631 if ((lossy != EET_IMAGE_ETC2_RGB) && (lossy != EET_IMAGE_ETC1)) goto on_error;
623 if (alpha != EINA_FALSE) goto on_error; 632 if (alpha != EINA_FALSE) goto on_error;
624 break; 633 break;
625 case EMILE_COLORSPACE_RGBA8_ETC2_EAC: 634 case EMILE_COLORSPACE_RGBA8_ETC2_EAC:
@@ -638,7 +647,7 @@ eet_data_image_etc2_decode(const void *data,
638 647
639 prop.cspace = cspace; 648 prop.cspace = cspace;
640 649
641 if (!emile_image_data(image, &prop, sizeof (Emile_Image_Load_Opts), p, &error)) 650 if (!emile_image_data(image, &prop, sizeof (prop), p, &error))
642 goto on_error; 651 goto on_error;
643 652
644 // TODO: Add support for more unpremultiplied modes (ETC2) 653 // TODO: Add support for more unpremultiplied modes (ETC2)
@@ -648,6 +657,7 @@ eet_data_image_etc2_decode(const void *data,
648 r = 1; 657 r = 1;
649 658
650 on_error: 659 on_error:
660 ERR("Failed to decode image inside Eet");
651 emile_image_close(image); 661 emile_image_close(image);
652 eina_binbuf_free(bin); 662 eina_binbuf_free(bin);
653 663
@@ -1641,6 +1651,7 @@ eet_data_image_encode(const void *data,
1641 1651
1642static const Eet_Colorspace _eet_etc1_colorspace[] = { 1652static const Eet_Colorspace _eet_etc1_colorspace[] = {
1643 EET_COLORSPACE_ETC1, 1653 EET_COLORSPACE_ETC1,
1654 EET_COLORSPACE_RGB8_ETC2,
1644 EET_COLORSPACE_ARGB8888 1655 EET_COLORSPACE_ARGB8888
1645}; 1656};
1646 1657
@@ -2201,9 +2212,8 @@ eet_data_image_decode_to_cspace_surface_cipher(const void *data,
2201 } 2212 }
2202 else 2213 else
2203 { 2214 {
2204 if ((cspaces != EET_COLORSPACE_ARGB8888) || 2215 if ((cspace != EET_COLORSPACE_ARGB8888) ||
2205 (cspace == EET_COLORSPACE_ARGB8888 && 2216 ((cspace == EET_COLORSPACE_ARGB8888) && (w * 4 > row_stride)))
2206 w * 4 > row_stride))
2207 return 0; 2217 return 0;
2208 } 2218 }
2209 2219
diff --git a/src/lib/emile/emile_image.c b/src/lib/emile/emile_image.c
index 58a37c5c45..c7d12b83a0 100644
--- a/src/lib/emile/emile_image.c
+++ b/src/lib/emile/emile_image.c
@@ -177,27 +177,28 @@ _roundup(int val, int rup)
177 177
178/* TGV Handling */ 178/* TGV Handling */
179 179
180static const Emile_Colorspace cspaces_etc1[2] = { 180static const Emile_Colorspace cspaces_etc1[] = {
181 EMILE_COLORSPACE_ETC1, 181 EMILE_COLORSPACE_ETC1,
182 EMILE_COLORSPACE_RGB8_ETC2,
182 EMILE_COLORSPACE_ARGB8888 183 EMILE_COLORSPACE_ARGB8888
183}; 184};
184 185
185static const Emile_Colorspace cspaces_rgb8_etc2[2] = { 186static const Emile_Colorspace cspaces_rgb8_etc2[] = {
186 EMILE_COLORSPACE_RGB8_ETC2, 187 EMILE_COLORSPACE_RGB8_ETC2,
187 EMILE_COLORSPACE_ARGB8888 188 EMILE_COLORSPACE_ARGB8888
188}; 189};
189 190
190static const Emile_Colorspace cspaces_rgba8_etc2_eac[2] = { 191static const Emile_Colorspace cspaces_rgba8_etc2_eac[] = {
191 EMILE_COLORSPACE_RGBA8_ETC2_EAC, 192 EMILE_COLORSPACE_RGBA8_ETC2_EAC,
192 EMILE_COLORSPACE_ARGB8888 193 EMILE_COLORSPACE_ARGB8888
193}; 194};
194 195
195static const Emile_Colorspace cspaces_etc1_alpha[2] = { 196static const Emile_Colorspace cspaces_etc1_alpha[] = {
196 EMILE_COLORSPACE_ETC1_ALPHA, 197 EMILE_COLORSPACE_ETC1_ALPHA,
197 EMILE_COLORSPACE_ARGB8888 198 EMILE_COLORSPACE_ARGB8888
198}; 199};
199 200
200static const Emile_Colorspace cspaces_agry[3] = { 201static const Emile_Colorspace cspaces_gry[] = {
201 EMILE_COLORSPACE_GRY8, 202 EMILE_COLORSPACE_GRY8,
202 EMILE_COLORSPACE_AGRY88, 203 EMILE_COLORSPACE_AGRY88,
203 EMILE_COLORSPACE_ARGB8888 204 EMILE_COLORSPACE_ARGB8888
@@ -1414,7 +1415,7 @@ _emile_jpeg_head(Emile_Image *image,
1414 if (cinfo.jpeg_color_space == JCS_GRAYSCALE) 1415 if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
1415 { 1416 {
1416 /* We do handle GRY8 and AGRY88 (with FF for alpha) colorspace as an output for JPEG */ 1417 /* We do handle GRY8 and AGRY88 (with FF for alpha) colorspace as an output for JPEG */
1417 prop->cspaces = cspaces_agry; 1418 prop->cspaces = cspaces_gry;
1418 } 1419 }
1419 1420
1420 /* rotation decoding */ 1421 /* rotation decoding */
diff --git a/src/lib/evas/common/evas_image_load.c b/src/lib/evas/common/evas_image_load.c
index eacb6326b4..0d0261510e 100644
--- a/src/lib/evas/common/evas_image_load.c
+++ b/src/lib/evas/common/evas_image_load.c
@@ -215,7 +215,7 @@ _evas_image_file_header(Evas_Module *em, Image_Entry *ie, int *error)
215 goto load_error; 215 goto load_error;
216 } 216 }
217 217
218 memset(&property, 0, sizeof (Evas_Image_Property)); 218 memset(&property, 0, sizeof (property));
219 if (evas_image_load_func->file_head(ie->loader_data, &property, 219 if (evas_image_load_func->file_head(ie->loader_data, &property,
220 error) && 220 error) &&
221 (*error == EVAS_LOAD_ERROR_NONE)) 221 (*error == EVAS_LOAD_ERROR_NONE))
@@ -412,7 +412,7 @@ evas_common_load_rgba_image_data_from_file(Image_Entry *ie)
412 412
413 if (!ie->f) return EVAS_LOAD_ERROR_DOES_NOT_EXIST; 413 if (!ie->f) return EVAS_LOAD_ERROR_DOES_NOT_EXIST;
414 414
415 memset(&property, 0, sizeof (Evas_Image_Property)); 415 memset(&property, 0, sizeof (property));
416 property.w = ie->w; 416 property.w = ie->w;
417 property.h = ie->h; 417 property.h = ie->h;
418 property.scale = ie->scale; 418 property.scale = ie->scale;
diff --git a/src/modules/evas/image_loaders/eet/evas_image_load_eet.c b/src/modules/evas/image_loaders/eet/evas_image_load_eet.c
index 3c8e49bcb3..4e1f168b00 100644
--- a/src/modules/evas/image_loaders/eet/evas_image_load_eet.c
+++ b/src/modules/evas/image_loaders/eet/evas_image_load_eet.c
@@ -64,8 +64,17 @@ _evas_image_load_return_error(int err, int *error)
64 return EINA_FALSE; 64 return EINA_FALSE;
65} 65}
66 66
67static const Evas_Colorspace cspaces_etc1[2] = { 67static int
68_roundup(int val, int rup)
69{
70 if (val >= 0 && rup > 0)
71 return (val + rup - 1) - ((val + rup - 1) % rup);
72 return 0;
73}
74
75static const Evas_Colorspace cspaces_etc1[] = {
68 EVAS_COLORSPACE_ETC1, 76 EVAS_COLORSPACE_ETC1,
77 EVAS_COLORSPACE_RGB8_ETC2,
69 EVAS_COLORSPACE_ARGB8888 78 EVAS_COLORSPACE_ARGB8888
70}; 79};
71 80
@@ -93,6 +102,7 @@ evas_image_load_file_head_eet(void *loader_data,
93 int a, compression, quality; 102 int a, compression, quality;
94 Eet_Image_Encoding lossy; 103 Eet_Image_Encoding lossy;
95 const Eet_Colorspace *cspaces = NULL; 104 const Eet_Colorspace *cspaces = NULL;
105 Eina_Bool border_set = EINA_FALSE;
96 int ok; 106 int ok;
97 107
98 ok = eet_data_image_header_read(loader->ef, loader->key, 108 ok = eet_data_image_header_read(loader->ef, loader->key,
@@ -113,21 +123,25 @@ evas_image_load_file_head_eet(void *loader_data,
113 if (cspaces[i] == EET_COLORSPACE_ETC1) 123 if (cspaces[i] == EET_COLORSPACE_ETC1)
114 { 124 {
115 prop->cspaces = cspaces_etc1; 125 prop->cspaces = cspaces_etc1;
126 border_set = EINA_TRUE;
116 break; 127 break;
117 } 128 }
118 else if (cspaces[i] == EET_COLORSPACE_ETC1_ALPHA) 129 else if (cspaces[i] == EET_COLORSPACE_ETC1_ALPHA)
119 { 130 {
120 prop->cspaces = cspaces_etc1_alpha; 131 prop->cspaces = cspaces_etc1_alpha;
132 border_set = EINA_TRUE;
121 break; 133 break;
122 } 134 }
123 else if (cspaces[i] == EET_COLORSPACE_RGB8_ETC2) 135 else if (cspaces[i] == EET_COLORSPACE_RGB8_ETC2)
124 { 136 {
125 prop->cspaces = cspaces_etc2_rgb; 137 prop->cspaces = cspaces_etc2_rgb;
138 border_set = EINA_TRUE;
126 break; 139 break;
127 } 140 }
128 else if (cspaces[i] == EET_COLORSPACE_RGBA8_ETC2_EAC) 141 else if (cspaces[i] == EET_COLORSPACE_RGBA8_ETC2_EAC)
129 { 142 {
130 prop->cspaces = cspaces_etc2_rgba; 143 prop->cspaces = cspaces_etc2_rgba;
144 border_set = EINA_TRUE;
131 break; 145 break;
132 } 146 }
133 } 147 }
@@ -135,6 +149,13 @@ evas_image_load_file_head_eet(void *loader_data,
135 } 149 }
136 150
137 prop->alpha = !!a; 151 prop->alpha = !!a;
152 if (border_set)
153 {
154 prop->borders.l = 1;
155 prop->borders.t = 1;
156 prop->borders.r = _roundup(prop->w + 2, 4) - prop->w - 1;
157 prop->borders.b = _roundup(prop->h + 2, 4) - prop->h - 1;
158 }
138 *error = EVAS_LOAD_ERROR_NONE; 159 *error = EVAS_LOAD_ERROR_NONE;
139 160
140 return EINA_TRUE; 161 return EINA_TRUE;
diff --git a/src/modules/evas/image_loaders/jpeg/evas_image_load_jpeg.c b/src/modules/evas/image_loaders/jpeg/evas_image_load_jpeg.c
index e8374bc8a6..6813358c88 100644
--- a/src/modules/evas/image_loaders/jpeg/evas_image_load_jpeg.c
+++ b/src/modules/evas/image_loaders/jpeg/evas_image_load_jpeg.c
@@ -77,7 +77,7 @@ evas_image_load_file_head_jpeg(void *loader_data,
77 Eina_Bool ret; 77 Eina_Bool ret;
78 78
79 ret = emile_image_head(loader->image, 79 ret = emile_image_head(loader->image,
80 prop, sizeof (Emile_Image_Property), 80 prop, sizeof (*prop),
81 &image_error); 81 &image_error);
82 *error = image_error; 82 *error = image_error;
83 83
@@ -95,7 +95,7 @@ evas_image_load_file_data_jpeg(void *loader_data,
95 Eina_Bool ret; 95 Eina_Bool ret;
96 96
97 ret = emile_image_data(loader->image, 97 ret = emile_image_data(loader->image,
98 prop, sizeof (Emile_Image_Property), 98 prop, sizeof (*prop),
99 pixels, 99 pixels,
100 &image_error); 100 &image_error);
101 *error = image_error; 101 *error = image_error;
diff --git a/src/modules/evas/image_loaders/tgv/evas_image_load_tgv.c b/src/modules/evas/image_loaders/tgv/evas_image_load_tgv.c
index b13fff0d48..a75f9e2402 100644
--- a/src/modules/evas/image_loaders/tgv/evas_image_load_tgv.c
+++ b/src/modules/evas/image_loaders/tgv/evas_image_load_tgv.c
@@ -77,7 +77,7 @@ evas_image_load_file_head_tgv(void *loader_data,
77 Eina_Bool ret; 77 Eina_Bool ret;
78 78
79 ret = emile_image_head(loader->image, 79 ret = emile_image_head(loader->image,
80 prop, sizeof (Emile_Image_Property), 80 prop, sizeof (*prop),
81 &image_error); 81 &image_error);
82 *error = image_error; 82 *error = image_error;
83 83
@@ -95,7 +95,7 @@ evas_image_load_file_data_tgv(void *loader_data,
95 Eina_Bool ret; 95 Eina_Bool ret;
96 96
97 ret = emile_image_data(loader->image, 97 ret = emile_image_data(loader->image,
98 prop, sizeof (Emile_Image_Property), 98 prop, sizeof (*prop),
99 pixels, 99 pixels,
100 &image_error); 100 &image_error);
101 *error = image_error; 101 *error = image_error;