Home | History | Annotate | Download | only in libjpeg-turbo
      1 /*
      2  * jdcol565.c
      3  *
      4  * This file was part of the Independent JPEG Group's software:
      5  * Copyright (C) 1991-1997, Thomas G. Lane.
      6  * Modifications:
      7  * Copyright (C) 2013, Linaro Limited.
      8  * Copyright (C) 2014, D. R. Commander.
      9  * For conditions of distribution and use, see the accompanying README file.
     10  *
     11  * This file contains output colorspace conversion routines.
     12  */
     13 
     14 /* This file is included by jdcolor.c */
     15 
     16 
     17 INLINE
     18 LOCAL(void)
     19 ycc_rgb565_convert_internal (j_decompress_ptr cinfo,
     20                              JSAMPIMAGE input_buf, JDIMENSION input_row,
     21                              JSAMPARRAY output_buf, int num_rows)
     22 {
     23   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
     24   register int y, cb, cr;
     25   register JSAMPROW outptr;
     26   register JSAMPROW inptr0, inptr1, inptr2;
     27   register JDIMENSION col;
     28   JDIMENSION num_cols = cinfo->output_width;
     29   /* copy these pointers into registers if possible */
     30   register JSAMPLE * range_limit = cinfo->sample_range_limit;
     31   register int * Crrtab = cconvert->Cr_r_tab;
     32   register int * Cbbtab = cconvert->Cb_b_tab;
     33   register INT32 * Crgtab = cconvert->Cr_g_tab;
     34   register INT32 * Cbgtab = cconvert->Cb_g_tab;
     35   SHIFT_TEMPS
     36 
     37   while (--num_rows >= 0) {
     38     INT32 rgb;
     39     unsigned int r, g, b;
     40     inptr0 = input_buf[0][input_row];
     41     inptr1 = input_buf[1][input_row];
     42     inptr2 = input_buf[2][input_row];
     43     input_row++;
     44     outptr = *output_buf++;
     45 
     46     if (PACK_NEED_ALIGNMENT(outptr)) {
     47       y  = GETJSAMPLE(*inptr0++);
     48       cb = GETJSAMPLE(*inptr1++);
     49       cr = GETJSAMPLE(*inptr2++);
     50       r = range_limit[y + Crrtab[cr]];
     51       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
     52                                             SCALEBITS))];
     53       b = range_limit[y + Cbbtab[cb]];
     54       rgb = PACK_SHORT_565(r, g, b);
     55       *(INT16*)outptr = rgb;
     56       outptr += 2;
     57       num_cols--;
     58     }
     59     for (col = 0; col < (num_cols >> 1); col++) {
     60       y  = GETJSAMPLE(*inptr0++);
     61       cb = GETJSAMPLE(*inptr1++);
     62       cr = GETJSAMPLE(*inptr2++);
     63       r = range_limit[y + Crrtab[cr]];
     64       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
     65                                             SCALEBITS))];
     66       b = range_limit[y + Cbbtab[cb]];
     67       rgb = PACK_SHORT_565(r, g, b);
     68 
     69       y  = GETJSAMPLE(*inptr0++);
     70       cb = GETJSAMPLE(*inptr1++);
     71       cr = GETJSAMPLE(*inptr2++);
     72       r = range_limit[y + Crrtab[cr]];
     73       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
     74                                             SCALEBITS))];
     75       b = range_limit[y + Cbbtab[cb]];
     76       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
     77 
     78       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
     79       outptr += 4;
     80     }
     81     if (num_cols & 1) {
     82       y  = GETJSAMPLE(*inptr0);
     83       cb = GETJSAMPLE(*inptr1);
     84       cr = GETJSAMPLE(*inptr2);
     85       r = range_limit[y + Crrtab[cr]];
     86       g = range_limit[y + ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
     87                                             SCALEBITS))];
     88       b = range_limit[y + Cbbtab[cb]];
     89       rgb = PACK_SHORT_565(r, g, b);
     90       *(INT16*)outptr = rgb;
     91     }
     92   }
     93 }
     94 
     95 
     96 INLINE
     97 LOCAL(void)
     98 ycc_rgb565D_convert_internal (j_decompress_ptr cinfo,
     99                               JSAMPIMAGE input_buf, JDIMENSION input_row,
    100                               JSAMPARRAY output_buf, int num_rows)
    101 {
    102   my_cconvert_ptr cconvert = (my_cconvert_ptr) cinfo->cconvert;
    103   register int y, cb, cr;
    104   register JSAMPROW outptr;
    105   register JSAMPROW inptr0, inptr1, inptr2;
    106   register JDIMENSION col;
    107   JDIMENSION num_cols = cinfo->output_width;
    108   /* copy these pointers into registers if possible */
    109   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    110   register int * Crrtab = cconvert->Cr_r_tab;
    111   register int * Cbbtab = cconvert->Cb_b_tab;
    112   register INT32 * Crgtab = cconvert->Cr_g_tab;
    113   register INT32 * Cbgtab = cconvert->Cb_g_tab;
    114   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
    115   SHIFT_TEMPS
    116 
    117   while (--num_rows >= 0) {
    118     INT32 rgb;
    119     unsigned int r, g, b;
    120 
    121     inptr0 = input_buf[0][input_row];
    122     inptr1 = input_buf[1][input_row];
    123     inptr2 = input_buf[2][input_row];
    124     input_row++;
    125     outptr = *output_buf++;
    126     if (PACK_NEED_ALIGNMENT(outptr)) {
    127       y  = GETJSAMPLE(*inptr0++);
    128       cb = GETJSAMPLE(*inptr1++);
    129       cr = GETJSAMPLE(*inptr2++);
    130       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
    131       g = range_limit[DITHER_565_G(y +
    132                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
    133                                                      SCALEBITS)), d0)];
    134       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
    135       rgb = PACK_SHORT_565(r, g, b);
    136       *(INT16*)outptr = rgb;
    137       outptr += 2;
    138       num_cols--;
    139     }
    140     for (col = 0; col < (num_cols >> 1); col++) {
    141       y  = GETJSAMPLE(*inptr0++);
    142       cb = GETJSAMPLE(*inptr1++);
    143       cr = GETJSAMPLE(*inptr2++);
    144       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
    145       g = range_limit[DITHER_565_G(y +
    146                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
    147                                                      SCALEBITS)), d0)];
    148       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
    149       d0 = DITHER_ROTATE(d0);
    150       rgb = PACK_SHORT_565(r, g, b);
    151 
    152       y  = GETJSAMPLE(*inptr0++);
    153       cb = GETJSAMPLE(*inptr1++);
    154       cr = GETJSAMPLE(*inptr2++);
    155       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
    156       g = range_limit[DITHER_565_G(y +
    157                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
    158                                                      SCALEBITS)), d0)];
    159       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
    160       d0 = DITHER_ROTATE(d0);
    161       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
    162 
    163       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
    164       outptr += 4;
    165     }
    166     if (num_cols & 1) {
    167       y  = GETJSAMPLE(*inptr0);
    168       cb = GETJSAMPLE(*inptr1);
    169       cr = GETJSAMPLE(*inptr2);
    170       r = range_limit[DITHER_565_R(y + Crrtab[cr], d0)];
    171       g = range_limit[DITHER_565_G(y +
    172                                    ((int)RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr],
    173                                                      SCALEBITS)), d0)];
    174       b = range_limit[DITHER_565_B(y + Cbbtab[cb], d0)];
    175       rgb = PACK_SHORT_565(r, g, b);
    176       *(INT16*)outptr = rgb;
    177     }
    178   }
    179 }
    180 
    181 
    182 INLINE
    183 LOCAL(void)
    184 rgb_rgb565_convert_internal (j_decompress_ptr cinfo,
    185                              JSAMPIMAGE input_buf, JDIMENSION input_row,
    186                              JSAMPARRAY output_buf, int num_rows)
    187 {
    188   register JSAMPROW outptr;
    189   register JSAMPROW inptr0, inptr1, inptr2;
    190   register JDIMENSION col;
    191   JDIMENSION num_cols = cinfo->output_width;
    192   SHIFT_TEMPS
    193 
    194   while (--num_rows >= 0) {
    195     INT32 rgb;
    196     unsigned int r, g, b;
    197 
    198     inptr0 = input_buf[0][input_row];
    199     inptr1 = input_buf[1][input_row];
    200     inptr2 = input_buf[2][input_row];
    201     input_row++;
    202     outptr = *output_buf++;
    203     if (PACK_NEED_ALIGNMENT(outptr)) {
    204       r = GETJSAMPLE(*inptr0++);
    205       g = GETJSAMPLE(*inptr1++);
    206       b = GETJSAMPLE(*inptr2++);
    207       rgb = PACK_SHORT_565(r, g, b);
    208       *(INT16*)outptr = rgb;
    209       outptr += 2;
    210       num_cols--;
    211     }
    212     for (col = 0; col < (num_cols >> 1); col++) {
    213       r = GETJSAMPLE(*inptr0++);
    214       g = GETJSAMPLE(*inptr1++);
    215       b = GETJSAMPLE(*inptr2++);
    216       rgb = PACK_SHORT_565(r, g, b);
    217 
    218       r = GETJSAMPLE(*inptr0++);
    219       g = GETJSAMPLE(*inptr1++);
    220       b = GETJSAMPLE(*inptr2++);
    221       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
    222 
    223       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
    224       outptr += 4;
    225     }
    226     if (num_cols & 1) {
    227       r = GETJSAMPLE(*inptr0);
    228       g = GETJSAMPLE(*inptr1);
    229       b = GETJSAMPLE(*inptr2);
    230       rgb = PACK_SHORT_565(r, g, b);
    231       *(INT16*)outptr = rgb;
    232     }
    233   }
    234 }
    235 
    236 
    237 INLINE
    238 LOCAL(void)
    239 rgb_rgb565D_convert_internal (j_decompress_ptr cinfo,
    240                               JSAMPIMAGE input_buf, JDIMENSION input_row,
    241                               JSAMPARRAY output_buf, int num_rows)
    242 {
    243   register JSAMPROW outptr;
    244   register JSAMPROW inptr0, inptr1, inptr2;
    245   register JDIMENSION col;
    246   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    247   JDIMENSION num_cols = cinfo->output_width;
    248   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
    249   SHIFT_TEMPS
    250 
    251   while (--num_rows >= 0) {
    252     INT32 rgb;
    253     unsigned int r, g, b;
    254 
    255     inptr0 = input_buf[0][input_row];
    256     inptr1 = input_buf[1][input_row];
    257     inptr2 = input_buf[2][input_row];
    258     input_row++;
    259     outptr = *output_buf++;
    260     if (PACK_NEED_ALIGNMENT(outptr)) {
    261       r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
    262       g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
    263       b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
    264       rgb = PACK_SHORT_565(r, g, b);
    265       *(INT16*)outptr = rgb;
    266       outptr += 2;
    267       num_cols--;
    268     }
    269     for (col = 0; col < (num_cols >> 1); col++) {
    270       r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
    271       g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
    272       b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
    273       d0 = DITHER_ROTATE(d0);
    274       rgb = PACK_SHORT_565(r, g, b);
    275 
    276       r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0++), d0)];
    277       g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1++), d0)];
    278       b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2++), d0)];
    279       d0 = DITHER_ROTATE(d0);
    280       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
    281 
    282       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
    283       outptr += 4;
    284     }
    285     if (num_cols & 1) {
    286       r = range_limit[DITHER_565_R(GETJSAMPLE(*inptr0), d0)];
    287       g = range_limit[DITHER_565_G(GETJSAMPLE(*inptr1), d0)];
    288       b = range_limit[DITHER_565_B(GETJSAMPLE(*inptr2), d0)];
    289       rgb = PACK_SHORT_565(r, g, b);
    290       *(INT16*)outptr = rgb;
    291     }
    292   }
    293 }
    294 
    295 
    296 INLINE
    297 LOCAL(void)
    298 gray_rgb565_convert_internal (j_decompress_ptr cinfo,
    299                               JSAMPIMAGE input_buf, JDIMENSION input_row,
    300                               JSAMPARRAY output_buf, int num_rows)
    301 {
    302   register JSAMPROW inptr, outptr;
    303   register JDIMENSION col;
    304   JDIMENSION num_cols = cinfo->output_width;
    305 
    306   while (--num_rows >= 0) {
    307     INT32 rgb;
    308     unsigned int g;
    309 
    310     inptr = input_buf[0][input_row++];
    311     outptr = *output_buf++;
    312     if (PACK_NEED_ALIGNMENT(outptr)) {
    313       g = *inptr++;
    314       rgb = PACK_SHORT_565(g, g, g);
    315       *(INT16*)outptr = rgb;
    316       outptr += 2;
    317       num_cols--;
    318     }
    319     for (col = 0; col < (num_cols >> 1); col++) {
    320       g = *inptr++;
    321       rgb = PACK_SHORT_565(g, g, g);
    322       g = *inptr++;
    323       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
    324       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
    325       outptr += 4;
    326     }
    327     if (num_cols & 1) {
    328       g = *inptr;
    329       rgb = PACK_SHORT_565(g, g, g);
    330       *(INT16*)outptr = rgb;
    331     }
    332   }
    333 }
    334 
    335 
    336 INLINE
    337 LOCAL(void)
    338 gray_rgb565D_convert_internal (j_decompress_ptr cinfo,
    339                                JSAMPIMAGE input_buf, JDIMENSION input_row,
    340                                JSAMPARRAY output_buf, int num_rows)
    341 {
    342   register JSAMPROW inptr, outptr;
    343   register JDIMENSION col;
    344   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    345   JDIMENSION num_cols = cinfo->output_width;
    346   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
    347 
    348   while (--num_rows >= 0) {
    349     INT32 rgb;
    350     unsigned int g;
    351 
    352     inptr = input_buf[0][input_row++];
    353     outptr = *output_buf++;
    354     if (PACK_NEED_ALIGNMENT(outptr)) {
    355       g = *inptr++;
    356       g = range_limit[DITHER_565_R(g, d0)];
    357       rgb = PACK_SHORT_565(g, g, g);
    358       *(INT16*)outptr = rgb;
    359       outptr += 2;
    360       num_cols--;
    361     }
    362     for (col = 0; col < (num_cols >> 1); col++) {
    363       g = *inptr++;
    364       g = range_limit[DITHER_565_R(g, d0)];
    365       rgb = PACK_SHORT_565(g, g, g);
    366       d0 = DITHER_ROTATE(d0);
    367 
    368       g = *inptr++;
    369       g = range_limit[DITHER_565_R(g, d0)];
    370       rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(g, g, g));
    371       d0 = DITHER_ROTATE(d0);
    372 
    373       WRITE_TWO_ALIGNED_PIXELS(outptr, rgb);
    374       outptr += 4;
    375     }
    376     if (num_cols & 1) {
    377       g = *inptr;
    378       g = range_limit[DITHER_565_R(g, d0)];
    379       rgb = PACK_SHORT_565(g, g, g);
    380       *(INT16*)outptr = rgb;
    381     }
    382   }
    383 }
    384