Path: blob/master/3rdparty/libjpeg-turbo/src/jccolor.c
16337 views
/*1* jccolor.c2*3* This file was part of the Independent JPEG Group's software:4* Copyright (C) 1991-1996, Thomas G. Lane.5* libjpeg-turbo Modifications:6* Copyright 2009 Pierre Ossman <[email protected]> for Cendio AB7* Copyright (C) 2009-2012, 2015, D. R. Commander.8* Copyright (C) 2014, MIPS Technologies, Inc., California.9* For conditions of distribution and use, see the accompanying README.ijg10* file.11*12* This file contains input colorspace conversion routines.13*/1415#define JPEG_INTERNALS16#include "jinclude.h"17#include "jpeglib.h"18#include "jsimd.h"19#include "jconfigint.h"202122/* Private subobject */2324typedef struct {25struct jpeg_color_converter pub; /* public fields */2627/* Private state for RGB->YCC conversion */28JLONG *rgb_ycc_tab; /* => table for RGB to YCbCr conversion */29} my_color_converter;3031typedef my_color_converter *my_cconvert_ptr;323334/**************** RGB -> YCbCr conversion: most common case **************/3536/*37* YCbCr is defined per CCIR 601-1, except that Cb and Cr are38* normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.39* The conversion equations to be implemented are therefore40* Y = 0.29900 * R + 0.58700 * G + 0.11400 * B41* Cb = -0.16874 * R - 0.33126 * G + 0.50000 * B + CENTERJSAMPLE42* Cr = 0.50000 * R - 0.41869 * G - 0.08131 * B + CENTERJSAMPLE43* (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)44* Note: older versions of the IJG code used a zero offset of MAXJSAMPLE/2,45* rather than CENTERJSAMPLE, for Cb and Cr. This gave equal positive and46* negative swings for Cb/Cr, but meant that grayscale values (Cb=Cr=0)47* were not represented exactly. Now we sacrifice exact representation of48* maximum red and maximum blue in order to get exact grayscales.49*50* To avoid floating-point arithmetic, we represent the fractional constants51* as integers scaled up by 2^16 (about 4 digits precision); we have to divide52* the products by 2^16, with appropriate rounding, to get the correct answer.53*54* For even more speed, we avoid doing any multiplications in the inner loop55* by precalculating the constants times R,G,B for all possible values.56* For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);57* for 12-bit samples it is still acceptable. It's not very reasonable for58* 16-bit samples, but if you want lossless storage you shouldn't be changing59* colorspace anyway.60* The CENTERJSAMPLE offsets and the rounding fudge-factor of 0.5 are included61* in the tables to save adding them separately in the inner loop.62*/6364#define SCALEBITS 16 /* speediest right-shift on some machines */65#define CBCR_OFFSET ((JLONG) CENTERJSAMPLE << SCALEBITS)66#define ONE_HALF ((JLONG) 1 << (SCALEBITS-1))67#define FIX(x) ((JLONG) ((x) * (1L<<SCALEBITS) + 0.5))6869/* We allocate one big table and divide it up into eight parts, instead of70* doing eight alloc_small requests. This lets us use a single table base71* address, which can be held in a register in the inner loops on many72* machines (more than can hold all eight addresses, anyway).73*/7475#define R_Y_OFF 0 /* offset to R => Y section */76#define G_Y_OFF (1*(MAXJSAMPLE+1)) /* offset to G => Y section */77#define B_Y_OFF (2*(MAXJSAMPLE+1)) /* etc. */78#define R_CB_OFF (3*(MAXJSAMPLE+1))79#define G_CB_OFF (4*(MAXJSAMPLE+1))80#define B_CB_OFF (5*(MAXJSAMPLE+1))81#define R_CR_OFF B_CB_OFF /* B=>Cb, R=>Cr are the same */82#define G_CR_OFF (6*(MAXJSAMPLE+1))83#define B_CR_OFF (7*(MAXJSAMPLE+1))84#define TABLE_SIZE (8*(MAXJSAMPLE+1))858687/* Include inline routines for colorspace extensions */8889#include "jccolext.c"90#undef RGB_RED91#undef RGB_GREEN92#undef RGB_BLUE93#undef RGB_PIXELSIZE9495#define RGB_RED EXT_RGB_RED96#define RGB_GREEN EXT_RGB_GREEN97#define RGB_BLUE EXT_RGB_BLUE98#define RGB_PIXELSIZE EXT_RGB_PIXELSIZE99#define rgb_ycc_convert_internal extrgb_ycc_convert_internal100#define rgb_gray_convert_internal extrgb_gray_convert_internal101#define rgb_rgb_convert_internal extrgb_rgb_convert_internal102#include "jccolext.c"103#undef RGB_RED104#undef RGB_GREEN105#undef RGB_BLUE106#undef RGB_PIXELSIZE107#undef rgb_ycc_convert_internal108#undef rgb_gray_convert_internal109#undef rgb_rgb_convert_internal110111#define RGB_RED EXT_RGBX_RED112#define RGB_GREEN EXT_RGBX_GREEN113#define RGB_BLUE EXT_RGBX_BLUE114#define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE115#define rgb_ycc_convert_internal extrgbx_ycc_convert_internal116#define rgb_gray_convert_internal extrgbx_gray_convert_internal117#define rgb_rgb_convert_internal extrgbx_rgb_convert_internal118#include "jccolext.c"119#undef RGB_RED120#undef RGB_GREEN121#undef RGB_BLUE122#undef RGB_PIXELSIZE123#undef rgb_ycc_convert_internal124#undef rgb_gray_convert_internal125#undef rgb_rgb_convert_internal126127#define RGB_RED EXT_BGR_RED128#define RGB_GREEN EXT_BGR_GREEN129#define RGB_BLUE EXT_BGR_BLUE130#define RGB_PIXELSIZE EXT_BGR_PIXELSIZE131#define rgb_ycc_convert_internal extbgr_ycc_convert_internal132#define rgb_gray_convert_internal extbgr_gray_convert_internal133#define rgb_rgb_convert_internal extbgr_rgb_convert_internal134#include "jccolext.c"135#undef RGB_RED136#undef RGB_GREEN137#undef RGB_BLUE138#undef RGB_PIXELSIZE139#undef rgb_ycc_convert_internal140#undef rgb_gray_convert_internal141#undef rgb_rgb_convert_internal142143#define RGB_RED EXT_BGRX_RED144#define RGB_GREEN EXT_BGRX_GREEN145#define RGB_BLUE EXT_BGRX_BLUE146#define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE147#define rgb_ycc_convert_internal extbgrx_ycc_convert_internal148#define rgb_gray_convert_internal extbgrx_gray_convert_internal149#define rgb_rgb_convert_internal extbgrx_rgb_convert_internal150#include "jccolext.c"151#undef RGB_RED152#undef RGB_GREEN153#undef RGB_BLUE154#undef RGB_PIXELSIZE155#undef rgb_ycc_convert_internal156#undef rgb_gray_convert_internal157#undef rgb_rgb_convert_internal158159#define RGB_RED EXT_XBGR_RED160#define RGB_GREEN EXT_XBGR_GREEN161#define RGB_BLUE EXT_XBGR_BLUE162#define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE163#define rgb_ycc_convert_internal extxbgr_ycc_convert_internal164#define rgb_gray_convert_internal extxbgr_gray_convert_internal165#define rgb_rgb_convert_internal extxbgr_rgb_convert_internal166#include "jccolext.c"167#undef RGB_RED168#undef RGB_GREEN169#undef RGB_BLUE170#undef RGB_PIXELSIZE171#undef rgb_ycc_convert_internal172#undef rgb_gray_convert_internal173#undef rgb_rgb_convert_internal174175#define RGB_RED EXT_XRGB_RED176#define RGB_GREEN EXT_XRGB_GREEN177#define RGB_BLUE EXT_XRGB_BLUE178#define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE179#define rgb_ycc_convert_internal extxrgb_ycc_convert_internal180#define rgb_gray_convert_internal extxrgb_gray_convert_internal181#define rgb_rgb_convert_internal extxrgb_rgb_convert_internal182#include "jccolext.c"183#undef RGB_RED184#undef RGB_GREEN185#undef RGB_BLUE186#undef RGB_PIXELSIZE187#undef rgb_ycc_convert_internal188#undef rgb_gray_convert_internal189#undef rgb_rgb_convert_internal190191192/*193* Initialize for RGB->YCC colorspace conversion.194*/195196METHODDEF(void)197rgb_ycc_start (j_compress_ptr cinfo)198{199my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;200JLONG *rgb_ycc_tab;201JLONG i;202203/* Allocate and fill in the conversion tables. */204cconvert->rgb_ycc_tab = rgb_ycc_tab = (JLONG *)205(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,206(TABLE_SIZE * sizeof(JLONG)));207208for (i = 0; i <= MAXJSAMPLE; i++) {209rgb_ycc_tab[i+R_Y_OFF] = FIX(0.29900) * i;210rgb_ycc_tab[i+G_Y_OFF] = FIX(0.58700) * i;211rgb_ycc_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;212rgb_ycc_tab[i+R_CB_OFF] = (-FIX(0.16874)) * i;213rgb_ycc_tab[i+G_CB_OFF] = (-FIX(0.33126)) * i;214/* We use a rounding fudge-factor of 0.5-epsilon for Cb and Cr.215* This ensures that the maximum output will round to MAXJSAMPLE216* not MAXJSAMPLE+1, and thus that we don't have to range-limit.217*/218rgb_ycc_tab[i+B_CB_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;219/* B=>Cb and R=>Cr tables are the same220rgb_ycc_tab[i+R_CR_OFF] = FIX(0.50000) * i + CBCR_OFFSET + ONE_HALF-1;221*/222rgb_ycc_tab[i+G_CR_OFF] = (-FIX(0.41869)) * i;223rgb_ycc_tab[i+B_CR_OFF] = (-FIX(0.08131)) * i;224}225}226227228/*229* Convert some rows of samples to the JPEG colorspace.230*/231232METHODDEF(void)233rgb_ycc_convert (j_compress_ptr cinfo,234JSAMPARRAY input_buf, JSAMPIMAGE output_buf,235JDIMENSION output_row, int num_rows)236{237switch (cinfo->in_color_space) {238case JCS_EXT_RGB:239extrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,240num_rows);241break;242case JCS_EXT_RGBX:243case JCS_EXT_RGBA:244extrgbx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,245num_rows);246break;247case JCS_EXT_BGR:248extbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,249num_rows);250break;251case JCS_EXT_BGRX:252case JCS_EXT_BGRA:253extbgrx_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,254num_rows);255break;256case JCS_EXT_XBGR:257case JCS_EXT_ABGR:258extxbgr_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,259num_rows);260break;261case JCS_EXT_XRGB:262case JCS_EXT_ARGB:263extxrgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,264num_rows);265break;266default:267rgb_ycc_convert_internal(cinfo, input_buf, output_buf, output_row,268num_rows);269break;270}271}272273274/**************** Cases other than RGB -> YCbCr **************/275276277/*278* Convert some rows of samples to the JPEG colorspace.279*/280281METHODDEF(void)282rgb_gray_convert (j_compress_ptr cinfo,283JSAMPARRAY input_buf, JSAMPIMAGE output_buf,284JDIMENSION output_row, int num_rows)285{286switch (cinfo->in_color_space) {287case JCS_EXT_RGB:288extrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,289num_rows);290break;291case JCS_EXT_RGBX:292case JCS_EXT_RGBA:293extrgbx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,294num_rows);295break;296case JCS_EXT_BGR:297extbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,298num_rows);299break;300case JCS_EXT_BGRX:301case JCS_EXT_BGRA:302extbgrx_gray_convert_internal(cinfo, input_buf, output_buf, output_row,303num_rows);304break;305case JCS_EXT_XBGR:306case JCS_EXT_ABGR:307extxbgr_gray_convert_internal(cinfo, input_buf, output_buf, output_row,308num_rows);309break;310case JCS_EXT_XRGB:311case JCS_EXT_ARGB:312extxrgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,313num_rows);314break;315default:316rgb_gray_convert_internal(cinfo, input_buf, output_buf, output_row,317num_rows);318break;319}320}321322323/*324* Extended RGB to plain RGB conversion325*/326327METHODDEF(void)328rgb_rgb_convert (j_compress_ptr cinfo,329JSAMPARRAY input_buf, JSAMPIMAGE output_buf,330JDIMENSION output_row, int num_rows)331{332switch (cinfo->in_color_space) {333case JCS_EXT_RGB:334extrgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,335num_rows);336break;337case JCS_EXT_RGBX:338case JCS_EXT_RGBA:339extrgbx_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,340num_rows);341break;342case JCS_EXT_BGR:343extbgr_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,344num_rows);345break;346case JCS_EXT_BGRX:347case JCS_EXT_BGRA:348extbgrx_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,349num_rows);350break;351case JCS_EXT_XBGR:352case JCS_EXT_ABGR:353extxbgr_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,354num_rows);355break;356case JCS_EXT_XRGB:357case JCS_EXT_ARGB:358extxrgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,359num_rows);360break;361default:362rgb_rgb_convert_internal(cinfo, input_buf, output_buf, output_row,363num_rows);364break;365}366}367368369/*370* Convert some rows of samples to the JPEG colorspace.371* This version handles Adobe-style CMYK->YCCK conversion,372* where we convert R=1-C, G=1-M, and B=1-Y to YCbCr using the same373* conversion as above, while passing K (black) unchanged.374* We assume rgb_ycc_start has been called.375*/376377METHODDEF(void)378cmyk_ycck_convert (j_compress_ptr cinfo,379JSAMPARRAY input_buf, JSAMPIMAGE output_buf,380JDIMENSION output_row, int num_rows)381{382my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;383register int r, g, b;384register JLONG *ctab = cconvert->rgb_ycc_tab;385register JSAMPROW inptr;386register JSAMPROW outptr0, outptr1, outptr2, outptr3;387register JDIMENSION col;388JDIMENSION num_cols = cinfo->image_width;389390while (--num_rows >= 0) {391inptr = *input_buf++;392outptr0 = output_buf[0][output_row];393outptr1 = output_buf[1][output_row];394outptr2 = output_buf[2][output_row];395outptr3 = output_buf[3][output_row];396output_row++;397for (col = 0; col < num_cols; col++) {398r = MAXJSAMPLE - GETJSAMPLE(inptr[0]);399g = MAXJSAMPLE - GETJSAMPLE(inptr[1]);400b = MAXJSAMPLE - GETJSAMPLE(inptr[2]);401/* K passes through as-is */402outptr3[col] = inptr[3]; /* don't need GETJSAMPLE here */403inptr += 4;404/* If the inputs are 0..MAXJSAMPLE, the outputs of these equations405* must be too; we do not need an explicit range-limiting operation.406* Hence the value being shifted is never negative, and we don't407* need the general RIGHT_SHIFT macro.408*/409/* Y */410outptr0[col] = (JSAMPLE)411((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])412>> SCALEBITS);413/* Cb */414outptr1[col] = (JSAMPLE)415((ctab[r+R_CB_OFF] + ctab[g+G_CB_OFF] + ctab[b+B_CB_OFF])416>> SCALEBITS);417/* Cr */418outptr2[col] = (JSAMPLE)419((ctab[r+R_CR_OFF] + ctab[g+G_CR_OFF] + ctab[b+B_CR_OFF])420>> SCALEBITS);421}422}423}424425426/*427* Convert some rows of samples to the JPEG colorspace.428* This version handles grayscale output with no conversion.429* The source can be either plain grayscale or YCbCr (since Y == gray).430*/431432METHODDEF(void)433grayscale_convert (j_compress_ptr cinfo,434JSAMPARRAY input_buf, JSAMPIMAGE output_buf,435JDIMENSION output_row, int num_rows)436{437register JSAMPROW inptr;438register JSAMPROW outptr;439register JDIMENSION col;440JDIMENSION num_cols = cinfo->image_width;441int instride = cinfo->input_components;442443while (--num_rows >= 0) {444inptr = *input_buf++;445outptr = output_buf[0][output_row];446output_row++;447for (col = 0; col < num_cols; col++) {448outptr[col] = inptr[0]; /* don't need GETJSAMPLE() here */449inptr += instride;450}451}452}453454455/*456* Convert some rows of samples to the JPEG colorspace.457* This version handles multi-component colorspaces without conversion.458* We assume input_components == num_components.459*/460461METHODDEF(void)462null_convert (j_compress_ptr cinfo,463JSAMPARRAY input_buf, JSAMPIMAGE output_buf,464JDIMENSION output_row, int num_rows)465{466register JSAMPROW inptr;467register JSAMPROW outptr, outptr0, outptr1, outptr2, outptr3;468register JDIMENSION col;469register int ci;470int nc = cinfo->num_components;471JDIMENSION num_cols = cinfo->image_width;472473if (nc == 3) {474while (--num_rows >= 0) {475inptr = *input_buf++;476outptr0 = output_buf[0][output_row];477outptr1 = output_buf[1][output_row];478outptr2 = output_buf[2][output_row];479output_row++;480for (col = 0; col < num_cols; col++) {481outptr0[col] = *inptr++;482outptr1[col] = *inptr++;483outptr2[col] = *inptr++;484}485}486} else if (nc == 4) {487while (--num_rows >= 0) {488inptr = *input_buf++;489outptr0 = output_buf[0][output_row];490outptr1 = output_buf[1][output_row];491outptr2 = output_buf[2][output_row];492outptr3 = output_buf[3][output_row];493output_row++;494for (col = 0; col < num_cols; col++) {495outptr0[col] = *inptr++;496outptr1[col] = *inptr++;497outptr2[col] = *inptr++;498outptr3[col] = *inptr++;499}500}501} else {502while (--num_rows >= 0) {503/* It seems fastest to make a separate pass for each component. */504for (ci = 0; ci < nc; ci++) {505inptr = *input_buf;506outptr = output_buf[ci][output_row];507for (col = 0; col < num_cols; col++) {508outptr[col] = inptr[ci]; /* don't need GETJSAMPLE() here */509inptr += nc;510}511}512input_buf++;513output_row++;514}515}516}517518519/*520* Empty method for start_pass.521*/522523METHODDEF(void)524null_method (j_compress_ptr cinfo)525{526/* no work needed */527}528529530/*531* Module initialization routine for input colorspace conversion.532*/533534GLOBAL(void)535jinit_color_converter (j_compress_ptr cinfo)536{537my_cconvert_ptr cconvert;538539cconvert = (my_cconvert_ptr)540(*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,541sizeof(my_color_converter));542cinfo->cconvert = (struct jpeg_color_converter *) cconvert;543/* set start_pass to null method until we find out differently */544cconvert->pub.start_pass = null_method;545546/* Make sure input_components agrees with in_color_space */547switch (cinfo->in_color_space) {548case JCS_GRAYSCALE:549if (cinfo->input_components != 1)550ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);551break;552553case JCS_RGB:554case JCS_EXT_RGB:555case JCS_EXT_RGBX:556case JCS_EXT_BGR:557case JCS_EXT_BGRX:558case JCS_EXT_XBGR:559case JCS_EXT_XRGB:560case JCS_EXT_RGBA:561case JCS_EXT_BGRA:562case JCS_EXT_ABGR:563case JCS_EXT_ARGB:564if (cinfo->input_components != rgb_pixelsize[cinfo->in_color_space])565ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);566break;567568case JCS_YCbCr:569if (cinfo->input_components != 3)570ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);571break;572573case JCS_CMYK:574case JCS_YCCK:575if (cinfo->input_components != 4)576ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);577break;578579default: /* JCS_UNKNOWN can be anything */580if (cinfo->input_components < 1)581ERREXIT(cinfo, JERR_BAD_IN_COLORSPACE);582break;583}584585/* Check num_components, set conversion method based on requested space */586switch (cinfo->jpeg_color_space) {587case JCS_GRAYSCALE:588if (cinfo->num_components != 1)589ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);590if (cinfo->in_color_space == JCS_GRAYSCALE)591cconvert->pub.color_convert = grayscale_convert;592else if (cinfo->in_color_space == JCS_RGB ||593cinfo->in_color_space == JCS_EXT_RGB ||594cinfo->in_color_space == JCS_EXT_RGBX ||595cinfo->in_color_space == JCS_EXT_BGR ||596cinfo->in_color_space == JCS_EXT_BGRX ||597cinfo->in_color_space == JCS_EXT_XBGR ||598cinfo->in_color_space == JCS_EXT_XRGB ||599cinfo->in_color_space == JCS_EXT_RGBA ||600cinfo->in_color_space == JCS_EXT_BGRA ||601cinfo->in_color_space == JCS_EXT_ABGR ||602cinfo->in_color_space == JCS_EXT_ARGB) {603if (jsimd_can_rgb_gray())604cconvert->pub.color_convert = jsimd_rgb_gray_convert;605else {606cconvert->pub.start_pass = rgb_ycc_start;607cconvert->pub.color_convert = rgb_gray_convert;608}609} else if (cinfo->in_color_space == JCS_YCbCr)610cconvert->pub.color_convert = grayscale_convert;611else612ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);613break;614615case JCS_RGB:616if (cinfo->num_components != 3)617ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);618if (rgb_red[cinfo->in_color_space] == 0 &&619rgb_green[cinfo->in_color_space] == 1 &&620rgb_blue[cinfo->in_color_space] == 2 &&621rgb_pixelsize[cinfo->in_color_space] == 3) {622#if defined(__mips__)623if (jsimd_c_can_null_convert())624cconvert->pub.color_convert = jsimd_c_null_convert;625else626#endif627cconvert->pub.color_convert = null_convert;628} else if (cinfo->in_color_space == JCS_RGB ||629cinfo->in_color_space == JCS_EXT_RGB ||630cinfo->in_color_space == JCS_EXT_RGBX ||631cinfo->in_color_space == JCS_EXT_BGR ||632cinfo->in_color_space == JCS_EXT_BGRX ||633cinfo->in_color_space == JCS_EXT_XBGR ||634cinfo->in_color_space == JCS_EXT_XRGB ||635cinfo->in_color_space == JCS_EXT_RGBA ||636cinfo->in_color_space == JCS_EXT_BGRA ||637cinfo->in_color_space == JCS_EXT_ABGR ||638cinfo->in_color_space == JCS_EXT_ARGB)639cconvert->pub.color_convert = rgb_rgb_convert;640else641ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);642break;643644case JCS_YCbCr:645if (cinfo->num_components != 3)646ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);647if (cinfo->in_color_space == JCS_RGB ||648cinfo->in_color_space == JCS_EXT_RGB ||649cinfo->in_color_space == JCS_EXT_RGBX ||650cinfo->in_color_space == JCS_EXT_BGR ||651cinfo->in_color_space == JCS_EXT_BGRX ||652cinfo->in_color_space == JCS_EXT_XBGR ||653cinfo->in_color_space == JCS_EXT_XRGB ||654cinfo->in_color_space == JCS_EXT_RGBA ||655cinfo->in_color_space == JCS_EXT_BGRA ||656cinfo->in_color_space == JCS_EXT_ABGR ||657cinfo->in_color_space == JCS_EXT_ARGB) {658if (jsimd_can_rgb_ycc())659cconvert->pub.color_convert = jsimd_rgb_ycc_convert;660else {661cconvert->pub.start_pass = rgb_ycc_start;662cconvert->pub.color_convert = rgb_ycc_convert;663}664} else if (cinfo->in_color_space == JCS_YCbCr) {665#if defined(__mips__)666if (jsimd_c_can_null_convert())667cconvert->pub.color_convert = jsimd_c_null_convert;668else669#endif670cconvert->pub.color_convert = null_convert;671} else672ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);673break;674675case JCS_CMYK:676if (cinfo->num_components != 4)677ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);678if (cinfo->in_color_space == JCS_CMYK) {679#if defined(__mips__)680if (jsimd_c_can_null_convert())681cconvert->pub.color_convert = jsimd_c_null_convert;682else683#endif684cconvert->pub.color_convert = null_convert;685} else686ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);687break;688689case JCS_YCCK:690if (cinfo->num_components != 4)691ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);692if (cinfo->in_color_space == JCS_CMYK) {693cconvert->pub.start_pass = rgb_ycc_start;694cconvert->pub.color_convert = cmyk_ycck_convert;695} else if (cinfo->in_color_space == JCS_YCCK) {696#if defined(__mips__)697if (jsimd_c_can_null_convert())698cconvert->pub.color_convert = jsimd_c_null_convert;699else700#endif701cconvert->pub.color_convert = null_convert;702} else703ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);704break;705706default: /* allow null conversion of JCS_UNKNOWN */707if (cinfo->jpeg_color_space != cinfo->in_color_space ||708cinfo->num_components != cinfo->input_components)709ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);710#if defined(__mips__)711if (jsimd_c_can_null_convert())712cconvert->pub.color_convert = jsimd_c_null_convert;713else714#endif715cconvert->pub.color_convert = null_convert;716break;717}718}719720721