home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / misc / volume44 / jpeg / part19 / jdmerge.c < prev    next >
C/C++ Source or Header  |  1994-09-27  |  14KB  |  390 lines

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