home *** CD-ROM | disk | FTP | other *** search
/ Tools / WinSN5.0Ver.iso / NETSCAP.50 / WIN1998.ZIP / ns / jpeg / jdmerge.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-04-08  |  31.0 KB  |  1,027 lines

  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. #include "xp_core.h"
  39.  
  40. #ifdef UPSAMPLE_MERGING_SUPPORTED
  41.  
  42. #ifdef XP_WIN32
  43.   __int64 const1 = 0x59BA0000D24B59BA;       // Cr_r Cr_b Cr_g Cr_r
  44.   __int64 const2 = 0x00007168E9FA0000;         // Cb-r Cb_b Cb_g Cb_r
  45.   __int64 const5 = 0x0000D24B59BA0000;         // Cr_b Cr_g Cr_r Cr_b
  46.   __int64 const6 = 0x7168E9FA00007168;         // Cb_b Cb_g Cb_r Cb_b
  47.  
  48.   // constants for factors (One_Half/fix(x)) << 2
  49.  
  50.   __int64 const05 = 0x0001000000000001;    // Cr_r Cr_b Cr_g Cr_r
  51.   __int64 const15 = 0x00000001FFFA0000;    // Cb-r Cb_b Cb_g Cb_r
  52.   __int64 const45 = 0x0000000000010000;    // Cr_b Cr_g Cr_r Cr_b
  53.   __int64 const55 = 0x0001FFFA00000001;    // Cb_b Cb_g Cb_r Cb_b
  54. #endif
  55.  
  56. /* Private subobject */
  57.  
  58. typedef struct {
  59.   struct jpeg_upsampler pub;    /* public fields */
  60.  
  61.   /* Pointer to routine to do actual upsampling/conversion of one row group */
  62.   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
  63.                JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  64.                JSAMPARRAY output_buf));
  65.  
  66.    
  67.                                          
  68.  
  69.   /* Private state for YCC->RGB conversion */
  70.   int * Cr_r_tab;        /* => table for Cr to R conversion */
  71.   int * Cb_b_tab;        /* => table for Cb to B conversion */
  72.   INT32 * Cr_g_tab;        /* => table for Cr to G conversion */
  73.   INT32 * Cb_g_tab;        /* => table for Cb to G conversion */
  74.  
  75.   /* For 2:1 vertical sampling, we produce two output rows at a time.
  76.    * We need a "spare" row buffer to hold the second output row if the
  77.    * application provides just a one-row buffer; we also use the spare
  78.    * to discard the dummy last row if the image height is odd.
  79.    */
  80.   JSAMPROW spare_row;
  81.   boolean spare_full;        /* T if spare buffer is occupied */
  82.  
  83.   JDIMENSION out_row_width;    /* samples per output row */
  84.   JDIMENSION rows_to_go;    /* counts rows remaining in image */
  85. } my_upsampler;
  86.  
  87. typedef my_upsampler * my_upsample_ptr;
  88.  
  89. #define SCALEBITS    16    /* speediest right-shift on some machines */
  90. #define ONE_HALF    ((INT32) 1 << (SCALEBITS-1))
  91. #define FIX(x)        ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  92.  
  93.  
  94. /*
  95.  * Initialize tables for YCC->RGB colorspace conversion.
  96.  * This is taken directly from jdcolor.c; see that file for more info.
  97.  */
  98.  
  99. LOCAL void
  100. build_ycc_rgb_table (j_decompress_ptr cinfo)
  101. {
  102.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  103.   int i;
  104.   INT32 x;
  105.   SHIFT_TEMPS
  106.  
  107.   upsample->Cr_r_tab = (int *)
  108.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  109.                 (MAXJSAMPLE+1) * SIZEOF(int));
  110.   upsample->Cb_b_tab = (int *)
  111.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  112.                 (MAXJSAMPLE+1) * SIZEOF(int));
  113.   upsample->Cr_g_tab = (INT32 *)
  114.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  115.                 (MAXJSAMPLE+1) * SIZEOF(INT32));
  116.   upsample->Cb_g_tab = (INT32 *)
  117.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  118.                 (MAXJSAMPLE+1) * SIZEOF(INT32));
  119.  
  120.   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
  121.     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
  122.     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
  123.     /* Cr=>R value is nearest int to 1.40200 * x */
  124.     upsample->Cr_r_tab[i] = (int)
  125.             RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
  126.     /* Cb=>B value is nearest int to 1.77200 * x */
  127.     upsample->Cb_b_tab[i] = (int)
  128.             RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
  129.     /* Cr=>G value is scaled-up -0.71414 * x */
  130.     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
  131.     /* Cb=>G value is scaled-up -0.34414 * x */
  132.     /* We also add in ONE_HALF so that need not do it in inner loop */
  133.     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
  134.   }
  135. }
  136.  
  137.  
  138. /*
  139.  * Initialize for an upsampling pass.
  140.  */
  141.  
  142. METHODDEF void
  143. start_pass_merged_upsample (j_decompress_ptr cinfo)
  144. {
  145.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  146.  
  147.   /* Mark the spare buffer empty */
  148.   upsample->spare_full = FALSE;
  149.   /* Initialize total-height counter for detecting bottom of image */
  150.   upsample->rows_to_go = cinfo->output_height;
  151. }
  152.  
  153.  
  154. /*
  155.  * Control routine to do upsampling (and color conversion).
  156.  *
  157.  * The control routine just handles the row buffering considerations.
  158.  */
  159.  
  160. METHODDEF void
  161. merged_2v_upsample (j_decompress_ptr cinfo,
  162.             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  163.             JDIMENSION in_row_groups_avail,
  164.             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  165.             JDIMENSION out_rows_avail)
  166. /* 2:1 vertical sampling case: may need a spare row. */
  167. {
  168.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  169.   JSAMPROW work_ptrs[2];
  170.   JDIMENSION num_rows;        /* number of rows returned to caller */
  171.  
  172.   if (upsample->spare_full) {
  173.     /* If we have a spare row saved from a previous cycle, just return it. */
  174.     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
  175.               1, upsample->out_row_width);
  176.     num_rows = 1;
  177.     upsample->spare_full = FALSE;
  178.   } else {
  179.     /* Figure number of rows to return to caller. */
  180.     num_rows = 2;
  181.     /* Not more than the distance to the end of the image. */
  182.     if (num_rows > upsample->rows_to_go)
  183.       num_rows = upsample->rows_to_go;
  184.     /* And not more than what the client can accept: */
  185.     out_rows_avail -= *out_row_ctr;
  186.     if (num_rows > out_rows_avail)
  187.       num_rows = out_rows_avail;
  188.     /* Create output pointer array for upsampler. */
  189.     work_ptrs[0] = output_buf[*out_row_ctr];
  190.     if (num_rows > 1) {
  191.       work_ptrs[1] = output_buf[*out_row_ctr + 1];
  192.     } else {
  193.       work_ptrs[1] = upsample->spare_row;
  194.       upsample->spare_full = TRUE;
  195.     }
  196.     /* Now do the upsampling. */
  197.     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
  198.   }
  199.  
  200.   /* Adjust counts */
  201.   *out_row_ctr += num_rows;
  202.   upsample->rows_to_go -= num_rows;
  203.   /* When the buffer is emptied, declare this input row group consumed */
  204.   if (! upsample->spare_full)
  205.     (*in_row_group_ctr)++;
  206. }
  207.  
  208.  
  209. METHODDEF void
  210. merged_1v_upsample (j_decompress_ptr cinfo,
  211.             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  212.             JDIMENSION in_row_groups_avail,
  213.             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  214.             JDIMENSION out_rows_avail)
  215. /* 1:1 vertical sampling case: much easier, never need a spare row. */
  216. {
  217.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  218.  
  219.   /* Just do the upsampling. */
  220.   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
  221.              output_buf + *out_row_ctr);
  222.   /* Adjust counts */
  223.   (*out_row_ctr)++;
  224.   (*in_row_group_ctr)++;
  225. }
  226.  
  227.  
  228. /*
  229.  * These are the routines invoked by the control routines to do
  230.  * the actual upsampling/conversion.  One row group is processed per call.
  231.  *
  232.  * Note: since we may be writing directly into application-supplied buffers,
  233.  * we have to be honest about the output width; we can't assume the buffer
  234.  * has been rounded up to an even width.
  235.  */
  236.  
  237.  
  238. /*
  239.  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
  240.  */
  241.  
  242. METHODDEF void
  243. h2v1_merged_upsample (j_decompress_ptr cinfo,
  244.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  245.               JSAMPARRAY output_buf)
  246. {
  247.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  248.   register int y, cred, cgreen, cblue;
  249.   int cb, cr;
  250.   register JSAMPROW outptr;
  251.   JSAMPROW inptr0, inptr1, inptr2;
  252.   JDIMENSION col;
  253.   /* copy these pointers into registers if possible */
  254.   register JSAMPLE * range_limit = cinfo->sample_range_limit;
  255.   int * Crrtab = upsample->Cr_r_tab;
  256.   int * Cbbtab = upsample->Cb_b_tab;
  257.   INT32 * Crgtab = upsample->Cr_g_tab;
  258.   INT32 * Cbgtab = upsample->Cb_g_tab;
  259.   SHIFT_TEMPS
  260.  
  261.   inptr0 = input_buf[0][in_row_group_ctr];
  262.   inptr1 = input_buf[1][in_row_group_ctr];
  263.   inptr2 = input_buf[2][in_row_group_ctr];
  264.   outptr = output_buf[0];
  265.   /* Loop for each pair of output pixels */
  266.   for (col = cinfo->output_width >> 1; col > 0; col--) {
  267.     /* Do the chroma part of the calculation */
  268.     cb = GETJSAMPLE(*inptr1++);
  269.     cr = GETJSAMPLE(*inptr2++);
  270.     cred = Crrtab[cr];
  271.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  272.     cblue = Cbbtab[cb];
  273.     /* Fetch 2 Y values and emit 2 pixels */
  274.     y  = GETJSAMPLE(*inptr0++);
  275.     outptr[RGB_RED] =   range_limit[y + cred];
  276.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  277.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  278.     outptr += RGB_PIXELSIZE;
  279.     y  = GETJSAMPLE(*inptr0++);
  280.     outptr[RGB_RED] =   range_limit[y + cred];
  281.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  282.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  283.     outptr += RGB_PIXELSIZE;
  284.   }
  285.   /* If image width is odd, do the last output column separately */
  286.   if (cinfo->output_width & 1) {
  287.     cb = GETJSAMPLE(*inptr1);
  288.     cr = GETJSAMPLE(*inptr2);
  289.     cred = Crrtab[cr];
  290.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  291.     cblue = Cbbtab[cb];
  292.     y  = GETJSAMPLE(*inptr0);
  293.     outptr[RGB_RED] =   range_limit[y + cred];
  294.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  295.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  296.   }
  297. }
  298.  
  299.  
  300.  
  301. /*
  302.  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
  303.  */
  304. #ifdef XP_WIN32
  305. __inline METHODDEF void
  306. h2v2_merged_upsample_orig (j_decompress_ptr cinfo,
  307.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  308.               JSAMPARRAY output_buf);
  309. __inline METHODDEF void
  310. h2v2_merged_upsample_mmx (j_decompress_ptr cinfo,
  311.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  312.               JSAMPARRAY output_buf);
  313. #endif
  314.  
  315. METHODDEF void
  316. h2v2_merged_upsample (j_decompress_ptr cinfo,
  317.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  318.               JSAMPARRAY output_buf);
  319.  
  320. #ifdef XP_WIN32
  321. METHODDEF void
  322. h2v2_merged_upsample (j_decompress_ptr cinfo,
  323.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  324.               JSAMPARRAY output_buf)
  325. {
  326. if (MMXAvailable)
  327.     h2v2_merged_upsample_mmx (cinfo, input_buf, in_row_group_ctr, output_buf);
  328. else
  329.     h2v2_merged_upsample_orig (cinfo, input_buf, in_row_group_ctr, output_buf);
  330.  
  331. }
  332.  
  333. __inline METHODDEF void
  334. h2v2_merged_upsample_orig (j_decompress_ptr cinfo,
  335.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  336.               JSAMPARRAY output_buf)
  337. {
  338.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  339.   register int y, cred, cgreen, cblue;
  340.   int cb, cr;
  341.   register JSAMPROW outptr0, outptr1;
  342.   JSAMPROW inptr00, inptr01, inptr1, inptr2;
  343.   JDIMENSION col;
  344.   /* copy these pointers into registers if possible */
  345.   register JSAMPLE * range_limit = cinfo->sample_range_limit;
  346.   int * Crrtab = upsample->Cr_r_tab;
  347.   int * Cbbtab = upsample->Cb_b_tab;
  348.   INT32 * Crgtab = upsample->Cr_g_tab;
  349.   INT32 * Cbgtab = upsample->Cb_g_tab;
  350.   SHIFT_TEMPS
  351.  
  352.   inptr00 = input_buf[0][in_row_group_ctr*2];
  353.   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  354.   inptr1 = input_buf[1][in_row_group_ctr];
  355.   inptr2 = input_buf[2][in_row_group_ctr];
  356.   outptr0 = output_buf[0];
  357.   outptr1 = output_buf[1];
  358.   /* Loop for each group of output pixels */
  359.   for (col = cinfo->output_width >> 1; col > 0; col--) {
  360.     /* Do the chroma part of the calculation */
  361.     cb = GETJSAMPLE(*inptr1++);
  362.     cr = GETJSAMPLE(*inptr2++);
  363.     cred = Crrtab[cr];
  364.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  365.     cblue = Cbbtab[cb];
  366.     /* Fetch 4 Y values and emit 4 pixels */
  367.     y  = GETJSAMPLE(*inptr00++);
  368.     outptr0[RGB_RED] =   range_limit[y + cred];
  369.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  370.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  371.     outptr0 += RGB_PIXELSIZE;
  372.     y  = GETJSAMPLE(*inptr00++);
  373.     outptr0[RGB_RED] =   range_limit[y + cred];
  374.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  375.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  376.     outptr0 += RGB_PIXELSIZE;
  377.     y  = GETJSAMPLE(*inptr01++);
  378.     outptr1[RGB_RED] =   range_limit[y + cred];
  379.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  380.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  381.     outptr1 += RGB_PIXELSIZE;
  382.     y  = GETJSAMPLE(*inptr01++);
  383.     outptr1[RGB_RED] =   range_limit[y + cred];
  384.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  385.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  386.     outptr1 += RGB_PIXELSIZE;
  387.   }
  388.   /* If image width is odd, do the last output column separately */
  389.   if (cinfo->output_width & 1) {
  390.     cb = GETJSAMPLE(*inptr1);
  391.     cr = GETJSAMPLE(*inptr2);
  392.     cred = Crrtab[cr];
  393.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  394.     cblue = Cbbtab[cb];
  395.     y  = GETJSAMPLE(*inptr00);
  396.     outptr0[RGB_RED] =   range_limit[y + cred];
  397.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  398.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  399.     y  = GETJSAMPLE(*inptr01);
  400.     outptr1[RGB_RED] =   range_limit[y + cred];
  401.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  402.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  403.   }
  404. }
  405.  
  406.  
  407. /*
  408.  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
  409.  */
  410. __inline METHODDEF void
  411. h2v2_merged_upsample_mmx (j_decompress_ptr cinfo,
  412.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  413.               JSAMPARRAY output_buf)
  414. {
  415.     // added for MMX
  416.   __int64 const128 = 0x0080008000800080;
  417.   __int64 empty = 0x0000000000000000;
  418.   __int64 davemask = 0x0000FFFFFFFF0000;
  419.   ////////////////////////////////
  420.  
  421.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  422.   register int y, cred, cgreen, cblue;
  423.   int cb, cr;
  424.   register JSAMPROW outptr0, outptr1;
  425.   JSAMPROW inptr00, inptr01, inptr1, inptr2;
  426.   JDIMENSION col;
  427.   /* copy these pointers into registers if possible */
  428.   register JSAMPLE * range_limit = cinfo->sample_range_limit;
  429.   int * Crrtab = upsample->Cr_r_tab;
  430.   int * Cbbtab = upsample->Cb_b_tab;
  431.   INT32 * Crgtab = upsample->Cr_g_tab;
  432.   INT32 * Cbgtab = upsample->Cb_g_tab;
  433.   SHIFT_TEMPS
  434.   
  435.  
  436.   // Added for MMX      
  437.   register int width = cinfo->image_width;
  438.   int cols = cinfo->output_width;
  439.   int cols_asm = (cols >> 3);
  440.   int diff = cols - (cols_asm<<3);
  441.   int cols_asm_copy = cols_asm;
  442.  ///////////////////////////////////////
  443.  
  444.   inptr00 = input_buf[0][in_row_group_ctr*2];
  445.   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  446.   inptr1 = input_buf[1][in_row_group_ctr];
  447.   inptr2 = input_buf[2][in_row_group_ctr];
  448.   outptr0 = output_buf[0];
  449.   outptr1 = output_buf[1];
  450.   /* Loop for each group of output pixels */
  451.  
  452.        
  453.   _asm
  454.   {
  455.       mov esi, inptr00
  456.  
  457.       mov eax, inptr01
  458.       
  459.       mov ebx, inptr2
  460.  
  461.       mov ecx, inptr1
  462.  
  463.       mov edi, outptr0
  464.  
  465.       mov edx, outptr1
  466.  
  467. do_next16:
  468.       
  469.       movd mm0, [ebx]            ; Cr7 Cr6.....Cr1 Cr0
  470.  
  471.       pxor mm6, mm6
  472.  
  473.       punpcklbw mm0, mm0        ; Cr3 Cr3 Cr2 Cr2 Cr1 Cr1 Cr0 Cr0
  474.  
  475.       movq mm7, const128
  476.  
  477.       punpcklwd mm0, mm0        ; Cr1 Cr1 Cr1 Cr1 Cr0 Cr0 Cr0 Cr0
  478.  
  479.       movq mm4, mm0
  480.  
  481.       punpcklbw mm0, mm6        ; Cr0 Cr0 Cr0 Cr0
  482.  
  483.       psubsw mm0, mm7            ; Cr0 - 128:Cr0-128:Cr0-128:Cr0 -128
  484.       
  485.       movd mm1, [ecx]            ; Cb7 Cb6...... Cb1 Cb0
  486.              
  487.       psllw mm0, 2                ; left shift by 2 bits
  488.  
  489.       punpcklbw mm1, mm1        ; Cb3 Cb3 Cb2 Cb2 Cb1 Cb1 Cb0 Cb0
  490.       
  491.       paddsw mm0, const05        ; add (one_half/fix(x)) << 2
  492.  
  493.       punpcklwd mm1, mm1        ; Cb1 Cb1 Cb1 Cb1 Cb0 Cb0 Cb0 Cb0
  494.  
  495.       movq mm5, mm1
  496.  
  497.       pmulhw mm0, const1        ; multiply by (fix(x) >> 1) 
  498.  
  499.       punpcklbw mm1, mm6        ; Cb0 Cb0 Cb0 Cb0
  500.  
  501.       punpckhbw mm4, mm6        ; Cr1 Cr1 Cr1 Cr1
  502.  
  503.       psubsw mm1, mm7            ; Cb0 - 128:Cb0-128:Cb0-128:Cb0 -128
  504.  
  505.       punpckhbw mm5, mm6        ; Cb1 Cb1 Cb1 Cb1
  506.  
  507.       psllw mm1, 2                ; left shift by 2 bits
  508.  
  509.       paddsw mm1, const15        ; add (one_half/fix(x)) << 2
  510.  
  511.       psubsw mm4, mm7            ; Cr1 - 128:Cr1-128:Cr1-128:Cr1 -128
  512.                         
  513.       psubsw mm5, mm7            ; Cb1 - 128:Cb1-128:Cb1-128:Cb1 -128
  514.  
  515.       pmulhw mm1, const2        ; multiply by (fix(x) >> 1) 
  516.  
  517.       psllw mm4, 2                ; left shift by 2 bits
  518.  
  519.       psllw mm5, 2                ; left shift by 2 bits
  520.  
  521.       paddsw mm4, const45        ; add (one_half/fix(x)) << 2
  522.  
  523.       movd mm7, [esi]            ;  Y13 Y12 Y9 Y8 Y5 Y4 Y1 Y0
  524.  
  525.       pmulhw mm4, const5        ; multiply by (fix(x) >> 1) 
  526.  
  527.       movq mm6, mm7
  528.  
  529.       punpcklbw mm7, mm7        ; Y5 Y5 Y4 Y4 Y1 Y1 Y0 Y0
  530.  
  531.       paddsw mm5, const55        ; add (one_half/fix(x)) << 2
  532.  
  533.       paddsw  mm0, mm1            ; cred0 cbl0 cgr0 cred0
  534.  
  535.       movq mm1, mm7
  536.  
  537.       pmulhw mm5, const6        ; multiply by (fix(x) >> 1) 
  538.  
  539.       movq    mm2, mm0            ; cred0 cbl0 cgr0 cred0
  540.  
  541.       punpcklwd mm7, mm6        ; Y5 Y4 Y1 Y1 Y1 Y0 Y0 Y0
  542.  
  543.       pand mm2, davemask        ; 0 cbl0 cgr0 0
  544.  
  545.       psrlq mm1, 16                ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
  546.  
  547.       psrlq    mm2, 16                ; 0 0 cbl0 cgr0
  548.  
  549.       punpcklbw mm7, empty        ; Y1 Y0 Y0 Y0
  550.  
  551.       paddsw mm4, mm5            ; cbl1 cgr1 cred1 cbl1
  552.  
  553.       movq    mm3, mm4            ; cbl1 cgr1 cred1 cbl1
  554.  
  555.       pand    mm3, davemask        ; 0 cgr1 cred1 0
  556.  
  557.       paddsw mm7, mm0            ; r1 b0 g0 r0
  558.  
  559.       psllq    mm3, 16                ; cgr1 cred1 0 0
  560.  
  561.       movq mm6, mm1                ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
  562.     
  563.       por    mm2, mm3            ; cgr1 cred1 cbl0 cgr0
  564.  
  565.       punpcklbw mm6, empty        ; Y4 Y4 Y1 Y1
  566.  
  567.       movd mm3, [eax]            ; Y15 Y14 Y11 Y10 Y7 Y6 Y3 Y2
  568.       
  569.       paddsw mm6, mm2            ; g4 r4 b1 g1
  570.  
  571.       packuswb mm7, mm6            ; g4 r4 b1 g1 r1 b0 g0 r0
  572.  
  573.       movq mm6, mm3                ; Y15 Y14 Y11 Y10 Y7 Y6 Y3 Y2
  574.  
  575.       punpcklbw mm3, mm3        ; Y7 Y7 Y6 Y6 Y3 Y3 Y2 Y2
  576.  
  577.       movq [edi], mm7            ; move to memory g4 r4 b1 g1 r1 b0 g0 r0
  578.  
  579.       movq mm5, mm3                ; Y7 Y7 Y6 Y6 Y3 Y3 Y2 Y2
  580.  
  581.       punpcklwd mm3, mm6        ; X X X X Y3 Y2 Y2 Y2
  582.  
  583.       punpcklbw mm3, empty        ; Y3 Y2 Y2 Y2
  584.  
  585.       psrlq mm5, 16                ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
  586.  
  587.       paddsw mm3, mm0            ; r3 b2 g2 r2
  588.  
  589.       movq mm6, mm5                ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
  590.  
  591.       movq mm0, mm1                ; 0 0 Y5 Y5 Y4 Y4 Y1 Y1
  592.  
  593.       punpckldq mm6, mm6        ; X X X X Y6 Y6 Y3 Y3
  594.  
  595.       punpcklbw mm6, empty        ; Y6 Y6 Y3 Y3
  596.  
  597.       psrlq mm1, 24                ; 0 0 0 0 0 Y5 Y5 Y4
  598.       
  599.       paddsw mm6, mm2            ; g6 r6 b3 g3
  600.  
  601.       packuswb mm3, mm6            ; g6 r6 b3 g3 r3 b2 g2 r2
  602.  
  603.       movq mm2, mm5                ; 0 0 Y7 Y7 Y6 Y6 Y3 Y3
  604.  
  605.       psrlq mm0, 32                ; 0 0 0 0 0 0 Y5 Y5
  606.  
  607.       movq [edx], mm3            ; move to memory g6 r6 b3 g3 r3 b2 g2 r2
  608.       
  609.       punpcklwd mm1, mm0        ; X X X X Y5 Y5 Y5 Y4
  610.  
  611.       psrlq mm5, 24                ; 0 0 0 0 0 Y7 Y7 Y6 
  612.  
  613.       movd mm0, [ebx]            ; Cr9 Cr8.....Cr3 Cr2
  614.  
  615.       psrlq mm2, 32                   ; 0 0 0 0 0 0 Y7 Y7     
  616.       
  617.       psrlq    mm0, 16        
  618.  
  619.       punpcklbw mm1, empty        ; Y5 Y5 Y5 Y4
  620.  
  621.       punpcklwd mm5, mm2        ; X X X X Y7 Y7 Y7 Y6
  622.  
  623.       paddsw mm1, mm4            ; b5 g5 r5 b4
  624.      
  625.       punpcklbw mm5, empty        ; Y7 Y7 Y7 Y6        
  626.  
  627.       pxor mm6, mm6                ; clear mm6 registr
  628.       
  629.       punpcklbw mm0, mm0        ; X X X X Cr3 Cr3 Cr2 Cr2
  630.   
  631.       paddsw mm5, mm4            ; b7 g7 r7 b6
  632.       
  633.       punpcklwd mm0, mm0        ; Cr3 Cr3 Cr3 Cr3 Cr2 Cr2 Cr2 Cr2
  634.  
  635.       movq mm4, mm0
  636.  
  637.       movd mm3, [ecx]            ; Cb9 Cb8...... Cb3 Cb2
  638.       
  639.       punpcklbw mm0, mm6        ; Cr2 Cr2 Cr2 Cr2
  640.  
  641.       psrlq    mm3, 16
  642.  
  643.       psubsw mm0, const128        ; Cr2 - 128:Cr2-128:Cr2-128:Cr2 -128
  644.  
  645.       punpcklbw mm3, mm3        ; X X X X Cb3 Cb3 Cb2 Cb2
  646.  
  647.       psllw mm0, 2                ; left shift by 2 bits
  648.  
  649.       paddsw mm0, const05        ; add (one_half/fix(x)) << 2
  650.  
  651.       punpcklwd mm3, mm3        ; Cb3 Cb3 Cb3 Cb3 Cb2 Cb2 Cb2 Cb2
  652.  
  653.       movq mm7, mm3
  654.       
  655.       pmulhw mm0, const1        ; multiply by (fix(x) >> 1)             
  656.  
  657.       punpcklbw mm3, mm6        ; Cb2 Cb2 Cb2 Cb2
  658.  
  659.       psubsw mm3, const128        ; Cb0 - 128:Cb0-128:Cb0-128:Cb0 -128
  660.  
  661.       punpckhbw mm4, mm6        ; Cr3 Cr3 Cr3 Cr3
  662.       
  663.       psllw mm3, 2                ; left shift by 2 bits
  664.  
  665.       paddsw mm3, const15        ; add (one_half/fix(x)) << 2
  666.  
  667.       punpckhbw mm7, mm6        ; Cb3 Cb3 Cb3 Cb3
  668.  
  669.       pmulhw mm3, const2        ; multiply by (fix(x) >> 1) 
  670.       
  671.       psubsw mm7, const128        ; Cb3 - 128:Cb3-128:Cb3-128:Cb3 -128
  672.  
  673.       paddsw  mm0, mm3            ; cred2 cbl2 cgr2 cred2
  674.         
  675.       psllw mm7, 2                ; left shift by 2 bits
  676.  
  677.       psubsw mm4, const128        ; Cr3 - 128:Cr3-128:Cr3-128:Cr3 -128
  678.       
  679.       movd mm3, [esi+4]            ;  Y21 Y20 Y17 Y16 Y13 Y12 Y9 Y8
  680.       
  681.       psllw mm4, 2                ; left shift by 2 bits
  682.  
  683.       paddsw mm7, const55        ; add (one_half/fix(x)) << 2
  684.             
  685.       movq mm6, mm3                ;  Y21 Y20 Y17 Y16 Y13 Y12 Y9 Y8
  686.  
  687.       movq    mm2, mm0
  688.             
  689.       pand mm2, davemask
  690.  
  691.       punpcklbw mm3, mm3        ; Y13 Y13 Y12 Y12 Y9 Y9 Y8 Y8
  692.  
  693.       psrlq    mm2, 16
  694.               
  695.       paddsw mm4, const45        ; add (one_half/fix(x)) << 2
  696.  
  697.       punpcklwd mm3, mm6        ; X X X X Y9 Y8 Y8 Y8
  698.       
  699.       pmulhw mm4, const5        ; multiply by (fix(x) >> 1) 
  700.  
  701.       pmulhw mm7, const6        ; multiply by (fix(x) >> 1) 
  702.  
  703.       punpcklbw mm3, empty        ; Y9 Y8 Y8 Y8
  704.       
  705.       paddsw mm4, mm7            ; cbl3 cgr3 cred3 cbl3
  706.  
  707.       paddsw mm3, mm0            ; r9 b8 g8 r8
  708.  
  709.       movq    mm7, mm4
  710.  
  711.       packuswb mm1, mm3            ; r9 b8 g8 r8 b5 g5 r5 b4
  712.  
  713.       movd mm3, [eax+4]            ; Y23 Y22 Y19 Y18 Y15 Y14 Y11 Y10
  714.        
  715.       pand    mm7, davemask
  716.  
  717.       psrlq mm6, 8                ; 0 Y21 Y20 Y17 Y16 Y13 Y12 Y9
  718.  
  719.       psllq    mm7, 16
  720.                            
  721.       movq [edi+8], mm1            ; move to memory r9 b8 g8 r8 b5 g5 r5 b4
  722.  
  723.       por    mm2, mm7
  724.  
  725.       movq mm7, mm3                ; Y23 Y22 Y19 Y18 Y15 Y14 Y11 Y10
  726.  
  727.       punpcklbw mm3, mm3        ; X X X X Y11 Y11 Y10 Y10
  728.  
  729.       pxor mm1, mm1
  730.  
  731.       punpcklwd mm3, mm7        ; X X X X Y11 Y10 Y10 Y10
  732.  
  733.       punpcklbw mm3, mm1        ; Y11 Y10 Y10 Y10
  734.  
  735.       psrlq mm7, 8                ; 0 Y23 Y22 Y19 Y18 Y15 Y14 Y11
  736.       
  737.       paddsw mm3, mm0            ; r11 b10 g10 r10
  738.  
  739.       movq mm0, mm7                ; 0 Y23 Y22 Y19 Y18 Y15 Y14 Y11
  740.  
  741.       packuswb mm5, mm3            ; r11 b10 g10 r10 b7 g7 r7 b6
  742.  
  743.       punpcklbw mm7, mm7        ; X X X X Y14 Y14 Y11 Y11
  744.  
  745.       movq [edx+8], mm5            ; move to memory r11 b10 g10 r10 b7 g7 r7 b6
  746.  
  747.       movq mm3, mm6                ; 0 Y21 Y20 Y17 Y16 Y13 Y12 Y9
  748.  
  749.       punpcklbw mm6, mm6        ; X X X X Y12 Y12 Y9 Y9
  750.  
  751.       punpcklbw mm7, mm1        ; Y14 Y14 Y11 Y11
  752.  
  753.       punpcklbw mm6, mm1        ; Y12 Y12 Y9 Y9
  754.  
  755.       paddsw mm7, mm2            ; g14 r14 b11 g11
  756.  
  757.       paddsw mm6, mm2            ; g12 r12 b9 g9
  758.  
  759.       psrlq mm3, 8                ; 0 0 Y21 Y20 Y17 Y16 Y13 Y12
  760.  
  761.       movq mm1, mm3                ; 0 0 Y21 Y20 Y17 Y16 Y13 Y12
  762.  
  763.       punpcklbw mm3, mm3        ; X X X X Y13 Y13 Y12 Y12
  764.  
  765.       add esi, 8
  766.  
  767.       psrlq mm3, 16                ; X X X X X X Y13 Y13 modified on 09/24
  768.  
  769.       punpcklwd mm1, mm3        ; X X X X Y13 Y13 Y13 Y12
  770.  
  771.       add eax, 8
  772.  
  773.       psrlq mm0, 8                ; 0 0 Y23 Y22 Y19 Y18 Y15 Y14    
  774.  
  775.       punpcklbw mm1, empty        ; Y13 Y13 Y13 Y12
  776.  
  777.       movq mm5, mm0                ; 0 0 Y23 Y22 Y19 Y18 Y15 Y14    
  778.  
  779.       punpcklbw mm0, mm0        ; X X X X Y15 Y15 Y14 Y14
  780.  
  781.       paddsw mm1, mm4            ; b13 g13 r13 b12
  782.  
  783.       psrlq mm0, 16                ; X X X X X X Y15 Y15
  784.  
  785.       add edi, 24
  786.       
  787.       punpcklwd mm5, mm0        ; X X X X Y15 Y15 Y15 Y14
  788.  
  789.       packuswb mm6, mm1            ; b13 g13 r13 b12 g12 r12 b9 g9
  790.  
  791.       add edx, 24
  792.       
  793.       punpcklbw mm5, empty        ; Y15 Y15 Y15 Y14
  794.  
  795.       add ebx, 4
  796.             
  797.       paddsw mm5, mm4            ; b15 g15 r15 b14
  798.  
  799.       movq [edi-8], mm6        ; move to memory b13 g13 r13 b12 g12 r12 b9 g9
  800.  
  801.       packuswb mm7, mm5            ; b15 g15 r15 b14 g14 r14 b11 g11
  802.  
  803.       add ecx, 4
  804.   
  805.       movq [edx-8], mm7        ; move to memory b15 g15 r15 b14 g14 r14 b11 g11
  806.  
  807.       dec cols_asm
  808.       
  809.       jnz do_next16
  810.  
  811.       EMMS
  812.             
  813.       }
  814.  
  815.       
  816.   inptr1 += (cols_asm_copy<<2);
  817.  
  818.   inptr2 += (cols_asm_copy<<2);
  819.  
  820.   inptr00 += (cols_asm_copy<<3);
  821.  
  822.   inptr01 += (cols_asm_copy<<3);
  823.  
  824.   outptr0 += cols_asm_copy*24;
  825.  
  826.   outptr1 += cols_asm_copy*24;
  827.             
  828.   //for (col = cinfo->output_width >> 1; col > 0; col--) {
  829.       /* Do the chroma part of the calculation */
  830.     /*cb = GETJSAMPLE(*inptr1++);
  831.     cr = GETJSAMPLE(*inptr2++);
  832.     cred = Crrtab[cr];
  833.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  834.     cblue = Cbbtab[cb];*/
  835.     /* Fetch 4 Y values and emit 4 pixels */
  836.     /*y  = GETJSAMPLE(*inptr00++);
  837.     outptr0[RGB_RED] =   range_limit[y + cred];
  838.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  839.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  840.     outptr0 += RGB_PIXELSIZE;
  841.     y  = GETJSAMPLE(*inptr00++);
  842.     outptr0[RGB_RED] =   range_limit[y + cred];
  843.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  844.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  845.     outptr0 += RGB_PIXELSIZE;
  846.     y  = GETJSAMPLE(*inptr01++);
  847.     outptr1[RGB_RED] =   range_limit[y + cred];
  848.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  849.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  850.     outptr1 += RGB_PIXELSIZE;
  851.     y  = GETJSAMPLE(*inptr01++);
  852.     outptr1[RGB_RED] =   range_limit[y + cred];
  853.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  854.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  855.     outptr1 += RGB_PIXELSIZE;
  856.   }      */
  857.  
  858.  
  859.   for (col = diff >> 1; col > 0; col--) {
  860.       /* Do the chroma part of the calculation */
  861.     cb = GETJSAMPLE(*inptr1++);
  862.     cr = GETJSAMPLE(*inptr2++);
  863.     cred = Crrtab[cr];
  864.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  865.     cblue = Cbbtab[cb];
  866.     /* Fetch 4 Y values and emit 4 pixels */
  867.     y  = GETJSAMPLE(*inptr00++);
  868.     outptr0[RGB_RED] =   range_limit[y + cred];
  869.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  870.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  871.     outptr0 += RGB_PIXELSIZE;
  872.     y  = GETJSAMPLE(*inptr00++);
  873.     outptr0[RGB_RED] =   range_limit[y + cred];
  874.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  875.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  876.     outptr0 += RGB_PIXELSIZE;
  877.     y  = GETJSAMPLE(*inptr01++);
  878.     outptr1[RGB_RED] =   range_limit[y + cred];
  879.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  880.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  881.     outptr1 += RGB_PIXELSIZE;
  882.     y  = GETJSAMPLE(*inptr01++);
  883.     outptr1[RGB_RED] =   range_limit[y + cred];
  884.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  885.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  886.     outptr1 += RGB_PIXELSIZE;
  887.   }      
  888.  
  889.                       
  890.   /* If image width is odd, do the last output column separately */
  891.   //if (cinfo->output_width & 1) {
  892.   if (diff & 1) {
  893.     cb = GETJSAMPLE(*inptr1);
  894.     cr = GETJSAMPLE(*inptr2);
  895.     cred = Crrtab[cr];
  896.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  897.     cblue = Cbbtab[cb];
  898.     y  = GETJSAMPLE(*inptr00);
  899.     outptr0[RGB_RED] =   range_limit[y + cred];
  900.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  901.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  902.     y  = GETJSAMPLE(*inptr01);
  903.     outptr1[RGB_RED] =   range_limit[y + cred];
  904.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  905.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  906.   }    
  907. }
  908. #else
  909.  
  910.  
  911. METHODDEF void
  912. h2v2_merged_upsample (j_decompress_ptr cinfo,
  913.               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  914.               JSAMPARRAY output_buf)
  915. {
  916.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  917.   register int y, cred, cgreen, cblue;
  918.   int cb, cr;
  919.   register JSAMPROW outptr0, outptr1;
  920.   JSAMPROW inptr00, inptr01, inptr1, inptr2;
  921.   JDIMENSION col;
  922.   /* copy these pointers into registers if possible */
  923.   register JSAMPLE * range_limit = cinfo->sample_range_limit;
  924.   int * Crrtab = upsample->Cr_r_tab;
  925.   int * Cbbtab = upsample->Cb_b_tab;
  926.   INT32 * Crgtab = upsample->Cr_g_tab;
  927.   INT32 * Cbgtab = upsample->Cb_g_tab;
  928.   SHIFT_TEMPS
  929.  
  930.   inptr00 = input_buf[0][in_row_group_ctr*2];
  931.   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  932.   inptr1 = input_buf[1][in_row_group_ctr];
  933.   inptr2 = input_buf[2][in_row_group_ctr];
  934.   outptr0 = output_buf[0];
  935.   outptr1 = output_buf[1];
  936.   /* Loop for each group of output pixels */
  937.   for (col = cinfo->output_width >> 1; col > 0; col--) {
  938.     /* Do the chroma part of the calculation */
  939.     cb = GETJSAMPLE(*inptr1++);
  940.     cr = GETJSAMPLE(*inptr2++);
  941.     cred = Crrtab[cr];
  942.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  943.     cblue = Cbbtab[cb];
  944.     /* Fetch 4 Y values and emit 4 pixels */
  945.     y  = GETJSAMPLE(*inptr00++);
  946.     outptr0[RGB_RED] =   range_limit[y + cred];
  947.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  948.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  949.     outptr0 += RGB_PIXELSIZE;
  950.     y  = GETJSAMPLE(*inptr00++);
  951.     outptr0[RGB_RED] =   range_limit[y + cred];
  952.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  953.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  954.     outptr0 += RGB_PIXELSIZE;
  955.     y  = GETJSAMPLE(*inptr01++);
  956.     outptr1[RGB_RED] =   range_limit[y + cred];
  957.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  958.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  959.     outptr1 += RGB_PIXELSIZE;
  960.     y  = GETJSAMPLE(*inptr01++);
  961.     outptr1[RGB_RED] =   range_limit[y + cred];
  962.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  963.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  964.     outptr1 += RGB_PIXELSIZE;
  965.   }
  966.   /* If image width is odd, do the last output column separately */
  967.   if (cinfo->output_width & 1) {
  968.     cb = GETJSAMPLE(*inptr1);
  969.     cr = GETJSAMPLE(*inptr2);
  970.     cred = Crrtab[cr];
  971.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  972.     cblue = Cbbtab[cb];
  973.     y  = GETJSAMPLE(*inptr00);
  974.     outptr0[RGB_RED] =   range_limit[y + cred];
  975.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  976.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  977.     y  = GETJSAMPLE(*inptr01);
  978.     outptr1[RGB_RED] =   range_limit[y + cred];
  979.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  980.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  981.   }
  982. }
  983. #endif
  984.  
  985.  
  986. /*
  987.  * Module initialization routine for merged upsampling/color conversion.
  988.  *
  989.  * NB: this is called under the conditions determined by use_merged_upsample()
  990.  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
  991.  * of this module; no safety checks are made here.
  992.  */
  993.  
  994. GLOBAL void
  995. jinit_merged_upsampler (j_decompress_ptr cinfo)
  996. {
  997.   my_upsample_ptr upsample;
  998.  
  999.   upsample = (my_upsample_ptr)
  1000.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  1001.                 SIZEOF(my_upsampler));
  1002.   cinfo->upsample = (struct jpeg_upsampler *) upsample;
  1003.   upsample->pub.start_pass = start_pass_merged_upsample;
  1004.   upsample->pub.need_context_rows = FALSE;
  1005.  
  1006.   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
  1007.  
  1008.   if (cinfo->max_v_samp_factor == 2) {
  1009.     upsample->pub.upsample = merged_2v_upsample;
  1010.     upsample->upmethod = h2v2_merged_upsample;
  1011.     /* Allocate a spare row buffer */
  1012.     upsample->spare_row = (JSAMPROW)
  1013.       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  1014.         (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
  1015.   } else {
  1016.     upsample->pub.upsample = merged_1v_upsample;
  1017.     upsample->upmethod = h2v1_merged_upsample;
  1018.     /* No spare row needed */
  1019.     upsample->spare_row = NULL;
  1020.   }
  1021.  
  1022.   build_ycc_rgb_table(cinfo);
  1023. }
  1024.  
  1025. #endif /* UPSAMPLE_MERGING_SUPPORTED */
  1026.  
  1027.