summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2015-01-26 15:49:21 +0100
committerCedric BAIL <cedric@osg.samsung.com>2015-02-16 14:47:49 +0100
commit89d0c8b5705e2edf3485ee3498591f29a17928f8 (patch)
tree9867e4e45b624a7af01ffb136a105c687faef173
parent0d36844555e9ea50d6652e4f2d37c28f02aeae25 (diff)
downloadefl-89d0c8b5705e2edf3485ee3498591f29a17928f8.tar.gz
emile: decode GRAY JPEG as GRY8.
-rw-r--r--src/lib/emile/emile_image.c225
1 files changed, 196 insertions, 29 deletions
diff --git a/src/lib/emile/emile_image.c b/src/lib/emile/emile_image.c
index ff5cff35e3..9c43e385a4 100644
--- a/src/lib/emile/emile_image.c
+++ b/src/lib/emile/emile_image.c
@@ -1077,6 +1077,88 @@ _rotate_change_wh(uint32_t *to, uint32_t *from,
}
}
+static void
+_rotate8_180(uint8_t *data, int w, int h)
+{
+ uint8_t *p1, *p2;
+ uint8_t pt;
+ int x;
+
+ p1 = data;
+ p2 = data + (h * w) - 1;
+ for (x = (w * h) / 2; --x >= 0;)
+ {
+ pt = *p1;
+ *p1 = *p2;
+ *p2 = pt;
+ p1++;
+ p2--;
+ }
+}
+
+static void
+_flip_horizontal8(uint8_t *data, int w, int h)
+{
+ uint8_t *p1, *p2;
+ uint8_t pt;
+ int x, y;
+
+ for (y = 0; y < h; y++)
+ {
+ p1 = data + (y * w);
+ p2 = data + ((y + 1) * w) - 1;
+ for (x = 0; x < (w >> 1); x++)
+ {
+ pt = *p1;
+ *p1 = *p2;
+ *p2 = pt;
+ p1++;
+ p2--;
+ }
+ }
+}
+
+static void
+_flip_vertical8(uint8_t *data, int w, int h)
+{
+ uint8_t *p1, *p2;
+ uint8_t pt;
+ int x, y;
+
+ for (y = 0; y < (h >> 1); y++)
+ {
+ p1 = data + (y * w);
+ p2 = data + ((h - 1 - y) * w);
+ for (x = 0; x < w; x++)
+ {
+ pt = *p1;
+ *p1 = *p2;
+ *p2 = pt;
+ p1++;
+ p2++;
+ }
+ }
+}
+
+static void
+_rotate_change_wh8(uint8_t *to, uint8_t *from,
+ int w, int h,
+ int dx, int dy)
+{
+ int x, y;
+
+ for (x = h; --x >= 0;)
+ {
+ for (y = w; --y >= 0;)
+ {
+ *to = *from;
+ from++;
+ to += dy;
+ }
+ to += dx;
+ }
+}
+
static Eina_Bool
_emile_jpeg_bind(Emile_Image *image EINA_UNUSED,
Emile_Image_Load_Opts *opts EINA_UNUSED,
@@ -1139,12 +1221,6 @@ _emile_jpeg_head(Emile_Image *image,
return EINA_FALSE;
}
- if (cinfo.output_components == 1)
- {
- // We do handle GRY8 colorspace as an output for JPEG
- prop->cspaces = cspaces_gry;
- }
-
jpeg_read_header(&cinfo, TRUE);
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
@@ -1153,6 +1229,12 @@ _emile_jpeg_head(Emile_Image *image,
cinfo.buffered_image = TRUE; // buffered mode in case jpg is progressive
jpeg_start_decompress(&cinfo);
+ if (cinfo.jpeg_color_space == JCS_GRAYSCALE)
+ {
+ // We do handle GRY8 colorspace as an output for JPEG
+ prop->cspaces = cspaces_gry;
+ }
+
/* rotation decoding */
if (opts->orientation)
{
@@ -1332,6 +1414,7 @@ _emile_jpeg_data(Emile_Image *image,
const unsigned char *m = NULL;
uint8_t *ptr, *line[16], *data;
uint32_t *ptr2, *ptr_rotate = NULL;
+ uint8_t *ptrg, *ptrg_rotate = NULL;
unsigned int x, y, l, i, scans;
int region = 0;
/* rotation setting */
@@ -1398,6 +1481,11 @@ _emile_jpeg_data(Emile_Image *image,
case JCS_UNKNOWN:
break;
case JCS_GRAYSCALE:
+ if (prop->cspace == EMILE_COLORSPACE_GRY8)
+ {
+ cinfo.out_color_space = JCS_GRAYSCALE;
+ break;
+ }
case JCS_RGB:
case JCS_YCbCr:
cinfo.out_color_space = JCS_RGB;
@@ -1485,12 +1573,27 @@ _emile_jpeg_data(Emile_Image *image,
/* } */
}
- if (!(((cinfo.out_color_space == JCS_RGB) &&
- ((cinfo.output_components == 3) || (cinfo.output_components == 1))) ||
- ((cinfo.out_color_space == JCS_CMYK) && (cinfo.output_components == 4))))
+ switch (prop->cspace)
{
- *error = EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT;
- goto on_error;
+ case EMILE_COLORSPACE_GRY8:
+ if (!(cinfo.out_color_space == JCS_GRAYSCALE &&
+ cinfo.output_components == 1))
+ {
+ *error = EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT;
+ goto on_error;
+ }
+ break;
+ case EMILE_COLORSPACE_ARGB8888:
+ if (!((cinfo.out_color_space == JCS_RGB && cinfo.output_components == 3) ||
+ (cinfo.out_color_space == JCS_CMYK && cinfo.output_components == 4)))
+ {
+ *error = EMILE_IMAGE_LOAD_ERROR_UNKNOWN_FORMAT;
+ goto on_error;
+ }
+ break;
+ default:
+ *error = EMILE_IMAGE_LOAD_ERROR_GENERIC;
+ goto on_error;
}
/* end head decoding */
@@ -1503,13 +1606,24 @@ _emile_jpeg_data(Emile_Image *image,
data = alloca(w * 16 * cinfo.output_components);
if ((prop->rotated) && change_wh)
{
- ptr2 = malloc(w * h * sizeof(uint32_t));
- ptr_rotate = ptr2;
+ if (prop->cspace == EMILE_COLORSPACE_GRY8)
+ {
+ ptrg = malloc(w * h * sizeof(uint8_t));
+ ptrg_rotate = ptrg;
+ }
+ else
+ {
+ ptr2 = malloc(w * h * sizeof(uint32_t));
+ ptr_rotate = ptr2;
+ }
}
else
- ptr2 = pixels;
+ {
+ ptr2 = pixels;
+ ptrg = pixels;
+ }
- if (!ptr2)
+ if (!ptr2 && !ptrg)
{
*error = EMILE_IMAGE_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED;
goto on_error;
@@ -1742,9 +1856,17 @@ _emile_jpeg_data(Emile_Image *image,
{
for (x = 0; x < w; x++)
{
- *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
+ if (prop->cspace == EMILE_COLORSPACE_GRY8)
+ {
+ *ptrg = ptr[0];
+ ptrg++;
+ }
+ else
+ {
+ *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
+ ptr2++;
+ }
ptr++;
- ptr2++;
}
}
}
@@ -1773,9 +1895,17 @@ _emile_jpeg_data(Emile_Image *image,
ptr += opts_region.x;
for (x = 0; x < opts_region.w; x++)
{
- *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
+ if (prop->cspace == EMILE_COLORSPACE_GRY8)
+ {
+ *ptrg = ptr[0];
+ ptrg++;
+ }
+ else
+ {
+ *ptr2 = ARGB_JOIN(0xff, ptr[0], ptr[0], ptr[0]);
+ ptr2++;
+ }
ptr++;
- ptr2++;
}
ptr += w - (opts_region.x + opts_region.w);
}
@@ -1792,34 +1922,71 @@ done:
if (prop->rotated)
{
uint32_t *to;
+ uint8_t *to8;
int hw;
hw = w * h;
to = pixels;
+ to8 = pixels;
switch (degree)
{
case 90:
- if (prop->flipped)
- _rotate_change_wh(to + hw - 1, ptr_rotate, w, h, hw - 1, -h);
+ if (prop->cspace == EMILE_COLORSPACE_GRY8)
+ {
+ if (prop->flipped)
+ _rotate_change_wh8(to8 + hw - 1, ptrg_rotate, w, h, hw - 1, -h);
+ else
+ _rotate_change_wh8(to8 + h - 1, ptrg_rotate, w, h, -hw - 1, h);
+ }
else
- _rotate_change_wh(to + h - 1, ptr_rotate, w, h, -hw - 1, h);
+ {
+ if (prop->flipped)
+ _rotate_change_wh(to + hw - 1, ptr_rotate, w, h, hw - 1, -h);
+ else
+ _rotate_change_wh(to + h - 1, ptr_rotate, w, h, -hw - 1, h);
+ }
break;
case 180:
- if (prop->flipped)
- _flip_vertical(to, w, h);
+ if (prop->cspace == EMILE_COLORSPACE_GRY8)
+ {
+ if (prop->flipped)
+ _flip_vertical8(to8, w, h);
+ else
+ _rotate8_180(to8, w, h);
+ }
else
- _rotate_180(to, w, h);
+ {
+ if (prop->flipped)
+ _flip_vertical(to, w, h);
+ else
+ _rotate_180(to, w, h);
+ }
break;
case 270:
- if (prop->flipped)
- _rotate_change_wh(to, ptr_rotate, w, h, -hw + 1, h);
+ if (prop->cspace == EMILE_COLORSPACE_GRY8)
+ {
+ if (prop->flipped)
+ _rotate_change_wh8(to8, ptrg_rotate, w, h, -hw + 1, h);
+ else
+ _rotate_change_wh8(to8 + hw - h, ptrg_rotate, w, h, hw + 1, -h);
+ }
else
- _rotate_change_wh(to + hw - h, ptr_rotate, w, h, hw + 1, -h);
+ {
+ if (prop->flipped)
+ _rotate_change_wh(to, ptr_rotate, w, h, -hw + 1, h);
+ else
+ _rotate_change_wh(to + hw - h, ptr_rotate, w, h, hw + 1, -h);
+ }
break;
default:
if (prop->flipped)
- _flip_horizontal(to, w, h);
+ {
+ if (prop->cspace == EMILE_COLORSPACE_GRY8)
+ _flip_horizontal8(to8, w, h);
+ else
+ _flip_horizontal(to, w, h);
+ }
break;
}
if (ptr_rotate)