LCOV - code coverage report
Current view: top level - media/libjpeg - jdcolor.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 284 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 18 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /*
       2             :  * jdcolor.c
       3             :  *
       4             :  * This file was part of the Independent JPEG Group's software:
       5             :  * Copyright (C) 1991-1997, Thomas G. Lane.
       6             :  * Modified 2011 by Guido Vollbeding.
       7             :  * libjpeg-turbo Modifications:
       8             :  * Copyright 2009 Pierre Ossman <ossman@cendio.se> for Cendio AB
       9             :  * Copyright (C) 2009, 2011-2012, 2014-2015, D. R. Commander.
      10             :  * Copyright (C) 2013, Linaro Limited.
      11             :  * For conditions of distribution and use, see the accompanying README.ijg
      12             :  * file.
      13             :  *
      14             :  * This file contains output colorspace conversion routines.
      15             :  */
      16             : 
      17             : #define JPEG_INTERNALS
      18             : #include "jinclude.h"
      19             : #include "jpeglib.h"
      20             : #include "jsimd.h"
      21             : #include "jconfigint.h"
      22             : 
      23             : 
      24             : /* Private subobject */
      25             : 
      26             : typedef struct {
      27             :   struct jpeg_color_deconverter pub; /* public fields */
      28             : 
      29             :   /* Private state for YCC->RGB conversion */
      30             :   int *Cr_r_tab;                /* => table for Cr to R conversion */
      31             :   int *Cb_b_tab;                /* => table for Cb to B conversion */
      32             :   JLONG *Cr_g_tab;              /* => table for Cr to G conversion */
      33             :   JLONG *Cb_g_tab;              /* => table for Cb to G conversion */
      34             : 
      35             :   /* Private state for RGB->Y conversion */
      36             :   JLONG *rgb_y_tab;             /* => table for RGB to Y conversion */
      37             : } my_color_deconverter;
      38             : 
      39             : typedef my_color_deconverter *my_cconvert_ptr;
      40             : 
      41             : 
      42             : /**************** YCbCr -> RGB conversion: most common case **************/
      43             : /****************   RGB -> Y   conversion: less common case **************/
      44             : 
      45             : /*
      46             :  * YCbCr is defined per CCIR 601-1, except that Cb and Cr are
      47             :  * normalized to the range 0..MAXJSAMPLE rather than -0.5 .. 0.5.
      48             :  * The conversion equations to be implemented are therefore
      49             :  *
      50             :  *      R = Y                + 1.40200 * Cr
      51             :  *      G = Y - 0.34414 * Cb - 0.71414 * Cr
      52             :  *      B = Y + 1.77200 * Cb
      53             :  *
      54             :  *      Y = 0.29900 * R + 0.58700 * G + 0.11400 * B
      55             :  *
      56             :  * where Cb and Cr represent the incoming values less CENTERJSAMPLE.
      57             :  * (These numbers are derived from TIFF 6.0 section 21, dated 3-June-92.)
      58             :  *
      59             :  * To avoid floating-point arithmetic, we represent the fractional constants
      60             :  * as integers scaled up by 2^16 (about 4 digits precision); we have to divide
      61             :  * the products by 2^16, with appropriate rounding, to get the correct answer.
      62             :  * Notice that Y, being an integral input, does not contribute any fraction
      63             :  * so it need not participate in the rounding.
      64             :  *
      65             :  * For even more speed, we avoid doing any multiplications in the inner loop
      66             :  * by precalculating the constants times Cb and Cr for all possible values.
      67             :  * For 8-bit JSAMPLEs this is very reasonable (only 256 entries per table);
      68             :  * for 12-bit samples it is still acceptable.  It's not very reasonable for
      69             :  * 16-bit samples, but if you want lossless storage you shouldn't be changing
      70             :  * colorspace anyway.
      71             :  * The Cr=>R and Cb=>B values can be rounded to integers in advance; the
      72             :  * values for the G calculation are left scaled up, since we must add them
      73             :  * together before rounding.
      74             :  */
      75             : 
      76             : #define SCALEBITS       16      /* speediest right-shift on some machines */
      77             : #define ONE_HALF        ((JLONG) 1 << (SCALEBITS-1))
      78             : #define FIX(x)          ((JLONG) ((x) * (1L<<SCALEBITS) + 0.5))
      79             : 
      80             : /* We allocate one big table for RGB->Y conversion and divide it up into
      81             :  * three parts, instead of doing three alloc_small requests.  This lets us
      82             :  * use a single table base address, which can be held in a register in the
      83             :  * inner loops on many machines (more than can hold all three addresses,
      84             :  * anyway).
      85             :  */
      86             : 
      87             : #define R_Y_OFF         0                       /* offset to R => Y section */
      88             : #define G_Y_OFF         (1*(MAXJSAMPLE+1))      /* offset to G => Y section */
      89             : #define B_Y_OFF         (2*(MAXJSAMPLE+1))      /* etc. */
      90             : #define TABLE_SIZE      (3*(MAXJSAMPLE+1))
      91             : 
      92             : 
      93             : /* Include inline routines for colorspace extensions */
      94             : 
      95             : #include "jdcolext.c"
      96             : #undef RGB_RED
      97             : #undef RGB_GREEN
      98             : #undef RGB_BLUE
      99             : #undef RGB_PIXELSIZE
     100             : 
     101             : #define RGB_RED EXT_RGB_RED
     102             : #define RGB_GREEN EXT_RGB_GREEN
     103             : #define RGB_BLUE EXT_RGB_BLUE
     104             : #define RGB_PIXELSIZE EXT_RGB_PIXELSIZE
     105             : #define ycc_rgb_convert_internal ycc_extrgb_convert_internal
     106             : #define gray_rgb_convert_internal gray_extrgb_convert_internal
     107             : #define rgb_rgb_convert_internal rgb_extrgb_convert_internal
     108             : #include "jdcolext.c"
     109             : #undef RGB_RED
     110             : #undef RGB_GREEN
     111             : #undef RGB_BLUE
     112             : #undef RGB_PIXELSIZE
     113             : #undef ycc_rgb_convert_internal
     114             : #undef gray_rgb_convert_internal
     115             : #undef rgb_rgb_convert_internal
     116             : 
     117             : #define RGB_RED EXT_RGBX_RED
     118             : #define RGB_GREEN EXT_RGBX_GREEN
     119             : #define RGB_BLUE EXT_RGBX_BLUE
     120             : #define RGB_ALPHA 3
     121             : #define RGB_PIXELSIZE EXT_RGBX_PIXELSIZE
     122             : #define ycc_rgb_convert_internal ycc_extrgbx_convert_internal
     123             : #define gray_rgb_convert_internal gray_extrgbx_convert_internal
     124             : #define rgb_rgb_convert_internal rgb_extrgbx_convert_internal
     125             : #include "jdcolext.c"
     126             : #undef RGB_RED
     127             : #undef RGB_GREEN
     128             : #undef RGB_BLUE
     129             : #undef RGB_ALPHA
     130             : #undef RGB_PIXELSIZE
     131             : #undef ycc_rgb_convert_internal
     132             : #undef gray_rgb_convert_internal
     133             : #undef rgb_rgb_convert_internal
     134             : 
     135             : #define RGB_RED EXT_BGR_RED
     136             : #define RGB_GREEN EXT_BGR_GREEN
     137             : #define RGB_BLUE EXT_BGR_BLUE
     138             : #define RGB_PIXELSIZE EXT_BGR_PIXELSIZE
     139             : #define ycc_rgb_convert_internal ycc_extbgr_convert_internal
     140             : #define gray_rgb_convert_internal gray_extbgr_convert_internal
     141             : #define rgb_rgb_convert_internal rgb_extbgr_convert_internal
     142             : #include "jdcolext.c"
     143             : #undef RGB_RED
     144             : #undef RGB_GREEN
     145             : #undef RGB_BLUE
     146             : #undef RGB_PIXELSIZE
     147             : #undef ycc_rgb_convert_internal
     148             : #undef gray_rgb_convert_internal
     149             : #undef rgb_rgb_convert_internal
     150             : 
     151             : #define RGB_RED EXT_BGRX_RED
     152             : #define RGB_GREEN EXT_BGRX_GREEN
     153             : #define RGB_BLUE EXT_BGRX_BLUE
     154             : #define RGB_ALPHA 3
     155             : #define RGB_PIXELSIZE EXT_BGRX_PIXELSIZE
     156             : #define ycc_rgb_convert_internal ycc_extbgrx_convert_internal
     157             : #define gray_rgb_convert_internal gray_extbgrx_convert_internal
     158             : #define rgb_rgb_convert_internal rgb_extbgrx_convert_internal
     159             : #include "jdcolext.c"
     160             : #undef RGB_RED
     161             : #undef RGB_GREEN
     162             : #undef RGB_BLUE
     163             : #undef RGB_ALPHA
     164             : #undef RGB_PIXELSIZE
     165             : #undef ycc_rgb_convert_internal
     166             : #undef gray_rgb_convert_internal
     167             : #undef rgb_rgb_convert_internal
     168             : 
     169             : #define RGB_RED EXT_XBGR_RED
     170             : #define RGB_GREEN EXT_XBGR_GREEN
     171             : #define RGB_BLUE EXT_XBGR_BLUE
     172             : #define RGB_ALPHA 0
     173             : #define RGB_PIXELSIZE EXT_XBGR_PIXELSIZE
     174             : #define ycc_rgb_convert_internal ycc_extxbgr_convert_internal
     175             : #define gray_rgb_convert_internal gray_extxbgr_convert_internal
     176             : #define rgb_rgb_convert_internal rgb_extxbgr_convert_internal
     177             : #include "jdcolext.c"
     178             : #undef RGB_RED
     179             : #undef RGB_GREEN
     180             : #undef RGB_BLUE
     181             : #undef RGB_ALPHA
     182             : #undef RGB_PIXELSIZE
     183             : #undef ycc_rgb_convert_internal
     184             : #undef gray_rgb_convert_internal
     185             : #undef rgb_rgb_convert_internal
     186             : 
     187             : #define RGB_RED EXT_XRGB_RED
     188             : #define RGB_GREEN EXT_XRGB_GREEN
     189             : #define RGB_BLUE EXT_XRGB_BLUE
     190             : #define RGB_ALPHA 0
     191             : #define RGB_PIXELSIZE EXT_XRGB_PIXELSIZE
     192             : #define ycc_rgb_convert_internal ycc_extxrgb_convert_internal
     193             : #define gray_rgb_convert_internal gray_extxrgb_convert_internal
     194             : #define rgb_rgb_convert_internal rgb_extxrgb_convert_internal
     195             : #include "jdcolext.c"
     196             : #undef RGB_RED
     197             : #undef RGB_GREEN
     198             : #undef RGB_BLUE
     199             : #undef RGB_ALPHA
     200             : #undef RGB_PIXELSIZE
     201             : #undef ycc_rgb_convert_internal
     202             : #undef gray_rgb_convert_internal
     203             : #undef rgb_rgb_convert_internal
     204             : 
     205             : 
     206             : /*
     207             :  * Initialize tables for YCC->RGB colorspace conversion.
     208             :  */
     209             : 
     210             : LOCAL(void)
     211           0 : build_ycc_rgb_table (j_decompress_ptr cinfo)
     212             : {
     213           0 :   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
     214             :   int i;
     215             :   JLONG x;
     216             :   SHIFT_TEMPS
     217             : 
     218           0 :   cconvert->Cr_r_tab = (int *)
     219           0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     220             :                                 (MAXJSAMPLE+1) * sizeof(int));
     221           0 :   cconvert->Cb_b_tab = (int *)
     222           0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     223             :                                 (MAXJSAMPLE+1) * sizeof(int));
     224           0 :   cconvert->Cr_g_tab = (JLONG *)
     225           0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     226             :                                 (MAXJSAMPLE+1) * sizeof(JLONG));
     227           0 :   cconvert->Cb_g_tab = (JLONG *)
     228           0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     229             :                                 (MAXJSAMPLE+1) * sizeof(JLONG));
     230             : 
     231           0 :   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
     232             :     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
     233             :     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
     234             :     /* Cr=>R value is nearest int to 1.40200 * x */
     235           0 :     cconvert->Cr_r_tab[i] = (int)
     236           0 :                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
     237             :     /* Cb=>B value is nearest int to 1.77200 * x */
     238           0 :     cconvert->Cb_b_tab[i] = (int)
     239           0 :                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
     240             :     /* Cr=>G value is scaled-up -0.71414 * x */
     241           0 :     cconvert->Cr_g_tab[i] = (- FIX(0.71414)) * x;
     242             :     /* Cb=>G value is scaled-up -0.34414 * x */
     243             :     /* We also add in ONE_HALF so that need not do it in inner loop */
     244           0 :     cconvert->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
     245             :   }
     246           0 : }
     247             : 
     248             : 
     249             : /*
     250             :  * Convert some rows of samples to the output colorspace.
     251             :  */
     252             : 
     253             : METHODDEF(void)
     254           0 : ycc_rgb_convert (j_decompress_ptr cinfo,
     255             :                  JSAMPIMAGE input_buf, JDIMENSION input_row,
     256             :                  JSAMPARRAY output_buf, int num_rows)
     257             : {
     258           0 :   switch (cinfo->out_color_space) {
     259             :     case JCS_EXT_RGB:
     260           0 :       ycc_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     261             :                                   num_rows);
     262           0 :       break;
     263             :     case JCS_EXT_RGBX:
     264             :     case JCS_EXT_RGBA:
     265           0 :       ycc_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
     266             :                                    num_rows);
     267           0 :       break;
     268             :     case JCS_EXT_BGR:
     269           0 :       ycc_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
     270             :                                   num_rows);
     271           0 :       break;
     272             :     case JCS_EXT_BGRX:
     273             :     case JCS_EXT_BGRA:
     274           0 :       ycc_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
     275             :                                    num_rows);
     276           0 :       break;
     277             :     case JCS_EXT_XBGR:
     278             :     case JCS_EXT_ABGR:
     279           0 :       ycc_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
     280             :                                    num_rows);
     281           0 :       break;
     282             :     case JCS_EXT_XRGB:
     283             :     case JCS_EXT_ARGB:
     284           0 :       ycc_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     285             :                                    num_rows);
     286           0 :       break;
     287             :     default:
     288           0 :       ycc_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     289             :                                num_rows);
     290           0 :       break;
     291             :   }
     292           0 : }
     293             : 
     294             : 
     295             : /**************** Cases other than YCbCr -> RGB **************/
     296             : 
     297             : 
     298             : /*
     299             :  * Initialize for RGB->grayscale colorspace conversion.
     300             :  */
     301             : 
     302             : LOCAL(void)
     303           0 : build_rgb_y_table (j_decompress_ptr cinfo)
     304             : {
     305           0 :   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
     306             :   JLONG *rgb_y_tab;
     307             :   JLONG i;
     308             : 
     309             :   /* Allocate and fill in the conversion tables. */
     310           0 :   cconvert->rgb_y_tab = rgb_y_tab = (JLONG *)
     311           0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     312             :                                 (TABLE_SIZE * sizeof(JLONG)));
     313             : 
     314           0 :   for (i = 0; i <= MAXJSAMPLE; i++) {
     315           0 :     rgb_y_tab[i+R_Y_OFF] = FIX(0.29900) * i;
     316           0 :     rgb_y_tab[i+G_Y_OFF] = FIX(0.58700) * i;
     317           0 :     rgb_y_tab[i+B_Y_OFF] = FIX(0.11400) * i + ONE_HALF;
     318             :   }
     319           0 : }
     320             : 
     321             : 
     322             : /*
     323             :  * Convert RGB to grayscale.
     324             :  */
     325             : 
     326             : METHODDEF(void)
     327           0 : rgb_gray_convert (j_decompress_ptr cinfo,
     328             :                   JSAMPIMAGE input_buf, JDIMENSION input_row,
     329             :                   JSAMPARRAY output_buf, int num_rows)
     330             : {
     331           0 :   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
     332             :   register int r, g, b;
     333           0 :   register JLONG *ctab = cconvert->rgb_y_tab;
     334             :   register JSAMPROW outptr;
     335             :   register JSAMPROW inptr0, inptr1, inptr2;
     336             :   register JDIMENSION col;
     337           0 :   JDIMENSION num_cols = cinfo->output_width;
     338             : 
     339           0 :   while (--num_rows >= 0) {
     340           0 :     inptr0 = input_buf[0][input_row];
     341           0 :     inptr1 = input_buf[1][input_row];
     342           0 :     inptr2 = input_buf[2][input_row];
     343           0 :     input_row++;
     344           0 :     outptr = *output_buf++;
     345           0 :     for (col = 0; col < num_cols; col++) {
     346           0 :       r = GETJSAMPLE(inptr0[col]);
     347           0 :       g = GETJSAMPLE(inptr1[col]);
     348           0 :       b = GETJSAMPLE(inptr2[col]);
     349             :       /* Y */
     350           0 :       outptr[col] = (JSAMPLE)
     351           0 :                 ((ctab[r+R_Y_OFF] + ctab[g+G_Y_OFF] + ctab[b+B_Y_OFF])
     352           0 :                  >> SCALEBITS);
     353             :     }
     354             :   }
     355           0 : }
     356             : 
     357             : 
     358             : /*
     359             :  * Color conversion for no colorspace change: just copy the data,
     360             :  * converting from separate-planes to interleaved representation.
     361             :  */
     362             : 
     363             : METHODDEF(void)
     364           0 : null_convert (j_decompress_ptr cinfo,
     365             :               JSAMPIMAGE input_buf, JDIMENSION input_row,
     366             :               JSAMPARRAY output_buf, int num_rows)
     367             : {
     368             :   register JSAMPROW inptr, inptr0, inptr1, inptr2, inptr3, outptr;
     369             :   register JDIMENSION col;
     370           0 :   register int num_components = cinfo->num_components;
     371           0 :   JDIMENSION num_cols = cinfo->output_width;
     372             :   int ci;
     373             : 
     374           0 :   if (num_components == 3) {
     375           0 :     while (--num_rows >= 0) {
     376           0 :       inptr0 = input_buf[0][input_row];
     377           0 :       inptr1 = input_buf[1][input_row];
     378           0 :       inptr2 = input_buf[2][input_row];
     379           0 :       input_row++;
     380           0 :       outptr = *output_buf++;
     381           0 :       for (col = 0; col < num_cols; col++) {
     382           0 :         *outptr++ = inptr0[col];
     383           0 :         *outptr++ = inptr1[col];
     384           0 :         *outptr++ = inptr2[col];
     385             :       }
     386             :     }
     387           0 :   } else if (num_components == 4) {
     388           0 :     while (--num_rows >= 0) {
     389           0 :       inptr0 = input_buf[0][input_row];
     390           0 :       inptr1 = input_buf[1][input_row];
     391           0 :       inptr2 = input_buf[2][input_row];
     392           0 :       inptr3 = input_buf[3][input_row];
     393           0 :       input_row++;
     394           0 :       outptr = *output_buf++;
     395           0 :       for (col = 0; col < num_cols; col++) {
     396           0 :         *outptr++ = inptr0[col];
     397           0 :         *outptr++ = inptr1[col];
     398           0 :         *outptr++ = inptr2[col];
     399           0 :         *outptr++ = inptr3[col];
     400             :       }
     401             :     }
     402             :   } else {
     403           0 :     while (--num_rows >= 0) {
     404           0 :       for (ci = 0; ci < num_components; ci++) {
     405           0 :         inptr = input_buf[ci][input_row];
     406           0 :         outptr = *output_buf;
     407           0 :         for (col = 0; col < num_cols; col++) {
     408           0 :           outptr[ci] = inptr[col];
     409           0 :           outptr += num_components;
     410             :         }
     411             :       }
     412           0 :       output_buf++;
     413           0 :       input_row++;
     414             :     }
     415             :   }
     416           0 : }
     417             : 
     418             : 
     419             : /*
     420             :  * Color conversion for grayscale: just copy the data.
     421             :  * This also works for YCbCr -> grayscale conversion, in which
     422             :  * we just copy the Y (luminance) component and ignore chrominance.
     423             :  */
     424             : 
     425             : METHODDEF(void)
     426           0 : grayscale_convert (j_decompress_ptr cinfo,
     427             :                    JSAMPIMAGE input_buf, JDIMENSION input_row,
     428             :                    JSAMPARRAY output_buf, int num_rows)
     429             : {
     430           0 :   jcopy_sample_rows(input_buf[0], (int) input_row, output_buf, 0,
     431             :                     num_rows, cinfo->output_width);
     432           0 : }
     433             : 
     434             : 
     435             : /*
     436             :  * Convert grayscale to RGB
     437             :  */
     438             : 
     439             : METHODDEF(void)
     440           0 : gray_rgb_convert (j_decompress_ptr cinfo,
     441             :                   JSAMPIMAGE input_buf, JDIMENSION input_row,
     442             :                   JSAMPARRAY output_buf, int num_rows)
     443             : {
     444           0 :   switch (cinfo->out_color_space) {
     445             :     case JCS_EXT_RGB:
     446           0 :       gray_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     447             :                                    num_rows);
     448           0 :       break;
     449             :     case JCS_EXT_RGBX:
     450             :     case JCS_EXT_RGBA:
     451           0 :       gray_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
     452             :                                     num_rows);
     453           0 :       break;
     454             :     case JCS_EXT_BGR:
     455           0 :       gray_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
     456             :                                    num_rows);
     457           0 :       break;
     458             :     case JCS_EXT_BGRX:
     459             :     case JCS_EXT_BGRA:
     460           0 :       gray_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
     461             :                                     num_rows);
     462           0 :       break;
     463             :     case JCS_EXT_XBGR:
     464             :     case JCS_EXT_ABGR:
     465           0 :       gray_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
     466             :                                     num_rows);
     467           0 :       break;
     468             :     case JCS_EXT_XRGB:
     469             :     case JCS_EXT_ARGB:
     470           0 :       gray_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     471             :                                     num_rows);
     472           0 :       break;
     473             :     default:
     474           0 :       gray_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     475             :                                 num_rows);
     476           0 :       break;
     477             :   }
     478           0 : }
     479             : 
     480             : 
     481             : /*
     482             :  * Convert plain RGB to extended RGB
     483             :  */
     484             : 
     485             : METHODDEF(void)
     486           0 : rgb_rgb_convert (j_decompress_ptr cinfo,
     487             :                   JSAMPIMAGE input_buf, JDIMENSION input_row,
     488             :                   JSAMPARRAY output_buf, int num_rows)
     489             : {
     490           0 :   switch (cinfo->out_color_space) {
     491             :     case JCS_EXT_RGB:
     492           0 :       rgb_extrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     493             :                                   num_rows);
     494           0 :       break;
     495             :     case JCS_EXT_RGBX:
     496             :     case JCS_EXT_RGBA:
     497           0 :       rgb_extrgbx_convert_internal(cinfo, input_buf, input_row, output_buf,
     498             :                                    num_rows);
     499           0 :       break;
     500             :     case JCS_EXT_BGR:
     501           0 :       rgb_extbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
     502             :                                   num_rows);
     503           0 :       break;
     504             :     case JCS_EXT_BGRX:
     505             :     case JCS_EXT_BGRA:
     506           0 :       rgb_extbgrx_convert_internal(cinfo, input_buf, input_row, output_buf,
     507             :                                    num_rows);
     508           0 :       break;
     509             :     case JCS_EXT_XBGR:
     510             :     case JCS_EXT_ABGR:
     511           0 :       rgb_extxbgr_convert_internal(cinfo, input_buf, input_row, output_buf,
     512             :                                    num_rows);
     513           0 :       break;
     514             :     case JCS_EXT_XRGB:
     515             :     case JCS_EXT_ARGB:
     516           0 :       rgb_extxrgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     517             :                                    num_rows);
     518           0 :       break;
     519             :     default:
     520           0 :       rgb_rgb_convert_internal(cinfo, input_buf, input_row, output_buf,
     521             :                                num_rows);
     522           0 :       break;
     523             :   }
     524           0 : }
     525             : 
     526             : 
     527             : /*
     528             :  * Adobe-style YCCK->CMYK conversion.
     529             :  * We convert YCbCr to R=1-C, G=1-M, and B=1-Y using the same
     530             :  * conversion as above, while passing K (black) unchanged.
     531             :  * We assume build_ycc_rgb_table has been called.
     532             :  */
     533             : 
     534             : METHODDEF(void)
     535           0 : ycck_cmyk_convert (j_decompress_ptr cinfo,
     536             :                    JSAMPIMAGE input_buf, JDIMENSION input_row,
     537             :                    JSAMPARRAY output_buf, int num_rows)
     538             : {
     539           0 :   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
     540             :   register int y, cb, cr;
     541             :   register JSAMPROW outptr;
     542             :   register JSAMPROW inptr0, inptr1, inptr2, inptr3;
     543             :   register JDIMENSION col;
     544           0 :   JDIMENSION num_cols = cinfo->output_width;
     545             :   /* copy these pointers into registers if possible */
     546           0 :   register JSAMPLE *range_limit = cinfo->sample_range_limit;
     547           0 :   register int *Crrtab = cconvert->Cr_r_tab;
     548           0 :   register int *Cbbtab = cconvert->Cb_b_tab;
     549           0 :   register JLONG *Crgtab = cconvert->Cr_g_tab;
     550           0 :   register JLONG *Cbgtab = cconvert->Cb_g_tab;
     551             :   SHIFT_TEMPS
     552             : 
     553           0 :   while (--num_rows >= 0) {
     554           0 :     inptr0 = input_buf[0][input_row];
     555           0 :     inptr1 = input_buf[1][input_row];
     556           0 :     inptr2 = input_buf[2][input_row];
     557           0 :     inptr3 = input_buf[3][input_row];
     558           0 :     input_row++;
     559           0 :     outptr = *output_buf++;
     560           0 :     for (col = 0; col < num_cols; col++) {
     561           0 :       y  = GETJSAMPLE(inptr0[col]);
     562           0 :       cb = GETJSAMPLE(inptr1[col]);
     563           0 :       cr = GETJSAMPLE(inptr2[col]);
     564             :       /* Range-limiting is essential due to noise introduced by DCT losses. */
     565           0 :       outptr[0] = range_limit[MAXJSAMPLE - (y + Crrtab[cr])];   /* red */
     566           0 :       outptr[1] = range_limit[MAXJSAMPLE - (y +                 /* green */
     567           0 :                               ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
     568             :                                                  SCALEBITS)))];
     569           0 :       outptr[2] = range_limit[MAXJSAMPLE - (y + Cbbtab[cb])];   /* blue */
     570             :       /* K passes through unchanged */
     571           0 :       outptr[3] = inptr3[col];  /* don't need GETJSAMPLE here */
     572           0 :       outptr += 4;
     573             :     }
     574             :   }
     575           0 : }
     576             : 
     577             : 
     578             : /*
     579             :  * RGB565 conversion
     580             :  */
     581             : 
     582             : #define PACK_SHORT_565_LE(r, g, b)   ((((r) << 8) & 0xF800) |  \
     583             :                                       (((g) << 3) & 0x7E0) | ((b) >> 3))
     584             : #define PACK_SHORT_565_BE(r, g, b)   (((r) & 0xF8) | ((g) >> 5) |  \
     585             :                                       (((g) << 11) & 0xE000) |  \
     586             :                                       (((b) << 5) & 0x1F00))
     587             : 
     588             : #define PACK_TWO_PIXELS_LE(l, r)     ((r << 16) | l)
     589             : #define PACK_TWO_PIXELS_BE(l, r)     ((l << 16) | r)
     590             : 
     591             : #define PACK_NEED_ALIGNMENT(ptr)     (((size_t)(ptr)) & 3)
     592             : 
     593             : #define WRITE_TWO_ALIGNED_PIXELS(addr, pixels)  ((*(int *)(addr)) = pixels)
     594             : 
     595             : #define DITHER_565_R(r, dither)  ((r) + ((dither) & 0xFF))
     596             : #define DITHER_565_G(g, dither)  ((g) + (((dither) & 0xFF) >> 1))
     597             : #define DITHER_565_B(b, dither)  ((b) + ((dither) & 0xFF))
     598             : 
     599             : 
     600             : /* Declarations for ordered dithering
     601             :  *
     602             :  * We use a 4x4 ordered dither array packed into 32 bits.  This array is
     603             :  * sufficent for dithering RGB888 to RGB565.
     604             :  */
     605             : 
     606             : #define DITHER_MASK       0x3
     607             : #define DITHER_ROTATE(x)  ((((x) & 0xFF) << 24) | (((x) >> 8) & 0x00FFFFFF))
     608             : static const JLONG dither_matrix[4] = {
     609             :   0x0008020A,
     610             :   0x0C040E06,
     611             :   0x030B0109,
     612             :   0x0F070D05
     613             : };
     614             : 
     615             : 
     616           0 : static INLINE boolean is_big_endian(void)
     617             : {
     618           0 :   int test_value = 1;
     619           0 :   if(*(char *)&test_value != 1)
     620           0 :     return TRUE;
     621           0 :   return FALSE;
     622             : }
     623             : 
     624             : 
     625             : /* Include inline routines for RGB565 conversion */
     626             : 
     627             : #define PACK_SHORT_565 PACK_SHORT_565_LE
     628             : #define PACK_TWO_PIXELS PACK_TWO_PIXELS_LE
     629             : #define ycc_rgb565_convert_internal ycc_rgb565_convert_le
     630             : #define ycc_rgb565D_convert_internal ycc_rgb565D_convert_le
     631             : #define rgb_rgb565_convert_internal rgb_rgb565_convert_le
     632             : #define rgb_rgb565D_convert_internal rgb_rgb565D_convert_le
     633             : #define gray_rgb565_convert_internal gray_rgb565_convert_le
     634             : #define gray_rgb565D_convert_internal gray_rgb565D_convert_le
     635             : #include "jdcol565.c"
     636             : #undef PACK_SHORT_565
     637             : #undef PACK_TWO_PIXELS
     638             : #undef ycc_rgb565_convert_internal
     639             : #undef ycc_rgb565D_convert_internal
     640             : #undef rgb_rgb565_convert_internal
     641             : #undef rgb_rgb565D_convert_internal
     642             : #undef gray_rgb565_convert_internal
     643             : #undef gray_rgb565D_convert_internal
     644             : 
     645             : #define PACK_SHORT_565 PACK_SHORT_565_BE
     646             : #define PACK_TWO_PIXELS PACK_TWO_PIXELS_BE
     647             : #define ycc_rgb565_convert_internal ycc_rgb565_convert_be
     648             : #define ycc_rgb565D_convert_internal ycc_rgb565D_convert_be
     649             : #define rgb_rgb565_convert_internal rgb_rgb565_convert_be
     650             : #define rgb_rgb565D_convert_internal rgb_rgb565D_convert_be
     651             : #define gray_rgb565_convert_internal gray_rgb565_convert_be
     652             : #define gray_rgb565D_convert_internal gray_rgb565D_convert_be
     653             : #include "jdcol565.c"
     654             : #undef PACK_SHORT_565
     655             : #undef PACK_TWO_PIXELS
     656             : #undef ycc_rgb565_convert_internal
     657             : #undef ycc_rgb565D_convert_internal
     658             : #undef rgb_rgb565_convert_internal
     659             : #undef rgb_rgb565D_convert_internal
     660             : #undef gray_rgb565_convert_internal
     661             : #undef gray_rgb565D_convert_internal
     662             : 
     663             : 
     664             : METHODDEF(void)
     665           0 : ycc_rgb565_convert (j_decompress_ptr cinfo,
     666             :                     JSAMPIMAGE input_buf, JDIMENSION input_row,
     667             :                     JSAMPARRAY output_buf, int num_rows)
     668             : {
     669           0 :   if (is_big_endian())
     670           0 :     ycc_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
     671             :   else
     672           0 :     ycc_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
     673           0 : }
     674             : 
     675             : 
     676             : METHODDEF(void)
     677           0 : ycc_rgb565D_convert (j_decompress_ptr cinfo,
     678             :                      JSAMPIMAGE input_buf, JDIMENSION input_row,
     679             :                      JSAMPARRAY output_buf, int num_rows)
     680             : {
     681           0 :   if (is_big_endian())
     682           0 :     ycc_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
     683             :   else
     684           0 :     ycc_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
     685           0 : }
     686             : 
     687             : 
     688             : METHODDEF(void)
     689           0 : rgb_rgb565_convert (j_decompress_ptr cinfo,
     690             :                     JSAMPIMAGE input_buf, JDIMENSION input_row,
     691             :                     JSAMPARRAY output_buf, int num_rows)
     692             : {
     693           0 :   if (is_big_endian())
     694           0 :     rgb_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
     695             :   else
     696           0 :     rgb_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
     697           0 : }
     698             : 
     699             : 
     700             : METHODDEF(void)
     701           0 : rgb_rgb565D_convert (j_decompress_ptr cinfo,
     702             :                      JSAMPIMAGE input_buf, JDIMENSION input_row,
     703             :                      JSAMPARRAY output_buf, int num_rows)
     704             : {
     705           0 :   if (is_big_endian())
     706           0 :     rgb_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
     707             :   else
     708           0 :     rgb_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
     709           0 : }
     710             : 
     711             : 
     712             : METHODDEF(void)
     713           0 : gray_rgb565_convert (j_decompress_ptr cinfo,
     714             :                      JSAMPIMAGE input_buf, JDIMENSION input_row,
     715             :                      JSAMPARRAY output_buf, int num_rows)
     716             : {
     717           0 :   if (is_big_endian())
     718           0 :     gray_rgb565_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
     719             :   else
     720           0 :     gray_rgb565_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
     721           0 : }
     722             : 
     723             : 
     724             : METHODDEF(void)
     725           0 : gray_rgb565D_convert (j_decompress_ptr cinfo,
     726             :                       JSAMPIMAGE input_buf, JDIMENSION input_row,
     727             :                       JSAMPARRAY output_buf, int num_rows)
     728             : {
     729           0 :   if (is_big_endian())
     730           0 :     gray_rgb565D_convert_be(cinfo, input_buf, input_row, output_buf, num_rows);
     731             :   else
     732           0 :     gray_rgb565D_convert_le(cinfo, input_buf, input_row, output_buf, num_rows);
     733           0 : }
     734             : 
     735             : 
     736             : /*
     737             :  * Empty method for start_pass.
     738             :  */
     739             : 
     740             : METHODDEF(void)
     741           0 : start_pass_dcolor (j_decompress_ptr cinfo)
     742             : {
     743             :   /* no work needed */
     744           0 : }
     745             : 
     746             : 
     747             : /*
     748             :  * Module initialization routine for output colorspace conversion.
     749             :  */
     750             : 
     751             : GLOBAL(void)
     752           0 : jinit_color_deconverter (j_decompress_ptr cinfo)
     753             : {
     754             :   my_cconvert_ptr cconvert;
     755             :   int ci;
     756             : 
     757           0 :   cconvert = (my_cconvert_ptr)
     758           0 :     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
     759             :                                 sizeof(my_color_deconverter));
     760           0 :   cinfo->cconvert = (struct jpeg_color_deconverter *) cconvert;
     761           0 :   cconvert->pub.start_pass = start_pass_dcolor;
     762             : 
     763             :   /* Make sure num_components agrees with jpeg_color_space */
     764           0 :   switch (cinfo->jpeg_color_space) {
     765             :   case JCS_GRAYSCALE:
     766           0 :     if (cinfo->num_components != 1)
     767           0 :       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
     768           0 :     break;
     769             : 
     770             :   case JCS_RGB:
     771             :   case JCS_YCbCr:
     772           0 :     if (cinfo->num_components != 3)
     773           0 :       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
     774           0 :     break;
     775             : 
     776             :   case JCS_CMYK:
     777             :   case JCS_YCCK:
     778           0 :     if (cinfo->num_components != 4)
     779           0 :       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
     780           0 :     break;
     781             : 
     782             :   default:                      /* JCS_UNKNOWN can be anything */
     783           0 :     if (cinfo->num_components < 1)
     784           0 :       ERREXIT(cinfo, JERR_BAD_J_COLORSPACE);
     785           0 :     break;
     786             :   }
     787             : 
     788             :   /* Set out_color_components and conversion method based on requested space.
     789             :    * Also clear the component_needed flags for any unused components,
     790             :    * so that earlier pipeline stages can avoid useless computation.
     791             :    */
     792             : 
     793           0 :   switch (cinfo->out_color_space) {
     794             :   case JCS_GRAYSCALE:
     795           0 :     cinfo->out_color_components = 1;
     796           0 :     if (cinfo->jpeg_color_space == JCS_GRAYSCALE ||
     797           0 :         cinfo->jpeg_color_space == JCS_YCbCr) {
     798           0 :       cconvert->pub.color_convert = grayscale_convert;
     799             :       /* For color->grayscale conversion, only the Y (0) component is needed */
     800           0 :       for (ci = 1; ci < cinfo->num_components; ci++)
     801           0 :         cinfo->comp_info[ci].component_needed = FALSE;
     802           0 :     } else if (cinfo->jpeg_color_space == JCS_RGB) {
     803           0 :       cconvert->pub.color_convert = rgb_gray_convert;
     804           0 :       build_rgb_y_table(cinfo);
     805             :     } else
     806           0 :       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     807           0 :     break;
     808             : 
     809             :   case JCS_RGB:
     810             :   case JCS_EXT_RGB:
     811             :   case JCS_EXT_RGBX:
     812             :   case JCS_EXT_BGR:
     813             :   case JCS_EXT_BGRX:
     814             :   case JCS_EXT_XBGR:
     815             :   case JCS_EXT_XRGB:
     816             :   case JCS_EXT_RGBA:
     817             :   case JCS_EXT_BGRA:
     818             :   case JCS_EXT_ABGR:
     819             :   case JCS_EXT_ARGB:
     820           0 :     cinfo->out_color_components = rgb_pixelsize[cinfo->out_color_space];
     821           0 :     if (cinfo->jpeg_color_space == JCS_YCbCr) {
     822           0 :       if (jsimd_can_ycc_rgb())
     823           0 :         cconvert->pub.color_convert = jsimd_ycc_rgb_convert;
     824             :       else {
     825           0 :         cconvert->pub.color_convert = ycc_rgb_convert;
     826           0 :         build_ycc_rgb_table(cinfo);
     827             :       }
     828           0 :     } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
     829           0 :       cconvert->pub.color_convert = gray_rgb_convert;
     830           0 :     } else if (cinfo->jpeg_color_space == JCS_RGB) {
     831           0 :       if (rgb_red[cinfo->out_color_space] == 0 &&
     832           0 :           rgb_green[cinfo->out_color_space] == 1 &&
     833           0 :           rgb_blue[cinfo->out_color_space] == 2 &&
     834           0 :           rgb_pixelsize[cinfo->out_color_space] == 3)
     835           0 :         cconvert->pub.color_convert = null_convert;
     836             :       else
     837           0 :         cconvert->pub.color_convert = rgb_rgb_convert;
     838             :     } else
     839           0 :       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     840           0 :     break;
     841             : 
     842             :   case JCS_RGB565:
     843           0 :     cinfo->out_color_components = 3;
     844           0 :     if (cinfo->dither_mode == JDITHER_NONE) {
     845           0 :       if (cinfo->jpeg_color_space == JCS_YCbCr) {
     846           0 :          if (jsimd_can_ycc_rgb565())
     847           0 :            cconvert->pub.color_convert = jsimd_ycc_rgb565_convert;
     848             :          else {
     849           0 :            cconvert->pub.color_convert = ycc_rgb565_convert;
     850           0 :            build_ycc_rgb_table(cinfo);
     851             :         }
     852           0 :       } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
     853           0 :         cconvert->pub.color_convert = gray_rgb565_convert;
     854           0 :       } else if (cinfo->jpeg_color_space == JCS_RGB) {
     855           0 :         cconvert->pub.color_convert = rgb_rgb565_convert;
     856             :       } else
     857           0 :         ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     858             :     } else {
     859             :       /* only ordered dithering is supported */
     860           0 :       if (cinfo->jpeg_color_space == JCS_YCbCr) {
     861           0 :         cconvert->pub.color_convert = ycc_rgb565D_convert;
     862           0 :         build_ycc_rgb_table(cinfo);
     863           0 :       } else if (cinfo->jpeg_color_space == JCS_GRAYSCALE) {
     864           0 :         cconvert->pub.color_convert = gray_rgb565D_convert;
     865           0 :       } else if (cinfo->jpeg_color_space == JCS_RGB) {
     866           0 :         cconvert->pub.color_convert = rgb_rgb565D_convert;
     867             :       } else
     868           0 :         ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     869             :     }
     870           0 :     break;
     871             : 
     872             :   case JCS_CMYK:
     873           0 :     cinfo->out_color_components = 4;
     874           0 :     if (cinfo->jpeg_color_space == JCS_YCCK) {
     875           0 :       cconvert->pub.color_convert = ycck_cmyk_convert;
     876           0 :       build_ycc_rgb_table(cinfo);
     877           0 :     } else if (cinfo->jpeg_color_space == JCS_CMYK) {
     878           0 :       cconvert->pub.color_convert = null_convert;
     879             :     } else
     880           0 :       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     881           0 :     break;
     882             : 
     883             :   default:
     884             :     /* Permit null conversion to same output space */
     885           0 :     if (cinfo->out_color_space == cinfo->jpeg_color_space) {
     886           0 :       cinfo->out_color_components = cinfo->num_components;
     887           0 :       cconvert->pub.color_convert = null_convert;
     888             :     } else                      /* unsupported non-null conversion */
     889           0 :       ERREXIT(cinfo, JERR_CONVERSION_NOTIMPL);
     890           0 :     break;
     891             :   }
     892             : 
     893           0 :   if (cinfo->quantize_colors)
     894           0 :     cinfo->output_components = 1; /* single colormapped output component */
     895             :   else
     896           0 :     cinfo->output_components = cinfo->out_color_components;
     897           0 : }

Generated by: LCOV version 1.13