forked from enlightenment/efl
emile: decode GRAY JPEG as GRY8.
This commit is contained in:
parent
1a8384cd3c
commit
bafe5e9a74
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue