From f6a8bc32c65c339092425d19f1ef8571e5b45ddc Mon Sep 17 00:00:00 2001 From: Pavel Charvat Date: Sat, 11 Nov 2006 21:11:11 +0100 Subject: [PATCH] partial YCCK colorspace support --- images/color.c | 60 +++++++++++++++++++++++++++++++++++++++++++++ images/io-libjpeg.c | 7 +++++- 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/images/color.c b/images/color.c index 193a0f13..ee1525e0 100644 --- a/images/color.c +++ b/images/color.c @@ -248,6 +248,47 @@ pixel_conv_rgb_to_cmyk(byte *dest, byte *src) #define IMAGE_WALK_DO_STEP do{ pixel_conv_rgb_to_cmyk(walk_pos, walk_sec_pos); }while(0) #include "images/image-walk.h" +/* YCCK <-> RGB */ + +static inline void +pixel_conv_ycck_to_rgb(byte *dest, byte *src) +{ + int y = src[0], cb = src[1] - 128, cr = src[2] - 128; + uns d = (255 - src[3]) * (0xffffffffU / 255 /255); + dest[0] = (d * CLAMP(y + (91881 * cr) / 0x10000, 0, 255) >> 24); + dest[1] = (d * CLAMP(y - (22553 * cb + 46801 * cr) / 0x10000, 0, 255) >> 24); + dest[2] = (d * CLAMP(y + (116129 * cb) / 0x10000, 0, 255) >> 24); +} + +#define IMAGE_WALK_PREFIX(x) walk_##x +#define IMAGE_WALK_FUNC_NAME image_conv_ycck_4_to_rgb_n +#define IMAGE_WALK_DOUBLE +#define IMAGE_WALK_SEC_COL_STEP 4 +#define IMAGE_WALK_DO_STEP do{ pixel_conv_ycck_to_rgb(walk_pos, walk_sec_pos); }while(0) +#include "images/image-walk.h" + +static inline void +pixel_conv_rgb_to_ycck(byte *dest, byte *src) +{ + uns k = MAX(src[0], src[1]); + k = MAX(k, src[2]); + uns d = fast_div_u32_u8(0x7fffffffU, k); /* == 0 for zero K */ + uns r = 255 - ((d * (k - src[0])) >> 23); + uns g = 255 - ((d * (k - src[1])) >> 23); + uns b = 255 - ((d * (k - src[2])) >> 23); + dest[0] = (19595 * r + 38470 * g + 7471 * b) / 0x10000; + dest[1] = (0x800000 + 0x8000 * b - 11058 * r - 21710 * g) / 0x10000; + dest[2] = (0x800000 + 0x8000 * r - 27439 * g - 5329 * b) / 0x10000; + dest[3] = 255 - k; +} + +#define IMAGE_WALK_PREFIX(x) walk_##x +#define IMAGE_WALK_FUNC_NAME image_conv_rgb_n_to_ycck_4 +#define IMAGE_WALK_DOUBLE +#define IMAGE_WALK_COL_STEP 4 +#define IMAGE_WALK_DO_STEP do{ pixel_conv_rgb_to_ycck(walk_pos, walk_sec_pos); }while(0) +#include "images/image-walk.h" + /* Main functions */ static int @@ -287,6 +328,13 @@ image_conv_color_space(struct image_context *ctx UNUSED, struct image *dest, str return 1; } break; + case COLOR_SPACE_YCCK: + if (src->pixel_size == 4) + { + image_conv_ycck_4_to_rgb_n(dest, src); + return 1; + } + break; } break; case COLOR_SPACE_YCBCR: @@ -309,6 +357,18 @@ image_conv_color_space(struct image_context *ctx UNUSED, struct image *dest, str break; } break; + case COLOR_SPACE_YCCK: + switch (src->flags & IMAGE_CHANNELS_FORMAT) + { + case COLOR_SPACE_RGB: + if (dest->pixel_size == 4) + { + image_conv_rgb_n_to_ycck_4(dest, src); + return 1; + } + break; + } + break; } return 0; } diff --git a/images/io-libjpeg.c b/images/io-libjpeg.c index 03952519..a3120dfb 100644 --- a/images/io-libjpeg.c +++ b/images/io-libjpeg.c @@ -358,7 +358,11 @@ libjpeg_read_data(struct image_io *io) { case JCS_CMYK: read_flags = (read_flags & ~IMAGE_COLOR_SPACE & IMAGE_CHANNELS_FORMAT) | COLOR_SPACE_CMYK; - i->cinfo.out_color_space = JCS_YCbCr; + i->cinfo.out_color_space = JCS_CMYK; + break; + case JCS_YCCK: + read_flags = (read_flags & ~IMAGE_COLOR_SPACE & IMAGE_CHANNELS_FORMAT) | COLOR_SPACE_YCCK; + i->cinfo.out_color_space = JCS_YCCK; break; default: read_flags = (read_flags & ~IMAGE_COLOR_SPACE & IMAGE_CHANNELS_FORMAT) | COLOR_SPACE_RGB; @@ -520,6 +524,7 @@ libjpeg_write(struct image_io *io) } i.cinfo.input_components = color_space_channels[img->flags & IMAGE_COLOR_SPACE]; jpeg_set_defaults(&i.cinfo); + jpeg_set_colorspace(&i.cinfo, i.cinfo.in_color_space); if (io->jpeg_quality) jpeg_set_quality(&i.cinfo, MIN(io->jpeg_quality, 100), 1); if (io->exif_size) -- 2.39.2