Doxygen Source Code Documentation
        
Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search   
jdmerge.c
Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 #define JPEG_INTERNALS
00036 #include "jinclude.h"
00037 #include "jpeglib.h"
00038 
00039 #ifdef UPSAMPLE_MERGING_SUPPORTED
00040 
00041 
00042 
00043 
00044 typedef struct {
00045   struct jpeg_upsampler pub;    
00046 
00047   
00048   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
00049                            JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00050                            JSAMPARRAY output_buf));
00051 
00052   
00053   int * Cr_r_tab;               
00054   int * Cb_b_tab;               
00055   INT32 * Cr_g_tab;             
00056   INT32 * Cb_g_tab;             
00057 
00058   
00059 
00060 
00061 
00062 
00063   JSAMPROW spare_row;
00064   boolean spare_full;           
00065 
00066   JDIMENSION out_row_width;     
00067   JDIMENSION rows_to_go;        
00068 } my_upsampler;
00069 
00070 typedef my_upsampler * my_upsample_ptr;
00071 
00072 #define SCALEBITS       16      
00073 #define ONE_HALF        ((INT32) 1 << (SCALEBITS-1))
00074 #define FIX(x)          ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 LOCAL(void)
00083 build_ycc_rgb_table (j_decompress_ptr cinfo)
00084 {
00085   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00086   int i;
00087   INT32 x;
00088   SHIFT_TEMPS
00089 
00090   upsample->Cr_r_tab = (int *)
00091     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00092                                 (MAXJSAMPLE+1) * SIZEOF(int));
00093   upsample->Cb_b_tab = (int *)
00094     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00095                                 (MAXJSAMPLE+1) * SIZEOF(int));
00096   upsample->Cr_g_tab = (INT32 *)
00097     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00098                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
00099   upsample->Cb_g_tab = (INT32 *)
00100     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00101                                 (MAXJSAMPLE+1) * SIZEOF(INT32));
00102 
00103   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
00104     
00105     
00106     
00107     upsample->Cr_r_tab[i] = (int)
00108                     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
00109     
00110     upsample->Cb_b_tab[i] = (int)
00111                     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
00112     
00113     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
00114     
00115     
00116     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
00117   }
00118 }
00119 
00120 
00121 
00122 
00123 
00124 
00125 METHODDEF(void)
00126 start_pass_merged_upsample (j_decompress_ptr cinfo)
00127 {
00128   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00129 
00130   
00131   upsample->spare_full = FALSE;
00132   
00133   upsample->rows_to_go = cinfo->output_height;
00134 }
00135 
00136 
00137 
00138 
00139 
00140 
00141 
00142 
00143 METHODDEF(void)
00144 merged_2v_upsample (j_decompress_ptr cinfo,
00145                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00146                     JDIMENSION in_row_groups_avail,
00147                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00148                     JDIMENSION out_rows_avail)
00149 
00150 {
00151   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00152   JSAMPROW work_ptrs[2];
00153   JDIMENSION num_rows;          
00154 
00155   if (upsample->spare_full) {
00156     
00157     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
00158                       1, upsample->out_row_width);
00159     num_rows = 1;
00160     upsample->spare_full = FALSE;
00161   } else {
00162     
00163     num_rows = 2;
00164     
00165     if (num_rows > upsample->rows_to_go)
00166       num_rows = upsample->rows_to_go;
00167     
00168     out_rows_avail -= *out_row_ctr;
00169     if (num_rows > out_rows_avail)
00170       num_rows = out_rows_avail;
00171     
00172     work_ptrs[0] = output_buf[*out_row_ctr];
00173     if (num_rows > 1) {
00174       work_ptrs[1] = output_buf[*out_row_ctr + 1];
00175     } else {
00176       work_ptrs[1] = upsample->spare_row;
00177       upsample->spare_full = TRUE;
00178     }
00179     
00180     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
00181   }
00182 
00183   
00184   *out_row_ctr += num_rows;
00185   upsample->rows_to_go -= num_rows;
00186   
00187   if (! upsample->spare_full)
00188     (*in_row_group_ctr)++;
00189 }
00190 
00191 
00192 METHODDEF(void)
00193 merged_1v_upsample (j_decompress_ptr cinfo,
00194                     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00195                     JDIMENSION in_row_groups_avail,
00196                     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00197                     JDIMENSION out_rows_avail)
00198 
00199 {
00200   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00201 
00202   
00203   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
00204                          output_buf + *out_row_ctr);
00205   
00206   (*out_row_ctr)++;
00207   (*in_row_group_ctr)++;
00208 }
00209 
00210 
00211 
00212 
00213 
00214 
00215 
00216 
00217 
00218 
00219 
00220 
00221 
00222 
00223 
00224 
00225 METHODDEF(void)
00226 h2v1_merged_upsample (j_decompress_ptr cinfo,
00227                       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00228                       JSAMPARRAY output_buf)
00229 {
00230   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00231   register int y, cred, cgreen, cblue;
00232   int cb, cr;
00233   register JSAMPROW outptr;
00234   JSAMPROW inptr0, inptr1, inptr2;
00235   JDIMENSION col;
00236   
00237   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00238   int * Crrtab = upsample->Cr_r_tab;
00239   int * Cbbtab = upsample->Cb_b_tab;
00240   INT32 * Crgtab = upsample->Cr_g_tab;
00241   INT32 * Cbgtab = upsample->Cb_g_tab;
00242   SHIFT_TEMPS
00243 
00244   inptr0 = input_buf[0][in_row_group_ctr];
00245   inptr1 = input_buf[1][in_row_group_ctr];
00246   inptr2 = input_buf[2][in_row_group_ctr];
00247   outptr = output_buf[0];
00248   
00249   for (col = cinfo->output_width >> 1; col > 0; col--) {
00250     
00251     cb = GETJSAMPLE(*inptr1++);
00252     cr = GETJSAMPLE(*inptr2++);
00253     cred = Crrtab[cr];
00254     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00255     cblue = Cbbtab[cb];
00256     
00257     y  = GETJSAMPLE(*inptr0++);
00258     outptr[RGB_RED] =   range_limit[y + cred];
00259     outptr[RGB_GREEN] = range_limit[y + cgreen];
00260     outptr[RGB_BLUE] =  range_limit[y + cblue];
00261     outptr += RGB_PIXELSIZE;
00262     y  = GETJSAMPLE(*inptr0++);
00263     outptr[RGB_RED] =   range_limit[y + cred];
00264     outptr[RGB_GREEN] = range_limit[y + cgreen];
00265     outptr[RGB_BLUE] =  range_limit[y + cblue];
00266     outptr += RGB_PIXELSIZE;
00267   }
00268   
00269   if (cinfo->output_width & 1) {
00270     cb = GETJSAMPLE(*inptr1);
00271     cr = GETJSAMPLE(*inptr2);
00272     cred = Crrtab[cr];
00273     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00274     cblue = Cbbtab[cb];
00275     y  = GETJSAMPLE(*inptr0);
00276     outptr[RGB_RED] =   range_limit[y + cred];
00277     outptr[RGB_GREEN] = range_limit[y + cgreen];
00278     outptr[RGB_BLUE] =  range_limit[y + cblue];
00279   }
00280 }
00281 
00282 
00283 
00284 
00285 
00286 
00287 METHODDEF(void)
00288 h2v2_merged_upsample (j_decompress_ptr cinfo,
00289                       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00290                       JSAMPARRAY output_buf)
00291 {
00292   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00293   register int y, cred, cgreen, cblue;
00294   int cb, cr;
00295   register JSAMPROW outptr0, outptr1;
00296   JSAMPROW inptr00, inptr01, inptr1, inptr2;
00297   JDIMENSION col;
00298   
00299   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00300   int * Crrtab = upsample->Cr_r_tab;
00301   int * Cbbtab = upsample->Cb_b_tab;
00302   INT32 * Crgtab = upsample->Cr_g_tab;
00303   INT32 * Cbgtab = upsample->Cb_g_tab;
00304   SHIFT_TEMPS
00305 
00306   inptr00 = input_buf[0][in_row_group_ctr*2];
00307   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
00308   inptr1 = input_buf[1][in_row_group_ctr];
00309   inptr2 = input_buf[2][in_row_group_ctr];
00310   outptr0 = output_buf[0];
00311   outptr1 = output_buf[1];
00312   
00313   for (col = cinfo->output_width >> 1; col > 0; col--) {
00314     
00315     cb = GETJSAMPLE(*inptr1++);
00316     cr = GETJSAMPLE(*inptr2++);
00317     cred = Crrtab[cr];
00318     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00319     cblue = Cbbtab[cb];
00320     
00321     y  = GETJSAMPLE(*inptr00++);
00322     outptr0[RGB_RED] =   range_limit[y + cred];
00323     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00324     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00325     outptr0 += RGB_PIXELSIZE;
00326     y  = GETJSAMPLE(*inptr00++);
00327     outptr0[RGB_RED] =   range_limit[y + cred];
00328     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00329     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00330     outptr0 += RGB_PIXELSIZE;
00331     y  = GETJSAMPLE(*inptr01++);
00332     outptr1[RGB_RED] =   range_limit[y + cred];
00333     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00334     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00335     outptr1 += RGB_PIXELSIZE;
00336     y  = GETJSAMPLE(*inptr01++);
00337     outptr1[RGB_RED] =   range_limit[y + cred];
00338     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00339     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00340     outptr1 += RGB_PIXELSIZE;
00341   }
00342   
00343   if (cinfo->output_width & 1) {
00344     cb = GETJSAMPLE(*inptr1);
00345     cr = GETJSAMPLE(*inptr2);
00346     cred = Crrtab[cr];
00347     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00348     cblue = Cbbtab[cb];
00349     y  = GETJSAMPLE(*inptr00);
00350     outptr0[RGB_RED] =   range_limit[y + cred];
00351     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00352     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00353     y  = GETJSAMPLE(*inptr01);
00354     outptr1[RGB_RED] =   range_limit[y + cred];
00355     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00356     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00357   }
00358 }
00359 
00360 
00361 
00362 
00363 
00364 
00365 
00366 
00367 
00368 
00369 GLOBAL(void)
00370 jinit_merged_upsampler (j_decompress_ptr cinfo)
00371 {
00372   my_upsample_ptr upsample;
00373 
00374   upsample = (my_upsample_ptr)
00375     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00376                                 SIZEOF(my_upsampler));
00377   cinfo->upsample = (struct jpeg_upsampler *) upsample;
00378   upsample->pub.start_pass = start_pass_merged_upsample;
00379   upsample->pub.need_context_rows = FALSE;
00380 
00381   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
00382 
00383   if (cinfo->max_v_samp_factor == 2) {
00384     upsample->pub.upsample = merged_2v_upsample;
00385     upsample->upmethod = h2v2_merged_upsample;
00386     
00387     upsample->spare_row = (JSAMPROW)
00388       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00389                 (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
00390   } else {
00391     upsample->pub.upsample = merged_1v_upsample;
00392     upsample->upmethod = h2v1_merged_upsample;
00393     
00394     upsample->spare_row = NULL;
00395   }
00396 
00397   build_ycc_rgb_table(cinfo);
00398 }
00399 
00400 #endif