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