Home | History | Annotate | Download | only in jpeg
      1 /*
      2  * jdmerge.c
      3  *
      4  * Copyright (C) 1994-1996, Thomas G. Lane.
      5  * This file is part of the Independent JPEG Group's software.
      6  * For conditions of distribution and use, see the accompanying README file.
      7  *
      8  * This file contains code for merged upsampling/color conversion.
      9  *
     10  * This file combines functions from jdsample.c and jdcolor.c;
     11  * read those files first to understand what's going on.
     12  *
     13  * When the chroma components are to be upsampled by simple replication
     14  * (ie, box filtering), we can save some work in color conversion by
     15  * calculating all the output pixels corresponding to a pair of chroma
     16  * samples at one time.  In the conversion equations
     17  *	R = Y           + K1 * Cr
     18  *	G = Y + K2 * Cb + K3 * Cr
     19  *	B = Y + K4 * Cb
     20  * only the Y term varies among the group of pixels corresponding to a pair
     21  * of chroma samples, so the rest of the terms can be calculated just once.
     22  * At typical sampling ratios, this eliminates half or three-quarters of the
     23  * multiplications needed for color conversion.
     24  *
     25  * This file currently provides implementations for the following cases:
     26  *	YCbCr => RGB color conversion only.
     27  *	Sampling ratios of 2h1v or 2h2v.
     28  *	No scaling needed at upsample time.
     29  *	Corner-aligned (non-CCIR601) sampling alignment.
     30  * Other special cases could be added, but in most applications these are
     31  * the only common cases.  (For uncommon cases we fall back on the more
     32  * general code in jdsample.c and jdcolor.c.)
     33  */
     34 
     35 #define JPEG_INTERNALS
     36 #include "jinclude.h"
     37 #include "jpeglib.h"
     38 
     39 #ifdef UPSAMPLE_MERGING_SUPPORTED
     40 
     41 #ifdef ANDROID_RGB
     42 
     43 /* Declarations for ordered dithering.
     44  *
     45  * We use 4x4 ordered dither array packed into 32 bits. This array is
     46  * sufficent for dithering RGB_888 to RGB_565.
     47  */
     48 
     49 #define DITHER_MASK         0x3
     50 #define DITHER_ROTATE(x)    (((x)<<24) | (((x)>>8)&0x00FFFFFF))
     51 static const INT32 dither_matrix[4] = {
     52   0x0008020A,
     53   0x0C040E06,
     54   0x030B0109,
     55   0x0F070D05
     56 };
     57 
     58 #endif
     59 
     60 /* Private subobject */
     61 
     62 typedef struct {
     63   struct jpeg_upsampler pub;	/* public fields */
     64 
     65   /* Pointer to routine to do actual upsampling/conversion of one row group */
     66   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
     67 			   JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
     68 			   JSAMPARRAY output_buf));
     69 
     70   /* Private state for YCC->RGB conversion */
     71   int * Cr_r_tab;		/* => table for Cr to R conversion */
     72   int * Cb_b_tab;		/* => table for Cb to B conversion */
     73   INT32 * Cr_g_tab;		/* => table for Cr to G conversion */
     74   INT32 * Cb_g_tab;		/* => table for Cb to G conversion */
     75 
     76   /* For 2:1 vertical sampling, we produce two output rows at a time.
     77    * We need a "spare" row buffer to hold the second output row if the
     78    * application provides just a one-row buffer; we also use the spare
     79    * to discard the dummy last row if the image height is odd.
     80    */
     81   JSAMPROW spare_row;
     82   boolean spare_full;		/* T if spare buffer is occupied */
     83 
     84   JDIMENSION out_row_width;	/* samples per output row */
     85   JDIMENSION rows_to_go;	/* counts rows remaining in image */
     86 } my_upsampler;
     87 
     88 typedef my_upsampler * my_upsample_ptr;
     89 
     90 #define SCALEBITS	16	/* speediest right-shift on some machines */
     91 #define ONE_HALF	((INT32) 1 << (SCALEBITS-1))
     92 #define FIX(x)		((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
     93 
     94 
     95 /*
     96  * Initialize tables for YCC->RGB colorspace conversion.
     97  * This is taken directly from jdcolor.c; see that file for more info.
     98  */
     99 
    100 LOCAL(void)
    101 build_ycc_rgb_table (j_decompress_ptr cinfo)
    102 {
    103   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    104   int i;
    105   INT32 x;
    106   SHIFT_TEMPS
    107 
    108   upsample->Cr_r_tab = (int *)
    109     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    110 				(MAXJSAMPLE+1) * SIZEOF(int));
    111   upsample->Cb_b_tab = (int *)
    112     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    113 				(MAXJSAMPLE+1) * SIZEOF(int));
    114   upsample->Cr_g_tab = (INT32 *)
    115     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    116 				(MAXJSAMPLE+1) * SIZEOF(INT32));
    117   upsample->Cb_g_tab = (INT32 *)
    118     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    119 				(MAXJSAMPLE+1) * SIZEOF(INT32));
    120 
    121   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
    122     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
    123     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
    124     /* Cr=>R value is nearest int to 1.40200 * x */
    125     upsample->Cr_r_tab[i] = (int)
    126 		    RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
    127     /* Cb=>B value is nearest int to 1.77200 * x */
    128     upsample->Cb_b_tab[i] = (int)
    129 		    RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
    130     /* Cr=>G value is scaled-up -0.71414 * x */
    131     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
    132     /* Cb=>G value is scaled-up -0.34414 * x */
    133     /* We also add in ONE_HALF so that need not do it in inner loop */
    134     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
    135   }
    136 }
    137 
    138 
    139 /*
    140  * Initialize for an upsampling pass.
    141  */
    142 
    143 METHODDEF(void)
    144 start_pass_merged_upsample (j_decompress_ptr cinfo)
    145 {
    146   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    147 
    148   /* Mark the spare buffer empty */
    149   upsample->spare_full = FALSE;
    150   /* Initialize total-height counter for detecting bottom of image */
    151   upsample->rows_to_go = cinfo->output_height;
    152 }
    153 
    154 
    155 /*
    156  * Control routine to do upsampling (and color conversion).
    157  *
    158  * The control routine just handles the row buffering considerations.
    159  */
    160 
    161 METHODDEF(void)
    162 merged_2v_upsample (j_decompress_ptr cinfo,
    163 		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    164 		    JDIMENSION in_row_groups_avail,
    165 		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    166 		    JDIMENSION out_rows_avail)
    167 /* 2:1 vertical sampling case: may need a spare row. */
    168 {
    169   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    170   JSAMPROW work_ptrs[2];
    171   JDIMENSION num_rows;		/* number of rows returned to caller */
    172 
    173   if (upsample->spare_full) {
    174     /* If we have a spare row saved from a previous cycle, just return it. */
    175       JDIMENSION size = upsample->out_row_width;
    176 #ifdef ANDROID_RGB
    177     if (cinfo->out_color_space == JCS_RGB_565)
    178       size = cinfo->output_width*2;
    179 #endif
    180     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
    181 		      1, size);
    182 
    183     num_rows = 1;
    184     upsample->spare_full = FALSE;
    185   } else {
    186     /* Figure number of rows to return to caller. */
    187     num_rows = 2;
    188     /* Not more than the distance to the end of the image. */
    189     if (num_rows > upsample->rows_to_go)
    190       num_rows = upsample->rows_to_go;
    191     /* And not more than what the client can accept: */
    192     out_rows_avail -= *out_row_ctr;
    193     if (num_rows > out_rows_avail)
    194       num_rows = out_rows_avail;
    195     /* Create output pointer array for upsampler. */
    196     work_ptrs[0] = output_buf[*out_row_ctr];
    197     if (num_rows > 1) {
    198       work_ptrs[1] = output_buf[*out_row_ctr + 1];
    199     } else {
    200       work_ptrs[1] = upsample->spare_row;
    201       upsample->spare_full = TRUE;
    202     }
    203     /* Now do the upsampling. */
    204     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
    205   }
    206 
    207   /* Adjust counts */
    208   *out_row_ctr += num_rows;
    209   upsample->rows_to_go -= num_rows;
    210   /* When the buffer is emptied, declare this input row group consumed */
    211   if (! upsample->spare_full)
    212     (*in_row_group_ctr)++;
    213 }
    214 
    215 
    216 METHODDEF(void)
    217 merged_1v_upsample (j_decompress_ptr cinfo,
    218 		    JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
    219 		    JDIMENSION in_row_groups_avail,
    220 		    JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
    221 		    JDIMENSION out_rows_avail)
    222 /* 1:1 vertical sampling case: much easier, never need a spare row. */
    223 {
    224   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    225 
    226   /* Just do the upsampling. */
    227   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
    228 			 output_buf + *out_row_ctr);
    229   /* Adjust counts */
    230   (*out_row_ctr)++;
    231   (*in_row_group_ctr)++;
    232 }
    233 
    234 
    235 /*
    236  * These are the routines invoked by the control routines to do
    237  * the actual upsampling/conversion.  One row group is processed per call.
    238  *
    239  * Note: since we may be writing directly into application-supplied buffers,
    240  * we have to be honest about the output width; we can't assume the buffer
    241  * has been rounded up to an even width.
    242  */
    243 
    244 
    245 /*
    246  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
    247  */
    248 
    249 METHODDEF(void)
    250 h2v1_merged_upsample (j_decompress_ptr cinfo,
    251 		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    252 		      JSAMPARRAY output_buf)
    253 {
    254   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    255   register int y, cred, cgreen, cblue;
    256   int cb, cr;
    257   register JSAMPROW outptr;
    258   JSAMPROW inptr0, inptr1, inptr2;
    259   JDIMENSION col;
    260   /* copy these pointers into registers if possible */
    261   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    262   int * Crrtab = upsample->Cr_r_tab;
    263   int * Cbbtab = upsample->Cb_b_tab;
    264   INT32 * Crgtab = upsample->Cr_g_tab;
    265   INT32 * Cbgtab = upsample->Cb_g_tab;
    266   SHIFT_TEMPS
    267 
    268   inptr0 = input_buf[0][in_row_group_ctr];
    269   inptr1 = input_buf[1][in_row_group_ctr];
    270   inptr2 = input_buf[2][in_row_group_ctr];
    271   outptr = output_buf[0];
    272   /* Loop for each pair of output pixels */
    273   for (col = cinfo->output_width >> 1; col > 0; col--) {
    274     /* Do the chroma part of the calculation */
    275     cb = GETJSAMPLE(*inptr1++);
    276     cr = GETJSAMPLE(*inptr2++);
    277     cred = Crrtab[cr];
    278     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    279     cblue = Cbbtab[cb];
    280     /* Fetch 2 Y values and emit 2 pixels */
    281     y  = GETJSAMPLE(*inptr0++);
    282     outptr[RGB_RED] = range_limit[y + cred];
    283     outptr[RGB_GREEN] = range_limit[y + cgreen];
    284     outptr[RGB_BLUE] = range_limit[y + cblue];
    285     outptr += RGB_PIXELSIZE;
    286     y  = GETJSAMPLE(*inptr0++);
    287     outptr[RGB_RED] = range_limit[y + cred];
    288     outptr[RGB_GREEN] = range_limit[y + cgreen];
    289     outptr[RGB_BLUE] = range_limit[y + cblue];
    290     outptr += RGB_PIXELSIZE;
    291   }
    292   /* If image width is odd, do the last output column separately */
    293   if (cinfo->output_width & 1) {
    294     cb = GETJSAMPLE(*inptr1);
    295     cr = GETJSAMPLE(*inptr2);
    296     cred = Crrtab[cr];
    297     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    298     cblue = Cbbtab[cb];
    299     y  = GETJSAMPLE(*inptr0);
    300     outptr[RGB_RED] = range_limit[y + cred];
    301     outptr[RGB_GREEN] = range_limit[y + cgreen];
    302     outptr[RGB_BLUE] = range_limit[y + cblue];
    303   }
    304 }
    305 
    306 
    307 #ifdef ANDROID_RGB
    308 METHODDEF(void)
    309 h2v1_merged_upsample_565 (j_decompress_ptr cinfo,
    310               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    311               JSAMPARRAY output_buf)
    312 {
    313   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    314   register int y, cred, cgreen, cblue;
    315   int cb, cr;
    316   register JSAMPROW outptr;
    317   JSAMPROW inptr0, inptr1, inptr2;
    318   JDIMENSION col;
    319   /* copy these pointers into registers if possible */
    320   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    321   int * Crrtab = upsample->Cr_r_tab;
    322   int * Cbbtab = upsample->Cb_b_tab;
    323   INT32 * Crgtab = upsample->Cr_g_tab;
    324   INT32 * Cbgtab = upsample->Cb_g_tab;
    325   unsigned int r, g, b;
    326   INT32 rgb;
    327   SHIFT_TEMPS
    328 
    329   inptr0 = input_buf[0][in_row_group_ctr];
    330   inptr1 = input_buf[1][in_row_group_ctr];
    331   inptr2 = input_buf[2][in_row_group_ctr];
    332   outptr = output_buf[0];
    333   /* Loop for each pair of output pixels */
    334   for (col = cinfo->output_width >> 1; col > 0; col--) {
    335     /* Do the chroma part of the calculation */
    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     /* Fetch 2 Y values and emit 2 pixels */
    342     y  = GETJSAMPLE(*inptr0++);
    343     r = range_limit[y + cred];
    344     g = range_limit[y + cgreen];
    345     b = range_limit[y + cblue];
    346     rgb = PACK_SHORT_565(r,g,b);
    347     y  = GETJSAMPLE(*inptr0++);
    348     r = range_limit[y + cred];
    349     g = range_limit[y + cgreen];
    350     b = range_limit[y + cblue];
    351     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r,g,b));
    352     WRITE_TWO_PIXELS(outptr, rgb);
    353     outptr += 4;
    354   }
    355   /* If image width is odd, do the last output column separately */
    356   if (cinfo->output_width & 1) {
    357     cb = GETJSAMPLE(*inptr1);
    358     cr = GETJSAMPLE(*inptr2);
    359     cred = Crrtab[cr];
    360     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    361     cblue = Cbbtab[cb];
    362     y  = GETJSAMPLE(*inptr0);
    363     r = range_limit[y + cred];
    364     g = range_limit[y + cgreen];
    365     b = range_limit[y + cblue];
    366     rgb = PACK_SHORT_565(r,g,b);
    367     *(INT16*)outptr = rgb;
    368   }
    369 }
    370 
    371 
    372 METHODDEF(void)
    373 h2v1_merged_upsample_565D (j_decompress_ptr cinfo,
    374               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    375               JSAMPARRAY output_buf)
    376 {
    377   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    378   register int y, cred, cgreen, cblue;
    379   int cb, cr;
    380   register JSAMPROW outptr;
    381   JSAMPROW inptr0, inptr1, inptr2;
    382   JDIMENSION col;
    383   /* copy these pointers into registers if possible */
    384   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    385   int * Crrtab = upsample->Cr_r_tab;
    386   int * Cbbtab = upsample->Cb_b_tab;
    387   INT32 * Crgtab = upsample->Cr_g_tab;
    388   INT32 * Cbgtab = upsample->Cb_g_tab;
    389   JDIMENSION col_index = 0;
    390   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
    391   unsigned int r, g, b;
    392   INT32 rgb;
    393   SHIFT_TEMPS
    394 
    395   inptr0 = input_buf[0][in_row_group_ctr];
    396   inptr1 = input_buf[1][in_row_group_ctr];
    397   inptr2 = input_buf[2][in_row_group_ctr];
    398   outptr = output_buf[0];
    399   /* Loop for each pair of output pixels */
    400   for (col = cinfo->output_width >> 1; col > 0; col--) {
    401     /* Do the chroma part of the calculation */
    402     cb = GETJSAMPLE(*inptr1++);
    403     cr = GETJSAMPLE(*inptr2++);
    404     cred = Crrtab[cr];
    405     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    406     cblue = Cbbtab[cb];
    407     /* Fetch 2 Y values and emit 2 pixels */
    408     y  = GETJSAMPLE(*inptr0++);
    409     r = range_limit[DITHER_565_R(y + cred, d0)];
    410     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    411     b = range_limit[DITHER_565_B(y + cblue, d0)];
    412     d0 = DITHER_ROTATE(d0);
    413     rgb = PACK_SHORT_565(r,g,b);
    414     y  = GETJSAMPLE(*inptr0++);
    415     r = range_limit[DITHER_565_R(y + cred, d0)];
    416     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    417     b = range_limit[DITHER_565_B(y + cblue, d0)];
    418     d0 = DITHER_ROTATE(d0);
    419     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r,g,b));
    420     WRITE_TWO_PIXELS(outptr, rgb);
    421     outptr += 4;
    422   }
    423   /* If image width is odd, do the last output column separately */
    424   if (cinfo->output_width & 1) {
    425     cb = GETJSAMPLE(*inptr1);
    426     cr = GETJSAMPLE(*inptr2);
    427     cred = Crrtab[cr];
    428     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    429     cblue = Cbbtab[cb];
    430     y  = GETJSAMPLE(*inptr0);
    431     r = range_limit[DITHER_565_R(y + cred, d0)];
    432     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    433     b = range_limit[DITHER_565_B(y + cblue, d0)];
    434     rgb = PACK_SHORT_565(r,g,b);
    435     *(INT16*)outptr = rgb;
    436   }
    437 }
    438 
    439 
    440 #endif
    441 
    442 /*
    443  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
    444  */
    445 
    446 METHODDEF(void)
    447 h2v2_merged_upsample (j_decompress_ptr cinfo,
    448 		      JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    449 		      JSAMPARRAY output_buf)
    450 {
    451   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    452   register int y, cred, cgreen, cblue;
    453   int cb, cr;
    454   register JSAMPROW outptr0, outptr1;
    455   JSAMPROW inptr00, inptr01, inptr1, inptr2;
    456   JDIMENSION col;
    457   /* copy these pointers into registers if possible */
    458   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    459   int * Crrtab = upsample->Cr_r_tab;
    460   int * Cbbtab = upsample->Cb_b_tab;
    461   INT32 * Crgtab = upsample->Cr_g_tab;
    462   INT32 * Cbgtab = upsample->Cb_g_tab;
    463   SHIFT_TEMPS
    464 
    465   inptr00 = input_buf[0][in_row_group_ctr*2];
    466   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
    467   inptr1 = input_buf[1][in_row_group_ctr];
    468   inptr2 = input_buf[2][in_row_group_ctr];
    469   outptr0 = output_buf[0];
    470   outptr1 = output_buf[1];
    471   /* Loop for each group of output pixels */
    472   for (col = cinfo->output_width >> 1; col > 0; col--) {
    473     /* Do the chroma part of the calculation */
    474     cb = GETJSAMPLE(*inptr1++);
    475     cr = GETJSAMPLE(*inptr2++);
    476     cred = Crrtab[cr];
    477     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    478     cblue = Cbbtab[cb];
    479     /* Fetch 4 Y values and emit 4 pixels */
    480     y  = GETJSAMPLE(*inptr00++);
    481     outptr0[RGB_RED] = range_limit[y + cred];
    482     outptr0[RGB_GREEN] = range_limit[y + cgreen];
    483     outptr0[RGB_BLUE] = range_limit[y + cblue];
    484     outptr0 += RGB_PIXELSIZE;
    485     y  = GETJSAMPLE(*inptr00++);
    486     outptr0[RGB_RED] = range_limit[y + cred];
    487     outptr0[RGB_GREEN] = range_limit[y + cgreen];
    488     outptr0[RGB_BLUE] = range_limit[y + cblue];
    489     outptr0 += RGB_PIXELSIZE;
    490     y  = GETJSAMPLE(*inptr01++);
    491     outptr1[RGB_RED] = range_limit[y + cred];
    492     outptr1[RGB_GREEN] = range_limit[y + cgreen];
    493     outptr1[RGB_BLUE] = range_limit[y + cblue];
    494     outptr1 += RGB_PIXELSIZE;
    495     y  = GETJSAMPLE(*inptr01++);
    496     outptr1[RGB_RED] = range_limit[y + cred];
    497     outptr1[RGB_GREEN] = range_limit[y + cgreen];
    498     outptr1[RGB_BLUE] = range_limit[y + cblue];
    499     outptr1 += RGB_PIXELSIZE;
    500   }
    501   /* If image width is odd, do the last output column separately */
    502   if (cinfo->output_width & 1) {
    503     cb = GETJSAMPLE(*inptr1);
    504     cr = GETJSAMPLE(*inptr2);
    505     cred = Crrtab[cr];
    506     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    507     cblue = Cbbtab[cb];
    508     y  = GETJSAMPLE(*inptr00);
    509     outptr0[RGB_RED] = range_limit[y + cred];
    510     outptr0[RGB_GREEN] = range_limit[y + cgreen];
    511     outptr0[RGB_BLUE] = range_limit[y + cblue];
    512     y  = GETJSAMPLE(*inptr01);
    513     outptr1[RGB_RED] = range_limit[y + cred];
    514     outptr1[RGB_GREEN] = range_limit[y + cgreen];
    515     outptr1[RGB_BLUE] = range_limit[y + cblue];
    516   }
    517 }
    518 
    519 
    520 #ifdef ANDROID_RGB
    521 
    522 METHODDEF(void)
    523 h2v2_merged_upsample_565 (j_decompress_ptr cinfo,
    524               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    525               JSAMPARRAY output_buf)
    526 {
    527   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    528   register int y, cred, cgreen, cblue;
    529   int cb, cr;
    530   register JSAMPROW outptr0, outptr1;
    531   JSAMPROW inptr00, inptr01, inptr1, inptr2;
    532   JDIMENSION col;
    533   /* copy these pointers into registers if possible */
    534   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    535   int * Crrtab = upsample->Cr_r_tab;
    536   int * Cbbtab = upsample->Cb_b_tab;
    537   INT32 * Crgtab = upsample->Cr_g_tab;
    538   INT32 * Cbgtab = upsample->Cb_g_tab;
    539   unsigned int r, g, b;
    540   INT32 rgb;
    541   SHIFT_TEMPS
    542 
    543   inptr00 = input_buf[0][in_row_group_ctr*2];
    544   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
    545   inptr1 = input_buf[1][in_row_group_ctr];
    546   inptr2 = input_buf[2][in_row_group_ctr];
    547   outptr0 = output_buf[0];
    548   outptr1 = output_buf[1];
    549   /* Loop for each group of output pixels */
    550   for (col = cinfo->output_width >> 1; col > 0; col--) {
    551     /* Do the chroma part of the calculation */
    552     cb = GETJSAMPLE(*inptr1++);
    553     cr = GETJSAMPLE(*inptr2++);
    554     cred = Crrtab[cr];
    555     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    556     cblue = Cbbtab[cb];
    557     /* Fetch 4 Y values and emit 4 pixels */
    558     y  = GETJSAMPLE(*inptr00++);
    559     r = range_limit[y + cred];
    560     g = range_limit[y + cgreen];
    561     b = range_limit[y + cblue];
    562     rgb = PACK_SHORT_565(r,g,b);
    563     y  = GETJSAMPLE(*inptr00++);
    564     r = range_limit[y + cred];
    565     g = range_limit[y + cgreen];
    566     b = range_limit[y + cblue];
    567     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r,g,b));
    568     WRITE_TWO_PIXELS(outptr0, rgb);
    569     outptr0 += 4;
    570     y  = GETJSAMPLE(*inptr01++);
    571     r = range_limit[y + cred];
    572     g = range_limit[y + cgreen];
    573     b = range_limit[y + cblue];
    574     rgb = PACK_SHORT_565(r,g,b);
    575     y  = GETJSAMPLE(*inptr01++);
    576     r = range_limit[y + cred];
    577     g = range_limit[y + cgreen];
    578     b = range_limit[y + cblue];
    579     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r,g,b));
    580     WRITE_TWO_PIXELS(outptr1, rgb);
    581     outptr1 += 4;
    582   }
    583   /* If image width is odd, do the last output column separately */
    584   if (cinfo->output_width & 1) {
    585     cb = GETJSAMPLE(*inptr1);
    586     cr = GETJSAMPLE(*inptr2);
    587     cred = Crrtab[cr];
    588     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    589     cblue = Cbbtab[cb];
    590     y  = GETJSAMPLE(*inptr00);
    591     r = range_limit[y + cred];
    592     g = range_limit[y + cgreen];
    593     b = range_limit[y + cblue];
    594     rgb = PACK_SHORT_565(r,g,b);
    595     *(INT16*)outptr0 = rgb;
    596    y  = GETJSAMPLE(*inptr01);
    597    r = range_limit[y + cred];
    598    g = range_limit[y + cgreen];
    599    b = range_limit[y + cblue];
    600    rgb = PACK_SHORT_565(r,g,b);
    601    *(INT16*)outptr1 = rgb;
    602   }
    603 }
    604 
    605 
    606 
    607 METHODDEF(void)
    608 h2v2_merged_upsample_565D (j_decompress_ptr cinfo,
    609               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
    610               JSAMPARRAY output_buf)
    611 {
    612   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
    613   register int y, cred, cgreen, cblue;
    614   int cb, cr;
    615   register JSAMPROW outptr0, outptr1;
    616   JSAMPROW inptr00, inptr01, inptr1, inptr2;
    617   JDIMENSION col;
    618   /* copy these pointers into registers if possible */
    619   register JSAMPLE * range_limit = cinfo->sample_range_limit;
    620   int * Crrtab = upsample->Cr_r_tab;
    621   int * Cbbtab = upsample->Cb_b_tab;
    622   INT32 * Crgtab = upsample->Cr_g_tab;
    623   INT32 * Cbgtab = upsample->Cb_g_tab;
    624   JDIMENSION col_index = 0;
    625   INT32 d0 = dither_matrix[cinfo->output_scanline & DITHER_MASK];
    626   INT32 d1 = dither_matrix[(cinfo->output_scanline+1) & DITHER_MASK];
    627   unsigned int r, g, b;
    628   INT32 rgb;
    629   SHIFT_TEMPS
    630 
    631   inptr00 = input_buf[0][in_row_group_ctr*2];
    632   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
    633   inptr1 = input_buf[1][in_row_group_ctr];
    634   inptr2 = input_buf[2][in_row_group_ctr];
    635   outptr0 = output_buf[0];
    636   outptr1 = output_buf[1];
    637   /* Loop for each group of output pixels */
    638   for (col = cinfo->output_width >> 1; col > 0; col--) {
    639 
    640     /* Do the chroma part of the calculation */
    641     cb = GETJSAMPLE(*inptr1++);
    642     cr = GETJSAMPLE(*inptr2++);
    643     cred = Crrtab[cr];
    644     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    645     cblue = Cbbtab[cb];
    646     /* Fetch 4 Y values and emit 4 pixels */
    647     y  = GETJSAMPLE(*inptr00++);
    648     r = range_limit[DITHER_565_R(y + cred, d0)];
    649     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    650     b = range_limit[DITHER_565_B(y + cblue, d0)];
    651     d0 = DITHER_ROTATE(d0);
    652     rgb = PACK_SHORT_565(r,g,b);
    653     y  = GETJSAMPLE(*inptr00++);
    654     r = range_limit[DITHER_565_R(y + cred, d1)];
    655     g = range_limit[DITHER_565_G(y + cgreen, d1)];
    656     b = range_limit[DITHER_565_B(y + cblue, d1)];
    657     d1 = DITHER_ROTATE(d1);
    658     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r,g,b));
    659     WRITE_TWO_PIXELS(outptr0, rgb);
    660     outptr0 += 4;
    661     y  = GETJSAMPLE(*inptr01++);
    662     r = range_limit[DITHER_565_R(y + cred, d0)];
    663     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    664     b = range_limit[DITHER_565_B(y + cblue, d0)];
    665     d0 = DITHER_ROTATE(d0);
    666     rgb = PACK_SHORT_565(r,g,b);
    667     y  = GETJSAMPLE(*inptr01++);
    668     r = range_limit[DITHER_565_R(y + cred, d1)];
    669     g = range_limit[DITHER_565_G(y + cgreen, d1)];
    670     b = range_limit[DITHER_565_B(y + cblue, d1)];
    671     d1 = DITHER_ROTATE(d1);
    672     rgb = PACK_TWO_PIXELS(rgb, PACK_SHORT_565(r,g,b));
    673     WRITE_TWO_PIXELS(outptr1, rgb);
    674     outptr1 += 4;
    675   }
    676   /* If image width is odd, do the last output column separately */
    677   if (cinfo->output_width & 1) {
    678     cb = GETJSAMPLE(*inptr1);
    679     cr = GETJSAMPLE(*inptr2);
    680     cred = Crrtab[cr];
    681     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
    682     cblue = Cbbtab[cb];
    683     y  = GETJSAMPLE(*inptr00);
    684     r = range_limit[DITHER_565_R(y + cred, d0)];
    685     g = range_limit[DITHER_565_G(y + cgreen, d0)];
    686     b = range_limit[DITHER_565_B(y + cblue, d0)];
    687     rgb = PACK_SHORT_565(r,g,b);
    688     *(INT16*)outptr0 = rgb;
    689    y  = GETJSAMPLE(*inptr01);
    690    r = range_limit[DITHER_565_R(y + cred, d1)];
    691    g = range_limit[DITHER_565_G(y + cgreen, d1)];
    692    b = range_limit[DITHER_565_B(y + cblue, d1)];
    693    rgb = PACK_SHORT_565(r,g,b);
    694    *(INT16*)outptr1 = rgb;
    695   }
    696 }
    697 
    698 #endif
    699 
    700 /*
    701  * Module initialization routine for merged upsampling/color conversion.
    702  *
    703  * NB: this is called under the conditions determined by use_merged_upsample()
    704  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
    705  * of this module; no safety checks are made here.
    706  */
    707 
    708 GLOBAL(void)
    709 jinit_merged_upsampler (j_decompress_ptr cinfo)
    710 {
    711   my_upsample_ptr upsample;
    712 
    713   upsample = (my_upsample_ptr)
    714     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    715 				SIZEOF(my_upsampler));
    716   cinfo->upsample = (struct jpeg_upsampler *) upsample;
    717   upsample->pub.start_pass = start_pass_merged_upsample;
    718   upsample->pub.need_context_rows = FALSE;
    719 
    720   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
    721 
    722   if (cinfo->max_v_samp_factor == 2) {
    723     upsample->pub.upsample = merged_2v_upsample;
    724     upsample->upmethod = h2v2_merged_upsample;
    725 #ifdef ANDROID_RGB
    726     if (cinfo->out_color_space == JCS_RGB_565) {
    727         if (cinfo->dither_mode == JDITHER_NONE) {
    728             upsample->upmethod = h2v2_merged_upsample_565;
    729         } else {
    730             upsample->upmethod = h2v2_merged_upsample_565D;
    731         }
    732     }
    733 #endif
    734     /* Allocate a spare row buffer */
    735     upsample->spare_row = (JSAMPROW)
    736       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
    737 		(size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
    738   } else {
    739     upsample->pub.upsample = merged_1v_upsample;
    740     upsample->upmethod = h2v1_merged_upsample;
    741 #ifdef ANDROID_RGB
    742     if (cinfo->out_color_space == JCS_RGB_565) {
    743         if (cinfo->dither_mode == JDITHER_NONE) {
    744             upsample->upmethod = h2v1_merged_upsample_565;
    745         } else {
    746             upsample->upmethod = h2v1_merged_upsample_565D;
    747         }
    748     }
    749 #endif
    750     /* No spare row needed */
    751     upsample->spare_row = NULL;
    752   }
    753 
    754   build_ycc_rgb_table(cinfo);
    755 }
    756 
    757 #endif /* UPSAMPLE_MERGING_SUPPORTED */
    758