Path: blob/master/thirdparty/libjpeg-turbo/src/jdcolor.c
9904 views
/*1* jdcolor.c2*3* This file was part of the Independent JPEG Group's software:4* Copyright (C) 1991-1997, Thomas G. Lane.5* Modified 2011 by Guido Vollbeding.6* libjpeg-turbo Modifications:7* Copyright 2009 Pierre Ossman <[email protected]> for Cendio AB8* Copyright (C) 2009, 2011-2012, 2014-2015, 2022, 2024, D. R. Commander.9* Copyright (C) 2013, Linaro Limited.10* For conditions of distribution and use, see the accompanying README.ijg11* file.12*13* This file contains output colorspace conversion routines.14*/1516#define JPEG_INTERNALS17#include "jinclude.h"18#include "jpeglib.h"19#include "jsimd.h"20#include "jsamplecomp.h"212223#if BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED)2425/* Private subobject */2627typedef struct {28struct jpeg_color_deconverter pub; /* public fields */2930#if BITS_IN_JSAMPLE != 1631/* Private state for YCC->RGB conversion */32int *Cr_r_tab; /* => table for Cr to R conversion */33int *Cb_b_tab; /* => table for Cb to B conversion */34JLONG *Cr_g_tab; /* => table for Cr to G conversion */35JLONG *Cb_g_tab; /* => table for Cb to G conversion */3637/* Private state for RGB->Y conversion */38JLONG *rgb_y_tab; /* => table for RGB to Y conversion */39#endif40} my_color_deconverter;4142typedef my_color_deconverter *my_cconvert_ptr;434445/**************** YCbCr -> RGB conversion: most common case **************/46/**************** RGB -> Y conversion: less common case **************/4748/*49* YCbCr is defined per CCIR 601-1, except that Cb and Cr are50* normalized to the range 0.._MAXJSAMPLE rather than -0.5 .. 0.5.51* The conversion equations to be implemented are therefore52*53* R = Y + 1.40200 * Cr54* G = Y - 0.34414 * Cb - 0.71414 * Cr55* B = Y + 1.77200 * Cb56*57* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B58*59* where Cb and Cr represent the incoming values less _CENTERJSAMPLE.60* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)61*62* To avoid floating-point arithmetic, we represent the fractional constants63* as integers scaled up by 2^16 (about 4 digits precision); we have to divide64* the products by 2^16, with appropriate rounding, to get the correct answer.65* Notice that Y, being an integral input, does not contribute any fraction66* so it need not participate in the rounding.67*68* For even more speed, we avoid doing any multiplications in the inner loop69* by precalculating the constants times Cb and Cr for all possible values.70* For 8-bit samples this is very reasonable (only 256 entries per table);71* for 12-bit samples it is still acceptable. It's not very reasonable for72* 16-bit samples, but if you want lossless storage you shouldn't be changing73* colorspace anyway.74* The Cr=>R and Cb=>B values can be rounded to integers in advance; the75* values for the G calculation are left scaled up, since we must add them76* together before rounding.77*/7879#define SCALEBITS 16 /* speediest right-shift on some machines */80#define ONE_HALF ((JLONG)1 << (SCALEBITS - 1))81#define FIX(x) ((JLONG)((x) * (1L << SCALEBITS) + 0.5))8283/* We allocate one big table for RGB->Y conversion and divide it up into84* three parts, instead of doing three alloc_small requests. This lets us85* use a single table base address, which can be held in a register in the86* inner loops on many machines (more than can hold all three addresses,87* anyway).88*/8990#define R_Y_OFF 0 /* offset to R => Y section */91#define G_Y_OFF (1 * (_MAXJSAMPLE + 1)) /* offset to G => Y section */92#define B_Y_OFF (2 * (_MAXJSAMPLE + 1)) /* etc. */93#define TABLE_SIZE (3 * (_MAXJSAMPLE + 1))949596/* Include inline routines for colorspace extensions */9798#include "jdcolext.c"99#undef RGB_RED100#undef RGB_GREEN101#undef RGB_BLUE102#undef RGB_PIXELSIZE103104#define RGB_RED EXT_RGB_RED105#define RGB_GREEN EXT_RGB_GREEN106#define RGB_BLUE EXT_RGB_BLUE107#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE108#define ycc_rgb_convert_internal ycc_extrgb_convert_internal109#define gray_rgb_convert_internal gray_extrgb_convert_internal110#define rgb_rgb_convert_internal rgb_extrgb_convert_internal111#include "jdcolext.c"112#undef RGB_RED113#undef RGB_GREEN114#undef RGB_BLUE115#undef RGB_PIXELSIZE116#undef ycc_rgb_convert_internal117#undef gray_rgb_convert_internal118#undef rgb_rgb_convert_internal119120#define RGB_RED EXT_RGBX_RED121#define RGB_GREEN EXT_RGBX_GREEN122#define RGB_BLUE EXT_RGBX_BLUE123#define RGB_ALPHA 3124#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE125#define ycc_rgb_convert_internal ycc_extrgbx_convert_internal126#define gray_rgb_convert_internal gray_extrgbx_convert_internal127#define rgb_rgb_convert_internal rgb_extrgbx_convert_internal128#include "jdcolext.c"129#undef RGB_RED130#undef RGB_GREEN131#undef RGB_BLUE132#undef RGB_ALPHA133#undef RGB_PIXELSIZE134#undef ycc_rgb_convert_internal135#undef gray_rgb_convert_internal136#undef rgb_rgb_convert_internal137138#define RGB_RED EXT_BGR_RED139#define RGB_GREEN EXT_BGR_GREEN140#define RGB_BLUE EXT_BGR_BLUE141#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE142#define ycc_rgb_convert_internal ycc_extbgr_convert_internal143#define gray_rgb_convert_internal gray_extbgr_convert_internal144#define rgb_rgb_convert_internal rgb_extbgr_convert_internal145#include "jdcolext.c"146#undef RGB_RED147#undef RGB_GREEN148#undef RGB_BLUE149#undef RGB_PIXELSIZE150#undef ycc_rgb_convert_internal151#undef gray_rgb_convert_internal152#undef rgb_rgb_convert_internal153154#define RGB_RED EXT_BGRX_RED155#define RGB_GREEN EXT_BGRX_GREEN156#define RGB_BLUE EXT_BGRX_BLUE157#define RGB_ALPHA 3158#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE159#define ycc_rgb_convert_internal ycc_extbgrx_convert_internal160#define gray_rgb_convert_internal gray_extbgrx_convert_internal161#define rgb_rgb_convert_internal rgb_extbgrx_convert_internal162#include "jdcolext.c"163#undef RGB_RED164#undef RGB_GREEN165#undef RGB_BLUE166#undef RGB_ALPHA167#undef RGB_PIXELSIZE168#undef ycc_rgb_convert_internal169#undef gray_rgb_convert_internal170#undef rgb_rgb_convert_internal171172#define RGB_RED EXT_XBGR_RED173#define RGB_GREEN EXT_XBGR_GREEN174#define RGB_BLUE EXT_XBGR_BLUE175#define RGB_ALPHA 0176#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE177#define ycc_rgb_convert_internal ycc_extxbgr_convert_internal178#define gray_rgb_convert_internal gray_extxbgr_convert_internal179#define rgb_rgb_convert_internal rgb_extxbgr_convert_internal180#include "jdcolext.c"181#undef RGB_RED182#undef RGB_GREEN183#undef RGB_BLUE184#undef RGB_ALPHA185#undef RGB_PIXELSIZE186#undef ycc_rgb_convert_internal187#undef gray_rgb_convert_internal188#undef rgb_rgb_convert_internal189190#define RGB_RED EXT_XRGB_RED191#define RGB_GREEN EXT_XRGB_GREEN192#define RGB_BLUE EXT_XRGB_BLUE193#define RGB_ALPHA 0194#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE195#define ycc_rgb_convert_internal ycc_extxrgb_convert_internal196#define gray_rgb_convert_internal gray_extxrgb_convert_internal197#define rgb_rgb_convert_internal rgb_extxrgb_convert_internal198#include "jdcolext.c"199#undef RGB_RED200#undef RGB_GREEN201#undef RGB_BLUE202#undef RGB_ALPHA203#undef RGB_PIXELSIZE204#undef ycc_rgb_convert_internal205#undef gray_rgb_convert_internal206#undef rgb_rgb_convert_internal207208209/*210* Initialize tables for YCC->RGB colorspace conversion.211*/212213LOCAL(void)214build_ycc_rgb_table(j_decompress_ptr cinfo)215{216#if BITS_IN_JSAMPLE != 16217my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;218int i;219JLONG x;220SHIFT_TEMPS221222cconvert->Cr_r_tab = (int *)223(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,224(_MAXJSAMPLE + 1) * sizeof(int));225cconvert->Cb_b_tab = (int *)226(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,227(_MAXJSAMPLE + 1) * sizeof(int));228cconvert->Cr_g_tab = (JLONG *)229(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,230(_MAXJSAMPLE + 1) * sizeof(JLONG));231cconvert->Cb_g_tab = (JLONG *)232(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,233(_MAXJSAMPLE + 1) * sizeof(JLONG));234235for (i = 0, x = -_CENTERJSAMPLE; i <= _MAXJSAMPLE; i++, x++) {236/* i is the actual input pixel value, in the range 0.._MAXJSAMPLE */237/* The Cb or Cr value we are thinking of is x = i - _CENTERJSAMPLE */238/* Cr=>R value is nearest int to 1.40200 * x */239cconvert->Cr_r_tab[i] = (int)240RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);241/* Cb=>B value is nearest int to 1.77200 * x */242cconvert->Cb_b_tab[i] = (int)243RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);244/* Cr=>G value is scaled-up -0.71414 * x */245cconvert->Cr_g_tab[i] = (-FIX(0.71414)) * x;246/* Cb=>G value is scaled-up -0.34414 * x */247/* We also add in ONE_HALF so that need not do it in inner loop */248cconvert->Cb_g_tab[i] = (-FIX(0.34414)) * x + ONE_HALF;249}250#else251ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);252#endif253}254255256/*257* Convert some rows of samples to the output colorspace.258*/259260METHODDEF(void)261ycc_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,262JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)263{264switch (cinfo->out_color_space) {265case JCS_EXT_RGB:266ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,267num_rows);268break;269case JCS_EXT_RGBX:270case JCS_EXT_RGBA:271ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,272num_rows);273break;274case JCS_EXT_BGR:275ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,276num_rows);277break;278case JCS_EXT_BGRX:279case JCS_EXT_BGRA:280ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,281num_rows);282break;283case JCS_EXT_XBGR:284case JCS_EXT_ABGR:285ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,286num_rows);287break;288case JCS_EXT_XRGB:289case JCS_EXT_ARGB:290ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,291num_rows);292break;293default:294ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,295num_rows);296break;297}298}299300301/**************** Cases other than YCbCr -> RGB **************/302303304/*305* Initialize for RGB->grayscale colorspace conversion.306*/307308LOCAL(void)309build_rgb_y_table(j_decompress_ptr cinfo)310{311#if BITS_IN_JSAMPLE != 16312my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;313JLONG *rgb_y_tab;314JLONG i;315316/* Allocate and fill in the conversion tables. */317cconvert->rgb_y_tab = rgb_y_tab = (JLONG *)318(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,319(TABLE_SIZE * sizeof(JLONG)));320321for (i = 0; i <= _MAXJSAMPLE; i++) {322rgb_y_tab[i + R_Y_OFF] = FIX(0.29900) * i;323rgb_y_tab[i + G_Y_OFF] = FIX(0.58700) * i;324rgb_y_tab[i + B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;325}326#else327ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);328#endif329}330331332/*333* Convert RGB to grayscale.334*/335336METHODDEF(void)337rgb_gray_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,338JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)339{340#if BITS_IN_JSAMPLE != 16341my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;342register int r, g, b;343register JLONG *ctab = cconvert->rgb_y_tab;344register _JSAMPROW outptr;345register _JSAMPROW inptr0, inptr1, inptr2;346register JDIMENSION col;347JDIMENSION num_cols = cinfo->output_width;348349while (--num_rows >= 0) {350inptr0 = input_buf[0][input_row];351inptr1 = input_buf[1][input_row];352inptr2 = input_buf[2][input_row];353input_row++;354outptr = *output_buf++;355for (col = 0; col < num_cols; col++) {356r = inptr0[col];357g = inptr1[col];358b = inptr2[col];359/* Y */360outptr[col] = (_JSAMPLE)((ctab[r + R_Y_OFF] + ctab[g + G_Y_OFF] +361ctab[b + B_Y_OFF]) >> SCALEBITS);362}363}364#else365ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);366#endif367}368369370/*371* Color conversion for no colorspace change: just copy the data,372* converting from separate-planes to interleaved representation.373*/374375METHODDEF(void)376null_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,377JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)378{379register _JSAMPROW inptr, inptr0, inptr1, inptr2, inptr3, outptr;380register JDIMENSION col;381register int num_components = cinfo->num_components;382JDIMENSION num_cols = cinfo->output_width;383int ci;384385if (num_components == 3) {386while (--num_rows >= 0) {387inptr0 = input_buf[0][input_row];388inptr1 = input_buf[1][input_row];389inptr2 = input_buf[2][input_row];390input_row++;391outptr = *output_buf++;392for (col = 0; col < num_cols; col++) {393*outptr++ = inptr0[col];394*outptr++ = inptr1[col];395*outptr++ = inptr2[col];396}397}398} else if (num_components == 4) {399while (--num_rows >= 0) {400inptr0 = input_buf[0][input_row];401inptr1 = input_buf[1][input_row];402inptr2 = input_buf[2][input_row];403inptr3 = input_buf[3][input_row];404input_row++;405outptr = *output_buf++;406for (col = 0; col < num_cols; col++) {407*outptr++ = inptr0[col];408*outptr++ = inptr1[col];409*outptr++ = inptr2[col];410*outptr++ = inptr3[col];411}412}413} else {414while (--num_rows >= 0) {415for (ci = 0; ci < num_components; ci++) {416inptr = input_buf[ci][input_row];417outptr = *output_buf;418for (col = 0; col < num_cols; col++) {419outptr[ci] = inptr[col];420outptr += num_components;421}422}423output_buf++;424input_row++;425}426}427}428429430/*431* Color conversion for grayscale: just copy the data.432* This also works for YCbCr -> grayscale conversion, in which433* we just copy the Y (luminance) component and ignore chrominance.434*/435436METHODDEF(void)437grayscale_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,438JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)439{440_jcopy_sample_rows(input_buf[0], (int)input_row, output_buf, 0, num_rows,441cinfo->output_width);442}443444445/*446* Convert grayscale to RGB447*/448449METHODDEF(void)450gray_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,451JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)452{453switch (cinfo->out_color_space) {454case JCS_EXT_RGB:455gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,456num_rows);457break;458case JCS_EXT_RGBX:459case JCS_EXT_RGBA:460gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,461num_rows);462break;463case JCS_EXT_BGR:464gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,465num_rows);466break;467case JCS_EXT_BGRX:468case JCS_EXT_BGRA:469gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,470num_rows);471break;472case JCS_EXT_XBGR:473case JCS_EXT_ABGR:474gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,475num_rows);476break;477case JCS_EXT_XRGB:478case JCS_EXT_ARGB:479gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,480num_rows);481break;482default:483gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,484num_rows);485break;486}487}488489490/*491* Convert plain RGB to extended RGB492*/493494METHODDEF(void)495rgb_rgb_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,496JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)497{498switch (cinfo->out_color_space) {499case JCS_EXT_RGB:500rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,501num_rows);502break;503case JCS_EXT_RGBX:504case JCS_EXT_RGBA:505rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,506num_rows);507break;508case JCS_EXT_BGR:509rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,510num_rows);511break;512case JCS_EXT_BGRX:513case JCS_EXT_BGRA:514rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,515num_rows);516break;517case JCS_EXT_XBGR:518case JCS_EXT_ABGR:519rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,520num_rows);521break;522case JCS_EXT_XRGB:523case JCS_EXT_ARGB:524rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,525num_rows);526break;527default:528rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,529num_rows);530break;531}532}533534535/*536* Adobe-style YCCK->CMYK conversion.537* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same538* conversion as above, while passing K (black) unchanged.539* We assume build_ycc_rgb_table has been called.540*/541542METHODDEF(void)543ycck_cmyk_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,544JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)545{546#if BITS_IN_JSAMPLE != 16547my_cconvert_ptr cconvert = (my_cconvert_ptr)cinfo->cconvert;548register int y, cb, cr;549register _JSAMPROW outptr;550register _JSAMPROW inptr0, inptr1, inptr2, inptr3;551register JDIMENSION col;552JDIMENSION num_cols = cinfo->output_width;553/* copy these pointers into registers if possible */554register _JSAMPLE *range_limit = (_JSAMPLE *)cinfo->sample_range_limit;555register int *Crrtab = cconvert->Cr_r_tab;556register int *Cbbtab = cconvert->Cb_b_tab;557register JLONG *Crgtab = cconvert->Cr_g_tab;558register JLONG *Cbgtab = cconvert->Cb_g_tab;559SHIFT_TEMPS560561while (--num_rows >= 0) {562inptr0 = input_buf[0][input_row];563inptr1 = input_buf[1][input_row];564inptr2 = input_buf[2][input_row];565inptr3 = input_buf[3][input_row];566input_row++;567outptr = *output_buf++;568for (col = 0; col < num_cols; col++) {569y = inptr0[col];570cb = inptr1[col];571cr = inptr2[col];572/* Range-limiting is essential due to noise introduced by DCT losses. */573outptr[0] = range_limit[_MAXJSAMPLE - (y + Crrtab[cr])]; /* red */574outptr[1] = range_limit[_MAXJSAMPLE - (y + /* green */575((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],576SCALEBITS)))];577outptr[2] = range_limit[_MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */578/* K passes through unchanged */579outptr[3] = inptr3[col];580outptr += 4;581}582}583#else584ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);585#endif586}587588589/*590* RGB565 conversion591*/592593#define PACK_SHORT_565_LE(r, g, b) \594((((r) << 8) & 0xF800) | (((g) << 3) & 0x7E0) | ((b) >> 3))595#define PACK_SHORT_565_BE(r, g, b) \596(((r) & 0xF8) | ((g) >> 5) | (((g) << 11) & 0xE000) | (((b) << 5) & 0x1F00))597598#define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l)599#define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r)600601#define PACK_NEED_ALIGNMENT(ptr) (((size_t)(ptr)) & 3)602603#define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(int *)(addr)) = pixels)604605#define DITHER_565_R(r, dither) ((r) + ((dither) & 0xFF))606#define DITHER_565_G(g, dither) ((g) + (((dither) & 0xFF) >> 1))607#define DITHER_565_B(b, dither) ((b) + ((dither) & 0xFF))608609610/* Declarations for ordered dithering611*612* We use a 4x4 ordered dither array packed into 32 bits. This array is613* sufficient for dithering RGB888 to RGB565.614*/615616#define DITHER_MASK 0x3617#define DITHER_ROTATE(x) ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF))618static const JLONG dither_matrix[4] = {6190x0008020A,6200x0C040E06,6210x030B0109,6220x0F070D05623};624625626static INLINE boolean is_big_endian(void)627{628int test_value = 1;629if (*(char *)&test_value != 1)630return TRUE;631return FALSE;632}633634635/* Include inline routines for RGB565 conversion */636637#define PACK_SHORT_565 PACK_SHORT_565_LE638#define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE639#define ycc_rgb565_convert_internal ycc_rgb565_convert_le640#define ycc_rgb565D_convert_internal ycc_rgb565D_convert_le641#define rgb_rgb565_convert_internal rgb_rgb565_convert_le642#define rgb_rgb565D_convert_internal rgb_rgb565D_convert_le643#define gray_rgb565_convert_internal gray_rgb565_convert_le644#define gray_rgb565D_convert_internal gray_rgb565D_convert_le645#include "jdcol565.c"646#undef PACK_SHORT_565647#undef PACK_TWO_PIXELS648#undef ycc_rgb565_convert_internal649#undef ycc_rgb565D_convert_internal650#undef rgb_rgb565_convert_internal651#undef rgb_rgb565D_convert_internal652#undef gray_rgb565_convert_internal653#undef gray_rgb565D_convert_internal654655#define PACK_SHORT_565 PACK_SHORT_565_BE656#define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE657#define ycc_rgb565_convert_internal ycc_rgb565_convert_be658#define ycc_rgb565D_convert_internal ycc_rgb565D_convert_be659#define rgb_rgb565_convert_internal rgb_rgb565_convert_be660#define rgb_rgb565D_convert_internal rgb_rgb565D_convert_be661#define gray_rgb565_convert_internal gray_rgb565_convert_be662#define gray_rgb565D_convert_internal gray_rgb565D_convert_be663#include "jdcol565.c"664#undef PACK_SHORT_565665#undef PACK_TWO_PIXELS666#undef ycc_rgb565_convert_internal667#undef ycc_rgb565D_convert_internal668#undef rgb_rgb565_convert_internal669#undef rgb_rgb565D_convert_internal670#undef gray_rgb565_convert_internal671#undef gray_rgb565D_convert_internal672673674METHODDEF(void)675ycc_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,676JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)677{678if (is_big_endian())679ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);680else681ycc_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);682}683684685METHODDEF(void)686ycc_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,687JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)688{689if (is_big_endian())690ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);691else692ycc_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);693}694695696METHODDEF(void)697rgb_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,698JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)699{700if (is_big_endian())701rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);702else703rgb_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);704}705706707METHODDEF(void)708rgb_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,709JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)710{711if (is_big_endian())712rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);713else714rgb_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);715}716717718METHODDEF(void)719gray_rgb565_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,720JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)721{722if (is_big_endian())723gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);724else725gray_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);726}727728729METHODDEF(void)730gray_rgb565D_convert(j_decompress_ptr cinfo, _JSAMPIMAGE input_buf,731JDIMENSION input_row, _JSAMPARRAY output_buf, int num_rows)732{733if (is_big_endian())734gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);735else736gray_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);737}738739740/*741* Empty method for start_pass.742*/743744METHODDEF(void)745start_pass_dcolor(j_decompress_ptr cinfo)746{747/* no work needed */748}749750751/*752* Module initialization routine for output colorspace conversion.753*/754755GLOBAL(void)756_jinit_color_deconverter(j_decompress_ptr cinfo)757{758my_cconvert_ptr cconvert;759int ci;760761#ifdef D_LOSSLESS_SUPPORTED762if (cinfo->master->lossless) {763#if BITS_IN_JSAMPLE == 8764if (cinfo->data_precision > BITS_IN_JSAMPLE || cinfo->data_precision < 2)765#else766if (cinfo->data_precision > BITS_IN_JSAMPLE ||767cinfo->data_precision < BITS_IN_JSAMPLE - 3)768#endif769ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);770} else771#endif772{773if (cinfo->data_precision != BITS_IN_JSAMPLE)774ERREXIT1(cinfo, JERR_BAD_PRECISION, cinfo->data_precision);775}776777cconvert = (my_cconvert_ptr)778(*cinfo->mem->alloc_small) ((j_common_ptr)cinfo, JPOOL_IMAGE,779sizeof(my_color_deconverter));780cinfo->cconvert = (struct jpeg_color_deconverter *)cconvert;781cconvert->pub.start_pass = start_pass_dcolor;782783/* Make sure num_components agrees with jpeg_color_space */784switch (cinfo->jpeg_color_space) {785case JCS_GRAYSCALE:786if (cinfo->num_components != 1)787ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);788break;789790case JCS_RGB:791case JCS_YCbCr:792if (cinfo->num_components != 3)793ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);794break;795796case JCS_CMYK:797case JCS_YCCK:798if (cinfo->num_components != 4)799ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);800break;801802default: /* JCS_UNKNOWN can be anything */803if (cinfo->num_components < 1)804ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);805break;806}807808/* Set out_color_components and conversion method based on requested space.809* Also clear the component_needed flags for any unused components,810* so that earlier pipeline stages can avoid useless computation.811* NOTE: We do not allow any lossy color conversion algorithms in lossless812* mode.813*/814815switch (cinfo->out_color_space) {816case JCS_GRAYSCALE:817#ifdef D_LOSSLESS_SUPPORTED818if (cinfo->master->lossless &&819cinfo->jpeg_color_space != cinfo->out_color_space)820ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);821#endif822cinfo->out_color_components = 1;823if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||824cinfo->jpeg_color_space == JCS_YCbCr) {825cconvert->pub._color_convert = grayscale_convert;826/* For color->grayscale conversion, only the Y (0) component is needed */827for (ci = 1; ci < cinfo->num_components; ci++)828cinfo->comp_info[ci].component_needed = FALSE;829} else if (cinfo->jpeg_color_space == JCS_RGB) {830cconvert->pub._color_convert = rgb_gray_convert;831build_rgb_y_table(cinfo);832} else833ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);834break;835836case JCS_RGB:837case JCS_EXT_RGB:838case JCS_EXT_RGBX:839case JCS_EXT_BGR:840case JCS_EXT_BGRX:841case JCS_EXT_XBGR:842case JCS_EXT_XRGB:843case JCS_EXT_RGBA:844case JCS_EXT_BGRA:845case JCS_EXT_ABGR:846case JCS_EXT_ARGB:847#ifdef D_LOSSLESS_SUPPORTED848if (cinfo->master->lossless && cinfo->jpeg_color_space != JCS_RGB)849ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);850#endif851cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];852if (cinfo->jpeg_color_space == JCS_YCbCr) {853#ifdef WITH_SIMD854if (jsimd_can_ycc_rgb())855cconvert->pub._color_convert = jsimd_ycc_rgb_convert;856else857#endif858{859cconvert->pub._color_convert = ycc_rgb_convert;860build_ycc_rgb_table(cinfo);861}862} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {863cconvert->pub._color_convert = gray_rgb_convert;864} else if (cinfo->jpeg_color_space == JCS_RGB) {865if (rgb_red[cinfo->out_color_space] == 0 &&866rgb_green[cinfo->out_color_space] == 1 &&867rgb_blue[cinfo->out_color_space] == 2 &&868rgb_pixelsize[cinfo->out_color_space] == 3)869cconvert->pub._color_convert = null_convert;870else871cconvert->pub._color_convert = rgb_rgb_convert;872} else873ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);874break;875876case JCS_RGB565:877#ifdef D_LOSSLESS_SUPPORTED878if (cinfo->master->lossless)879ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);880#endif881cinfo->out_color_components = 3;882if (cinfo->dither_mode == JDITHER_NONE) {883if (cinfo->jpeg_color_space == JCS_YCbCr) {884#ifdef WITH_SIMD885if (jsimd_can_ycc_rgb565())886cconvert->pub._color_convert = jsimd_ycc_rgb565_convert;887else888#endif889{890cconvert->pub._color_convert = ycc_rgb565_convert;891build_ycc_rgb_table(cinfo);892}893} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {894cconvert->pub._color_convert = gray_rgb565_convert;895} else if (cinfo->jpeg_color_space == JCS_RGB) {896cconvert->pub._color_convert = rgb_rgb565_convert;897} else898ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);899} else {900/* only ordered dithering is supported */901if (cinfo->jpeg_color_space == JCS_YCbCr) {902cconvert->pub._color_convert = ycc_rgb565D_convert;903build_ycc_rgb_table(cinfo);904} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {905cconvert->pub._color_convert = gray_rgb565D_convert;906} else if (cinfo->jpeg_color_space == JCS_RGB) {907cconvert->pub._color_convert = rgb_rgb565D_convert;908} else909ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);910}911break;912913case JCS_CMYK:914#ifdef D_LOSSLESS_SUPPORTED915if (cinfo->master->lossless &&916cinfo->jpeg_color_space != cinfo->out_color_space)917ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);918#endif919cinfo->out_color_components = 4;920if (cinfo->jpeg_color_space == JCS_YCCK) {921cconvert->pub._color_convert = ycck_cmyk_convert;922build_ycc_rgb_table(cinfo);923} else if (cinfo->jpeg_color_space == JCS_CMYK) {924cconvert->pub._color_convert = null_convert;925} else926ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);927break;928929default:930/* Permit null conversion to same output space */931if (cinfo->out_color_space == cinfo->jpeg_color_space) {932cinfo->out_color_components = cinfo->num_components;933cconvert->pub._color_convert = null_convert;934} else /* unsupported non-null conversion */935ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);936break;937}938939if (cinfo->quantize_colors)940cinfo->output_components = 1; /* single colormapped output component */941else942cinfo->output_components = cinfo->out_color_components;943}944945#endif /* BITS_IN_JSAMPLE != 16 || defined(D_LOSSLESS_SUPPORTED) */946947948