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

jdsample.c
Go to the documentation of this file.
00001 /*
00002  * jdsample.c
00003  *
00004  * Copyright (C) 1991-1996, Thomas G. Lane.
00005  * Modified 2002-2008 by Guido Vollbeding.
00006  * This file is part of the Independent JPEG Group's software.
00007  * For conditions of distribution and use, see the accompanying README file.
00008  *
00009  * This file contains upsampling routines.
00010  *
00011  * Upsampling input data is counted in "row groups".  A row group
00012  * is defined to be (v_samp_factor * DCT_v_scaled_size / min_DCT_v_scaled_size)
00013  * sample rows of each component.  Upsampling will normally produce
00014  * max_v_samp_factor pixel rows from each row group (but this could vary
00015  * if the upsampler is applying a scale factor of its own).
00016  *
00017  * An excellent reference for image resampling is
00018  *   Digital Image Warping, George Wolberg, 1990.
00019  *   Pub. by IEEE Computer Society Press, Los Alamitos, CA. ISBN 0-8186-8944-7.
00020  */
00021 
00022 #define JPEG_INTERNALS
00023 #include "jinclude.h"
00024 #include "jpeglib.h"
00025 
00026 
00027 /* Pointer to routine to upsample a single component */
00028 typedef JMETHOD(void, upsample1_ptr,
00029         (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00030          JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr));
00031 
00032 /* Private subobject */
00033 
00034 typedef struct {
00035   struct jpeg_upsampler pub;    /* public fields */
00036 
00037   /* Color conversion buffer.  When using separate upsampling and color
00038    * conversion steps, this buffer holds one upsampled row group until it
00039    * has been color converted and output.
00040    * Note: we do not allocate any storage for component(s) which are full-size,
00041    * ie do not need rescaling.  The corresponding entry of color_buf[] is
00042    * simply set to point to the input data array, thereby avoiding copying.
00043    */
00044   JSAMPARRAY color_buf[MAX_COMPONENTS];
00045 
00046   /* Per-component upsampling method pointers */
00047   upsample1_ptr methods[MAX_COMPONENTS];
00048 
00049   int next_row_out;     /* counts rows emitted from color_buf */
00050   JDIMENSION rows_to_go;    /* counts rows remaining in image */
00051 
00052   /* Height of an input row group for each component. */
00053   int rowgroup_height[MAX_COMPONENTS];
00054 
00055   /* These arrays save pixel expansion factors so that int_expand need not
00056    * recompute them each time.  They are unused for other upsampling methods.
00057    */
00058   UINT8 h_expand[MAX_COMPONENTS];
00059   UINT8 v_expand[MAX_COMPONENTS];
00060 } my_upsampler;
00061 
00062 typedef my_upsampler * my_upsample_ptr;
00063 
00064 
00065 /*
00066  * Initialize for an upsampling pass.
00067  */
00068 
00069 METHODDEF(void)
00070 start_pass_upsample (j_decompress_ptr cinfo)
00071 {
00072   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00073 
00074   /* Mark the conversion buffer empty */
00075   upsample->next_row_out = cinfo->max_v_samp_factor;
00076   /* Initialize total-height counter for detecting bottom of image */
00077   upsample->rows_to_go = cinfo->output_height;
00078 }
00079 
00080 
00081 /*
00082  * Control routine to do upsampling (and color conversion).
00083  *
00084  * In this version we upsample each component independently.
00085  * We upsample one row group into the conversion buffer, then apply
00086  * color conversion a row at a time.
00087  */
00088 
00089 METHODDEF(void)
00090 sep_upsample (j_decompress_ptr cinfo,
00091           JSAMPIMAGE input_buf, JDIMENSION *in_row_group_ctr,
00092           JDIMENSION in_row_groups_avail,
00093           JSAMPARRAY output_buf, JDIMENSION *out_row_ctr,
00094           JDIMENSION out_rows_avail)
00095 {
00096   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00097   int ci;
00098   jpeg_component_info * compptr;
00099   JDIMENSION num_rows;
00100 
00101   /* Fill the conversion buffer, if it's empty */
00102   if (upsample->next_row_out >= cinfo->max_v_samp_factor) {
00103     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00104      ci++, compptr++) {
00105       /* Invoke per-component upsample method.  Notice we pass a POINTER
00106        * to color_buf[ci], so that fullsize_upsample can change it.
00107        */
00108       (*upsample->methods[ci]) (cinfo, compptr,
00109     input_buf[ci] + (*in_row_group_ctr * upsample->rowgroup_height[ci]),
00110     upsample->color_buf + ci);
00111     }
00112     upsample->next_row_out = 0;
00113   }
00114 
00115   /* Color-convert and emit rows */
00116 
00117   /* How many we have in the buffer: */
00118   num_rows = (JDIMENSION) (cinfo->max_v_samp_factor - upsample->next_row_out);
00119   /* Not more than the distance to the end of the image.  Need this test
00120    * in case the image height is not a multiple of max_v_samp_factor:
00121    */
00122   if (num_rows > upsample->rows_to_go) 
00123     num_rows = upsample->rows_to_go;
00124   /* And not more than what the client can accept: */
00125   out_rows_avail -= *out_row_ctr;
00126   if (num_rows > out_rows_avail)
00127     num_rows = out_rows_avail;
00128 
00129   (*cinfo->cconvert->color_convert) (cinfo, upsample->color_buf,
00130                      (JDIMENSION) upsample->next_row_out,
00131                      output_buf + *out_row_ctr,
00132                      (int) num_rows);
00133 
00134   /* Adjust counts */
00135   *out_row_ctr += num_rows;
00136   upsample->rows_to_go -= num_rows;
00137   upsample->next_row_out += num_rows;
00138   /* When the buffer is emptied, declare this input row group consumed */
00139   if (upsample->next_row_out >= cinfo->max_v_samp_factor)
00140     (*in_row_group_ctr)++;
00141 }
00142 
00143 
00144 /*
00145  * These are the routines invoked by sep_upsample to upsample pixel values
00146  * of a single component.  One row group is processed per call.
00147  */
00148 
00149 
00150 /*
00151  * For full-size components, we just make color_buf[ci] point at the
00152  * input buffer, and thus avoid copying any data.  Note that this is
00153  * safe only because sep_upsample doesn't declare the input row group
00154  * "consumed" until we are done color converting and emitting it.
00155  */
00156 
00157 METHODDEF(void)
00158 fullsize_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00159            JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00160 {
00161   *output_data_ptr = input_data;
00162 }
00163 
00164 
00165 /*
00166  * This is a no-op version used for "uninteresting" components.
00167  * These components will not be referenced by color conversion.
00168  */
00169 
00170 METHODDEF(void)
00171 noop_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00172            JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00173 {
00174   *output_data_ptr = NULL;  /* safety check */
00175 }
00176 
00177 
00178 /*
00179  * This version handles any integral sampling ratios.
00180  * This is not used for typical JPEG files, so it need not be fast.
00181  * Nor, for that matter, is it particularly accurate: the algorithm is
00182  * simple replication of the input pixel onto the corresponding output
00183  * pixels.  The hi-falutin sampling literature refers to this as a
00184  * "box filter".  A box filter tends to introduce visible artifacts,
00185  * so if you are actually going to use 3:1 or 4:1 sampling ratios
00186  * you would be well advised to improve this code.
00187  */
00188 
00189 METHODDEF(void)
00190 int_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00191           JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00192 {
00193   my_upsample_ptr upsample = (my_upsample_ptr) cinfo->upsample;
00194   JSAMPARRAY output_data = *output_data_ptr;
00195   register JSAMPROW inptr, outptr;
00196   register JSAMPLE invalue;
00197   register int h;
00198   JSAMPROW outend;
00199   int h_expand, v_expand;
00200   int inrow, outrow;
00201 
00202   h_expand = upsample->h_expand[compptr->component_index];
00203   v_expand = upsample->v_expand[compptr->component_index];
00204 
00205   inrow = outrow = 0;
00206   while (outrow < cinfo->max_v_samp_factor) {
00207     /* Generate one output row with proper horizontal expansion */
00208     inptr = input_data[inrow];
00209     outptr = output_data[outrow];
00210     outend = outptr + cinfo->output_width;
00211     while (outptr < outend) {
00212       invalue = *inptr++;   /* don't need GETJSAMPLE() here */
00213       for (h = h_expand; h > 0; h--) {
00214     *outptr++ = invalue;
00215       }
00216     }
00217     /* Generate any additional output rows by duplicating the first one */
00218     if (v_expand > 1) {
00219       jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
00220             v_expand-1, cinfo->output_width);
00221     }
00222     inrow++;
00223     outrow += v_expand;
00224   }
00225 }
00226 
00227 
00228 /*
00229  * Fast processing for the common case of 2:1 horizontal and 1:1 vertical.
00230  * It's still a box filter.
00231  */
00232 
00233 METHODDEF(void)
00234 h2v1_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00235            JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00236 {
00237   JSAMPARRAY output_data = *output_data_ptr;
00238   register JSAMPROW inptr, outptr;
00239   register JSAMPLE invalue;
00240   JSAMPROW outend;
00241   int outrow;
00242 
00243   for (outrow = 0; outrow < cinfo->max_v_samp_factor; outrow++) {
00244     inptr = input_data[outrow];
00245     outptr = output_data[outrow];
00246     outend = outptr + cinfo->output_width;
00247     while (outptr < outend) {
00248       invalue = *inptr++;   /* don't need GETJSAMPLE() here */
00249       *outptr++ = invalue;
00250       *outptr++ = invalue;
00251     }
00252   }
00253 }
00254 
00255 
00256 /*
00257  * Fast processing for the common case of 2:1 horizontal and 2:1 vertical.
00258  * It's still a box filter.
00259  */
00260 
00261 METHODDEF(void)
00262 h2v2_upsample (j_decompress_ptr cinfo, jpeg_component_info * compptr,
00263            JSAMPARRAY input_data, JSAMPARRAY * output_data_ptr)
00264 {
00265   JSAMPARRAY output_data = *output_data_ptr;
00266   register JSAMPROW inptr, outptr;
00267   register JSAMPLE invalue;
00268   JSAMPROW outend;
00269   int inrow, outrow;
00270 
00271   inrow = outrow = 0;
00272   while (outrow < cinfo->max_v_samp_factor) {
00273     inptr = input_data[inrow];
00274     outptr = output_data[outrow];
00275     outend = outptr + cinfo->output_width;
00276     while (outptr < outend) {
00277       invalue = *inptr++;   /* don't need GETJSAMPLE() here */
00278       *outptr++ = invalue;
00279       *outptr++ = invalue;
00280     }
00281     jcopy_sample_rows(output_data, outrow, output_data, outrow+1,
00282               1, cinfo->output_width);
00283     inrow++;
00284     outrow += 2;
00285   }
00286 }
00287 
00288 
00289 /*
00290  * Module initialization routine for upsampling.
00291  */
00292 
00293 GLOBAL(void)
00294 jinit_upsampler (j_decompress_ptr cinfo)
00295 {
00296   my_upsample_ptr upsample;
00297   int ci;
00298   jpeg_component_info * compptr;
00299   boolean need_buffer;
00300   int h_in_group, v_in_group, h_out_group, v_out_group;
00301 
00302   upsample = (my_upsample_ptr)
00303     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00304                 SIZEOF(my_upsampler));
00305   cinfo->upsample = (struct jpeg_upsampler *) upsample;
00306   upsample->pub.start_pass = start_pass_upsample;
00307   upsample->pub.upsample = sep_upsample;
00308   upsample->pub.need_context_rows = FALSE; /* until we find out differently */
00309 
00310   if (cinfo->CCIR601_sampling)  /* this isn't supported */
00311     ERREXIT(cinfo, JERR_CCIR601_NOTIMPL);
00312 
00313   /* Verify we can handle the sampling factors, select per-component methods,
00314    * and create storage as needed.
00315    */
00316   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00317        ci++, compptr++) {
00318     /* Compute size of an "input group" after IDCT scaling.  This many samples
00319      * are to be converted to max_h_samp_factor * max_v_samp_factor pixels.
00320      */
00321     h_in_group = (compptr->h_samp_factor * compptr->DCT_h_scaled_size) /
00322          cinfo->min_DCT_h_scaled_size;
00323     v_in_group = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
00324          cinfo->min_DCT_v_scaled_size;
00325     h_out_group = cinfo->max_h_samp_factor;
00326     v_out_group = cinfo->max_v_samp_factor;
00327     upsample->rowgroup_height[ci] = v_in_group; /* save for use later */
00328     need_buffer = TRUE;
00329     if (! compptr->component_needed) {
00330       /* Don't bother to upsample an uninteresting component. */
00331       upsample->methods[ci] = noop_upsample;
00332       need_buffer = FALSE;
00333     } else if (h_in_group == h_out_group && v_in_group == v_out_group) {
00334       /* Fullsize components can be processed without any work. */
00335       upsample->methods[ci] = fullsize_upsample;
00336       need_buffer = FALSE;
00337     } else if (h_in_group * 2 == h_out_group &&
00338            v_in_group == v_out_group) {
00339       /* Special case for 2h1v upsampling */
00340       upsample->methods[ci] = h2v1_upsample;
00341     } else if (h_in_group * 2 == h_out_group &&
00342            v_in_group * 2 == v_out_group) {
00343       /* Special case for 2h2v upsampling */
00344       upsample->methods[ci] = h2v2_upsample;
00345     } else if ((h_out_group % h_in_group) == 0 &&
00346            (v_out_group % v_in_group) == 0) {
00347       /* Generic integral-factors upsampling method */
00348       upsample->methods[ci] = int_upsample;
00349       upsample->h_expand[ci] = (UINT8) (h_out_group / h_in_group);
00350       upsample->v_expand[ci] = (UINT8) (v_out_group / v_in_group);
00351     } else
00352       ERREXIT(cinfo, JERR_FRACT_SAMPLE_NOTIMPL);
00353     if (need_buffer) {
00354       upsample->color_buf[ci] = (*cinfo->mem->alloc_sarray)
00355     ((j_common_ptr) cinfo, JPOOL_IMAGE,
00356      (JDIMENSION) jround_up((long) cinfo->output_width,
00357                 (long) cinfo->max_h_samp_factor),
00358      (JDIMENSION) cinfo->max_v_samp_factor);
00359     }
00360   }
00361 }

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.