diff --git a/ChangeLog.txt b/ChangeLog.txt index 1338f997..0f1f45c5 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -9,6 +9,10 @@ will not be SIMD-accelerated when using any of these scaling factors. platforms. This speeds up the decompression of 4:2:2 JPEGs by 20-25% on such platforms. +[3] Creating or decoding a JPEG file that uses the RGB colorspace should now +properly work when the input or output colorspace is one of the libjpeg-turbo +colorspace extensions. + 1.2.0 ===== diff --git a/jccolext.c b/jccolext.c index acbfa235..dbac84a9 100644 --- a/jccolext.c +++ b/jccolext.c @@ -2,7 +2,7 @@ * jccolext.c * * Copyright (C) 1991-1996, Thomas G. Lane. - * Copyright (C) 2009-2011, D. R. Commander. + * Copyright (C) 2009-2012, D. R. Commander. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -112,3 +112,35 @@ rgb_gray_convert_internal (j_compress_ptr cinfo, } } } + + +/* + * Convert some rows of samples to the JPEG colorspace. + * This version handles extended RGB->plain RGB conversion + */ + +INLINE +LOCAL(void) +rgb_rgb_convert_internal (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + register JSAMPROW inptr; + register JSAMPROW outptr0, outptr1, outptr2; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->image_width; + + while (--num_rows >= 0) { + inptr = *input_buf++; + outptr0 = output_buf[0][output_row]; + outptr1 = output_buf[1][output_row]; + outptr2 = output_buf[2][output_row]; + output_row++; + for (col = 0; col < num_cols; col++) { + outptr0[col] = GETJSAMPLE(inptr[RGB_RED]); + outptr1[col] = GETJSAMPLE(inptr[RGB_GREEN]); + outptr2[col] = GETJSAMPLE(inptr[RGB_BLUE]); + inptr += RGB_PIXELSIZE; + } + } +} diff --git a/jccolor.c b/jccolor.c index 97305557..3a0772bb 100644 --- a/jccolor.c +++ b/jccolor.c @@ -3,7 +3,7 @@ * * Copyright (C) 1991-1996, Thomas G. Lane. * Copyright 2009 Pierre Ossman for Cendio AB - * Copyright (C) 2009-2011, D. R. Commander. + * Copyright (C) 2009-2012, D. R. Commander. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -96,6 +96,7 @@ typedef my_color_converter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE #define rgb_ycc_convert_internal extrgb_ycc_convert_internal #define rgb_gray_convert_internal extrgb_gray_convert_internal +#define rgb_rgb_convert_internal extrgb_rgb_convert_internal #include "jccolext.c" #undef RGB_RED #undef RGB_GREEN @@ -103,6 +104,7 @@ typedef my_color_converter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef rgb_ycc_convert_internal #undef rgb_gray_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_RGBX_RED #define RGB_GREEN EXT_RGBX_GREEN @@ -110,6 +112,7 @@ typedef my_color_converter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE #define rgb_ycc_convert_internal extrgbx_ycc_convert_internal #define rgb_gray_convert_internal extrgbx_gray_convert_internal +#define rgb_rgb_convert_internal extrgbx_rgb_convert_internal #include "jccolext.c" #undef RGB_RED #undef RGB_GREEN @@ -117,6 +120,7 @@ typedef my_color_converter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef rgb_ycc_convert_internal #undef rgb_gray_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_BGR_RED #define RGB_GREEN EXT_BGR_GREEN @@ -124,6 +128,7 @@ typedef my_color_converter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE #define rgb_ycc_convert_internal extbgr_ycc_convert_internal #define rgb_gray_convert_internal extbgr_gray_convert_internal +#define rgb_rgb_convert_internal extbgr_rgb_convert_internal #include "jccolext.c" #undef RGB_RED #undef RGB_GREEN @@ -131,6 +136,7 @@ typedef my_color_converter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef rgb_ycc_convert_internal #undef rgb_gray_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_BGRX_RED #define RGB_GREEN EXT_BGRX_GREEN @@ -138,6 +144,7 @@ typedef my_color_converter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE #define rgb_ycc_convert_internal extbgrx_ycc_convert_internal #define rgb_gray_convert_internal extbgrx_gray_convert_internal +#define rgb_rgb_convert_internal extbgrx_rgb_convert_internal #include "jccolext.c" #undef RGB_RED #undef RGB_GREEN @@ -145,6 +152,7 @@ typedef my_color_converter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef rgb_ycc_convert_internal #undef rgb_gray_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_XBGR_RED #define RGB_GREEN EXT_XBGR_GREEN @@ -152,6 +160,7 @@ typedef my_color_converter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE #define rgb_ycc_convert_internal extxbgr_ycc_convert_internal #define rgb_gray_convert_internal extxbgr_gray_convert_internal +#define rgb_rgb_convert_internal extxbgr_rgb_convert_internal #include "jccolext.c" #undef RGB_RED #undef RGB_GREEN @@ -159,6 +168,7 @@ typedef my_color_converter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef rgb_ycc_convert_internal #undef rgb_gray_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_XRGB_RED #define RGB_GREEN EXT_XRGB_GREEN @@ -166,6 +176,7 @@ typedef my_color_converter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE #define rgb_ycc_convert_internal extxrgb_ycc_convert_internal #define rgb_gray_convert_internal extxrgb_gray_convert_internal +#define rgb_rgb_convert_internal extxrgb_rgb_convert_internal #include "jccolext.c" #undef RGB_RED #undef RGB_GREEN @@ -173,6 +184,7 @@ typedef my_color_converter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef rgb_ycc_convert_internal #undef rgb_gray_convert_internal +#undef rgb_rgb_convert_internal /* @@ -306,6 +318,52 @@ rgb_gray_convert (j_compress_ptr cinfo, } +/* + * Extended RGB to plain RGB conversion + */ + +METHODDEF(void) +rgb_rgb_convert (j_compress_ptr cinfo, + JSAMPARRAY input_buf, JSAMPIMAGE output_buf, + JDIMENSION output_row, int num_rows) +{ + switch (cinfo->in_color_space) { + case JCS_EXT_RGB: + extrgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, + num_rows); + break; + case JCS_EXT_RGBX: + case JCS_EXT_RGBA: + extrgbx_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, + num_rows); + break; + case JCS_EXT_BGR: + extbgr_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, + num_rows); + break; + case JCS_EXT_BGRX: + case JCS_EXT_BGRA: + extbgrx_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, + num_rows); + break; + case JCS_EXT_XBGR: + case JCS_EXT_ABGR: + extxbgr_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, + num_rows); + break; + case JCS_EXT_XRGB: + case JCS_EXT_ARGB: + extxrgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, + num_rows); + break; + default: + rgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row, + num_rows); + break; + } +} + + /* * Convert some rows of samples to the JPEG colorspace. * This version handles Adobe-style CMYK->YCCK conversion, @@ -523,21 +581,25 @@ jinit_color_converter (j_compress_ptr cinfo) break; case JCS_RGB: - case JCS_EXT_RGB: - case JCS_EXT_RGBX: - case JCS_EXT_BGR: - case JCS_EXT_BGRX: - case JCS_EXT_XBGR: - case JCS_EXT_XRGB: - case JCS_EXT_RGBA: - case JCS_EXT_BGRA: - case JCS_EXT_ABGR: - case JCS_EXT_ARGB: if (cinfo->num_components != 3) ERREXIT(cinfo, JERR_BAD_J_COLORSPACE); - if (cinfo->in_color_space == cinfo->jpeg_color_space && - rgb_pixelsize[cinfo->in_color_space] == 3) + if (rgb_red[cinfo->in_color_space] == 0 && + rgb_green[cinfo->in_color_space] == 1 && + rgb_blue[cinfo->in_color_space] == 2 && + rgb_pixelsize[cinfo->in_color_space] == 3) cconvert->pub.color_convert = null_convert; + else if (cinfo->in_color_space == JCS_RGB || + cinfo->in_color_space == JCS_EXT_RGB || + cinfo->in_color_space == JCS_EXT_RGBX || + cinfo->in_color_space == JCS_EXT_BGR || + cinfo->in_color_space == JCS_EXT_BGRX || + cinfo->in_color_space == JCS_EXT_XBGR || + cinfo->in_color_space == JCS_EXT_XRGB || + cinfo->in_color_space == JCS_EXT_RGBA || + cinfo->in_color_space == JCS_EXT_BGRA || + cinfo->in_color_space == JCS_EXT_ABGR || + cinfo->in_color_space == JCS_EXT_ARGB) + cconvert->pub.color_convert = rgb_rgb_convert; else ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); break; diff --git a/jdcolext.c b/jdcolext.c index 07da949f..3b8aeffc 100644 --- a/jdcolext.c +++ b/jdcolext.c @@ -102,3 +102,40 @@ gray_rgb_convert_internal (j_decompress_ptr cinfo, } } } + + +/* + * Convert RGB to extended RGB: just swap the order of source pixels + */ + +INLINE +LOCAL(void) +rgb_rgb_convert_internal (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + register JSAMPROW inptr0, inptr1, inptr2; + register JSAMPROW outptr; + register JDIMENSION col; + JDIMENSION num_cols = cinfo->output_width; + + while (--num_rows >= 0) { + inptr0 = input_buf[0][input_row]; + inptr1 = input_buf[1][input_row]; + inptr2 = input_buf[2][input_row]; + input_row++; + outptr = *output_buf++; + for (col = 0; col < num_cols; col++) { + /* We can dispense with GETJSAMPLE() here */ + outptr[RGB_RED] = inptr0[col]; + outptr[RGB_GREEN] = inptr1[col]; + outptr[RGB_BLUE] = inptr2[col]; + /* Set unused byte to 0xFF so it can be interpreted as an opaque */ + /* alpha channel value */ +#ifdef RGB_ALPHA + outptr[RGB_ALPHA] = 0xFF; +#endif + outptr += RGB_PIXELSIZE; + } + } +} diff --git a/jdcolor.c b/jdcolor.c index d9268dbb..694de9b6 100644 --- a/jdcolor.c +++ b/jdcolor.c @@ -3,7 +3,7 @@ * * Copyright (C) 1991-1997, Thomas G. Lane. * Copyright 2009 Pierre Ossman for Cendio AB - * Copyright (C) 2009, 2011, D. R. Commander. + * Copyright (C) 2009, 2011-2012, D. R. Commander. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -80,6 +80,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE #define ycc_rgb_convert_internal ycc_extrgb_convert_internal #define gray_rgb_convert_internal gray_extrgb_convert_internal +#define rgb_rgb_convert_internal rgb_extrgb_convert_internal #include "jdcolext.c" #undef RGB_RED #undef RGB_GREEN @@ -87,6 +88,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef ycc_rgb_convert_internal #undef gray_rgb_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_RGBX_RED #define RGB_GREEN EXT_RGBX_GREEN @@ -95,6 +97,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE #define ycc_rgb_convert_internal ycc_extrgbx_convert_internal #define gray_rgb_convert_internal gray_extrgbx_convert_internal +#define rgb_rgb_convert_internal rgb_extrgbx_convert_internal #include "jdcolext.c" #undef RGB_RED #undef RGB_GREEN @@ -103,6 +106,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef ycc_rgb_convert_internal #undef gray_rgb_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_BGR_RED #define RGB_GREEN EXT_BGR_GREEN @@ -110,6 +114,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE #define ycc_rgb_convert_internal ycc_extbgr_convert_internal #define gray_rgb_convert_internal gray_extbgr_convert_internal +#define rgb_rgb_convert_internal rgb_extbgr_convert_internal #include "jdcolext.c" #undef RGB_RED #undef RGB_GREEN @@ -117,6 +122,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef ycc_rgb_convert_internal #undef gray_rgb_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_BGRX_RED #define RGB_GREEN EXT_BGRX_GREEN @@ -125,6 +131,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE #define ycc_rgb_convert_internal ycc_extbgrx_convert_internal #define gray_rgb_convert_internal gray_extbgrx_convert_internal +#define rgb_rgb_convert_internal rgb_extbgrx_convert_internal #include "jdcolext.c" #undef RGB_RED #undef RGB_GREEN @@ -133,6 +140,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef ycc_rgb_convert_internal #undef gray_rgb_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_XBGR_RED #define RGB_GREEN EXT_XBGR_GREEN @@ -141,6 +149,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE #define ycc_rgb_convert_internal ycc_extxbgr_convert_internal #define gray_rgb_convert_internal gray_extxbgr_convert_internal +#define rgb_rgb_convert_internal rgb_extxbgr_convert_internal #include "jdcolext.c" #undef RGB_RED #undef RGB_GREEN @@ -149,6 +158,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef ycc_rgb_convert_internal #undef gray_rgb_convert_internal +#undef rgb_rgb_convert_internal #define RGB_RED EXT_XRGB_RED #define RGB_GREEN EXT_XRGB_GREEN @@ -157,6 +167,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE #define ycc_rgb_convert_internal ycc_extxrgb_convert_internal #define gray_rgb_convert_internal gray_extxrgb_convert_internal +#define rgb_rgb_convert_internal rgb_extxrgb_convert_internal #include "jdcolext.c" #undef RGB_RED #undef RGB_GREEN @@ -165,6 +176,7 @@ typedef my_color_deconverter * my_cconvert_ptr; #undef RGB_PIXELSIZE #undef ycc_rgb_convert_internal #undef gray_rgb_convert_internal +#undef rgb_rgb_convert_internal /* @@ -352,6 +364,51 @@ gray_rgb_convert (j_decompress_ptr cinfo, } +/* + * Convert plain RGB to extended RGB + */ + +METHODDEF(void) +rgb_rgb_convert (j_decompress_ptr cinfo, + JSAMPIMAGE input_buf, JDIMENSION input_row, + JSAMPARRAY output_buf, int num_rows) +{ + switch (cinfo->out_color_space) { + case JCS_EXT_RGB: + rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf, + num_rows); + break; + case JCS_EXT_RGBX: + case JCS_EXT_RGBA: + rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf, + num_rows); + break; + case JCS_EXT_BGR: + rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf, + num_rows); + break; + case JCS_EXT_BGRX: + case JCS_EXT_BGRA: + rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf, + num_rows); + break; + case JCS_EXT_XBGR: + case JCS_EXT_ABGR: + rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf, + num_rows); + break; + case JCS_EXT_XRGB: + case JCS_EXT_ARGB: + rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf, + num_rows); + break; + default: + rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf, + num_rows); + break; + } +} + /* * Adobe-style YCCK->CMYK conversion. * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same @@ -494,9 +551,14 @@ jinit_color_deconverter (j_decompress_ptr cinfo) } } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) { cconvert->pub.color_convert = gray_rgb_convert; - } else if (cinfo->jpeg_color_space == cinfo->out_color_space && - rgb_pixelsize[cinfo->out_color_space] == 3) { - cconvert->pub.color_convert = null_convert; + } else if (cinfo->jpeg_color_space == JCS_RGB) { + if (rgb_red[cinfo->out_color_space] == 0 && + rgb_green[cinfo->out_color_space] == 1 && + rgb_blue[cinfo->out_color_space] == 2 && + rgb_pixelsize[cinfo->out_color_space] == 3) + cconvert->pub.color_convert = null_convert; + else + cconvert->pub.color_convert = rgb_rgb_convert; } else ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL); break;