* add support of CMYK, ICCK and grayscale images

* remove trailing spaces

fix ticket #303


SVN revision: 40515
This commit is contained in:
Vincent Torri 2009-05-05 21:48:50 +00:00
parent f73ad689da
commit 48c7e28b20
1 changed files with 90 additions and 15 deletions

View File

@ -1,4 +1,3 @@
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
@ -106,7 +105,7 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
w = cinfo.output_width;
h = cinfo.output_height;
if ((w < 1) || (h < 1) || (w > 8192) || (h > 8192))
{
{
jpeg_destroy_decompress(&cinfo);
return 0;
}
@ -143,18 +142,18 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
}
if (w < 1) w = 1;
if (h < 1) h = 1;
if ((w != cinfo.output_width) || (h != cinfo.output_height))
{
scalew = cinfo.output_width / w;
scaleh = cinfo.output_height / h;
ie->scale = scalew;
if (scaleh < scalew) ie->scale = scaleh;
if (ie->scale > 8) ie->scale = 8;
else if (ie->scale < 1) ie->scale = 1;
if (ie->scale == 3) ie->scale = 2;
else if (ie->scale == 5) ie->scale = 4;
else if (ie->scale == 6) ie->scale = 4;
@ -164,7 +163,7 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
if (ie->scale > 1)
{
jpeg_destroy_decompress(&cinfo);
rewind(f);
jpeg_create_decompress(&cinfo);
jpeg_stdio_src(&cinfo, f);
@ -176,7 +175,7 @@ evas_image_load_file_head_jpeg_internal(Image_Entry *ie, FILE *f)
jpeg_calc_output_dimensions(&(cinfo));
jpeg_start_decompress(&cinfo);
}
ie->w = cinfo.output_width;
ie->h = cinfo.output_height;
/* end head decoding */
@ -218,20 +217,46 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
cinfo.scale_num = 1;
cinfo.scale_denom = ie->scale;
}
/* Colorspace conversion options */
/* libjpeg can do the following conversions: */
/* GRAYSCLAE => RGB YCbCr => RGB and YCCK => CMYK */
switch (cinfo.jpeg_color_space)
{
case JCS_UNKNOWN:
break;
case JCS_GRAYSCALE:
case JCS_RGB:
case JCS_YCbCr:
cinfo.out_color_space = JCS_RGB;
break;
case JCS_CMYK:
case JCS_YCCK:
cinfo.out_color_space = JCS_CMYK;
break;
}
/* head decoding */
jpeg_calc_output_dimensions(&(cinfo));
jpeg_start_decompress(&cinfo);
w = cinfo.output_width;
h = cinfo.output_height;
if ((w != ie->w) || (h != ie->h))
{
jpeg_destroy_decompress(&cinfo);
return 0;
}
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)))
{
jpeg_destroy_decompress(&cinfo);
return 0;
}
/* end head decoding */
/* data decoding */
if (cinfo.rec_outbuf_height > 16)
@ -239,7 +264,7 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
jpeg_destroy_decompress(&cinfo);
return 0;
}
data = alloca(w * 16 * 3);
data = alloca(w * 16 * cinfo.output_components);
evas_cache_image_surface_alloc(ie, w, h);
if (ie->flags.loaded)
{
@ -249,7 +274,56 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
ptr2 = evas_cache_image_pixels(ie);
count = 0;
prevy = 0;
if (cinfo.output_components == 3)
/* We handle first CMYK (4 components) */
if (cinfo.output_components == 4)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
line[i] = data + (i * w * 4);
for (l = 0; l < h; l += cinfo.rec_outbuf_height)
{
jpeg_read_scanlines(&cinfo, line, cinfo.rec_outbuf_height);
scans = cinfo.rec_outbuf_height;
if ((h - l) < scans) scans = h - l;
ptr = data;
for (y = 0; y < scans; y++)
{
for (x = 0; x < w; x++)
{
if (cinfo.saw_Adobe_marker)
/* According to libjpeg doc, Photoshop inverse the values of C, M, Y and K, */
/* that is C is replaces by 255 - C, etc...*/
/* See the comment below for the computation of RGB values from CMYK ones. */
*ptr2 =
(0xff000000) |
((ptr[0] * ptr[3] / 255) << 16) |
((ptr[1] * ptr[3] / 255) << 8) |
((ptr[2] * ptr[3] / 255));
else
/* Conversion from CMYK to RGB is done in 2 steps: */
/* CMYK => CMY => RGB (see http://www.easyrgb.com/index.php?X=MATH) */
/* after computation, if C, M, Y and K are between 0 and 1, we have: */
/* R = (1 - C) * (1 - K) * 255 */
/* G = (1 - M) * (1 - K) * 255 */
/* B = (1 - Y) * (1 - K) * 255 */
/* libjpeg stores CMYK values between 0 and 255, */
/* so we replace C by C * 255 / 255, etc... and we obtain: */
/* R = (255 - C) * (255 - K) / 255 */
/* G = (255 - M) * (255 - K) / 255 */
/* B = (255 - Y) * (255 - K) / 255 */
/* with C, M, Y and K between 0 and 255. */
*ptr2 =
(0xff000000) |
(((255 - ptr[0]) * (255 - ptr[3]) / 255) << 16) |
(((255 - ptr[1]) * (255 - ptr[3]) / 255) << 8) |
(((255 - ptr[2]) * (255 - ptr[3]) / 255));
ptr += 4;
ptr2++;
}
}
}
}
/* We handle then RGB with 3 components */
else if (cinfo.output_components == 3)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
line[i] = data + (i * w * 3);
@ -271,6 +345,7 @@ evas_image_load_file_data_jpeg_internal(Image_Entry *ie, FILE *f)
}
}
}
/* We finally handle RGB with 1 component */
else if (cinfo.output_components == 1)
{
for (i = 0; i < cinfo.rec_outbuf_height; i++)
@ -440,7 +515,7 @@ module_open(Evas_Module *em)
EAPI void
module_close(void)
{
}
EAPI Evas_Module_Api evas_modapi =