Home | History | Annotate | Download | only in libjpeg-turbo
      1 /*
      2  * jdmrg565.c
      3  *
      4  * This file was part of the Independent JPEG Group's software:
      5  * Copyright (C) 1994-1996, Thomas G. Lane.
      6  * libjpeg-turbo 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 code for merged upsampling/color conversion.
     12  */
     13 
     14 
     15 INLINE
     16 LOCAL(void)
     17 h2v1_merged_upsample_565_internal (j_decompress_ptr cinfo,
     18                                    JSAMPIMAGE input_buf,
     19                                    JDIMENSION in_row_group_ctr,
     20                                    JSAMPARRAY output_buf)
     21 {
     22   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
     23   register int y, cred, cgreen, cblue;
     24   int cb, cr;
     25   register JSAMPROW outptr;
     26   JSAMPROW inptr0, inptr1, inptr2;
     27   JDIMENSION col;
     28   /* copy these pointers into registers if possible */
     29   register JSAMPLE * range_limit = cinfo->sample_range_limit;
     30   int * Crrtab = upsample->Cr_r_tab;
     31   int * Cbbtab = upsample->Cb_b_tab;
     32   INT32 * Crgtab = upsample->Cr_g_tab;
     33   INT32 * Cbgtab = upsample->Cb_g_tab;
     34   unsigned int r, g, b;
     35   INT32 rgb;
     36   SHIFT_TEMPS
     37 
     38   inptr0 = input_buf[0][in_row_group_ctr];
     39   inptr1 = input_buf[1][in_row_group_ctr];
     40   inptr2 = input_buf[2][in_row_group_ctr];
     41   outptr = output_buf[0];
     42 
     43   /* Loop for each pair of output pixels */
     44   for (col = cinfo->output_width >> 1; col > 0; col--) {
     45     /* Do the chroma part of the calculation */
     46     cb = GETJSAMPLE(*inptr1++);
     47     cr = GETJSAMPLE(*inptr2++);
     48     cred = Crrtab[cr];
     49     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     50     cblue = Cbbtab[cb];
     51 
     52     /* Fetch 2 Y values and emit 2 pixels */
     53     y  = GETJSAMPLE(*inptr0++);
     54     r = range_limit[y + cred];
     55     g = range_limit[y + cgreen];
     56     b = range_limit[y + cblue];
     57     rgb = PACK_SHORT_565(r, g, b);
     58 
     59     y  = GETJSAMPLE(*inptr0++);
     60     r = range_limit[y + cred];
     61     g = range_limit[y + cgreen];
     62     b = range_limit[y + cblue];
     63     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
     64 
     65     WRITE_TWO_PIXELS(outptr, rgb);
     66     outptr += 4;
     67   }
     68 
     69   /* If image width is odd, do the last output column separately */
     70   if (cinfo->output_width & 1) {
     71     cb = GETJSAMPLE(*inptr1);
     72     cr = GETJSAMPLE(*inptr2);
     73     cred = Crrtab[cr];
     74     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
     75     cblue = Cbbtab[cb];
     76     y  = GETJSAMPLE(*inptr0);
     77     r = range_limit[y + cred];
     78     g = range_limit[y + cgreen];
     79     b = range_limit[y + cblue];
     80     rgb = PACK_SHORT_565(r, g, b);
     81     *(INT16*)outptr = rgb;
     82    }
     83  }
     84 
     85 
     86 INLINE
     87 LOCAL(void)
     88 h2v1_merged_upsample_565D_internal (j_decompress_ptr cinfo,
     89                                     JSAMPIMAGE input_buf,
     90                                     JDIMENSION in_row_group_ctr,
     91                                     JSAMPARRAY output_buf)
     92 {
     93   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
     94   register int y, cred, cgreen, cblue;
     95   int cb, cr;
     96   register JSAMPROW outptr;
     97   JSAMPROW inptr0, inptr1, inptr2;
     98   JDIMENSION col;
     99   /* copy these pointers into registers if possible */
    100   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    101   int * Crrtab = upsample->Cr_r_tab;
    102   int * Cbbtab = upsample->Cb_b_tab;
    103   INT32 * Crgtab = upsample->Cr_g_tab;
    104   INT32 * Cbgtab = upsample->Cb_g_tab;
    105   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
    106   unsigned int r, g, b;
    107   INT32 rgb;
    108   SHIFT_TEMPS
    109 
    110   inptr0 = input_buf[0][in_row_group_ctr];
    111   inptr1 = input_buf[1][in_row_group_ctr];
    112   inptr2 = input_buf[2][in_row_group_ctr];
    113   outptr = output_buf[0];
    114 
    115   /* Loop for each pair of output pixels */
    116   for (col = cinfo->output_width >> 1; col > 0; col--) {
    117     /* Do the chroma part of the calculation */
    118     cb = GETJSAMPLE(*inptr1++);
    119     cr = GETJSAMPLE(*inptr2++);
    120     cred = Crrtab[cr];
    121     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    122     cblue = Cbbtab[cb];
    123 
    124     /* Fetch 2 Y values and emit 2 pixels */
    125     y  = GETJSAMPLE(*inptr0++);
    126     r = range_limit[DITHER_565_R(y + cred, d0)];
    127     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    128     b = range_limit[DITHER_565_B(y + cblue, d0)];
    129     d0 = DITHER_ROTATE(d0);
    130     rgb = PACK_SHORT_565(r, g, b);
    131 
    132     y  = GETJSAMPLE(*inptr0++);
    133     r = range_limit[DITHER_565_R(y + cred, d0)];
    134     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    135     b = range_limit[DITHER_565_B(y + cblue, d0)];
    136     d0 = DITHER_ROTATE(d0);
    137     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
    138 
    139     WRITE_TWO_PIXELS(outptr, rgb);
    140     outptr += 4;
    141   }
    142 
    143   /* If image width is odd, do the last output column separately */
    144   if (cinfo->output_width & 1) {
    145     cb = GETJSAMPLE(*inptr1);
    146     cr = GETJSAMPLE(*inptr2);
    147     cred = Crrtab[cr];
    148     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    149     cblue = Cbbtab[cb];
    150     y  = GETJSAMPLE(*inptr0);
    151     r = range_limit[DITHER_565_R(y + cred, d0)];
    152     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    153     b = range_limit[DITHER_565_B(y + cblue, d0)];
    154     rgb = PACK_SHORT_565(r, g, b);
    155     *(INT16*)outptr = rgb;
    156   }
    157 }
    158 
    159 
    160 INLINE
    161 LOCAL(void)
    162 h2v2_merged_upsample_565_internal (j_decompress_ptr cinfo,
    163                                    JSAMPIMAGE input_buf,
    164                                    JDIMENSION in_row_group_ctr,
    165                                    JSAMPARRAY output_buf)
    166 {
    167   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    168   register int y, cred, cgreen, cblue;
    169   int cb, cr;
    170   register JSAMPROW outptr0, outptr1;
    171   JSAMPROW inptr00, inptr01, inptr1, inptr2;
    172   JDIMENSION col;
    173   /* copy these pointers into registers if possible */
    174   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    175   int * Crrtab = upsample->Cr_r_tab;
    176   int * Cbbtab = upsample->Cb_b_tab;
    177   INT32 * Crgtab = upsample->Cr_g_tab;
    178   INT32 * Cbgtab = upsample->Cb_g_tab;
    179   unsigned int r, g, b;
    180   INT32 rgb;
    181   SHIFT_TEMPS
    182 
    183   inptr00 = input_buf[0][in_row_group_ctr * 2];
    184   inptr01 = input_buf[0][in_row_group_ctr * 2 + 1];
    185   inptr1 = input_buf[1][in_row_group_ctr];
    186   inptr2 = input_buf[2][in_row_group_ctr];
    187   outptr0 = output_buf[0];
    188   outptr1 = output_buf[1];
    189 
    190   /* Loop for each group of output pixels */
    191   for (col = cinfo->output_width >> 1; col > 0; col--) {
    192     /* Do the chroma part of the calculation */
    193     cb = GETJSAMPLE(*inptr1++);
    194     cr = GETJSAMPLE(*inptr2++);
    195     cred = Crrtab[cr];
    196     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    197     cblue = Cbbtab[cb];
    198 
    199     /* Fetch 4 Y values and emit 4 pixels */
    200     y  = GETJSAMPLE(*inptr00++);
    201     r = range_limit[y + cred];
    202     g = range_limit[y + cgreen];
    203     b = range_limit[y + cblue];
    204     rgb = PACK_SHORT_565(r, g, b);
    205 
    206     y  = GETJSAMPLE(*inptr00++);
    207     r = range_limit[y + cred];
    208     g = range_limit[y + cgreen];
    209     b = range_limit[y + cblue];
    210     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
    211 
    212     WRITE_TWO_PIXELS(outptr0, rgb);
    213     outptr0 += 4;
    214 
    215     y  = GETJSAMPLE(*inptr01++);
    216     r = range_limit[y + cred];
    217     g = range_limit[y + cgreen];
    218     b = range_limit[y + cblue];
    219     rgb = PACK_SHORT_565(r, g, b);
    220 
    221     y  = GETJSAMPLE(*inptr01++);
    222     r = range_limit[y + cred];
    223     g = range_limit[y + cgreen];
    224     b = range_limit[y + cblue];
    225     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
    226 
    227     WRITE_TWO_PIXELS(outptr1, rgb);
    228     outptr1 += 4;
    229   }
    230 
    231   /* If image width is odd, do the last output column separately */
    232   if (cinfo->output_width & 1) {
    233     cb = GETJSAMPLE(*inptr1);
    234     cr = GETJSAMPLE(*inptr2);
    235     cred = Crrtab[cr];
    236     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    237     cblue = Cbbtab[cb];
    238 
    239     y  = GETJSAMPLE(*inptr00);
    240     r = range_limit[y + cred];
    241     g = range_limit[y + cgreen];
    242     b = range_limit[y + cblue];
    243     rgb = PACK_SHORT_565(r, g, b);
    244     *(INT16*)outptr0 = rgb;
    245 
    246     y  = GETJSAMPLE(*inptr01);
    247     r = range_limit[y + cred];
    248     g = range_limit[y + cgreen];
    249     b = range_limit[y + cblue];
    250     rgb = PACK_SHORT_565(r, g, b);
    251     *(INT16*)outptr1 = rgb;
    252   }
    253 }
    254 
    255 
    256 INLINE
    257 LOCAL(void)
    258 h2v2_merged_upsample_565D_internal (j_decompress_ptr cinfo,
    259                                     JSAMPIMAGE input_buf,
    260                                     JDIMENSION in_row_group_ctr,
    261                                     JSAMPARRAY output_buf)
    262 {
    263   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    264   register int y, cred, cgreen, cblue;
    265   int cb, cr;
    266   register JSAMPROW outptr0, outptr1;
    267   JSAMPROW inptr00, inptr01, inptr1, inptr2;
    268   JDIMENSION col;
    269   /* copy these pointers into registers if possible */
    270   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    271   int * Crrtab = upsample->Cr_r_tab;
    272   int * Cbbtab = upsample->Cb_b_tab;
    273   INT32 * Crgtab = upsample->Cr_g_tab;
    274   INT32 * Cbgtab = upsample->Cb_g_tab;
    275   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
    276   INT32 d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK];
    277   unsigned int r, g, b;
    278   INT32 rgb;
    279   SHIFT_TEMPS
    280 
    281   inptr00 = input_buf[0][in_row_group_ctr*2];
    282   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
    283   inptr1 = input_buf[1][in_row_group_ctr];
    284   inptr2 = input_buf[2][in_row_group_ctr];
    285   outptr0 = output_buf[0];
    286   outptr1 = output_buf[1];
    287 
    288   /* Loop for each group of output pixels */
    289   for (col = cinfo->output_width >> 1; col > 0; col--) {
    290     /* Do the chroma part of the calculation */
    291     cb = GETJSAMPLE(*inptr1++);
    292     cr = GETJSAMPLE(*inptr2++);
    293     cred = Crrtab[cr];
    294     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    295     cblue = Cbbtab[cb];
    296 
    297     /* Fetch 4 Y values and emit 4 pixels */
    298     y  = GETJSAMPLE(*inptr00++);
    299     r = range_limit[DITHER_565_R(y + cred, d0)];
    300     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    301     b = range_limit[DITHER_565_B(y + cblue, d0)];
    302     d0 = DITHER_ROTATE(d0);
    303     rgb = PACK_SHORT_565(r, g, b);
    304 
    305     y  = GETJSAMPLE(*inptr00++);
    306     r = range_limit[DITHER_565_R(y + cred, d1)];
    307     g = range_limit[DITHER_565_G(y + cgreen, d1)];
    308     b = range_limit[DITHER_565_B(y + cblue, d1)];
    309     d1 = DITHER_ROTATE(d1);
    310     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
    311 
    312     WRITE_TWO_PIXELS(outptr0, rgb);
    313     outptr0 += 4;
    314 
    315     y  = GETJSAMPLE(*inptr01++);
    316     r = range_limit[DITHER_565_R(y + cred, d0)];
    317     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    318     b = range_limit[DITHER_565_B(y + cblue, d0)];
    319     d0 = DITHER_ROTATE(d0);
    320     rgb = PACK_SHORT_565(r, g, b);
    321 
    322     y  = GETJSAMPLE(*inptr01++);
    323     r = range_limit[DITHER_565_R(y + cred, d1)];
    324     g = range_limit[DITHER_565_G(y + cgreen, d1)];
    325     b = range_limit[DITHER_565_B(y + cblue, d1)];
    326     d1 = DITHER_ROTATE(d1);
    327     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r, g, b));
    328 
    329     WRITE_TWO_PIXELS(outptr1, rgb);
    330     outptr1 += 4;
    331   }
    332 
    333   /* If image width is odd, do the last output column separately */
    334   if (cinfo->output_width & 1) {
    335     cb = GETJSAMPLE(*inptr1);
    336     cr = GETJSAMPLE(*inptr2);
    337     cred = Crrtab[cr];
    338     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    339     cblue = Cbbtab[cb];
    340 
    341     y  = GETJSAMPLE(*inptr00);
    342     r = range_limit[DITHER_565_R(y + cred, d0)];
    343     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    344     b = range_limit[DITHER_565_B(y + cblue, d0)];
    345     rgb = PACK_SHORT_565(r, g, b);
    346     *(INT16*)outptr0 = rgb;
    347 
    348     y  = GETJSAMPLE(*inptr01);
    349     r = range_limit[DITHER_565_R(y + cred, d1)];
    350     g = range_limit[DITHER_565_G(y + cgreen, d1)];
    351     b = range_limit[DITHER_565_B(y + cblue, d1)];
    352     rgb = PACK_SHORT_565(r, g, b);
    353     *(INT16*)outptr1 = rgb;
    354   }
    355 }
    356