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. 
   8  * This file contains code for merged upsampling/color conversion. 
  10  * This file combines functions from jdsample.c and jdcolor.c; 
  11  * read those files first to understand what's going on. 
  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 
  18  *      G = Y + K2 * Cb + K3 * Cr 
  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. 
  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.) 
  35 #define JPEG_INTERNALS 
  39 #ifdef UPSAMPLE_MERGING_SUPPORTED 
  42 /* Private subobject */ 
  45   struct jpeg_upsampler pub
;    /* public fields */ 
  47   /* Pointer to routine to do actual upsampling/conversion of one row group */ 
  48   JMETHOD(void, upmethod
, (j_decompress_ptr cinfo
, 
  49                            JSAMPIMAGE input_buf
, JDIMENSION in_row_group_ctr
, 
  50                            JSAMPARRAY output_buf
)); 
  52   /* Private state for YCC->RGB conversion */ 
  53   int * Cr_r_tab
;               /* => table for Cr to R conversion */ 
  54   int * Cb_b_tab
;               /* => table for Cb to B conversion */ 
  55   INT32 
* Cr_g_tab
;             /* => table for Cr to G conversion */ 
  56   INT32 
* Cb_g_tab
;             /* => table for Cb to G conversion */ 
  58   /* For 2:1 vertical sampling, we produce two output rows at a time. 
  59    * We need a "spare" row buffer to hold the second output row if the 
  60    * application provides just a one-row buffer; we also use the spare 
  61    * to discard the dummy last row if the image height is odd. 
  64   boolean spare_full
;           /* T if spare buffer is occupied */ 
  66   JDIMENSION out_row_width
;     /* samples per output row */ 
  67   JDIMENSION rows_to_go
;        /* counts rows remaining in image */ 
  70 typedef my_upsampler 
* my_upsample_ptr
; 
  72 #define SCALEBITS       16      /* speediest right-shift on some machines */ 
  73 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1)) 
  74 #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5)) 
  78  * Initialize tables for YCC->RGB colorspace conversion. 
  79  * This is taken directly from jdcolor.c; see that file for more info. 
  83 build_ycc_rgb_table (j_decompress_ptr cinfo
) 
  85   my_upsample_ptr upsample 
= (my_upsample_ptr
) cinfo
->upsample
; 
  90   upsample
->Cr_r_tab 
= (int *) 
  91     (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, 
  92                                 (MAXJSAMPLE
+1) * SIZEOF(int)); 
  93   upsample
->Cb_b_tab 
= (int *) 
  94     (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, 
  95                                 (MAXJSAMPLE
+1) * SIZEOF(int)); 
  96   upsample
->Cr_g_tab 
= (INT32 
*) 
  97     (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, 
  98                                 (MAXJSAMPLE
+1) * SIZEOF(INT32
)); 
  99   upsample
->Cb_g_tab 
= (INT32 
*) 
 100     (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, 
 101                                 (MAXJSAMPLE
+1) * SIZEOF(INT32
)); 
 103   for (i 
= 0, x 
= -CENTERJSAMPLE
; i 
<= MAXJSAMPLE
; i
++, x
++) { 
 104     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */ 
 105     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */ 
 106     /* Cr=>R value is nearest int to 1.40200 * x */ 
 107     upsample
->Cr_r_tab
[i
] = (int) 
 108                     RIGHT_SHIFT(FIX(1.40200) * x 
+ ONE_HALF
, SCALEBITS
); 
 109     /* Cb=>B value is nearest int to 1.77200 * x */ 
 110     upsample
->Cb_b_tab
[i
] = (int) 
 111                     RIGHT_SHIFT(FIX(1.77200) * x 
+ ONE_HALF
, SCALEBITS
); 
 112     /* Cr=>G value is scaled-up -0.71414 * x */ 
 113     upsample
->Cr_g_tab
[i
] = (- FIX(0.71414)) * x
; 
 114     /* Cb=>G value is scaled-up -0.34414 * x */ 
 115     /* We also add in ONE_HALF so that need not do it in inner loop */ 
 116     upsample
->Cb_g_tab
[i
] = (- FIX(0.34414)) * x 
+ ONE_HALF
; 
 122  * Initialize for an upsampling pass. 
 126 start_pass_merged_upsample (j_decompress_ptr cinfo
) 
 128   my_upsample_ptr upsample 
= (my_upsample_ptr
) cinfo
->upsample
; 
 130   /* Mark the spare buffer empty */ 
 131   upsample
->spare_full 
= FALSE
; 
 132   /* Initialize total-height counter for detecting bottom of image */ 
 133   upsample
->rows_to_go 
= cinfo
->output_height
; 
 138  * Control routine to do upsampling (and color conversion). 
 140  * The control routine just handles the row buffering considerations. 
 144 merged_2v_upsample (j_decompress_ptr cinfo
, 
 145                     JSAMPIMAGE input_buf
, JDIMENSION 
*in_row_group_ctr
, 
 146                     JDIMENSION in_row_groups_avail
, 
 147                     JSAMPARRAY output_buf
, JDIMENSION 
*out_row_ctr
, 
 148                     JDIMENSION out_rows_avail
) 
 149 /* 2:1 vertical sampling case: may need a spare row. */ 
 151   my_upsample_ptr upsample 
= (my_upsample_ptr
) cinfo
->upsample
; 
 152   JSAMPROW work_ptrs
[2]; 
 153   JDIMENSION num_rows
;          /* number of rows returned to caller */ 
 155   if (upsample
->spare_full
) { 
 156     /* If we have a spare row saved from a previous cycle, just return it. */ 
 157     jcopy_sample_rows(& upsample
->spare_row
, 0, output_buf 
+ *out_row_ctr
, 0, 
 158                       1, upsample
->out_row_width
); 
 160     upsample
->spare_full 
= FALSE
; 
 162     /* Figure number of rows to return to caller. */ 
 164     /* Not more than the distance to the end of the image. */ 
 165     if (num_rows 
> upsample
->rows_to_go
) 
 166       num_rows 
= upsample
->rows_to_go
; 
 167     /* And not more than what the client can accept: */ 
 168     out_rows_avail 
-= *out_row_ctr
; 
 169     if (num_rows 
> out_rows_avail
) 
 170       num_rows 
= out_rows_avail
; 
 171     /* Create output pointer array for upsampler. */ 
 172     work_ptrs
[0] = output_buf
[*out_row_ctr
]; 
 174       work_ptrs
[1] = output_buf
[*out_row_ctr 
+ 1]; 
 176       work_ptrs
[1] = upsample
->spare_row
; 
 177       upsample
->spare_full 
= TRUE
; 
 179     /* Now do the upsampling. */ 
 180     (*upsample
->upmethod
) (cinfo
, input_buf
, *in_row_group_ctr
, work_ptrs
); 
 184   *out_row_ctr 
+= num_rows
; 
 185   upsample
->rows_to_go 
-= num_rows
; 
 186   /* When the buffer is emptied, declare this input row group consumed */ 
 187   if (! upsample
->spare_full
) 
 188     (*in_row_group_ctr
)++; 
 193 merged_1v_upsample (j_decompress_ptr cinfo
, 
 194                     JSAMPIMAGE input_buf
, JDIMENSION 
*in_row_group_ctr
, 
 195                     JDIMENSION in_row_groups_avail
, 
 196                     JSAMPARRAY output_buf
, JDIMENSION 
*out_row_ctr
, 
 197                     JDIMENSION out_rows_avail
) 
 198 /* 1:1 vertical sampling case: much easier, never need a spare row. */ 
 200   my_upsample_ptr upsample 
= (my_upsample_ptr
) cinfo
->upsample
; 
 202   /* Just do the upsampling. */ 
 203   (*upsample
->upmethod
) (cinfo
, input_buf
, *in_row_group_ctr
, 
 204                          output_buf 
+ *out_row_ctr
); 
 207   (*in_row_group_ctr
)++; 
 212  * These are the routines invoked by the control routines to do 
 213  * the actual upsampling/conversion.  One row group is processed per call. 
 215  * Note: since we may be writing directly into application-supplied buffers, 
 216  * we have to be honest about the output width; we can't assume the buffer 
 217  * has been rounded up to an even width. 
 222  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical. 
 226 h2v1_merged_upsample (j_decompress_ptr cinfo
, 
 227                       JSAMPIMAGE input_buf
, JDIMENSION in_row_group_ctr
, 
 228                       JSAMPARRAY output_buf
) 
 230   my_upsample_ptr upsample 
= (my_upsample_ptr
) cinfo
->upsample
; 
 231   register int y
, cred
, cgreen
, cblue
; 
 233   register JSAMPROW outptr
; 
 234   JSAMPROW inptr0
, inptr1
, inptr2
; 
 236   /* copy these pointers into registers if possible */ 
 237   register JSAMPLE 
* range_limit 
= cinfo
->sample_range_limit
; 
 238   int * Crrtab 
= upsample
->Cr_r_tab
; 
 239   int * Cbbtab 
= upsample
->Cb_b_tab
; 
 240   INT32 
* Crgtab 
= upsample
->Cr_g_tab
; 
 241   INT32 
* Cbgtab 
= upsample
->Cb_g_tab
; 
 244   inptr0 
= input_buf
[0][in_row_group_ctr
]; 
 245   inptr1 
= input_buf
[1][in_row_group_ctr
]; 
 246   inptr2 
= input_buf
[2][in_row_group_ctr
]; 
 247   outptr 
= output_buf
[0]; 
 248   /* Loop for each pair of output pixels */ 
 249   for (col 
= cinfo
->output_width 
>> 1; col 
> 0; col
--) { 
 250     /* Do the chroma part of the calculation */ 
 251     cb 
= GETJSAMPLE(*inptr1
++); 
 252     cr 
= GETJSAMPLE(*inptr2
++); 
 254     cgreen 
= (int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
], SCALEBITS
); 
 256     /* Fetch 2 Y values and emit 2 pixels */ 
 257     y  
= GETJSAMPLE(*inptr0
++); 
 258     outptr
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 259     outptr
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 260     outptr
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 261     outptr 
+= RGB_PIXELSIZE
; 
 262     y  
= GETJSAMPLE(*inptr0
++); 
 263     outptr
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 264     outptr
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 265     outptr
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 266     outptr 
+= RGB_PIXELSIZE
; 
 268   /* If image width is odd, do the last output column separately */ 
 269   if (cinfo
->output_width 
& 1) { 
 270     cb 
= GETJSAMPLE(*inptr1
); 
 271     cr 
= GETJSAMPLE(*inptr2
); 
 273     cgreen 
= (int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
], SCALEBITS
); 
 275     y  
= GETJSAMPLE(*inptr0
); 
 276     outptr
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 277     outptr
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 278     outptr
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 283  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical. 
 287 h2v2_merged_upsample (j_decompress_ptr cinfo
, 
 288                       JSAMPIMAGE input_buf
, JDIMENSION in_row_group_ctr
, 
 289                       JSAMPARRAY output_buf
) 
 291   my_upsample_ptr upsample 
= (my_upsample_ptr
) cinfo
->upsample
; 
 292   register int y
, cred
, cgreen
, cblue
; 
 294   register JSAMPROW outptr0
, outptr1
; 
 295   JSAMPROW inptr00
, inptr01
, inptr1
, inptr2
; 
 297   /* copy these pointers into registers if possible */ 
 298   register JSAMPLE 
* range_limit 
= cinfo
->sample_range_limit
; 
 299   int * Crrtab 
= upsample
->Cr_r_tab
; 
 300   int * Cbbtab 
= upsample
->Cb_b_tab
; 
 301   INT32 
* Crgtab 
= upsample
->Cr_g_tab
; 
 302   INT32 
* Cbgtab 
= upsample
->Cb_g_tab
; 
 305   inptr00 
= input_buf
[0][in_row_group_ctr
*2]; 
 306   inptr01 
= input_buf
[0][in_row_group_ctr
*2 + 1]; 
 307   inptr1 
= input_buf
[1][in_row_group_ctr
]; 
 308   inptr2 
= input_buf
[2][in_row_group_ctr
]; 
 309   outptr0 
= output_buf
[0]; 
 310   outptr1 
= output_buf
[1]; 
 311   /* Loop for each group of output pixels */ 
 312   for (col 
= cinfo
->output_width 
>> 1; col 
> 0; col
--) { 
 313     /* Do the chroma part of the calculation */ 
 314     cb 
= GETJSAMPLE(*inptr1
++); 
 315     cr 
= GETJSAMPLE(*inptr2
++); 
 317     cgreen 
= (int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
], SCALEBITS
); 
 319     /* Fetch 4 Y values and emit 4 pixels */ 
 320     y  
= GETJSAMPLE(*inptr00
++); 
 321     outptr0
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 322     outptr0
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 323     outptr0
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 324     outptr0 
+= RGB_PIXELSIZE
; 
 325     y  
= GETJSAMPLE(*inptr00
++); 
 326     outptr0
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 327     outptr0
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 328     outptr0
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 329     outptr0 
+= RGB_PIXELSIZE
; 
 330     y  
= GETJSAMPLE(*inptr01
++); 
 331     outptr1
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 332     outptr1
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 333     outptr1
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 334     outptr1 
+= RGB_PIXELSIZE
; 
 335     y  
= GETJSAMPLE(*inptr01
++); 
 336     outptr1
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 337     outptr1
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 338     outptr1
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 339     outptr1 
+= RGB_PIXELSIZE
; 
 341   /* If image width is odd, do the last output column separately */ 
 342   if (cinfo
->output_width 
& 1) { 
 343     cb 
= GETJSAMPLE(*inptr1
); 
 344     cr 
= GETJSAMPLE(*inptr2
); 
 346     cgreen 
= (int) RIGHT_SHIFT(Cbgtab
[cb
] + Crgtab
[cr
], SCALEBITS
); 
 348     y  
= GETJSAMPLE(*inptr00
); 
 349     outptr0
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 350     outptr0
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 351     outptr0
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 352     y  
= GETJSAMPLE(*inptr01
); 
 353     outptr1
[RGB_RED
] =   range_limit
[y 
+ cred
]; 
 354     outptr1
[RGB_GREEN
] = range_limit
[y 
+ cgreen
]; 
 355     outptr1
[RGB_BLUE
] =  range_limit
[y 
+ cblue
]; 
 361  * Module initialization routine for merged upsampling/color conversion. 
 363  * NB: this is called under the conditions determined by use_merged_upsample() 
 364  * in jdmaster.c.  That routine MUST correspond to the actual capabilities 
 365  * of this module; no safety checks are made here. 
 369 jinit_merged_upsampler (j_decompress_ptr cinfo
) 
 371   my_upsample_ptr upsample
; 
 373   upsample 
= (my_upsample_ptr
) 
 374     (*cinfo
->mem
->alloc_small
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, 
 375                                 SIZEOF(my_upsampler
)); 
 376   cinfo
->upsample 
= (struct jpeg_upsampler 
*) upsample
; 
 377   upsample
->pub
.start_pass 
= start_pass_merged_upsample
; 
 378   upsample
->pub
.need_context_rows 
= FALSE
; 
 380   upsample
->out_row_width 
= cinfo
->output_width 
* cinfo
->out_color_components
; 
 382   if (cinfo
->max_v_samp_factor 
== 2) { 
 383     upsample
->pub
.upsample 
= merged_2v_upsample
; 
 384     upsample
->upmethod 
= h2v2_merged_upsample
; 
 385     /* Allocate a spare row buffer */ 
 386     upsample
->spare_row 
= (JSAMPROW
) 
 387       (*cinfo
->mem
->alloc_large
) ((j_common_ptr
) cinfo
, JPOOL_IMAGE
, 
 388                 (size_t) (upsample
->out_row_width 
* SIZEOF(JSAMPLE
))); 
 390     upsample
->pub
.upsample 
= merged_1v_upsample
; 
 391     upsample
->upmethod 
= h2v1_merged_upsample
; 
 392     /* No spare row needed */ 
 393     upsample
->spare_row 
= NULL
; 
 396   build_ycc_rgb_table(cinfo
); 
 399 #endif /* UPSAMPLE_MERGING_SUPPORTED */