ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

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 
00042 /* Private subobject */
00043 
00044 typedef struct {
00045   struct jpeg_upsampler pub;    /* public fields */
00046 
00047   /* Pointer to routine to do actual upsampling/conversion of one row group */
00048   JMETHOD(void, upmethod, (j_decompress_ptr cinfo,
00049                JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00050                JSAMPARRAY output_buf));
00051 
00052   /* Private state for YCC->RGB conversion */
00053   int * Cr_r_tab;       /* => table for Cr to R conversion */
00054   int * Cb_b_tab;       /* => table for Cb to B conversion */
00055   INT32 * Cr_g_tab;     /* => table for Cr to G conversion */
00056   INT32 * Cb_g_tab;     /* => table for Cb to G conversion */
00057 
00058   /* For 2:1 vertical sampling, we produce two output rows at a time.
00059    * We need a "spare" row buffer to hold the second output row if the
00060    * application provides just a one-row buffer; we also use the spare
00061    * to discard the dummy last row if the image height is odd.
00062    */
00063   JSAMPROW spare_row;
00064   boolean spare_full;       /* T if spare buffer is occupied */
00065 
00066   JDIMENSION out_row_width; /* samples per output row */
00067   JDIMENSION rows_to_go;    /* counts rows remaining in image */
00068 } my_upsampler;
00069 
00070 typedef my_upsampler * my_upsample_ptr;
00071 
00072 #define SCALEBITS   16  /* speediest right-shift on some machines */
00073 #define ONE_HALF    ((INT32) 1 << (SCALEBITS-1))
00074 #define FIX(x)      ((INT32) ((x) * (1L<<SCALEBITS) + 0.5))
00075 
00076 
00077 /*
00078  * Initialize tables for YCC->RGB colorspace conversion.
00079  * This is taken directly from jdcolor.c; see that file for more info.
00080  */
00081 
00082 LOCAL(void)
00083 build_ycc_rgb_table (j_decompress_ptr cinfo)
00084 {
00085   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00086   int i;
00087   INT32 x;
00088   SHIFT_TEMPS
00089 
00090   upsample->Cr_r_tab = (int *)
00091     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00092                 (MAXJSAMPLE+1) * SIZEOF(int));
00093   upsample->Cb_b_tab = (int *)
00094     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00095                 (MAXJSAMPLE+1) * SIZEOF(int));
00096   upsample->Cr_g_tab = (INT32 *)
00097     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00098                 (MAXJSAMPLE+1) * SIZEOF(INT32));
00099   upsample->Cb_g_tab = (INT32 *)
00100     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00101                 (MAXJSAMPLE+1) * SIZEOF(INT32));
00102 
00103   for (i = 0, x = -CENTERJSAMPLE; i <= MAXJSAMPLE; i++, x++) {
00104     /* i is the actual input pixel value, in the range 0..MAXJSAMPLE */
00105     /* The Cb or Cr value we are thinking of is x = i - CENTERJSAMPLE */
00106     /* Cr=>R value is nearest int to 1.40200 * x */
00107     upsample->Cr_r_tab[i] = (int)
00108             RIGHT_SHIFT(FIX(1.40200) * x + ONE_HALF, SCALEBITS);
00109     /* Cb=>B value is nearest int to 1.77200 * x */
00110     upsample->Cb_b_tab[i] = (int)
00111             RIGHT_SHIFT(FIX(1.77200) * x + ONE_HALF, SCALEBITS);
00112     /* Cr=>G value is scaled-up -0.71414 * x */
00113     upsample->Cr_g_tab[i] = (- FIX(0.71414)) * x;
00114     /* Cb=>G value is scaled-up -0.34414 * x */
00115     /* We also add in ONE_HALF so that need not do it in inner loop */
00116     upsample->Cb_g_tab[i] = (- FIX(0.34414)) * x + ONE_HALF;
00117   }
00118 }
00119 
00120 
00121 /*
00122  * Initialize for an upsampling pass.
00123  */
00124 
00125 METHODDEF(void)
00126 start_pass_merged_upsample (j_decompress_ptr cinfo)
00127 {
00128   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00129 
00130   /* Mark the spare buffer empty */
00131   upsample->spare_full = FALSE;
00132   /* Initialize total-height counter for detecting bottom of image */
00133   upsample->rows_to_go = cinfo->output_height;
00134 }
00135 
00136 
00137 /*
00138  * Control routine to do upsampling (and color conversion).
00139  *
00140  * The control routine just handles the row buffering considerations.
00141  */
00142 
00143 METHODDEF(void)
00144 merged_2v_upsample (j_decompress_ptr cinfo,
00145             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00146             JDIMENSION in_row_groups_avail,
00147             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00148             JDIMENSION out_rows_avail)
00149 /* 2:1 vertical sampling case: may need a spare row. */
00150 {
00151   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00152   JSAMPROW work_ptrs[2];
00153   JDIMENSION num_rows;      /* number of rows returned to caller */
00154 
00155   if (upsample->spare_full) {
00156     /* If we have a spare row saved from a previous cycle, just return it. */
00157     jcopy_sample_rows(& upsample->spare_row, 0, output_buf + *out_row_ctr, 0,
00158               1, upsample->out_row_width);
00159     num_rows = 1;
00160     upsample->spare_full = FALSE;
00161   } else {
00162     /* Figure number of rows to return to caller. */
00163     num_rows = 2;
00164     /* Not more than the distance to the end of the image. */
00165     if (num_rows > upsample->rows_to_go)
00166       num_rows = upsample->rows_to_go;
00167     /* And not more than what the client can accept: */
00168     out_rows_avail -= *out_row_ctr;
00169     if (num_rows > out_rows_avail)
00170       num_rows = out_rows_avail;
00171     /* Create output pointer array for upsampler. */
00172     work_ptrs[0] = output_buf[*out_row_ctr];
00173     if (num_rows > 1) {
00174       work_ptrs[1] = output_buf[*out_row_ctr + 1];
00175     } else {
00176       work_ptrs[1] = upsample->spare_row;
00177       upsample->spare_full = TRUE;
00178     }
00179     /* Now do the upsampling. */
00180     (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr, work_ptrs);
00181   }
00182 
00183   /* Adjust counts */
00184   *out_row_ctr += num_rows;
00185   upsample->rows_to_go -= num_rows;
00186   /* When the buffer is emptied, declare this input row group consumed */
00187   if (! upsample->spare_full)
00188     (*in_row_group_ctr)++;
00189 }
00190 
00191 
00192 METHODDEF(void)
00193 merged_1v_upsample (j_decompress_ptr cinfo,
00194             JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00195             JDIMENSION in_row_groups_avail,
00196             JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00197             JDIMENSION out_rows_avail)
00198 /* 1:1 vertical sampling case: much easier, never need a spare row. */
00199 {
00200   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00201 
00202   /* Just do the upsampling. */
00203   (*upsample->upmethod) (cinfo, input_buf, *in_row_group_ctr,
00204              output_buf + *out_row_ctr);
00205   /* Adjust counts */
00206   (*out_row_ctr)++;
00207   (*in_row_group_ctr)++;
00208 }
00209 
00210 
00211 /*
00212  * These are the routines invoked by the control routines to do
00213  * the actual upsampling/conversion.  One row group is processed per call.
00214  *
00215  * Note: since we may be writing directly into application-supplied buffers,
00216  * we have to be honest about the output width; we can't assume the buffer
00217  * has been rounded up to an even width.
00218  */
00219 
00220 
00221 /*
00222  * Upsample and color convert for the case of 2:1 horizontal and 1:1 vertical.
00223  */
00224 
00225 METHODDEF(void)
00226 h2v1_merged_upsample (j_decompress_ptr cinfo,
00227               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00228               JSAMPARRAY output_buf)
00229 {
00230   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00231   register int y, cred, cgreen, cblue;
00232   int cb, cr;
00233   register JSAMPROW outptr;
00234   JSAMPROW inptr0, inptr1, inptr2;
00235   JDIMENSION col;
00236   /* copy these pointers into registers if possible */
00237   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00238   int * Crrtab = upsample->Cr_r_tab;
00239   int * Cbbtab = upsample->Cb_b_tab;
00240   INT32 * Crgtab = upsample->Cr_g_tab;
00241   INT32 * Cbgtab = upsample->Cb_g_tab;
00242   SHIFT_TEMPS
00243 
00244   inptr0 = input_buf[0][in_row_group_ctr];
00245   inptr1 = input_buf[1][in_row_group_ctr];
00246   inptr2 = input_buf[2][in_row_group_ctr];
00247   outptr = output_buf[0];
00248   /* Loop for each pair of output pixels */
00249   for (col = cinfo->output_width >> 1; col > 0; col--) {
00250     /* Do the chroma part of the calculation */
00251     cb = GETJSAMPLE(*inptr1++);
00252     cr = GETJSAMPLE(*inptr2++);
00253     cred = Crrtab[cr];
00254     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00255     cblue = Cbbtab[cb];
00256     /* Fetch 2 Y values and emit 2 pixels */
00257     y  = GETJSAMPLE(*inptr0++);
00258     outptr[RGB_RED] =   range_limit[y + cred];
00259     outptr[RGB_GREEN] = range_limit[y + cgreen];
00260     outptr[RGB_BLUE] =  range_limit[y + cblue];
00261     outptr += RGB_PIXELSIZE;
00262     y  = GETJSAMPLE(*inptr0++);
00263     outptr[RGB_RED] =   range_limit[y + cred];
00264     outptr[RGB_GREEN] = range_limit[y + cgreen];
00265     outptr[RGB_BLUE] =  range_limit[y + cblue];
00266     outptr += RGB_PIXELSIZE;
00267   }
00268   /* If image width is odd, do the last output column separately */
00269   if (cinfo->output_width & 1) {
00270     cb = GETJSAMPLE(*inptr1);
00271     cr = GETJSAMPLE(*inptr2);
00272     cred = Crrtab[cr];
00273     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00274     cblue = Cbbtab[cb];
00275     y  = GETJSAMPLE(*inptr0);
00276     outptr[RGB_RED] =   range_limit[y + cred];
00277     outptr[RGB_GREEN] = range_limit[y + cgreen];
00278     outptr[RGB_BLUE] =  range_limit[y + cblue];
00279   }
00280 }
00281 
00282 
00283 /*
00284  * Upsample and color convert for the case of 2:1 horizontal and 2:1 vertical.
00285  */
00286 
00287 METHODDEF(void)
00288 h2v2_merged_upsample (j_decompress_ptr cinfo,
00289               JSAMPIMAGE input_buf, JDIMENSION in_row_group_ctr,
00290               JSAMPARRAY output_buf)
00291 {
00292   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00293   register int y, cred, cgreen, cblue;
00294   int cb, cr;
00295   register JSAMPROW outptr0, outptr1;
00296   JSAMPROW inptr00, inptr01, inptr1, inptr2;
00297   JDIMENSION col;
00298   /* copy these pointers into registers if possible */
00299   register JSAMPLE * range_limit = cinfo->sample_range_limit;
00300   int * Crrtab = upsample->Cr_r_tab;
00301   int * Cbbtab = upsample->Cb_b_tab;
00302   INT32 * Crgtab = upsample->Cr_g_tab;
00303   INT32 * Cbgtab = upsample->Cb_g_tab;
00304   SHIFT_TEMPS
00305 
00306   inptr00 = input_buf[0][in_row_group_ctr*2];
00307   inptr01 = input_buf[0][in_row_group_ctr*2 + 1];
00308   inptr1 = input_buf[1][in_row_group_ctr];
00309   inptr2 = input_buf[2][in_row_group_ctr];
00310   outptr0 = output_buf[0];
00311   outptr1 = output_buf[1];
00312   /* Loop for each group of output pixels */
00313   for (col = cinfo->output_width >> 1; col > 0; col--) {
00314     /* Do the chroma part of the calculation */
00315     cb = GETJSAMPLE(*inptr1++);
00316     cr = GETJSAMPLE(*inptr2++);
00317     cred = Crrtab[cr];
00318     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00319     cblue = Cbbtab[cb];
00320     /* Fetch 4 Y values and emit 4 pixels */
00321     y  = GETJSAMPLE(*inptr00++);
00322     outptr0[RGB_RED] =   range_limit[y + cred];
00323     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00324     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00325     outptr0 += RGB_PIXELSIZE;
00326     y  = GETJSAMPLE(*inptr00++);
00327     outptr0[RGB_RED] =   range_limit[y + cred];
00328     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00329     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00330     outptr0 += RGB_PIXELSIZE;
00331     y  = GETJSAMPLE(*inptr01++);
00332     outptr1[RGB_RED] =   range_limit[y + cred];
00333     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00334     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00335     outptr1 += RGB_PIXELSIZE;
00336     y  = GETJSAMPLE(*inptr01++);
00337     outptr1[RGB_RED] =   range_limit[y + cred];
00338     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00339     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00340     outptr1 += RGB_PIXELSIZE;
00341   }
00342   /* If image width is odd, do the last output column separately */
00343   if (cinfo->output_width & 1) {
00344     cb = GETJSAMPLE(*inptr1);
00345     cr = GETJSAMPLE(*inptr2);
00346     cred = Crrtab[cr];
00347     cgreen = (int) RIGHT_SHIFT(Cbgtab[cb] + Crgtab[cr], SCALEBITS);
00348     cblue = Cbbtab[cb];
00349     y  = GETJSAMPLE(*inptr00);
00350     outptr0[RGB_RED] =   range_limit[y + cred];
00351     outptr0[RGB_GREEN] = range_limit[y + cgreen];
00352     outptr0[RGB_BLUE] =  range_limit[y + cblue];
00353     y  = GETJSAMPLE(*inptr01);
00354     outptr1[RGB_RED] =   range_limit[y + cred];
00355     outptr1[RGB_GREEN] = range_limit[y + cgreen];
00356     outptr1[RGB_BLUE] =  range_limit[y + cblue];
00357   }
00358 }
00359 
00360 
00361 /*
00362  * Module initialization routine for merged upsampling/color conversion.
00363  *
00364  * NB: this is called under the conditions determined by use_merged_upsample()
00365  * in jdmaster.c.  That routine MUST correspond to the actual capabilities
00366  * of this module; no safety checks are made here.
00367  */
00368 
00369 GLOBAL(void)
00370 jinit_merged_upsampler (j_decompress_ptr cinfo)
00371 {
00372   my_upsample_ptr upsample;
00373 
00374   upsample = (my_upsample_ptr)
00375     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00376                 SIZEOF(my_upsampler));
00377   cinfo->upsample = (struct jpeg_upsampler *) upsample;
00378   upsample->pub.start_pass = start_pass_merged_upsample;
00379   upsample->pub.need_context_rows = FALSE;
00380 
00381   upsample->out_row_width = cinfo->output_width * cinfo->out_color_components;
00382 
00383   if (cinfo->max_v_samp_factor == 2) {
00384     upsample->pub.upsample = merged_2v_upsample;
00385     upsample->upmethod = h2v2_merged_upsample;
00386     /* Allocate a spare row buffer */
00387     upsample->spare_row = (JSAMPROW)
00388       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00389         (size_t) (upsample->out_row_width * SIZEOF(JSAMPLE)));
00390   } else {
00391     upsample->pub.upsample = merged_1v_upsample;
00392     upsample->upmethod = h2v1_merged_upsample;
00393     /* No spare row needed */
00394     upsample->spare_row = NULL;
00395   }
00396 
00397   build_ycc_rgb_table(cinfo);
00398 }
00399 
00400 #endif /* UPSAMPLE_MERGING_SUPPORTED */

Generated on Sat May 26 2012 04:18:12 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.