jdmerge.c
上传用户:wuyixingx
上传日期:2007-01-08
资源大小:745k
文件大小:14k
源码类别:

图形图象

开发平台:

C/C++

  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. #define JPEG_INTERNALS
  35. #include "jinclude.h"
  36. #include "jpeglib.h"
  37. #ifdef UPSAMPLE_MERGING_SUPPORTED
  38. /* Private subobject */
  39. typedef struct {
  40.   struct jpeg_upsampler pub; /* public fields */
  41.   /* Pointer to routine to do actual upsampling/conversion of one row group */
  42.   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
  43.    JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  44.    JSAMPARRAY output_buf));
  45.   /* Private state for YCC->RGB conversion */
  46.   int * Cr_r_tab; /* => table for Cr to R conversion */
  47.   int * Cb_b_tab; /* => table for Cb to B conversion */
  48.   INT32 * Cr_g_tab; /* => table for Cr to G conversion */
  49.   INT32 * Cb_g_tab; /* => table for Cb to G conversion */
  50.   /* For 2:1 vertical sampling, we produce two output rows at a time.
  51.    * We need a "spare" row buffer to hold the second output row if the
  52.    * application provides just a one-row buffer; we also use the spare
  53.    * to discard the dummy last row if the image height is odd.
  54.    */
  55.   JSAMPROW spare_row;
  56.   boolean spare_full; /* T if spare buffer is occupied */
  57.   JDIMENSION out_row_width; /* samples per output row */
  58.   JDIMENSION rows_to_go; /* counts rows remaining in image */
  59. } my_upsampler;
  60. typedef my_upsampler * my_upsample_ptr;
  61. #define SCALEBITS 16 /* speediest right-shift on some machines */
  62. #define ONE_HALF ((INT32) 1 << (SCALEBITS-1))
  63. #define FIX(x) ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
  64. /*
  65.  * Initialize tables for YCC->RGB colorspace conversion.
  66.  * This is taken directly from jdcolor.c; see that file for more info.
  67.  */
  68. LOCAL(void)
  69. build_ycc_rgb_table (j_decompress_ptr cinfo)
  70. {
  71.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  72.   int i;
  73.   INT32 x;
  74.   SHIFT_TEMPS
  75.   upsample->Cr_r_tab = (int *)
  76.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  77. (MAXJSAMPLE+1) * SIZEOF(int));
  78.   upsample->Cb_b_tab = (int *)
  79.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  80. (MAXJSAMPLE+1) * SIZEOF(int));
  81.   upsample->Cr_g_tab = (INT32 *)
  82.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  83. (MAXJSAMPLE+1) * SIZEOF(INT32));
  84.   upsample->Cb_g_tab = (INT32 *)
  85.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  86. (MAXJSAMPLE+1) * SIZEOF(INT32));
  87.   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
  88.     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
  89.     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
  90.     /* Cr=>R value is nearest int to 1.40200 * x */
  91.     upsample->Cr_r_tab[i] = (int)
  92.     RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
  93.     /* Cb=>B value is nearest int to 1.77200 * x */
  94.     upsample->Cb_b_tab[i] = (int)
  95.     RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
  96.     /* Cr=>G value is scaled-up -0.71414 * x */
  97.     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
  98.     /* Cb=>G value is scaled-up -0.34414 * x */
  99.     /* We also add in ONE_HALF so that need not do it in inner loop */
  100.     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
  101.   }
  102. }
  103. /*
  104.  * Initialize for an upsampling pass.
  105.  */
  106. METHODDEF(void)
  107. start_pass_merged_upsample (j_decompress_ptr cinfo)
  108. {
  109.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  110.   /* Mark the spare buffer empty */
  111.   upsample->spare_full = FALSE;
  112.   /* Initialize total-height counter for detecting bottom of image */
  113.   upsample->rows_to_go = cinfo->output_height;
  114. }
  115. /*
  116.  * Control routine to do upsampling (and color conversion).
  117.  *
  118.  * The control routine just handles the row buffering considerations.
  119.  */
  120. METHODDEF(void)
  121. merged_2v_upsample (j_decompress_ptr cinfo,
  122.     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  123.     JDIMENSION in_row_groups_avail,
  124.     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  125.     JDIMENSION out_rows_avail)
  126. /* 2:1 vertical sampling case: may need a spare row. */
  127. {
  128.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  129.   JSAMPROW work_ptrs[2];
  130.   JDIMENSION num_rows; /* number of rows returned to caller */
  131.   if (upsample->spare_full) {
  132.     /* If we have a spare row saved from a previous cycle, just return it. */
  133.     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
  134.       1, upsample->out_row_width);
  135.     num_rows = 1;
  136.     upsample->spare_full = FALSE;
  137.   } else {
  138.     /* Figure number of rows to return to caller. */
  139.     num_rows = 2;
  140.     /* Not more than the distance to the end of the image. */
  141.     if (num_rows > upsample->rows_to_go)
  142.       num_rows = upsample->rows_to_go;
  143.     /* And not more than what the client can accept: */
  144.     out_rows_avail -= *out_row_ctr;
  145.     if (num_rows > out_rows_avail)
  146.       num_rows = out_rows_avail;
  147.     /* Create output pointer array for upsampler. */
  148.     work_ptrs[0] = output_buf[*out_row_ctr];
  149.     if (num_rows > 1) {
  150.       work_ptrs[1] = output_buf[*out_row_ctr + 1];
  151.     } else {
  152.       work_ptrs[1] = upsample->spare_row;
  153.       upsample->spare_full = TRUE;
  154.     }
  155.     /* Now do the upsampling. */
  156.     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
  157.   }
  158.   /* Adjust counts */
  159.   *out_row_ctr += num_rows;
  160.   upsample->rows_to_go -= num_rows;
  161.   /* When the buffer is emptied, declare this input row group consumed */
  162.   if (! upsample->spare_full)
  163.     (*in_row_group_ctr)++;
  164. }
  165. METHODDEF(void)
  166. merged_1v_upsample (j_decompress_ptr cinfo,
  167.     JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
  168.     JDIMENSION in_row_groups_avail,
  169.     JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
  170.     JDIMENSION out_rows_avail)
  171. /* 1:1 vertical sampling case: much easier, never need a spare row. */
  172. {
  173.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  174.   /* Just do the upsampling. */
  175.   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
  176.  output_buf + *out_row_ctr);
  177.   /* Adjust counts */
  178.   (*out_row_ctr)++;
  179.   (*in_row_group_ctr)++;
  180. }
  181. /*
  182.  * These are the routines invoked by the control routines to do
  183.  * the actual upsampling/conversion.  One row group is processed per call.
  184.  *
  185.  * Note: since we may be writing directly into application-supplied buffers,
  186.  * we have to be honest about the output width; we can't assume the buffer
  187.  * has been rounded up to an even width.
  188.  */
  189. /*
  190.  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
  191.  */
  192. METHODDEF(void)
  193. h2v1_merged_upsample (j_decompress_ptr cinfo,
  194.       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  195.       JSAMPARRAY output_buf)
  196. {
  197.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  198.   register int y, cred, cgreen, cblue;
  199.   int cb, cr;
  200.   register JSAMPROW outptr;
  201.   JSAMPROW inptr0, inptr1, inptr2;
  202.   JDIMENSION col;
  203.   /* copy these pointers into registers if possible */
  204.   register JSAMPLE * range_limit = cinfo->sample_range_limit;
  205.   int * Crrtab = upsample->Cr_r_tab;
  206.   int * Cbbtab = upsample->Cb_b_tab;
  207.   INT32 * Crgtab = upsample->Cr_g_tab;
  208.   INT32 * Cbgtab = upsample->Cb_g_tab;
  209.   SHIFT_TEMPS
  210.   inptr0 = input_buf[0][in_row_group_ctr];
  211.   inptr1 = input_buf[1][in_row_group_ctr];
  212.   inptr2 = input_buf[2][in_row_group_ctr];
  213.   outptr = output_buf[0];
  214.   /* Loop for each pair of output pixels */
  215.   for (col = cinfo->output_width >> 1; col > 0; col--) {
  216.     /* Do the chroma part of the calculation */
  217.     cb = GETJSAMPLE(*inptr1++);
  218.     cr = GETJSAMPLE(*inptr2++);
  219.     cred = Crrtab[cr];
  220.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  221.     cblue = Cbbtab[cb];
  222.     /* Fetch 2 Y values and emit 2 pixels */
  223.     y  = GETJSAMPLE(*inptr0++);
  224.     outptr[RGB_RED] =   range_limit[y + cred];
  225.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  226.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  227.     outptr += RGB_PIXELSIZE;
  228.     y  = GETJSAMPLE(*inptr0++);
  229.     outptr[RGB_RED] =   range_limit[y + cred];
  230.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  231.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  232.     outptr += RGB_PIXELSIZE;
  233.   }
  234.   /* If image width is odd, do the last output column separately */
  235.   if (cinfo->output_width & 1) {
  236.     cb = GETJSAMPLE(*inptr1);
  237.     cr = GETJSAMPLE(*inptr2);
  238.     cred = Crrtab[cr];
  239.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  240.     cblue = Cbbtab[cb];
  241.     y  = GETJSAMPLE(*inptr0);
  242.     outptr[RGB_RED] =   range_limit[y + cred];
  243.     outptr[RGB_GREEN] = range_limit[y + cgreen];
  244.     outptr[RGB_BLUE] =  range_limit[y + cblue];
  245.   }
  246. }
  247. /*
  248.  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
  249.  */
  250. METHODDEF(void)
  251. h2v2_merged_upsample (j_decompress_ptr cinfo,
  252.       JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
  253.       JSAMPARRAY output_buf)
  254. {
  255.   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
  256.   register int y, cred, cgreen, cblue;
  257.   int cb, cr;
  258.   register JSAMPROW outptr0, outptr1;
  259.   JSAMPROW inptr00, inptr01, inptr1, inptr2;
  260.   JDIMENSION col;
  261.   /* copy these pointers into registers if possible */
  262.   register JSAMPLE * range_limit = cinfo->sample_range_limit;
  263.   int * Crrtab = upsample->Cr_r_tab;
  264.   int * Cbbtab = upsample->Cb_b_tab;
  265.   INT32 * Crgtab = upsample->Cr_g_tab;
  266.   INT32 * Cbgtab = upsample->Cb_g_tab;
  267.   SHIFT_TEMPS
  268.   inptr00 = input_buf[0][in_row_group_ctr*2];
  269.   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
  270.   inptr1 = input_buf[1][in_row_group_ctr];
  271.   inptr2 = input_buf[2][in_row_group_ctr];
  272.   outptr0 = output_buf[0];
  273.   outptr1 = output_buf[1];
  274.   /* Loop for each group of output pixels */
  275.   for (col = cinfo->output_width >> 1; col > 0; col--) {
  276.     /* Do the chroma part of the calculation */
  277.     cb = GETJSAMPLE(*inptr1++);
  278.     cr = GETJSAMPLE(*inptr2++);
  279.     cred = Crrtab[cr];
  280.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  281.     cblue = Cbbtab[cb];
  282.     /* Fetch 4 Y values and emit 4 pixels */
  283.     y  = GETJSAMPLE(*inptr00++);
  284.     outptr0[RGB_RED] =   range_limit[y + cred];
  285.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  286.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  287.     outptr0 += RGB_PIXELSIZE;
  288.     y  = GETJSAMPLE(*inptr00++);
  289.     outptr0[RGB_RED] =   range_limit[y + cred];
  290.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  291.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  292.     outptr0 += RGB_PIXELSIZE;
  293.     y  = GETJSAMPLE(*inptr01++);
  294.     outptr1[RGB_RED] =   range_limit[y + cred];
  295.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  296.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  297.     outptr1 += RGB_PIXELSIZE;
  298.     y  = GETJSAMPLE(*inptr01++);
  299.     outptr1[RGB_RED] =   range_limit[y + cred];
  300.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  301.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  302.     outptr1 += RGB_PIXELSIZE;
  303.   }
  304.   /* If image width is odd, do the last output column separately */
  305.   if (cinfo->output_width & 1) {
  306.     cb = GETJSAMPLE(*inptr1);
  307.     cr = GETJSAMPLE(*inptr2);
  308.     cred = Crrtab[cr];
  309.     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
  310.     cblue = Cbbtab[cb];
  311.     y  = GETJSAMPLE(*inptr00);
  312.     outptr0[RGB_RED] =   range_limit[y + cred];
  313.     outptr0[RGB_GREEN] = range_limit[y + cgreen];
  314.     outptr0[RGB_BLUE] =  range_limit[y + cblue];
  315.     y  = GETJSAMPLE(*inptr01);
  316.     outptr1[RGB_RED] =   range_limit[y + cred];
  317.     outptr1[RGB_GREEN] = range_limit[y + cgreen];
  318.     outptr1[RGB_BLUE] =  range_limit[y + cblue];
  319.   }
  320. }
  321. /*
  322.  * Module initialization routine for merged upsampling/color conversion.
  323.  *
  324.  * NB: this is called under the conditions determined by use_merged_upsample()
  325.  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
  326.  * of this module; no safety checks are made here.
  327.  */
  328. GLOBAL(void)
  329. jinit_merged_upsampler (j_decompress_ptr cinfo)
  330. {
  331.   my_upsample_ptr upsample;
  332.   upsample = (my_upsample_ptr)
  333.     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  334. SIZEOF(my_upsampler));
  335.   cinfo->upsample = (struct jpeg_upsampler *) upsample;
  336.   upsample->pub.start_pass = start_pass_merged_upsample;
  337.   upsample->pub.need_context_rows = FALSE;
  338.   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
  339.   if (cinfo->max_v_samp_factor == 2) {
  340.     upsample->pub.upsample = merged_2v_upsample;
  341.     upsample->upmethod = h2v2_merged_upsample;
  342.     /* Allocate a spare row buffer */
  343.     upsample->spare_row = (JSAMPROW)
  344.       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
  345. (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
  346.   } else {
  347.     upsample->pub.upsample = merged_1v_upsample;
  348.     upsample->upmethod = h2v1_merged_upsample;
  349.     /* No spare row needed */
  350.     upsample->spare_row = NULL;
  351.   }
  352.   build_ycc_rgb_table(cinfo);
  353. }
  354. #endif /* UPSAMPLE_MERGING_SUPPORTED */