| Index: jdcolor.c
|
| diff --git a/jdcolor.c b/jdcolor.c
|
| index ccf9047911120dd2dde2b45e9626727fcbf1f4c7..2c68ed83b7d7f2eff1f079296f778f1516095058 100644
|
| --- a/jdcolor.c
|
| +++ b/jdcolor.c
|
| @@ -6,7 +6,8 @@
|
| * Modified 2011 by Guido Vollbeding.
|
| * libjpeg-turbo Modifications:
|
| * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
|
| - * Copyright (C) 2009, 2011-2012, D. R. Commander.
|
| + * Copyright (C) 2009, 2011-2012, 2014, D. R. Commander.
|
| + * Copyright (C) 2013, Linaro Limited.
|
| * For conditions of distribution and use, see the accompanying README file.
|
| *
|
| * This file contains output colorspace conversion routines.
|
| @@ -544,6 +545,164 @@ ycck_cmyk_convert (j_decompress_ptr cinfo,
|
|
|
|
|
| /*
|
| + * RGB565 conversion
|
| + */
|
| +
|
| +#define PACK_SHORT_565_LE(r, g, b) ((((r) << 8) & 0xF800) | \
|
| + (((g) << 3) & 0x7E0) | ((b) >> 3))
|
| +#define PACK_SHORT_565_BE(r, g, b) (((r) & 0xF8) | ((g) >> 5) | \
|
| + (((g) << 11) & 0xE000) | \
|
| + (((b) << 5) & 0x1F00))
|
| +
|
| +#define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l)
|
| +#define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r)
|
| +
|
| +#define PACK_NEED_ALIGNMENT(ptr) (((size_t)(ptr)) & 3)
|
| +
|
| +#define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(int *)(addr)) = pixels)
|
| +
|
| +#define DITHER_565_R(r, dither) ((r) + ((dither) & 0xFF))
|
| +#define DITHER_565_G(g, dither) ((g) + (((dither) & 0xFF) >> 1))
|
| +#define DITHER_565_B(b, dither) ((b) + ((dither) & 0xFF))
|
| +
|
| +
|
| +/* Declarations for ordered dithering
|
| + *
|
| + * We use a 4x4 ordered dither array packed into 32 bits. This array is
|
| + * sufficent for dithering RGB888 to RGB565.
|
| + */
|
| +
|
| +#define DITHER_MASK 0x3
|
| +#define DITHER_ROTATE(x) (((x) << 24) | (((x) >> 8) & 0x00FFFFFF))
|
| +static const INT32 dither_matrix[4] = {
|
| + 0x0008020A,
|
| + 0x0C040E06,
|
| + 0x030B0109,
|
| + 0x0F070D05
|
| +};
|
| +
|
| +
|
| +static INLINE boolean is_big_endian(void)
|
| +{
|
| + int test_value = 1;
|
| + if(*(char *)&test_value != 1)
|
| + return TRUE;
|
| + return FALSE;
|
| +}
|
| +
|
| +
|
| +/* Include inline routines for RGB565 conversion */
|
| +
|
| +#define PACK_SHORT_565 PACK_SHORT_565_LE
|
| +#define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE
|
| +#define ycc_rgb565_convert_internal ycc_rgb565_convert_le
|
| +#define ycc_rgb565D_convert_internal ycc_rgb565D_convert_le
|
| +#define rgb_rgb565_convert_internal rgb_rgb565_convert_le
|
| +#define rgb_rgb565D_convert_internal rgb_rgb565D_convert_le
|
| +#define gray_rgb565_convert_internal gray_rgb565_convert_le
|
| +#define gray_rgb565D_convert_internal gray_rgb565D_convert_le
|
| +#include "jdcol565.c"
|
| +#undef PACK_SHORT_565
|
| +#undef PACK_TWO_PIXELS
|
| +#undef ycc_rgb565_convert_internal
|
| +#undef ycc_rgb565D_convert_internal
|
| +#undef rgb_rgb565_convert_internal
|
| +#undef rgb_rgb565D_convert_internal
|
| +#undef gray_rgb565_convert_internal
|
| +#undef gray_rgb565D_convert_internal
|
| +
|
| +#define PACK_SHORT_565 PACK_SHORT_565_BE
|
| +#define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE
|
| +#define ycc_rgb565_convert_internal ycc_rgb565_convert_be
|
| +#define ycc_rgb565D_convert_internal ycc_rgb565D_convert_be
|
| +#define rgb_rgb565_convert_internal rgb_rgb565_convert_be
|
| +#define rgb_rgb565D_convert_internal rgb_rgb565D_convert_be
|
| +#define gray_rgb565_convert_internal gray_rgb565_convert_be
|
| +#define gray_rgb565D_convert_internal gray_rgb565D_convert_be
|
| +#include "jdcol565.c"
|
| +#undef PACK_SHORT_565
|
| +#undef PACK_TWO_PIXELS
|
| +#undef ycc_rgb565_convert_internal
|
| +#undef ycc_rgb565D_convert_internal
|
| +#undef rgb_rgb565_convert_internal
|
| +#undef rgb_rgb565D_convert_internal
|
| +#undef gray_rgb565_convert_internal
|
| +#undef gray_rgb565D_convert_internal
|
| +
|
| +
|
| +METHODDEF(void)
|
| +ycc_rgb565_convert (j_decompress_ptr cinfo,
|
| + JSAMPIMAGE input_buf, JDIMENSION input_row,
|
| + JSAMPARRAY output_buf, int num_rows)
|
| +{
|
| + if (is_big_endian())
|
| + ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
| + else
|
| + ycc_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
|
| +}
|
| +
|
| +
|
| +METHODDEF(void)
|
| +ycc_rgb565D_convert (j_decompress_ptr cinfo,
|
| + JSAMPIMAGE input_buf, JDIMENSION input_row,
|
| + JSAMPARRAY output_buf, int num_rows)
|
| +{
|
| + if (is_big_endian())
|
| + ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
| + else
|
| + ycc_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
|
| +}
|
| +
|
| +
|
| +METHODDEF(void)
|
| +rgb_rgb565_convert (j_decompress_ptr cinfo,
|
| + JSAMPIMAGE input_buf, JDIMENSION input_row,
|
| + JSAMPARRAY output_buf, int num_rows)
|
| +{
|
| + if (is_big_endian())
|
| + rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
| + else
|
| + rgb_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
|
| +}
|
| +
|
| +
|
| +METHODDEF(void)
|
| +rgb_rgb565D_convert (j_decompress_ptr cinfo,
|
| + JSAMPIMAGE input_buf, JDIMENSION input_row,
|
| + JSAMPARRAY output_buf, int num_rows)
|
| +{
|
| + if (is_big_endian())
|
| + rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
| + else
|
| + rgb_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
|
| +}
|
| +
|
| +
|
| +METHODDEF(void)
|
| +gray_rgb565_convert (j_decompress_ptr cinfo,
|
| + JSAMPIMAGE input_buf, JDIMENSION input_row,
|
| + JSAMPARRAY output_buf, int num_rows)
|
| +{
|
| + if (is_big_endian())
|
| + gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
| + else
|
| + gray_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
|
| +}
|
| +
|
| +
|
| +METHODDEF(void)
|
| +gray_rgb565D_convert (j_decompress_ptr cinfo,
|
| + JSAMPIMAGE input_buf, JDIMENSION input_row,
|
| + JSAMPARRAY output_buf, int num_rows)
|
| +{
|
| + if (is_big_endian())
|
| + gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
|
| + else
|
| + gray_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
|
| +}
|
| +
|
| +
|
| +/*
|
| * Empty method for start_pass.
|
| */
|
|
|
| @@ -649,7 +808,37 @@ jinit_color_deconverter (j_decompress_ptr cinfo)
|
| ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
| break;
|
|
|
| - case JCS_CMYK:
|
| + case JCS_RGB565:
|
| + cinfo->out_color_components = 3;
|
| + if (cinfo->dither_mode == JDITHER_NONE) {
|
| + if (cinfo->jpeg_color_space == JCS_YCbCr) {
|
| + if (jsimd_can_ycc_rgb565())
|
| + cconvert->pub.color_convert = jsimd_ycc_rgb565_convert;
|
| + else {
|
| + cconvert->pub.color_convert = ycc_rgb565_convert;
|
| + build_ycc_rgb_table(cinfo);
|
| + }
|
| + } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
|
| + cconvert->pub.color_convert = gray_rgb565_convert;
|
| + } else if (cinfo->jpeg_color_space == JCS_RGB) {
|
| + cconvert->pub.color_convert = rgb_rgb565_convert;
|
| + } else
|
| + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
| + } else {
|
| + /* only ordered dithering is supported */
|
| + if (cinfo->jpeg_color_space == JCS_YCbCr) {
|
| + cconvert->pub.color_convert = ycc_rgb565D_convert;
|
| + build_ycc_rgb_table(cinfo);
|
| + } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
|
| + cconvert->pub.color_convert = gray_rgb565D_convert;
|
| + } else if (cinfo->jpeg_color_space == JCS_RGB) {
|
| + cconvert->pub.color_convert = rgb_rgb565D_convert;
|
| + } else
|
| + ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
|
| + }
|
| + break;
|
| +
|
| +case JCS_CMYK:
|
| cinfo->out_color_components = 4;
|
| if (cinfo->jpeg_color_space == JCS_YCCK) {
|
| cconvert->pub.color_convert = ycck_cmyk_convert;
|
|
|