Home | History | Annotate | Download | only in libjpeg_turbo
      1 /*
      2  * jdcolext.c
      3  *
      4  * This file was part of the Independent JPEG Group's software:
      5  * Copyright (C) 1991-1997, Thomas G. Lane.
      6  * libjpeg-turbo Modifications:
      7  * Copyright (C) 2009, 2011, D. R. Commander.
      8  * For conditions of distribution and use, see the accompanying README file.
      9  *
     10  * This file contains output colorspace conversion routines.
     11  */
     12 
     13 
     14 /* This file is included by jdcolor.c */
     15 
     16 
     17 /*
     18  * Convert some rows of samples to the output colorspace.
     19  *
     20  * Note that we change from noninterleaved, one-plane-per-component format
     21  * to interleaved-pixel format.  The output buffer is therefore three times
     22  * as wide as the input buffer.
     23  * A starting row offset is provided only for the input buffer.  The caller
     24  * can easily adjust the passed output_buf value to accommodate any row
     25  * offset required on that side.
     26  */
     27 
     28 INLINE
     29 LOCAL(void)
     30 ycc_rgb_convert_internal (j_decompress_ptr cinfo,
     31                           JSAMPIMAGE input_buf, JDIMENSION input_row,
     32                           JSAMPARRAY output_buf, int num_rows)
     33 {
     34   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
     35   register int y, cb, cr;
     36   register JSAMPROW outptr;
     37   register JSAMPROW inptr0, inptr1, inptr2;
     38   register JDIMENSION col;
     39   JDIMENSION num_cols = cinfo->output_width;
     40   /* copy these pointers into registers if possible */
     41   register JSAMPLE * range_limit = cinfo->sample_range_limit;
     42   register int * Crrtab = cconvert->Cr_r_tab;
     43   register int * Cbbtab = cconvert->Cb_b_tab;
     44   register INT32 * Crgtab = cconvert->Cr_g_tab;
     45   register INT32 * Cbgtab = cconvert->Cb_g_tab;
     46   SHIFT_TEMPS
     47 
     48   while (--num_rows >= 0) {
     49     inptr0 = input_buf[0][input_row];
     50     inptr1 = input_buf[1][input_row];
     51     inptr2 = input_buf[2][input_row];
     52     input_row++;
     53     outptr = *output_buf++;
     54     for (col = 0; col < num_cols; col++) {
     55       y  = GETJSAMPLE(inptr0[col]);
     56       cb = GETJSAMPLE(inptr1[col]);
     57       cr = GETJSAMPLE(inptr2[col]);
     58       /* Range-limiting is essential due to noise introduced by DCT losses. */
     59       outptr[RGB_RED] =   range_limit[y + Crrtab[cr]];
     60       outptr[RGB_GREEN] = range_limit[y +
     61 			      ((int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
     62 						 SCALEBITS))];
     63       outptr[RGB_BLUE] =  range_limit[y + Cbbtab[cb]];
     64       /* Set unused byte to 0xFF so it can be interpreted as an opaque */
     65       /* alpha channel value */
     66 #ifdef RGB_ALPHA
     67       outptr[RGB_ALPHA] = 0xFF;
     68 #endif
     69       outptr += RGB_PIXELSIZE;
     70     }
     71   }
     72 }
     73 
     74 
     75 /*
     76  * Convert grayscale to RGB: just duplicate the graylevel three times.
     77  * This is provided to support applications that don't want to cope
     78  * with grayscale as a separate case.
     79  */
     80 
     81 INLINE
     82 LOCAL(void)
     83 gray_rgb_convert_internal (j_decompress_ptr cinfo,
     84                            JSAMPIMAGE input_buf, JDIMENSION input_row,
     85                            JSAMPARRAY output_buf, int num_rows)
     86 {
     87   register JSAMPROW inptr, outptr;
     88   register JDIMENSION col;
     89   JDIMENSION num_cols = cinfo->output_width;
     90 
     91   while (--num_rows >= 0) {
     92     inptr = input_buf[0][input_row++];
     93     outptr = *output_buf++;
     94     for (col = 0; col < num_cols; col++) {
     95       /* We can dispense with GETJSAMPLE() here */
     96       outptr[RGB_RED] = outptr[RGB_GREEN] = outptr[RGB_BLUE] = inptr[col];
     97       /* Set unused byte to 0xFF so it can be interpreted as an opaque */
     98       /* alpha channel value */
     99 #ifdef RGB_ALPHA
    100       outptr[RGB_ALPHA] = 0xFF;
    101 #endif
    102       outptr += RGB_PIXELSIZE;
    103     }
    104   }
    105 }
    106 
    107 
    108 /*
    109  * Convert RGB to extended RGB: just swap the order of source pixels
    110  */
    111 
    112 INLINE
    113 LOCAL(void)
    114 rgb_rgb_convert_internal (j_decompress_ptr cinfo,
    115                           JSAMPIMAGE input_buf, JDIMENSION input_row,
    116                           JSAMPARRAY output_buf, int num_rows)
    117 {
    118   register JSAMPROW inptr0, inptr1, inptr2;
    119   register JSAMPROW outptr;
    120   register JDIMENSION col;
    121   JDIMENSION num_cols = cinfo->output_width;
    122 
    123   while (--num_rows >= 0) {
    124     inptr0 = input_buf[0][input_row];
    125     inptr1 = input_buf[1][input_row];
    126     inptr2 = input_buf[2][input_row];
    127     input_row++;
    128     outptr = *output_buf++;
    129     for (col = 0; col < num_cols; col++) {
    130       /* We can dispense with GETJSAMPLE() here */
    131       outptr[RGB_RED] = inptr0[col];
    132       outptr[RGB_GREEN] = inptr1[col];
    133       outptr[RGB_BLUE] = inptr2[col];
    134       /* Set unused byte to 0xFF so it can be interpreted as an opaque */
    135       /* alpha channel value */
    136 #ifdef RGB_ALPHA
    137       outptr[RGB_ALPHA] = 0xFF;
    138 #endif
    139       outptr += RGB_PIXELSIZE;
    140     }
    141   }
    142 }
    143