Path: blob/master/3rdparty/libjpeg-turbo/src/jdcolor.c
16337 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, 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 "jconfigint.h"212223/* Private subobject */2425typedef struct {26struct jpeg_color_deconverter pub; /* public fields */2728/* Private state for YCC->RGB conversion */29int *Cr_r_tab; /* => table for Cr to R conversion */30int *Cb_b_tab; /* => table for Cb to B conversion */31JLONG *Cr_g_tab; /* => table for Cr to G conversion */32JLONG *Cb_g_tab; /* => table for Cb to G conversion */3334/* Private state for RGB->Y conversion */35JLONG *rgb_y_tab; /* => table for RGB to Y conversion */36} my_color_deconverter;3738typedef my_color_deconverter *my_cconvert_ptr;394041/**************** YCbCr -> RGB conversion: most common case **************/42/**************** RGB -> Y conversion: less common case **************/4344/*45* YCbCr is defined per CCIR 601-1, except that Cb and Cr are46* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.47* The conversion equations to be implemented are therefore48*49* R = Y + 1.40200 * Cr50* G = Y - 0.34414 * Cb - 0.71414 * Cr51* B = Y + 1.77200 * Cb52*53* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B54*55* where Cb and Cr represent the incoming values less CENTERJSAMPLE.56* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)57*58* To avoid floating-point arithmetic, we represent the fractional constants59* as integers scaled up by 2^16 (about 4 digits precision); we have to divide60* the products by 2^16, with appropriate rounding, to get the correct answer.61* Notice that Y, being an integral input, does not contribute any fraction62* so it need not participate in the rounding.63*64* For even more speed, we avoid doing any multiplications in the inner loop65* by precalculating the constants times Cb and Cr for all possible values.66* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);67* for 12-bit samples it is still acceptable. It's not very reasonable for68* 16-bit samples, but if you want lossless storage you shouldn't be changing69* colorspace anyway.70* The Cr=>R and Cb=>B values can be rounded to integers in advance; the71* values for the G calculation are left scaled up, since we must add them72* together before rounding.73*/7475#define SCALEBITS 16 /* speediest right-shift on some machines */76#define ONE_HALF ((JLONG) 1 << (SCALEBITS-1))77#define FIX(x) ((JLONG) ((x) * (1L<<SCALEBITS) + 0.5))7879/* We allocate one big table for RGB->Y conversion and divide it up into80* three parts, instead of doing three alloc_small requests. This lets us81* use a single table base address, which can be held in a register in the82* inner loops on many machines (more than can hold all three addresses,83* anyway).84*/8586#define R_Y_OFF 0 /* offset to R => Y section */87#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */88#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */89#define TABLE_SIZE (3*(MAXJSAMPLE+1))909192/* Include inline routines for colorspace extensions */9394#include "jdcolext.c"95#undef RGB_RED96#undef RGB_GREEN97#undef RGB_BLUE98#undef RGB_PIXELSIZE99100#define RGB_RED EXT_RGB_RED101#define RGB_GREEN EXT_RGB_GREEN102#define RGB_BLUE EXT_RGB_BLUE103#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE104#define ycc_rgb_convert_internal ycc_extrgb_convert_internal105#define gray_rgb_convert_internal gray_extrgb_convert_internal106#define rgb_rgb_convert_internal rgb_extrgb_convert_internal107#include "jdcolext.c"108#undef RGB_RED109#undef RGB_GREEN110#undef RGB_BLUE111#undef RGB_PIXELSIZE112#undef ycc_rgb_convert_internal113#undef gray_rgb_convert_internal114#undef rgb_rgb_convert_internal115116#define RGB_RED EXT_RGBX_RED117#define RGB_GREEN EXT_RGBX_GREEN118#define RGB_BLUE EXT_RGBX_BLUE119#define RGB_ALPHA 3120#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE121#define ycc_rgb_convert_internal ycc_extrgbx_convert_internal122#define gray_rgb_convert_internal gray_extrgbx_convert_internal123#define rgb_rgb_convert_internal rgb_extrgbx_convert_internal124#include "jdcolext.c"125#undef RGB_RED126#undef RGB_GREEN127#undef RGB_BLUE128#undef RGB_ALPHA129#undef RGB_PIXELSIZE130#undef ycc_rgb_convert_internal131#undef gray_rgb_convert_internal132#undef rgb_rgb_convert_internal133134#define RGB_RED EXT_BGR_RED135#define RGB_GREEN EXT_BGR_GREEN136#define RGB_BLUE EXT_BGR_BLUE137#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE138#define ycc_rgb_convert_internal ycc_extbgr_convert_internal139#define gray_rgb_convert_internal gray_extbgr_convert_internal140#define rgb_rgb_convert_internal rgb_extbgr_convert_internal141#include "jdcolext.c"142#undef RGB_RED143#undef RGB_GREEN144#undef RGB_BLUE145#undef RGB_PIXELSIZE146#undef ycc_rgb_convert_internal147#undef gray_rgb_convert_internal148#undef rgb_rgb_convert_internal149150#define RGB_RED EXT_BGRX_RED151#define RGB_GREEN EXT_BGRX_GREEN152#define RGB_BLUE EXT_BGRX_BLUE153#define RGB_ALPHA 3154#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE155#define ycc_rgb_convert_internal ycc_extbgrx_convert_internal156#define gray_rgb_convert_internal gray_extbgrx_convert_internal157#define rgb_rgb_convert_internal rgb_extbgrx_convert_internal158#include "jdcolext.c"159#undef RGB_RED160#undef RGB_GREEN161#undef RGB_BLUE162#undef RGB_ALPHA163#undef RGB_PIXELSIZE164#undef ycc_rgb_convert_internal165#undef gray_rgb_convert_internal166#undef rgb_rgb_convert_internal167168#define RGB_RED EXT_XBGR_RED169#define RGB_GREEN EXT_XBGR_GREEN170#define RGB_BLUE EXT_XBGR_BLUE171#define RGB_ALPHA 0172#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE173#define ycc_rgb_convert_internal ycc_extxbgr_convert_internal174#define gray_rgb_convert_internal gray_extxbgr_convert_internal175#define rgb_rgb_convert_internal rgb_extxbgr_convert_internal176#include "jdcolext.c"177#undef RGB_RED178#undef RGB_GREEN179#undef RGB_BLUE180#undef RGB_ALPHA181#undef RGB_PIXELSIZE182#undef ycc_rgb_convert_internal183#undef gray_rgb_convert_internal184#undef rgb_rgb_convert_internal185186#define RGB_RED EXT_XRGB_RED187#define RGB_GREEN EXT_XRGB_GREEN188#define RGB_BLUE EXT_XRGB_BLUE189#define RGB_ALPHA 0190#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE191#define ycc_rgb_convert_internal ycc_extxrgb_convert_internal192#define gray_rgb_convert_internal gray_extxrgb_convert_internal193#define rgb_rgb_convert_internal rgb_extxrgb_convert_internal194#include "jdcolext.c"195#undef RGB_RED196#undef RGB_GREEN197#undef RGB_BLUE198#undef RGB_ALPHA199#undef RGB_PIXELSIZE200#undef ycc_rgb_convert_internal201#undef gray_rgb_convert_internal202#undef rgb_rgb_convert_internal203204205/*206* Initialize tables for YCC->RGB colorspace conversion.207*/208209LOCAL(void)210build_ycc_rgb_table (j_decompress_ptr cinfo)211{212my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;213int i;214JLONG x;215SHIFT_TEMPS216217cconvert->Cr_r_tab = (int *)218(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,219(MAXJSAMPLE+1) * sizeof(int));220cconvert->Cb_b_tab = (int *)221(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,222(MAXJSAMPLE+1) * sizeof(int));223cconvert->Cr_g_tab = (JLONG *)224(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,225(MAXJSAMPLE+1) * sizeof(JLONG));226cconvert->Cb_g_tab = (JLONG *)227(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,228(MAXJSAMPLE+1) * sizeof(JLONG));229230for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {231/* i is the actual input pixel value, in the range 0..MAXJSAMPLE */232/* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */233/* Cr=>R value is nearest int to 1.40200 * x */234cconvert->Cr_r_tab[i] = (int)235RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);236/* Cb=>B value is nearest int to 1.77200 * x */237cconvert->Cb_b_tab[i] = (int)238RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);239/* Cr=>G value is scaled-up -0.71414 * x */240cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;241/* Cb=>G value is scaled-up -0.34414 * x */242/* We also add in ONE_HALF so that need not do it in inner loop */243cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;244}245}246247248/*249* Convert some rows of samples to the output colorspace.250*/251252METHODDEF(void)253ycc_rgb_convert (j_decompress_ptr cinfo,254JSAMPIMAGE input_buf, JDIMENSION input_row,255JSAMPARRAY output_buf, int num_rows)256{257switch (cinfo->out_color_space) {258case JCS_EXT_RGB:259ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,260num_rows);261break;262case JCS_EXT_RGBX:263case JCS_EXT_RGBA:264ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,265num_rows);266break;267case JCS_EXT_BGR:268ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,269num_rows);270break;271case JCS_EXT_BGRX:272case JCS_EXT_BGRA:273ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,274num_rows);275break;276case JCS_EXT_XBGR:277case JCS_EXT_ABGR:278ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,279num_rows);280break;281case JCS_EXT_XRGB:282case JCS_EXT_ARGB:283ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,284num_rows);285break;286default:287ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,288num_rows);289break;290}291}292293294/**************** Cases other than YCbCr -> RGB **************/295296297/*298* Initialize for RGB->grayscale colorspace conversion.299*/300301LOCAL(void)302build_rgb_y_table (j_decompress_ptr cinfo)303{304my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;305JLONG *rgb_y_tab;306JLONG i;307308/* Allocate and fill in the conversion tables. */309cconvert->rgb_y_tab = rgb_y_tab = (JLONG *)310(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,311(TABLE_SIZE * sizeof(JLONG)));312313for (i = 0; i <= MAXJSAMPLE; i++) {314rgb_y_tab[i+R_Y_OFF] = FIX(0.29900) * i;315rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i;316rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;317}318}319320321/*322* Convert RGB to grayscale.323*/324325METHODDEF(void)326rgb_gray_convert (j_decompress_ptr cinfo,327JSAMPIMAGE input_buf, JDIMENSION input_row,328JSAMPARRAY output_buf, int num_rows)329{330my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;331register int r, g, b;332register JLONG *ctab = cconvert->rgb_y_tab;333register JSAMPROW outptr;334register JSAMPROW inptr0, inptr1, inptr2;335register JDIMENSION col;336JDIMENSION num_cols = cinfo->output_width;337338while (--num_rows >= 0) {339inptr0 = input_buf[0][input_row];340inptr1 = input_buf[1][input_row];341inptr2 = input_buf[2][input_row];342input_row++;343outptr = *output_buf++;344for (col = 0; col < num_cols; col++) {345r = GETJSAMPLE(inptr0[col]);346g = GETJSAMPLE(inptr1[col]);347b = GETJSAMPLE(inptr2[col]);348/* Y */349outptr[col] = (JSAMPLE)350((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])351>> SCALEBITS);352}353}354}355356357/*358* Color conversion for no colorspace change: just copy the data,359* converting from separate-planes to interleaved representation.360*/361362METHODDEF(void)363null_convert (j_decompress_ptr cinfo,364JSAMPIMAGE input_buf, JDIMENSION input_row,365JSAMPARRAY output_buf, int num_rows)366{367register JSAMPROW inptr, inptr0, inptr1, inptr2, inptr3, outptr;368register JDIMENSION col;369register int num_components = cinfo->num_components;370JDIMENSION num_cols = cinfo->output_width;371int ci;372373if (num_components == 3) {374while (--num_rows >= 0) {375inptr0 = input_buf[0][input_row];376inptr1 = input_buf[1][input_row];377inptr2 = input_buf[2][input_row];378input_row++;379outptr = *output_buf++;380for (col = 0; col < num_cols; col++) {381*outptr++ = inptr0[col];382*outptr++ = inptr1[col];383*outptr++ = inptr2[col];384}385}386} else if (num_components == 4) {387while (--num_rows >= 0) {388inptr0 = input_buf[0][input_row];389inptr1 = input_buf[1][input_row];390inptr2 = input_buf[2][input_row];391inptr3 = input_buf[3][input_row];392input_row++;393outptr = *output_buf++;394for (col = 0; col < num_cols; col++) {395*outptr++ = inptr0[col];396*outptr++ = inptr1[col];397*outptr++ = inptr2[col];398*outptr++ = inptr3[col];399}400}401} else {402while (--num_rows >= 0) {403for (ci = 0; ci < num_components; ci++) {404inptr = input_buf[ci][input_row];405outptr = *output_buf;406for (col = 0; col < num_cols; col++) {407outptr[ci] = inptr[col];408outptr += num_components;409}410}411output_buf++;412input_row++;413}414}415}416417418/*419* Color conversion for grayscale: just copy the data.420* This also works for YCbCr -> grayscale conversion, in which421* we just copy the Y (luminance) component and ignore chrominance.422*/423424METHODDEF(void)425grayscale_convert (j_decompress_ptr cinfo,426JSAMPIMAGE input_buf, JDIMENSION input_row,427JSAMPARRAY output_buf, int num_rows)428{429jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,430num_rows, cinfo->output_width);431}432433434/*435* Convert grayscale to RGB436*/437438METHODDEF(void)439gray_rgb_convert (j_decompress_ptr cinfo,440JSAMPIMAGE input_buf, JDIMENSION input_row,441JSAMPARRAY output_buf, int num_rows)442{443switch (cinfo->out_color_space) {444case JCS_EXT_RGB:445gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,446num_rows);447break;448case JCS_EXT_RGBX:449case JCS_EXT_RGBA:450gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,451num_rows);452break;453case JCS_EXT_BGR:454gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,455num_rows);456break;457case JCS_EXT_BGRX:458case JCS_EXT_BGRA:459gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,460num_rows);461break;462case JCS_EXT_XBGR:463case JCS_EXT_ABGR:464gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,465num_rows);466break;467case JCS_EXT_XRGB:468case JCS_EXT_ARGB:469gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,470num_rows);471break;472default:473gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,474num_rows);475break;476}477}478479480/*481* Convert plain RGB to extended RGB482*/483484METHODDEF(void)485rgb_rgb_convert (j_decompress_ptr cinfo,486JSAMPIMAGE input_buf, JDIMENSION input_row,487JSAMPARRAY output_buf, int num_rows)488{489switch (cinfo->out_color_space) {490case JCS_EXT_RGB:491rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,492num_rows);493break;494case JCS_EXT_RGBX:495case JCS_EXT_RGBA:496rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,497num_rows);498break;499case JCS_EXT_BGR:500rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,501num_rows);502break;503case JCS_EXT_BGRX:504case JCS_EXT_BGRA:505rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,506num_rows);507break;508case JCS_EXT_XBGR:509case JCS_EXT_ABGR:510rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,511num_rows);512break;513case JCS_EXT_XRGB:514case JCS_EXT_ARGB:515rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,516num_rows);517break;518default:519rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,520num_rows);521break;522}523}524525526/*527* Adobe-style YCCK->CMYK conversion.528* We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same529* conversion as above, while passing K (black) unchanged.530* We assume build_ycc_rgb_table has been called.531*/532533METHODDEF(void)534ycck_cmyk_convert (j_decompress_ptr cinfo,535JSAMPIMAGE input_buf, JDIMENSION input_row,536JSAMPARRAY output_buf, int num_rows)537{538my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;539register int y, cb, cr;540register JSAMPROW outptr;541register JSAMPROW inptr0, inptr1, inptr2, inptr3;542register JDIMENSION col;543JDIMENSION num_cols = cinfo->output_width;544/* copy these pointers into registers if possible */545register JSAMPLE *range_limit = cinfo->sample_range_limit;546register int *Crrtab = cconvert->Cr_r_tab;547register int *Cbbtab = cconvert->Cb_b_tab;548register JLONG *Crgtab = cconvert->Cr_g_tab;549register JLONG *Cbgtab = cconvert->Cb_g_tab;550SHIFT_TEMPS551552while (--num_rows >= 0) {553inptr0 = input_buf[0][input_row];554inptr1 = input_buf[1][input_row];555inptr2 = input_buf[2][input_row];556inptr3 = input_buf[3][input_row];557input_row++;558outptr = *output_buf++;559for (col = 0; col < num_cols; col++) {560y = GETJSAMPLE(inptr0[col]);561cb = GETJSAMPLE(inptr1[col]);562cr = GETJSAMPLE(inptr2[col]);563/* Range-limiting is essential due to noise introduced by DCT losses. */564outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])]; /* red */565outptr[1] = range_limit[MAXJSAMPLE - (y + /* green */566((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],567SCALEBITS)))];568outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])]; /* blue */569/* K passes through unchanged */570outptr[3] = inptr3[col]; /* don't need GETJSAMPLE here */571outptr += 4;572}573}574}575576577/*578* RGB565 conversion579*/580581#define PACK_SHORT_565_LE(r, g, b) ((((r) << 8) & 0xF800) | \582(((g) << 3) & 0x7E0) | ((b) >> 3))583#define PACK_SHORT_565_BE(r, g, b) (((r) & 0xF8) | ((g) >> 5) | \584(((g) << 11) & 0xE000) | \585(((b) << 5) & 0x1F00))586587#define PACK_TWO_PIXELS_LE(l, r) ((r << 16) | l)588#define PACK_TWO_PIXELS_BE(l, r) ((l << 16) | r)589590#define PACK_NEED_ALIGNMENT(ptr) (((size_t)(ptr)) & 3)591592#define WRITE_TWO_ALIGNED_PIXELS(addr, pixels) ((*(int *)(addr)) = pixels)593594#define DITHER_565_R(r, dither) ((r) + ((dither) & 0xFF))595#define DITHER_565_G(g, dither) ((g) + (((dither) & 0xFF) >> 1))596#define DITHER_565_B(b, dither) ((b) + ((dither) & 0xFF))597598599/* Declarations for ordered dithering600*601* We use a 4x4 ordered dither array packed into 32 bits. This array is602* sufficent for dithering RGB888 to RGB565.603*/604605#define DITHER_MASK 0x3606#define DITHER_ROTATE(x) ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF))607static const JLONG dither_matrix[4] = {6080x0008020A,6090x0C040E06,6100x030B0109,6110x0F070D05612};613614615static INLINE boolean is_big_endian(void)616{617int test_value = 1;618if (*(char *)&test_value != 1)619return TRUE;620return FALSE;621}622623624/* Include inline routines for RGB565 conversion */625626#define PACK_SHORT_565 PACK_SHORT_565_LE627#define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE628#define ycc_rgb565_convert_internal ycc_rgb565_convert_le629#define ycc_rgb565D_convert_internal ycc_rgb565D_convert_le630#define rgb_rgb565_convert_internal rgb_rgb565_convert_le631#define rgb_rgb565D_convert_internal rgb_rgb565D_convert_le632#define gray_rgb565_convert_internal gray_rgb565_convert_le633#define gray_rgb565D_convert_internal gray_rgb565D_convert_le634#include "jdcol565.c"635#undef PACK_SHORT_565636#undef PACK_TWO_PIXELS637#undef ycc_rgb565_convert_internal638#undef ycc_rgb565D_convert_internal639#undef rgb_rgb565_convert_internal640#undef rgb_rgb565D_convert_internal641#undef gray_rgb565_convert_internal642#undef gray_rgb565D_convert_internal643644#define PACK_SHORT_565 PACK_SHORT_565_BE645#define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE646#define ycc_rgb565_convert_internal ycc_rgb565_convert_be647#define ycc_rgb565D_convert_internal ycc_rgb565D_convert_be648#define rgb_rgb565_convert_internal rgb_rgb565_convert_be649#define rgb_rgb565D_convert_internal rgb_rgb565D_convert_be650#define gray_rgb565_convert_internal gray_rgb565_convert_be651#define gray_rgb565D_convert_internal gray_rgb565D_convert_be652#include "jdcol565.c"653#undef PACK_SHORT_565654#undef PACK_TWO_PIXELS655#undef ycc_rgb565_convert_internal656#undef ycc_rgb565D_convert_internal657#undef rgb_rgb565_convert_internal658#undef rgb_rgb565D_convert_internal659#undef gray_rgb565_convert_internal660#undef gray_rgb565D_convert_internal661662663METHODDEF(void)664ycc_rgb565_convert (j_decompress_ptr cinfo,665JSAMPIMAGE input_buf, JDIMENSION input_row,666JSAMPARRAY output_buf, int num_rows)667{668if (is_big_endian())669ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);670else671ycc_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);672}673674675METHODDEF(void)676ycc_rgb565D_convert (j_decompress_ptr cinfo,677JSAMPIMAGE input_buf, JDIMENSION input_row,678JSAMPARRAY output_buf, int num_rows)679{680if (is_big_endian())681ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);682else683ycc_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);684}685686687METHODDEF(void)688rgb_rgb565_convert (j_decompress_ptr cinfo,689JSAMPIMAGE input_buf, JDIMENSION input_row,690JSAMPARRAY output_buf, int num_rows)691{692if (is_big_endian())693rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);694else695rgb_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);696}697698699METHODDEF(void)700rgb_rgb565D_convert (j_decompress_ptr cinfo,701JSAMPIMAGE input_buf, JDIMENSION input_row,702JSAMPARRAY output_buf, int num_rows)703{704if (is_big_endian())705rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);706else707rgb_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);708}709710711METHODDEF(void)712gray_rgb565_convert (j_decompress_ptr cinfo,713JSAMPIMAGE input_buf, JDIMENSION input_row,714JSAMPARRAY output_buf, int num_rows)715{716if (is_big_endian())717gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);718else719gray_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);720}721722723METHODDEF(void)724gray_rgb565D_convert (j_decompress_ptr cinfo,725JSAMPIMAGE input_buf, JDIMENSION input_row,726JSAMPARRAY output_buf, int num_rows)727{728if (is_big_endian())729gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);730else731gray_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);732}733734735/*736* Empty method for start_pass.737*/738739METHODDEF(void)740start_pass_dcolor (j_decompress_ptr cinfo)741{742/* no work needed */743}744745746/*747* Module initialization routine for output colorspace conversion.748*/749750GLOBAL(void)751jinit_color_deconverter (j_decompress_ptr cinfo)752{753my_cconvert_ptr cconvert;754int ci;755756cconvert = (my_cconvert_ptr)757(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,758sizeof(my_color_deconverter));759cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;760cconvert->pub.start_pass = start_pass_dcolor;761762/* Make sure num_components agrees with jpeg_color_space */763switch (cinfo->jpeg_color_space) {764case JCS_GRAYSCALE:765if (cinfo->num_components != 1)766ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);767break;768769case JCS_RGB:770case JCS_YCbCr:771if (cinfo->num_components != 3)772ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);773break;774775case JCS_CMYK:776case JCS_YCCK:777if (cinfo->num_components != 4)778ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);779break;780781default: /* JCS_UNKNOWN can be anything */782if (cinfo->num_components < 1)783ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);784break;785}786787/* Set out_color_components and conversion method based on requested space.788* Also clear the component_needed flags for any unused components,789* so that earlier pipeline stages can avoid useless computation.790*/791792switch (cinfo->out_color_space) {793case JCS_GRAYSCALE:794cinfo->out_color_components = 1;795if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||796cinfo->jpeg_color_space == JCS_YCbCr) {797cconvert->pub.color_convert = grayscale_convert;798/* For color->grayscale conversion, only the Y (0) component is needed */799for (ci = 1; ci < cinfo->num_components; ci++)800cinfo->comp_info[ci].component_needed = FALSE;801} else if (cinfo->jpeg_color_space == JCS_RGB) {802cconvert->pub.color_convert = rgb_gray_convert;803build_rgb_y_table(cinfo);804} else805ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);806break;807808case JCS_RGB:809case JCS_EXT_RGB:810case JCS_EXT_RGBX:811case JCS_EXT_BGR:812case JCS_EXT_BGRX:813case JCS_EXT_XBGR:814case JCS_EXT_XRGB:815case JCS_EXT_RGBA:816case JCS_EXT_BGRA:817case JCS_EXT_ABGR:818case JCS_EXT_ARGB:819cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];820if (cinfo->jpeg_color_space == JCS_YCbCr) {821if (jsimd_can_ycc_rgb())822cconvert->pub.color_convert = jsimd_ycc_rgb_convert;823else {824cconvert->pub.color_convert = ycc_rgb_convert;825build_ycc_rgb_table(cinfo);826}827} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {828cconvert->pub.color_convert = gray_rgb_convert;829} else if (cinfo->jpeg_color_space == JCS_RGB) {830if (rgb_red[cinfo->out_color_space] == 0 &&831rgb_green[cinfo->out_color_space] == 1 &&832rgb_blue[cinfo->out_color_space] == 2 &&833rgb_pixelsize[cinfo->out_color_space] == 3)834cconvert->pub.color_convert = null_convert;835else836cconvert->pub.color_convert = rgb_rgb_convert;837} else838ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);839break;840841case JCS_RGB565:842cinfo->out_color_components = 3;843if (cinfo->dither_mode == JDITHER_NONE) {844if (cinfo->jpeg_color_space == JCS_YCbCr) {845if (jsimd_can_ycc_rgb565())846cconvert->pub.color_convert = jsimd_ycc_rgb565_convert;847else {848cconvert->pub.color_convert = ycc_rgb565_convert;849build_ycc_rgb_table(cinfo);850}851} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {852cconvert->pub.color_convert = gray_rgb565_convert;853} else if (cinfo->jpeg_color_space == JCS_RGB) {854cconvert->pub.color_convert = rgb_rgb565_convert;855} else856ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);857} else {858/* only ordered dithering is supported */859if (cinfo->jpeg_color_space == JCS_YCbCr) {860cconvert->pub.color_convert = ycc_rgb565D_convert;861build_ycc_rgb_table(cinfo);862} else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {863cconvert->pub.color_convert = gray_rgb565D_convert;864} else if (cinfo->jpeg_color_space == JCS_RGB) {865cconvert->pub.color_convert = rgb_rgb565D_convert;866} else867ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);868}869break;870871case JCS_CMYK:872cinfo->out_color_components = 4;873if (cinfo->jpeg_color_space == JCS_YCCK) {874cconvert->pub.color_convert = ycck_cmyk_convert;875build_ycc_rgb_table(cinfo);876} else if (cinfo->jpeg_color_space == JCS_CMYK) {877cconvert->pub.color_convert = null_convert;878} else879ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);880break;881882default:883/* Permit null conversion to same output space */884if (cinfo->out_color_space == cinfo->jpeg_color_space) {885cinfo->out_color_components = cinfo->num_components;886cconvert->pub.color_convert = null_convert;887} else /* unsupported non-null conversion */888ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);889break;890}891892if (cinfo->quantize_colors)893cinfo->output_components = 1; /* single colormapped output component */894else895cinfo->output_components = cinfo->out_color_components;896}897898899