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