From 48c7e28b20d408f04208637aba0e260d102c90d6 Mon Sep 17 00:00:00 2001 From: Vincent Torri Date: Tue, 5 May 2009 21:48:50 +0000 Subject: [PATCH] * add support of CMYK, ICCK and grayscale images * remove trailing spaces fix ticket #303 SVN revision: 40515 --- .../loaders/jpeg/evas_image_load_jpeg.c | 105 +++++++++++++++--- 1 file changed, 90 insertions(+), 15 deletions(-) diff --git a/legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c b/legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c index 0b9210ce9b..de2c87a2c0 100644 --- a/legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c +++ b/legacy/evas/src/modules/loaders/jpeg/evas_image_load_jpeg.c @@ -1,4 +1,3 @@ - #ifdef HAVE_CONFIG_H # include #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 =