Back to index

lightning-sunbird  0.9+nobinonly
jdmerge.c
Go to the documentation of this file.
00001 /*
00002  * jdmerge.c
00003  *
00004  * Copyright (C) 1994-1996, Thomas G. Lane.
00005  * This file is part of the Independent JPEG Group's software.
00006  * For conditions of distribution and use, see the accompanying README file.
00007  *
00008  * This file contains code for merged upsampling/color conversion.
00009  *
00010  * This file combines functions from jdsample.c and jdcolor.c;
00011  * read those files first to understand what's going on.
00012  *
00013  * When the chroma components are to be upsampled by simple replication
00014  * (ie, box filtering), we can save some work in color conversion by
00015  * calculating all the output pixels corresponding to a pair of chroma
00016  * samples at one time.  In the conversion equations
00017  *     R = Y           + K1 * Cr
00018  *     G = Y + K2 * Cb + K3 * Cr
00019  *     B = Y + K4 * Cb
00020  * only the Y term varies among the group of pixels corresponding to a pair
00021  * of chroma samples, so the rest of the terms can be calculated just once.
00022  * At typical sampling ratios, this eliminates half or three-quarters of the
00023  * multiplications needed for color conversion.
00024  *
00025  * This file currently provides implementations for the following cases:
00026  *     YCbCr => RGB color conversion only.
00027  *     Sampling ratios of 2h1v or 2h2v.
00028  *     No scaling needed at upsample time.
00029  *     Corner-aligned (non-CCIR601) sampling alignment.
00030  * Other special cases could be added, but in most applications these are
00031  * the only common cases.  (For uncommon cases we fall back on the more
00032  * general code in jdsample.c and jdcolor.c.)
00033  */
00034 
00035 #define JPEG_INTERNALS
00036 #include "jinclude.h"
00037 #include "jpeglib.h"
00038 
00039 #ifdef UPSAMPLE_MERGING_SUPPORTED
00040 
00041 #ifdef HAVE_MMX_INTEL_MNEMONICS
00042   __int64 const1 = 0x59BA0000D24B59BA;       // Cr_r Cr_b Cr_g Cr_r
00043   __int64 const2 = 0x00007168E9FA0000;            // Cb-r Cb_b Cb_g Cb_r
00044   __int64 const5 = 0x0000D24B59BA0000;            // Cr_b Cr_g Cr_r Cr_b
00045   __int64 const6 = 0x7168E9FA00007168;            // Cb_b Cb_g Cb_r Cb_b
00046 
00047   // constants for factors (One_Half/fix(x)) << 2
00048 
00049   __int64 const05 = 0x0001000000000001;   // Cr_r Cr_b Cr_g Cr_r
00050   __int64 const15 = 0x00000001FFFA0000;   // Cb-r Cb_b Cb_g Cb_r
00051   __int64 const45 = 0x0000000000010000;   // Cr_b Cr_g Cr_r Cr_b
00052   __int64 const55 = 0x0001FFFA00000001;   // Cb_b Cb_g Cb_r Cb_b
00053 #endif
00054 
00055 /* Private subobject */
00056 
00057 typedef struct {
00058   struct jpeg_upsampler pub;       /* public fields */
00059 
00060   /* Pointer to routine to do actual upsampling/conversion of one row group */
00061   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
00062                         JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00063                         JSAMPARRAY output_buf));
00064 
00065   /* Private state for YCC->RGB conversion */
00066   int * Cr_r_tab;           /* => table for Cr to R conversion */
00067   int * Cb_b_tab;           /* => table for Cb to B conversion */
00068   INT32 * Cr_g_tab;         /* => table for Cr to G conversion */
00069   INT32 * Cb_g_tab;         /* => table for Cb to G conversion */
00070 
00071   /* For 2:1 vertical sampling, we produce two output rows at a time.
00072    * We need a "spare" row buffer to hold the second output row if the
00073    * application provides just a one-row buffer; we also use the spare
00074    * to discard the dummy last row if the image height is odd.
00075    */
00076   JSAMPROW spare_row;
00077   boolean spare_full;              /* T if spare buffer is occupied */
00078 
00079   JDIMENSION out_row_width; /* samples per output row */
00080   JDIMENSION rows_to_go;    /* counts rows remaining in image */
00081 } my_upsampler;
00082 
00083 typedef my_upsampler * my_upsample_ptr;
00084 
00085 #define SCALEBITS    16     /* speediest right-shift on some machines */
00086 #define ONE_HALF     ((INT32) 1 << (SCALEBITS-1))
00087 #define FIX(x)              ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
00088 
00089 
00090 /*
00091  * Initialize tables for YCC->RGB colorspace conversion.
00092  * This is taken directly from jdcolor.c; see that file for more info.
00093  */
00094 
00095 LOCAL(void)
00096 build_ycc_rgb_table (j_decompress_ptr cinfo)
00097 {
00098   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00099   int i;
00100   INT32 x;
00101   SHIFT_TEMPS
00102 
00103   upsample->Cr_r_tab = (int *)
00104     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00105                             (MAXJSAMPLE+1) * SIZEOF(int));
00106   upsample->Cb_b_tab = (int *)
00107     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00108                             (MAXJSAMPLE+1) * SIZEOF(int));
00109   upsample->Cr_g_tab = (INT32 *)
00110     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00111                             (MAXJSAMPLE+1) * SIZEOF(INT32));
00112   upsample->Cb_g_tab = (INT32 *)
00113     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00114                             (MAXJSAMPLE+1) * SIZEOF(INT32));
00115 
00116   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
00117     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
00118     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
00119     /* Cr=>R value is nearest int to 1.40200 * x */
00120     upsample->Cr_r_tab[i] = (int)
00121                   RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
00122     /* Cb=>B value is nearest int to 1.77200 * x */
00123     upsample->Cb_b_tab[i] = (int)
00124                   RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
00125     /* Cr=>G value is scaled-up -0.71414 * x */
00126     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
00127     /* Cb=>G value is scaled-up -0.34414 * x */
00128     /* We also add in ONE_HALF so that need not do it in inner loop */
00129     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
00130   }
00131 }
00132 
00133 
00134 /*
00135  * Initialize for an upsampling pass.
00136  */
00137 
00138 METHODDEF(void)
00139 start_pass_merged_upsample (j_decompress_ptr cinfo)
00140 {
00141   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00142 
00143   /* Mark the spare buffer empty */
00144   upsample->spare_full = FALSE;
00145   /* Initialize total-height counter for detecting bottom of image */
00146   upsample->rows_to_go = cinfo->output_height;
00147 }
00148 
00149 
00150 /*
00151  * Control routine to do upsampling (and color conversion).
00152  *
00153  * The control routine just handles the row buffering considerations.
00154  */
00155 
00156 METHODDEF(void)
00157 merged_2v_upsample (j_decompress_ptr cinfo,
00158                   JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00159                   JDIMENSION in_row_groups_avail,
00160                   JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00161                   JDIMENSION out_rows_avail)
00162 /* 2:1 vertical sampling case: may need a spare row. */
00163 {
00164   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00165   JSAMPROW work_ptrs[2];
00166   JDIMENSION num_rows;             /* number of rows returned to caller */
00167 
00168   if (upsample->spare_full) {
00169     /* If we have a spare row saved from a previous cycle, just return it. */
00170     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
00171                     1, upsample->out_row_width);
00172     num_rows = 1;
00173     upsample->spare_full = FALSE;
00174   } else {
00175     /* Figure number of rows to return to caller. */
00176     num_rows = 2;
00177     /* Not more than the distance to the end of the image. */
00178     if (num_rows > upsample->rows_to_go)
00179       num_rows = upsample->rows_to_go;
00180     /* And not more than what the client can accept: */
00181     out_rows_avail -= *out_row_ctr;
00182     if (num_rows > out_rows_avail)
00183       num_rows = out_rows_avail;
00184     /* Create output pointer array for upsampler. */
00185     work_ptrs[0] = output_buf[*out_row_ctr];
00186     if (num_rows > 1) {
00187       work_ptrs[1] = output_buf[*out_row_ctr + 1];
00188     } else {
00189       work_ptrs[1] = upsample->spare_row;
00190       upsample->spare_full = TRUE;
00191     }
00192     /* Now do the upsampling. */
00193     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
00194   }
00195 
00196   /* Adjust counts */
00197   *out_row_ctr += num_rows;
00198   upsample->rows_to_go -= num_rows;
00199   /* When the buffer is emptied, declare this input row group consumed */
00200   if (! upsample->spare_full)
00201     (*in_row_group_ctr)++;
00202 }
00203 
00204 
00205 METHODDEF(void)
00206 merged_1v_upsample (j_decompress_ptr cinfo,
00207                   JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00208                   JDIMENSION in_row_groups_avail,
00209                   JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00210                   JDIMENSION out_rows_avail)
00211 /* 1:1 vertical sampling case: much easier, never need a spare row. */
00212 {
00213   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00214 
00215   /* Just do the upsampling. */
00216   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
00217                       output_buf + *out_row_ctr);
00218   /* Adjust counts */
00219   (*out_row_ctr)++;
00220   (*in_row_group_ctr)++;
00221 }
00222 
00223 
00224 /*
00225  * These are the routines invoked by the control routines to do
00226  * the actual upsampling/conversion.  One row group is processed per call.
00227  *
00228  * Note: since we may be writing directly into application-supplied buffers,
00229  * we have to be honest about the output width; we can't assume the buffer
00230  * has been rounded up to an even width.
00231  */
00232 
00233 
00234 /*
00235  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
00236  */
00237 
00238 METHODDEF(void)
00239 h2v1_merged_upsample (j_decompress_ptr cinfo,
00240                     JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00241                     JSAMPARRAY output_buf)
00242 {
00243  
00244 
00245  my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00246   register int y, cred, cgreen, cblue;
00247   int cb, cr;
00248   register JSAMPROW outptr;
00249   JSAMPROW inptr0, inptr1, inptr2;
00250   JDIMENSION col;
00251   /* copy these pointers into registers if possible */
00252   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00253   int * Crrtab = upsample->Cr_r_tab;
00254   int * Cbbtab = upsample->Cb_b_tab;
00255   INT32 * Crgtab = upsample->Cr_g_tab;
00256   INT32 * Cbgtab = upsample->Cb_g_tab;
00257   SHIFT_TEMPS
00258 
00259   inptr0 = input_buf[0][in_row_group_ctr];
00260   inptr1 = input_buf[1][in_row_group_ctr];
00261   inptr2 = input_buf[2][in_row_group_ctr];
00262   outptr = output_buf[0];
00263   /* Loop for each pair of output pixels */
00264   for (col = cinfo->output_width >> 1; col > 0; col--) {
00265     /* Do the chroma part of the calculation */
00266     cb = GETJSAMPLE(*inptr1++);
00267     cr = GETJSAMPLE(*inptr2++);
00268     cred = Crrtab[cr];
00269     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00270     cblue = Cbbtab[cb];
00271     /* Fetch 2 Y values and emit 2 pixels */
00272     y  = GETJSAMPLE(*inptr0++);
00273     outptr[RGB_RED] =   range_limit[y + cred];
00274     outptr[RGB_GREEN] = range_limit[y + cgreen];
00275     outptr[RGB_BLUE] =  range_limit[y + cblue];
00276     outptr += RGB_PIXELSIZE;
00277     y  = GETJSAMPLE(*inptr0++);
00278     outptr[RGB_RED] =   range_limit[y + cred];
00279     outptr[RGB_GREEN] = range_limit[y + cgreen];
00280     outptr[RGB_BLUE] =  range_limit[y + cblue];
00281     outptr += RGB_PIXELSIZE;
00282   }
00283   /* If image width is odd, do the last output column separately */
00284   if (cinfo->output_width & 1) {
00285     cb = GETJSAMPLE(*inptr1);
00286     cr = GETJSAMPLE(*inptr2);
00287     cred = Crrtab[cr];
00288     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00289     cblue = Cbbtab[cb];
00290     y  = GETJSAMPLE(*inptr0);
00291     outptr[RGB_RED] =   range_limit[y + cred];
00292     outptr[RGB_GREEN] = range_limit[y + cgreen];
00293     outptr[RGB_BLUE] =  range_limit[y + cblue];
00294   }
00295 }
00296 
00297 
00298 /*
00299  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
00300  */
00301 
00302 #ifdef HAVE_MMX_INTEL_MNEMONICS
00303 __inline METHODDEF(void)
00304 h2v2_merged_upsample_orig (j_decompress_ptr cinfo,
00305                     JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00306                     JSAMPARRAY output_buf);
00307 __inline METHODDEF(void)
00308 h2v2_merged_upsample_mmx (j_decompress_ptr cinfo,
00309                     JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00310                     JSAMPARRAY output_buf);
00311 #endif
00312  
00313 METHODDEF(void)
00314 h2v2_merged_upsample (j_decompress_ptr cinfo,
00315                     JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00316                     JSAMPARRAY output_buf);
00317 
00318 #ifdef HAVE_MMX_INTEL_MNEMONICS
00319 METHODDEF(void)
00320 h2v2_merged_upsample (j_decompress_ptr cinfo,
00321                     JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00322                     JSAMPARRAY output_buf)
00323 {
00324 if (MMXAvailable && (cinfo->image_width >= 8))
00325        h2v2_merged_upsample_mmx (cinfo, input_buf, in_row_group_ctr, output_buf);
00326 else
00327        h2v2_merged_upsample_orig (cinfo, input_buf, in_row_group_ctr, output_buf);
00328 
00329 }
00330 
00331 __inline METHODDEF(void)
00332 h2v2_merged_upsample_orig (j_decompress_ptr cinfo,
00333                     JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00334                     JSAMPARRAY output_buf)
00335 {
00336 
00337   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00338   register int y, cred, cgreen, cblue;
00339   int cb, cr;
00340   register JSAMPROW outptr0, outptr1;
00341   JSAMPROW inptr00, inptr01, inptr1, inptr2;
00342   JDIMENSION col;
00343   /* copy these pointers into registers if possible */
00344   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00345   int * Crrtab = upsample->Cr_r_tab;
00346   int * Cbbtab = upsample->Cb_b_tab;
00347   INT32 * Crgtab = upsample->Cr_g_tab;
00348   INT32 * Cbgtab = upsample->Cb_g_tab;
00349   SHIFT_TEMPS
00350 
00351   inptr00 = input_buf[0][in_row_group_ctr*2];
00352   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
00353   inptr1 = input_buf[1][in_row_group_ctr];
00354   inptr2 = input_buf[2][in_row_group_ctr];
00355   outptr0 = output_buf[0];
00356   outptr1 = output_buf[1];
00357   /* Loop for each group of output pixels */
00358   for (col = cinfo->output_width >> 1; col > 0; col--) {
00359     /* Do the chroma part of the calculation */
00360     cb = GETJSAMPLE(*inptr1++);
00361     cr = GETJSAMPLE(*inptr2++);
00362     cred = Crrtab[cr];
00363     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00364     cblue = Cbbtab[cb];
00365     /* Fetch 4 Y values and emit 4 pixels */
00366     y  = GETJSAMPLE(*inptr00++);
00367     outptr0[RGB_RED] =   range_limit[y + cred];
00368     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00369     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00370     outptr0 += RGB_PIXELSIZE;
00371     y  = GETJSAMPLE(*inptr00++);
00372     outptr0[RGB_RED] =   range_limit[y + cred];
00373     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00374     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00375     outptr0 += RGB_PIXELSIZE;
00376     y  = GETJSAMPLE(*inptr01++);
00377     outptr1[RGB_RED] =   range_limit[y + cred];
00378     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00379     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00380     outptr1 += RGB_PIXELSIZE;
00381     y  = GETJSAMPLE(*inptr01++);
00382     outptr1[RGB_RED] =   range_limit[y + cred];
00383     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00384     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00385     outptr1 += RGB_PIXELSIZE;
00386   }
00387   /* If image width is odd, do the last output column separately */
00388   if (cinfo->output_width & 1) {
00389     cb = GETJSAMPLE(*inptr1);
00390     cr = GETJSAMPLE(*inptr2);
00391     cred = Crrtab[cr];
00392     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00393     cblue = Cbbtab[cb];
00394     y  = GETJSAMPLE(*inptr00);
00395     outptr0[RGB_RED] =   range_limit[y + cred];
00396     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00397     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00398     y  = GETJSAMPLE(*inptr01);
00399     outptr1[RGB_RED] =   range_limit[y + cred];
00400     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00401     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00402   }
00403 }
00404 
00405 /*
00406  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
00407  */
00408 __inline METHODDEF(void)
00409 h2v2_merged_upsample_mmx (j_decompress_ptr cinfo,
00410                     JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00411                     JSAMPARRAY output_buf)
00412 {
00413        // added for MMX
00414   __int64 const128 = 0x0080008000800080;
00415   __int64 empty = 0x0000000000000000;
00416   __int64 davemask = 0x0000FFFFFFFF0000;
00418 
00419   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00420   register int y, cred, cgreen, cblue;
00421   int cb, cr;
00422   register JSAMPROW outptr0, outptr1;
00423   JSAMPROW inptr00, inptr01, inptr1, inptr2;
00424   JDIMENSION col;
00425   /* copy these pointers into registers if possible */
00426   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00427   int * Crrtab = upsample->Cr_r_tab;
00428   int * Cbbtab = upsample->Cb_b_tab;
00429   INT32 * Crgtab = upsample->Cr_g_tab;
00430   INT32 * Cbgtab = upsample->Cb_g_tab;
00431   SHIFT_TEMPS
00432   
00433 
00434   // Added for MMX     
00435   register int width = cinfo->image_width;
00436   int cols = cinfo->output_width;
00437   int cols_asm = (cols >> 3);
00438   int diff = cols - (cols_asm<<3);
00439   int cols_asm_copy = cols_asm;
00440 
00442 
00443   inptr00 = input_buf[0][in_row_group_ctr*2];
00444   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
00445   inptr1 = input_buf[1][in_row_group_ctr];
00446   inptr2 = input_buf[2][in_row_group_ctr];
00447   outptr0 = output_buf[0];
00448   outptr1 = output_buf[1];
00449   /* Loop for each group of output pixels */
00450 
00451           
00452   _asm
00453   {
00454          mov esi, inptr00
00455 
00456          mov eax, inptr01
00457          
00458          mov ebx, inptr2
00459 
00460          mov ecx, inptr1
00461 
00462          mov edi, outptr0
00463 
00464          mov edx, outptr1
00465 
00466 do_next16:
00467          
00468          movd mm0, [ebx]                  ; Cr7 Cr6.....Cr1 Cr0
00469 
00470          pxor mm6, mm6
00471 
00472          punpcklbw mm0, mm0        ; Cr3 Cr3 Cr2 Cr2 Cr1 Cr1 Cr0 Cr0
00473 
00474          movq mm7, const128
00475 
00476          punpcklwd mm0, mm0        ; Cr1 Cr1 Cr1 Cr1 Cr0 Cr0 Cr0 Cr0
00477 
00478          movq mm4, mm0
00479 
00480          punpcklbw mm0, mm6        ; Cr0 Cr0 Cr0 Cr0
00481 
00482          psubsw mm0, mm7                  ; Cr0 - 128:Cr0-128:Cr0-128:Cr0 -128
00483          
00484          movd mm1, [ecx]                  ; Cb7 Cb6...... Cb1 Cb0
00485                  
00486          psllw mm0, 2                            ; left shift by 2 bits
00487 
00488          punpcklbw mm1, mm1        ; Cb3 Cb3 Cb2 Cb2 Cb1 Cb1 Cb0 Cb0
00489          
00490          paddsw mm0, const05              ; add (one_half/fix(x)) << 2
00491 
00492          punpcklwd mm1, mm1        ; Cb1 Cb1 Cb1 Cb1 Cb0 Cb0 Cb0 Cb0
00493 
00494          movq mm5, mm1
00495 
00496          pmulhw mm0, const1        ; multiply by (fix(x) >> 1) 
00497 
00498          punpcklbw mm1, mm6        ; Cb0 Cb0 Cb0 Cb0
00499 
00500          punpckhbw mm4, mm6        ; Cr1 Cr1 Cr1 Cr1
00501 
00502          psubsw mm1, mm7                  ; Cb0 - 128:Cb0-128:Cb0-128:Cb0 -128
00503 
00504          punpckhbw mm5, mm6        ; Cb1 Cb1 Cb1 Cb1
00505 
00506          psllw mm1, 2                            ; left shift by 2 bits
00507  
00508          paddsw mm1, const15              ; add (one_half/fix(x)) << 2
00509 
00510          psubsw mm4, mm7                  ; Cr1 - 128:Cr1-128:Cr1-128:Cr1 -128
00511                                           
00512          psubsw mm5, mm7                  ; Cb1 - 128:Cb1-128:Cb1-128:Cb1 -128
00513 
00514          pmulhw mm1, const2        ; multiply by (fix(x) >> 1) 
00515 
00516          psllw mm4, 2                            ; left shift by 2 bits
00517 
00518          psllw mm5, 2                            ; left shift by 2 bits
00519 
00520          paddsw mm4, const45              ; add (one_half/fix(x)) << 2
00521 
00522          movd mm7, [esi]                  ;  Y13 Y12 Y9 Y8 Y5 Y4 Y1 Y0
00523 
00524          pmulhw mm4, const5        ; multiply by (fix(x) >> 1) 
00525 
00526          movq mm6, mm7
00527 
00528          punpcklbw mm7, mm7        ; Y5 Y5 Y4 Y4 Y1 Y1 Y0 Y0
00529 
00530          paddsw mm5, const55              ; add (one_half/fix(x)) << 2
00531 
00532          paddsw  mm0, mm1                 ; cred0 cbl0 cgr0 cred0
00533 
00534          movq mm1, mm7
00535 
00536          pmulhw mm5, const6        ; multiply by (fix(x) >> 1) 
00537 
00538          movq mm2, mm0                    ; cred0 cbl0 cgr0 cred0
00539 
00540          punpcklwd mm7, mm6        ; Y5 Y4 Y1 Y1 Y1 Y0 Y0 Y0
00541 
00542          pand mm2, davemask        ; 0 cbl0 cgr0 0
00543 
00544          psrlq mm1, 16                           ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
00545 
00546          psrlq       mm2, 16                            ; 0 0 cbl0 cgr0
00547 
00548          punpcklbw mm7, empty             ; Y1 Y0 Y0 Y0
00549 
00550          paddsw mm4, mm5                  ; cbl1 cgr1 cred1 cbl1
00551 
00552          movq mm3, mm4                    ; cbl1 cgr1 cred1 cbl1
00553 
00554          pand mm3, davemask        ; 0 cgr1 cred1 0
00555 
00556          paddsw mm7, mm0                  ; r1 b0 g0 r0
00557 
00558          psllq       mm3, 16                            ; cgr1 cred1 0 0
00559 
00560          movq mm6, mm1                           ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
00561        
00562          por  mm2, mm3                    ; cgr1 cred1 cbl0 cgr0
00563 
00564          punpcklbw mm6, empty             ; Y4 Y4 Y1 Y1
00565 
00566          movd mm3, [eax]                  ; Y15 Y14 Y11 Y10 Y7 Y6 Y3 Y2
00567          
00568          paddsw mm6, mm2                  ; g4 r4 b1 g1
00569 
00570          packuswb mm7, mm6                ; g4 r4 b1 g1 r1 b0 g0 r0
00571 
00572          movq mm6, mm3                           ; Y15 Y14 Y11 Y10 Y7 Y6 Y3 Y2
00573 
00574          punpcklbw mm3, mm3        ; Y7 Y7 Y6 Y6 Y3 Y3 Y2 Y2
00575 
00576          movq [edi], mm7                  ; move to memory g4 r4 b1 g1 r1 b0 g0 r0
00577 
00578          movq mm5, mm3                           ; Y7 Y7 Y6 Y6 Y3 Y3 Y2 Y2
00579 
00580          punpcklwd mm3, mm6        ; X X X X Y3 Y2 Y2 Y2
00581 
00582          punpcklbw mm3, empty             ; Y3 Y2 Y2 Y2
00583 
00584          psrlq mm5, 16                           ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
00585 
00586          paddsw mm3, mm0                  ; r3 b2 g2 r2
00587 
00588          movq mm6, mm5                           ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
00589 
00590          movq mm0, mm1                           ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
00591 
00592          punpckldq mm6, mm6        ; X X X X Y6 Y6 Y3 Y3
00593 
00594          punpcklbw mm6, empty             ; Y6 Y6 Y3 Y3
00595 
00596          psrlq mm1, 24                           ; 0 0 0 0 0 Y5 Y5 Y4
00597          
00598          paddsw mm6, mm2                  ; g6 r6 b3 g3
00599 
00600          packuswb mm3, mm6                ; g6 r6 b3 g3 r3 b2 g2 r2
00601 
00602          movq mm2, mm5                           ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
00603 
00604          psrlq mm0, 32                           ; 0 0 0 0 0 0 Y5 Y5
00605 
00606          movq [edx], mm3                  ; move to memory g6 r6 b3 g3 r3 b2 g2 r2
00607          
00608          punpcklwd mm1, mm0        ; X X X X Y5 Y5 Y5 Y4
00609 
00610          psrlq mm5, 24                           ; 0 0 0 0 0 Y7 Y7 Y6 
00611 
00612          movd mm0, [ebx]                  ; Cr9 Cr8.....Cr3 Cr2
00613 
00614          psrlq mm2, 32                           ; 0 0 0 0 0 0 Y7 Y7   
00615          
00616          psrlq       mm0, 16              
00617 
00618          punpcklbw mm1, empty             ; Y5 Y5 Y5 Y4
00619 
00620          punpcklwd mm5, mm2        ; X X X X Y7 Y7 Y7 Y6
00621 
00622          paddsw mm1, mm4                  ; b5 g5 r5 b4
00623         
00624          punpcklbw mm5, empty             ; Y7 Y7 Y7 Y6     
00625 
00626          pxor mm6, mm6                           ; clear mm6 registr
00627          
00628          punpcklbw mm0, mm0        ; X X X X Cr3 Cr3 Cr2 Cr2
00629   
00630          paddsw mm5, mm4                  ; b7 g7 r7 b6
00631          
00632          punpcklwd mm0, mm0        ; Cr3 Cr3 Cr3 Cr3 Cr2 Cr2 Cr2 Cr2
00633 
00634          movq mm4, mm0
00635 
00636          movd mm3, [ecx]                  ; Cb9 Cb8...... Cb3 Cb2
00637          
00638          punpcklbw mm0, mm6        ; Cr2 Cr2 Cr2 Cr2
00639 
00640          psrlq       mm3, 16
00641 
00642          psubsw mm0, const128             ; Cr2 - 128:Cr2-128:Cr2-128:Cr2 -128
00643 
00644          punpcklbw mm3, mm3        ; X X X X Cb3 Cb3 Cb2 Cb2
00645 
00646          psllw mm0, 2                            ; left shift by 2 bits
00647 
00648          paddsw mm0, const05              ; add (one_half/fix(x)) << 2
00649 
00650          punpcklwd mm3, mm3        ; Cb3 Cb3 Cb3 Cb3 Cb2 Cb2 Cb2 Cb2
00651 
00652          movq mm7, mm3
00653          
00654          pmulhw mm0, const1        ; multiply by (fix(x) >> 1)                 
00655 
00656          punpcklbw mm3, mm6        ; Cb2 Cb2 Cb2 Cb2
00657 
00658          psubsw mm3, const128             ; Cb0 - 128:Cb0-128:Cb0-128:Cb0 -128
00659 
00660          punpckhbw mm4, mm6        ; Cr3 Cr3 Cr3 Cr3
00661          
00662          psllw mm3, 2                            ; left shift by 2 bits
00663 
00664          paddsw mm3, const15              ; add (one_half/fix(x)) << 2
00665 
00666          punpckhbw mm7, mm6        ; Cb3 Cb3 Cb3 Cb3
00667 
00668          pmulhw mm3, const2        ; multiply by (fix(x) >> 1) 
00669          
00670          psubsw mm7, const128             ; Cb3 - 128:Cb3-128:Cb3-128:Cb3 -128
00671 
00672          paddsw  mm0, mm3                 ; cred2 cbl2 cgr2 cred2
00673            
00674          psllw mm7, 2                            ; left shift by 2 bits
00675 
00676          psubsw mm4, const128             ; Cr3 - 128:Cr3-128:Cr3-128:Cr3 -128
00677          
00678          movd mm3, [esi+4]                ;  Y21 Y20 Y17 Y16 Y13 Y12 Y9 Y8
00679          
00680          psllw mm4, 2                            ; left shift by 2 bits
00681 
00682          paddsw mm7, const55              ; add (one_half/fix(x)) << 2
00683                 
00684          movq mm6, mm3                           ;  Y21 Y20 Y17 Y16 Y13 Y12 Y9 Y8
00685 
00686          movq mm2, mm0
00687                 
00688          pand mm2, davemask
00689 
00690          punpcklbw mm3, mm3        ; Y13 Y13 Y12 Y12 Y9 Y9 Y8 Y8
00691 
00692          psrlq       mm2, 16
00693                 
00694          paddsw mm4, const45              ; add (one_half/fix(x)) << 2
00695 
00696          punpcklwd mm3, mm6        ; X X X X Y9 Y8 Y8 Y8
00697          
00698          pmulhw mm4, const5        ; multiply by (fix(x) >> 1) 
00699 
00700          pmulhw mm7, const6        ; multiply by (fix(x) >> 1) 
00701 
00702          punpcklbw mm3, empty             ; Y9 Y8 Y8 Y8
00703          
00704          paddsw mm4, mm7                  ; cbl3 cgr3 cred3 cbl3
00705 
00706          paddsw mm3, mm0                  ; r9 b8 g8 r8
00707 
00708          movq mm7, mm4
00709 
00710          packuswb mm1, mm3                ; r9 b8 g8 r8 b5 g5 r5 b4
00711 
00712          movd mm3, [eax+4]                ; Y23 Y22 Y19 Y18 Y15 Y14 Y11 Y10
00713          
00714          pand mm7, davemask
00715 
00716          psrlq mm6, 8                            ; 0 Y21 Y20 Y17 Y16 Y13 Y12 Y9
00717 
00718          psllq       mm7, 16
00719                                              
00720          movq [edi+8], mm1                ; move to memory r9 b8 g8 r8 b5 g5 r5 b4
00721 
00722          por  mm2, mm7
00723 
00724          movq mm7, mm3                           ; Y23 Y22 Y19 Y18 Y15 Y14 Y11 Y10
00725 
00726          punpcklbw mm3, mm3        ; X X X X Y11 Y11 Y10 Y10
00727 
00728          pxor mm1, mm1
00729 
00730          punpcklwd mm3, mm7        ; X X X X Y11 Y10 Y10 Y10
00731 
00732          punpcklbw mm3, mm1        ; Y11 Y10 Y10 Y10
00733 
00734          psrlq mm7, 8                            ; 0 Y23 Y22 Y19 Y18 Y15 Y14 Y11
00735          
00736          paddsw mm3, mm0                  ; r11 b10 g10 r10
00737 
00738          movq mm0, mm7                           ; 0 Y23 Y22 Y19 Y18 Y15 Y14 Y11
00739 
00740          packuswb mm5, mm3                ; r11 b10 g10 r10 b7 g7 r7 b6
00741 
00742          punpcklbw mm7, mm7        ; X X X X Y14 Y14 Y11 Y11
00743 
00744          movq [edx+8], mm5                ; move to memory r11 b10 g10 r10 b7 g7 r7 b6
00745 
00746          movq mm3, mm6                           ; 0 Y21 Y20 Y17 Y16 Y13 Y12 Y9
00747 
00748          punpcklbw mm6, mm6        ; X X X X Y12 Y12 Y9 Y9
00749 
00750          punpcklbw mm7, mm1        ; Y14 Y14 Y11 Y11
00751 
00752          punpcklbw mm6, mm1        ; Y12 Y12 Y9 Y9
00753 
00754          paddsw mm7, mm2                  ; g14 r14 b11 g11
00755 
00756          paddsw mm6, mm2                  ; g12 r12 b9 g9
00757 
00758          psrlq mm3, 8                            ; 0 0 Y21 Y20 Y17 Y16 Y13 Y12
00759 
00760          movq mm1, mm3                           ; 0 0 Y21 Y20 Y17 Y16 Y13 Y12
00761 
00762          punpcklbw mm3, mm3        ; X X X X Y13 Y13 Y12 Y12
00763 
00764          add esi, 8
00765 
00766          psrlq mm3, 16                           ; X X X X X X Y13 Y13 modified on 09/24
00767 
00768          punpcklwd mm1, mm3        ; X X X X Y13 Y13 Y13 Y12
00769 
00770          add eax, 8
00771 
00772          psrlq mm0, 8                            ; 0 0 Y23 Y22 Y19 Y18 Y15 Y14      
00773 
00774          punpcklbw mm1, empty             ; Y13 Y13 Y13 Y12
00775 
00776          movq mm5, mm0                           ; 0 0 Y23 Y22 Y19 Y18 Y15 Y14      
00777 
00778          punpcklbw mm0, mm0        ; X X X X Y15 Y15 Y14 Y14
00779 
00780          paddsw mm1, mm4                  ; b13 g13 r13 b12
00781 
00782          psrlq mm0, 16                           ; X X X X X X Y15 Y15
00783 
00784          add edi, 24
00785          
00786          punpcklwd mm5, mm0        ; X X X X Y15 Y15 Y15 Y14
00787 
00788          packuswb mm6, mm1                ; b13 g13 r13 b12 g12 r12 b9 g9
00789 
00790          add edx, 24
00791          
00792          punpcklbw mm5, empty             ; Y15 Y15 Y15 Y14
00793 
00794          add ebx, 4
00795                 
00796          paddsw mm5, mm4                  ; b15 g15 r15 b14
00797 
00798          movq [edi-8], mm6         ; move to memory b13 g13 r13 b12 g12 r12 b9 g9
00799 
00800          packuswb mm7, mm5                ; b15 g15 r15 b14 g14 r14 b11 g11
00801 
00802          add ecx, 4
00803   
00804          movq [edx-8], mm7         ; move to memory b15 g15 r15 b14 g14 r14 b11 g11
00805 
00806          dec cols_asm
00807          
00808          jnz do_next16
00809 
00810          EMMS
00811                 
00812          }
00813 
00814          
00815   inptr1 += (cols_asm_copy<<2);
00816 
00817   inptr2 += (cols_asm_copy<<2);
00818 
00819   inptr00 += (cols_asm_copy<<3);
00820 
00821   inptr01 += (cols_asm_copy<<3);
00822 
00823   outptr0 += cols_asm_copy*24;
00824 
00825   outptr1 += cols_asm_copy*24;
00826                 
00827   //for (col = cinfo->output_width >> 1; col > 0; col--) {
00828       /* Do the chroma part of the calculation */
00829     /*cb = GETJSAMPLE(*inptr1++);
00830     cr = GETJSAMPLE(*inptr2++);
00831     cred = Crrtab[cr];
00832     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00833     cblue = Cbbtab[cb];*/
00834     /* Fetch 4 Y values and emit 4 pixels */
00835     /*y  = GETJSAMPLE(*inptr00++);
00836     outptr0[RGB_RED] =   range_limit[y + cred];
00837     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00838     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00839     outptr0 += RGB_PIXELSIZE;
00840     y  = GETJSAMPLE(*inptr00++);
00841     outptr0[RGB_RED] =   range_limit[y + cred];
00842     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00843     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00844     outptr0 += RGB_PIXELSIZE;
00845     y  = GETJSAMPLE(*inptr01++);
00846     outptr1[RGB_RED] =   range_limit[y + cred];
00847     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00848     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00849     outptr1 += RGB_PIXELSIZE;
00850     y  = GETJSAMPLE(*inptr01++);
00851     outptr1[RGB_RED] =   range_limit[y + cred];
00852     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00853     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00854     outptr1 += RGB_PIXELSIZE;
00855   }      */
00856 
00857 
00858   for (col = diff >> 1; col > 0; col--) {
00859       /* Do the chroma part of the calculation */
00860     cb = GETJSAMPLE(*inptr1++);
00861     cr = GETJSAMPLE(*inptr2++);
00862     cred = Crrtab[cr];
00863     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00864     cblue = Cbbtab[cb];
00865     /* Fetch 4 Y values and emit 4 pixels */
00866     y  = GETJSAMPLE(*inptr00++);
00867     outptr0[RGB_RED] =   range_limit[y + cred];
00868     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00869     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00870     outptr0 += RGB_PIXELSIZE;
00871     y  = GETJSAMPLE(*inptr00++);
00872     outptr0[RGB_RED] =   range_limit[y + cred];
00873     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00874     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00875     outptr0 += RGB_PIXELSIZE;
00876     y  = GETJSAMPLE(*inptr01++);
00877     outptr1[RGB_RED] =   range_limit[y + cred];
00878     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00879     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00880     outptr1 += RGB_PIXELSIZE;
00881     y  = GETJSAMPLE(*inptr01++);
00882     outptr1[RGB_RED] =   range_limit[y + cred];
00883     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00884     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00885     outptr1 += RGB_PIXELSIZE;
00886   }      
00887 
00888                                      
00889   /* If image width is odd, do the last output column separately */
00890   //if (cinfo->output_width & 1) {
00891   if (diff & 1) {
00892     cb = GETJSAMPLE(*inptr1);
00893     cr = GETJSAMPLE(*inptr2);
00894     cred = Crrtab[cr];
00895     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00896     cblue = Cbbtab[cb];
00897     y  = GETJSAMPLE(*inptr00);
00898     outptr0[RGB_RED] =   range_limit[y + cred];
00899     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00900     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00901     y  = GETJSAMPLE(*inptr01);
00902     outptr1[RGB_RED] =   range_limit[y + cred];
00903     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00904     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00905   }    
00906 }
00907 #else
00908 
00909 
00910 METHODDEF(void)
00911 h2v2_merged_upsample (j_decompress_ptr cinfo,
00912                     JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00913                     JSAMPARRAY output_buf)
00914 {
00915   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00916   register int y, cred, cgreen, cblue;
00917   int cb, cr;
00918   register JSAMPROW outptr0, outptr1;
00919   JSAMPROW inptr00, inptr01, inptr1, inptr2;
00920   JDIMENSION col;
00921   /* copy these pointers into registers if possible */
00922   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00923   int * Crrtab = upsample->Cr_r_tab;
00924   int * Cbbtab = upsample->Cb_b_tab;
00925   INT32 * Crgtab = upsample->Cr_g_tab;
00926   INT32 * Cbgtab = upsample->Cb_g_tab;
00927   SHIFT_TEMPS
00928 
00929   inptr00 = input_buf[0][in_row_group_ctr*2];
00930   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
00931   inptr1 = input_buf[1][in_row_group_ctr];
00932   inptr2 = input_buf[2][in_row_group_ctr];
00933   outptr0 = output_buf[0];
00934   outptr1 = output_buf[1];
00935   /* Loop for each group of output pixels */
00936   for (col = cinfo->output_width >> 1; col > 0; col--) {
00937     /* Do the chroma part of the calculation */
00938     cb = GETJSAMPLE(*inptr1++);
00939     cr = GETJSAMPLE(*inptr2++);
00940     cred = Crrtab[cr];
00941     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00942     cblue = Cbbtab[cb];
00943     /* Fetch 4 Y values and emit 4 pixels */
00944     y  = GETJSAMPLE(*inptr00++);
00945     outptr0[RGB_RED] =   range_limit[y + cred];
00946     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00947     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00948     outptr0 += RGB_PIXELSIZE;
00949     y  = GETJSAMPLE(*inptr00++);
00950     outptr0[RGB_RED] =   range_limit[y + cred];
00951     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00952     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00953     outptr0 += RGB_PIXELSIZE;
00954     y  = GETJSAMPLE(*inptr01++);
00955     outptr1[RGB_RED] =   range_limit[y + cred];
00956     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00957     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00958     outptr1 += RGB_PIXELSIZE;
00959     y  = GETJSAMPLE(*inptr01++);
00960     outptr1[RGB_RED] =   range_limit[y + cred];
00961     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00962     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00963     outptr1 += RGB_PIXELSIZE;
00964   }
00965   /* If image width is odd, do the last output column separately */
00966   if (cinfo->output_width & 1) {
00967     cb = GETJSAMPLE(*inptr1);
00968     cr = GETJSAMPLE(*inptr2);
00969     cred = Crrtab[cr];
00970     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00971     cblue = Cbbtab[cb];
00972     y  = GETJSAMPLE(*inptr00);
00973     outptr0[RGB_RED] =   range_limit[y + cred];
00974     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00975     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00976     y  = GETJSAMPLE(*inptr01);
00977     outptr1[RGB_RED] =   range_limit[y + cred];
00978     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00979     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00980   }
00981 }
00982 #endif
00983 
00984 
00985 /*
00986  * Module initialization routine for merged upsampling/color conversion.
00987  *
00988  * NB: this is called under the conditions determined by use_merged_upsample()
00989  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
00990  * of this module; no safety checks are made here.
00991  */
00992 
00993 GLOBAL(void)
00994 jinit_merged_upsampler (j_decompress_ptr cinfo)
00995 {
00996   my_upsample_ptr upsample;
00997 
00998   upsample = (my_upsample_ptr)
00999     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
01000                             SIZEOF(my_upsampler));
01001   cinfo->upsample = (struct jpeg_upsampler *) upsample;
01002   upsample->pub.start_pass = start_pass_merged_upsample;
01003   upsample->pub.need_context_rows = FALSE;
01004 
01005   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
01006 
01007   if (cinfo->max_v_samp_factor == 2) {
01008     upsample->pub.upsample = merged_2v_upsample;
01009     upsample->upmethod = h2v2_merged_upsample;
01010     /* Allocate a spare row buffer */
01011     upsample->spare_row = (JSAMPROW)
01012       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
01013               (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
01014   } else {
01015     upsample->pub.upsample = merged_1v_upsample;
01016     upsample->upmethod = h2v1_merged_upsample;
01017     /* No spare row needed */
01018     upsample->spare_row = NULL;
01019   }
01020 
01021   build_ycc_rgb_table(cinfo);
01022 }
01023 
01024 #endif /* UPSAMPLE_MERGING_SUPPORTED */