aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/eet
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2015-03-17 08:50:18 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-03-17 09:58:18 +0100
commitf9125499f9743a3ed551f1f1f2144b331d7e2056 (patch)
tree64dddb6bf77fb0b725510eb74457d925a2468aa3 /src/lib/eet
parentemile: remove use of custom structure and prefer Eina_Rectangle. (diff)
downloadefl-f9125499f9743a3ed551f1f1f2144b331d7e2056.tar.gz
eet: use Emile to decode TGV image section.
Diffstat (limited to 'src/lib/eet')
-rw-r--r--src/lib/eet/Eet.h19
-rw-r--r--src/lib/eet/eet_image.c318
2 files changed, 56 insertions, 281 deletions
diff --git a/src/lib/eet/Eet.h b/src/lib/eet/Eet.h
index 59560a5f07..2a100ae93c 100644
--- a/src/lib/eet/Eet.h
+++ b/src/lib/eet/Eet.h
@@ -96,8 +96,9 @@
#include <stdlib.h>
#include <stdio.h>
-#include <Eina.h>
#include <Efl_Config.h>
+#include <Eina.h>
+#include <Emile.h>
#ifdef EAPI
# undef EAPI
@@ -491,15 +492,13 @@ typedef enum _Eet_Image_Encoding
EET_IMAGE_ETC1_ALPHA = 5,
} Eet_Image_Encoding;
-typedef enum _Eet_Colorspace
-{
- EET_COLORSPACE_ARGB8888 = 0,
- /* The number between are reserved to preserve compatibility with evas */
- EET_COLORSPACE_ETC1 = 9,
- EET_COLORSPACE_RGB8_ETC2 = 10,
- EET_COLORSPACE_RGBA8_ETC2_EAC = 11,
- EET_COLORSPACE_ETC1_ALPHA = 12
-} Eet_Colorspace;
+typedef Emile_Colorspace Eet_Colorspace;
+
+#define EET_COLORSPACE_ARGB8888 EMILE_COLORSPACE_ARGB8888
+#define EET_COLORSPACE_ETC1 EMILE_COLORSPACE_ETC1
+#define EET_COLORSPACE_RGB8_ETC2 EMILE_COLORSPACE_RGB8_ETC2
+#define EET_COLORSPACE_RGBA8_ETC2_EAC EMILE_COLORSPACE_RGBA8_ETC2_EAC
+#define EET_COLORSPACE_ETC1_ALPHA EMILE_COLORSPACE_ETC1_ALPHA
/**
* @typedef Eet_File
diff --git a/src/lib/eet/eet_image.c b/src/lib/eet/eet_image.c
index ff77fe1b6b..f6aee861d9 100644
--- a/src/lib/eet/eet_image.c
+++ b/src/lib/eet/eet_image.c
@@ -775,36 +775,6 @@ _eet_argb_unpremul(unsigned int *data, unsigned int len)
}
}
-static inline unsigned int
-_tgv_length_get(const char *m, unsigned int length, unsigned int *offset)
-{
- unsigned int r = 0;
- unsigned int shift = 0;
-
- while (*offset < length && ((*m) & 0x80))
- {
- r = r | (((*m) & 0x7F) << shift);
- shift += 7;
- m++;
- (*offset)++;
- }
- if (*offset < length)
- {
- r = r | (((*m) & 0x7F) << shift);
- (*offset)++;
- }
-
- return r;
-}
-
-static int
-roundup(int val, int rup)
-{
- if (val >= 0 && rup > 0)
- return (val + rup - 1) - ((val + rup - 1) % rup);
- return 0;
-}
-
static int
eet_data_image_etc2_decode(const void *data,
unsigned int length,
@@ -817,266 +787,71 @@ eet_data_image_etc2_decode(const void *data,
Eet_Colorspace cspace,
Eet_Image_Encoding lossy)
{
- const char *m = NULL;
- unsigned int bwidth, bheight;
- unsigned char *p_etc;
- Eina_Binbuf *buffer = NULL;
- Eina_Rectangle master;
- unsigned int block_length;
- unsigned int offset;
- unsigned int x, y, w, h;
- unsigned int block_count;
- unsigned int etc_width = 0;
- unsigned int etc_block_size;
- unsigned int num_planes = 1, plane, alpha_offset = 0;
- Eet_Colorspace file_cspace;
- Eina_Bool compress, blockless, unpremul;
-
- m = data;
+ Emile_Image_Load_Opts opts;
+ Emile_Image_Property prop;
+ Emile_Image *image;
+ Eina_Binbuf *bin;
+ Emile_Image_Load_Error error;
+ int i;
// Fix for ABI incompatibility between 1.10 and 1.11
if (cspace == 8) cspace = 9;
- if (strncmp(m, "TGV1", 4) != 0)
- return 0;
+ bin = eina_binbuf_manage_read_only_new_length(data, length);
+ if (!bin) return 0;
- compress = m[OFFSET_OPTIONS] & 0x1;
- blockless = (m[OFFSET_OPTIONS] & 0x2) != 0;
- unpremul = (m[OFFSET_OPTIONS] & 0x4) != 0;
- w = ntohl(*((unsigned int*) &(m[OFFSET_WIDTH])));
- h = ntohl(*((unsigned int*) &(m[OFFSET_HEIGHT])));
+ opts.region.x = dst_x;
+ opts.region.y = dst_y;
+ opts.region.w = dst_w;
+ opts.region.h = dst_h;
- switch (m[OFFSET_ALGORITHM] & 0xFF)
- {
- case 0:
- if (lossy != EET_IMAGE_ETC1) return 0;
- file_cspace = EET_COLORSPACE_ETC1;
- if (alpha != EINA_FALSE) return 0;
- etc_block_size = 8;
- break;
- case 1:
- if (lossy != EET_IMAGE_ETC2_RGB) return 0;
- file_cspace = EET_COLORSPACE_RGB8_ETC2;
- if (alpha != EINA_FALSE) return 0;
- etc_block_size = 8;
- break;
- case 2:
- if (lossy != EET_IMAGE_ETC2_RGBA) return 0;
- file_cspace = EET_COLORSPACE_RGBA8_ETC2_EAC;
- if (alpha != EINA_TRUE) return 0;
- etc_block_size = 16;
- break;
- case 3:
- if (lossy != EET_IMAGE_ETC1_ALPHA) return 0;
- file_cspace = EET_COLORSPACE_ETC1_ALPHA;
- if (alpha != EINA_TRUE) return 0;
- etc_block_size = 8;
- num_planes = 2;
- alpha_offset = ((w + 2 + 3) / 4) * ((h + 2 + 3) / 4) * 8 / sizeof(*p_etc);
- break;
- default:
- return 0;
- }
- etc_width = ((w + 2 + 3) / 4) * etc_block_size;
+ image = emile_image_tgv_memory_open(bin, &opts, NULL, &error);
+ if (!image) return 0;
- if (cspace != EET_COLORSPACE_ARGB8888 && cspace != file_cspace)
- {
- if (!((cspace == EET_COLORSPACE_RGB8_ETC2) && (file_cspace == EET_COLORSPACE_ETC1)))
- return 0;
- // else: ETC2 is compatible with ETC1 and is preferred
- }
+ memset(&prop, sizeof (prop), 0);
- if (blockless)
- {
- bwidth = roundup(w + 2, 4);
- bheight = roundup(h + 2, 4);
- }
- else
+ if (!emile_image_head(image, &prop, sizeof (Emile_Image_Load_Opts), &error))
+ return 0;
+
+ for (i = 0; prop.cspaces[i] != EMILE_COLORSPACE_ARGB8888; i++)
{
- bwidth = 4 << (m[OFFSET_BLOCK_SIZE] & 0x0f);
- bheight = 4 << ((m[OFFSET_BLOCK_SIZE] & 0xf0) >> 4);
+ if (prop.cspaces[i] == cspace) break;
}
- EINA_RECTANGLE_SET(&master, dst_x, dst_y, dst_w, dst_h);
-
switch (cspace)
{
- case EET_COLORSPACE_ETC1:
- case EET_COLORSPACE_RGB8_ETC2:
- case EET_COLORSPACE_RGBA8_ETC2_EAC:
- case EET_COLORSPACE_ETC1_ALPHA:
- if (master.x % 4 || master.y % 4)
- abort();
- break;
+ case EMILE_COLORSPACE_ETC1:
+ if (lossy != EET_IMAGE_ETC1) return 0;
+ if (alpha != EINA_FALSE) return 0;
+ break;
+ case EMILE_COLORSPACE_RGB8_ETC2:
+ if (lossy != EET_IMAGE_ETC2_RGB) return 0;
+ if (alpha != EINA_FALSE) return 0;
+ break;
+ case EMILE_COLORSPACE_RGBA8_ETC2_EAC:
+ if (lossy != EET_IMAGE_ETC2_RGBA) return 0;
+ if (alpha != EINA_TRUE) return 0;
+ break;
+ case EMILE_COLORSPACE_ETC1_ALPHA:
+ if (lossy != EET_IMAGE_ETC1_ALPHA) return 0;
+ if (alpha != EINA_TRUE) return 0;
+ break;
case EET_COLORSPACE_ARGB8888:
- // Offset to take duplicated pixels into account
- master.x += 1;
- master.y += 1;
- break;
- default: abort();
+ break;
+ default:
+ return 0;
}
- p_etc = (unsigned char*) p;
- offset = OFFSET_BLOCKS;
-
- // Allocate space for each ETC block (8 or 16 bytes per 4 * 4 pixels group)
- block_count = bwidth * bheight / (4 * 4);
- if (compress)
- buffer = eina_binbuf_manage_read_only_new_length(alloca(etc_block_size * block_count), etc_block_size * block_count);
-
- for (plane = 0; plane < num_planes; plane++)
- for (y = 0; y < h + 2; y += bheight)
- for (x = 0; x < w + 2; x += bwidth)
- {
- Eina_Rectangle current;
- Eina_Binbuf *data_start;
- const char *it;
- unsigned int expand_length;
- unsigned int i, j;
-
- block_length = _tgv_length_get(m + offset, length, &offset);
-
- if (block_length == 0) goto on_error;
-
- data_start = eina_binbuf_manage_read_only_new_length(m + offset, block_length);
- offset += block_length;
-
- EINA_RECTANGLE_SET(&current, x, y,
- bwidth, bheight);
-
- if (!eina_rectangle_intersection(&current, &master))
- continue;
-
- if (compress)
- {
- if (!emile_binbuf_expand(data_start, buffer, EMILE_LZ4HC))
- goto on_error;
- }
- else
- {
- buffer = data_start;
- if (block_count * etc_block_size != block_length)
- goto on_error;
- }
- it = eina_binbuf_string_get(buffer);
-
- for (i = 0; i < bheight; i += 4)
- for (j = 0; j < bwidth; j += 4, it += etc_block_size)
- {
- Eina_Rectangle current_etc;
- unsigned int temporary[4 * 4];
- unsigned int offset_x, offset_y;
- int k, l;
-
- EINA_RECTANGLE_SET(&current_etc, x + j, y + i, 4, 4);
-
- if (!eina_rectangle_intersection(&current_etc, &current))
- continue;
-
- switch (cspace)
- {
- case EET_COLORSPACE_ARGB8888:
- switch (file_cspace)
- {
- case EET_COLORSPACE_ETC1:
- case EET_COLORSPACE_ETC1_ALPHA:
- if (!rg_etc1_unpack_block(it, temporary, 0))
- {
- // TODO: Should we decode as RGB8_ETC2?
- fprintf(stderr, "ETC1: Block starting at {%i, %i} is corrupted!\n", x + j, y + i);
- continue;
- }
- break;
- case EET_COLORSPACE_RGB8_ETC2:
- rg_etc2_rgb8_decode_block((uint8_t *) it, temporary);
- break;
- case EET_COLORSPACE_RGBA8_ETC2_EAC:
- rg_etc2_rgba8_decode_block((uint8_t *) it, temporary);
- break;
- default: abort();
- }
-
- offset_x = current_etc.x - x - j;
- offset_y = current_etc.y - y - i;
-
- if (!plane)
- {
-#ifdef BUILD_NEON
- if (eina_cpu_features_get() & EINA_CPU_NEON)
- {
- uint32_t *dst = &p[current_etc.x - 1 + (current_etc.y - 1) * master.w];
- uint32_t *src = &temporary[offset_x + offset_y * 4];
- for (k = 0; k < current_etc.h; k++)
- {
- if (current_etc.w == 4)
- vst1q_u32(dst, vld1q_u32(src));
- else if (current_etc.w == 3)
- {
- vst1_u32(dst, vld1_u32(src));
- *(dst + 2) = *(src + 2);
- }
- else if (current_etc.w == 2)
- vst1_u32(dst, vld1_u32(src));
- else
- *dst = *src;
- dst += master.w;
- src += 4;
- }
- }
- else
-#endif
- for (k = 0; k < current_etc.h; k++)
- {
- memcpy(&p[current_etc.x - 1 + (current_etc.y - 1 + k) * master.w],
- &temporary[offset_x + (offset_y + k) * 4],
- current_etc.w * sizeof (unsigned int));
- }
- }
- else
- {
- for (k = 0; k < current_etc.h; k++)
- for (l = 0; l < current_etc.w; l++)
- {
- unsigned int *rgbdata =
- &p[current_etc.x - 1 + (current_etc.y - 1 + k) * master.w + l];
- unsigned int *adata =
- &temporary[offset_x + (offset_y + k) * 4 + l];
- A_VAL(rgbdata) = G_VAL(adata);
- }
- }
- break;
- case EET_COLORSPACE_ETC1:
- case EET_COLORSPACE_RGB8_ETC2:
- case EET_COLORSPACE_RGBA8_ETC2_EAC:
- memcpy(&p_etc[(current_etc.x / 4) * etc_block_size +
- (current_etc.y / 4) * etc_width],
- it, etc_block_size);
- break;
- case EET_COLORSPACE_ETC1_ALPHA:
- memcpy(&p_etc[(current_etc.x / 4) * etc_block_size +
- (current_etc.y / 4) * etc_width +
- plane * alpha_offset],
- it, etc_block_size);
- break;
- default:
- abort();
- }
- } // bx,by inside blocks
-
- eina_binbuf_free(data_start);
- } // x,y macroblocks
-
- if (compress) eina_binbuf_free(buffer);
+ prop.cspace = cspace;
+
+ if (!emile_image_data(image, &prop, sizeof (Emile_Image_Load_Opts), p, &error))
+ return 0;
// TODO: Add support for more unpremultiplied modes (ETC2)
- if ((cspace == EET_COLORSPACE_ARGB8888) && unpremul)
- _eet_argb_premul(p, w * h);
+ if ((cspace == EET_COLORSPACE_ARGB8888) && !prop.premul)
+ _eet_argb_premul(p, prop.w * prop.h);
return 1;
-
-on_error:
- ERR("ETC image data is corrupted in this EET file");
- return 0;
}
static void *
@@ -2145,6 +1920,7 @@ eet_data_image_header_decode_cipher(const void *data,
{
const char *m = data;
+ // We only use Emile for decoding the actual data, seems simpler this way.
if (w) *w = ntohl(*((unsigned int*) &(m[OFFSET_WIDTH])));
if (h) *h = ntohl(*((unsigned int*) &(m[OFFSET_HEIGHT])));
if (comp) *comp = m[OFFSET_OPTIONS] & 0x1;
@@ -2306,7 +2082,7 @@ _eet_data_image_decode_inside(const void *data,
unsigned int src_x,
unsigned int src_y,
unsigned int src_w,
- EINA_UNUSED unsigned int src_h, /* useful for fast path detection */
+ unsigned int src_h, /* useful for fast path detection */
unsigned int *d,
unsigned int w,
unsigned int h,