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

jcprepct.c
Go to the documentation of this file.
00001 /*
00002  * jcprepct.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 the compression preprocessing controller.
00009  * This controller manages the color conversion, downsampling,
00010  * and edge expansion steps.
00011  *
00012  * Most of the complexity here is associated with buffering input rows
00013  * as required by the downsampler.  See the comments at the head of
00014  * jcsample.c for the downsampler's needs.
00015  */
00016 
00017 #define JPEG_INTERNALS
00018 #include "jinclude.h"
00019 #include "jpeglib.h"
00020 
00021 
00022 /* At present, jcsample.c can request context rows only for smoothing.
00023  * In the future, we might also need context rows for CCIR601 sampling
00024  * or other more-complex downsampling procedures.  The code to support
00025  * context rows should be compiled only if needed.
00026  */
00027 #ifdef INPUT_SMOOTHING_SUPPORTED
00028 #define CONTEXT_ROWS_SUPPORTED
00029 #endif
00030 
00031 
00032 /*
00033  * For the simple (no-context-row) case, we just need to buffer one
00034  * row group's worth of pixels for the downsampling step.  At the bottom of
00035  * the image, we pad to a full row group by replicating the last pixel row.
00036  * The downsampler's last output row is then replicated if needed to pad
00037  * out to a full iMCU row.
00038  *
00039  * When providing context rows, we must buffer three row groups' worth of
00040  * pixels.  Three row groups are physically allocated, but the row pointer
00041  * arrays are made five row groups high, with the extra pointers above and
00042  * below "wrapping around" to point to the last and first real row groups.
00043  * This allows the downsampler to access the proper context rows.
00044  * At the top and bottom of the image, we create dummy context rows by
00045  * copying the first or last real pixel row.  This copying could be avoided
00046  * by pointer hacking as is done in jdmainct.c, but it doesn't seem worth the
00047  * trouble on the compression side.
00048  */
00049 
00050 
00051 /* Private buffer controller object */
00052 
00053 typedef struct {
00054   struct jpeg_c_prep_controller pub; /* public fields */
00055 
00056   /* Downsampling input buffer.  This buffer holds color-converted data
00057    * until we have enough to do a downsample step.
00058    */
00059   JSAMPARRAY color_buf[MAX_COMPONENTS];
00060 
00061   JDIMENSION rows_to_go;    /* counts rows remaining in source image */
00062   int next_buf_row;     /* index of next row to store in color_buf */
00063 
00064 #ifdef CONTEXT_ROWS_SUPPORTED   /* only needed for context case */
00065   int this_row_group;       /* starting row index of group to process */
00066   int next_buf_stop;        /* downsample when we reach this index */
00067 #endif
00068 } my_prep_controller;
00069 
00070 typedef my_prep_controller * my_prep_ptr;
00071 
00072 
00073 /*
00074  * Initialize for a processing pass.
00075  */
00076 
00077 METHODDEF(void)
00078 start_pass_prep (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
00079 {
00080   my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
00081 
00082   if (pass_mode != JBUF_PASS_THRU)
00083     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00084 
00085   /* Initialize total-height counter for detecting bottom of image */
00086   prep->rows_to_go = cinfo->image_height;
00087   /* Mark the conversion buffer empty */
00088   prep->next_buf_row = 0;
00089 #ifdef CONTEXT_ROWS_SUPPORTED
00090   /* Preset additional state variables for context mode.
00091    * These aren't used in non-context mode, so we needn't test which mode.
00092    */
00093   prep->this_row_group = 0;
00094   /* Set next_buf_stop to stop after two row groups have been read in. */
00095   prep->next_buf_stop = 2 * cinfo->max_v_samp_factor;
00096 #endif
00097 }
00098 
00099 
00100 /*
00101  * Expand an image vertically from height input_rows to height output_rows,
00102  * by duplicating the bottom row.
00103  */
00104 
00105 LOCAL(void)
00106 expand_bottom_edge (JSAMPARRAY image_data, JDIMENSION num_cols,
00107             int input_rows, int output_rows)
00108 {
00109   register int row;
00110 
00111   for (row = input_rows; row < output_rows; row++) {
00112     jcopy_sample_rows(image_data, input_rows-1, image_data, row,
00113               1, num_cols);
00114   }
00115 }
00116 
00117 
00118 /*
00119  * Process some data in the simple no-context case.
00120  *
00121  * Preprocessor output data is counted in "row groups".  A row group
00122  * is defined to be v_samp_factor sample rows of each component.
00123  * Downsampling will produce this much data from each max_v_samp_factor
00124  * input rows.
00125  */
00126 
00127 METHODDEF(void)
00128 pre_process_data (j_compress_ptr cinfo,
00129           JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
00130           JDIMENSION in_rows_avail,
00131           JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
00132           JDIMENSION out_row_groups_avail)
00133 {
00134   my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
00135   int numrows, ci;
00136   JDIMENSION inrows;
00137   jpeg_component_info * compptr;
00138 
00139   while (*in_row_ctr < in_rows_avail &&
00140      *out_row_group_ctr < out_row_groups_avail) {
00141     /* Do color conversion to fill the conversion buffer. */
00142     inrows = in_rows_avail - *in_row_ctr;
00143     numrows = cinfo->max_v_samp_factor - prep->next_buf_row;
00144     numrows = (int) MIN((JDIMENSION) numrows, inrows);
00145     (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
00146                        prep->color_buf,
00147                        (JDIMENSION) prep->next_buf_row,
00148                        numrows);
00149     *in_row_ctr += numrows;
00150     prep->next_buf_row += numrows;
00151     prep->rows_to_go -= numrows;
00152     /* If at bottom of image, pad to fill the conversion buffer. */
00153     if (prep->rows_to_go == 0 &&
00154     prep->next_buf_row < cinfo->max_v_samp_factor) {
00155       for (ci = 0; ci < cinfo->num_components; ci++) {
00156     expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
00157                prep->next_buf_row, cinfo->max_v_samp_factor);
00158       }
00159       prep->next_buf_row = cinfo->max_v_samp_factor;
00160     }
00161     /* If we've filled the conversion buffer, empty it. */
00162     if (prep->next_buf_row == cinfo->max_v_samp_factor) {
00163       (*cinfo->downsample->downsample) (cinfo,
00164                     prep->color_buf, (JDIMENSION) 0,
00165                     output_buf, *out_row_group_ctr);
00166       prep->next_buf_row = 0;
00167       (*out_row_group_ctr)++;
00168     }
00169     /* If at bottom of image, pad the output to a full iMCU height.
00170      * Note we assume the caller is providing a one-iMCU-height output buffer!
00171      */
00172     if (prep->rows_to_go == 0 &&
00173     *out_row_group_ctr < out_row_groups_avail) {
00174       for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00175        ci++, compptr++) {
00176     numrows = (compptr->v_samp_factor * compptr->DCT_v_scaled_size) /
00177           cinfo->min_DCT_v_scaled_size;
00178     expand_bottom_edge(output_buf[ci],
00179                compptr->width_in_blocks * compptr->DCT_h_scaled_size,
00180                (int) (*out_row_group_ctr * numrows),
00181                (int) (out_row_groups_avail * numrows));
00182       }
00183       *out_row_group_ctr = out_row_groups_avail;
00184       break;            /* can exit outer loop without test */
00185     }
00186   }
00187 }
00188 
00189 
00190 #ifdef CONTEXT_ROWS_SUPPORTED
00191 
00192 /*
00193  * Process some data in the context case.
00194  */
00195 
00196 METHODDEF(void)
00197 pre_process_context (j_compress_ptr cinfo,
00198              JSAMPARRAY input_buf, JDIMENSION *in_row_ctr,
00199              JDIMENSION in_rows_avail,
00200              JSAMPIMAGE output_buf, JDIMENSION *out_row_group_ctr,
00201              JDIMENSION out_row_groups_avail)
00202 {
00203   my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
00204   int numrows, ci;
00205   int buf_height = cinfo->max_v_samp_factor * 3;
00206   JDIMENSION inrows;
00207 
00208   while (*out_row_group_ctr < out_row_groups_avail) {
00209     if (*in_row_ctr < in_rows_avail) {
00210       /* Do color conversion to fill the conversion buffer. */
00211       inrows = in_rows_avail - *in_row_ctr;
00212       numrows = prep->next_buf_stop - prep->next_buf_row;
00213       numrows = (int) MIN((JDIMENSION) numrows, inrows);
00214       (*cinfo->cconvert->color_convert) (cinfo, input_buf + *in_row_ctr,
00215                      prep->color_buf,
00216                      (JDIMENSION) prep->next_buf_row,
00217                      numrows);
00218       /* Pad at top of image, if first time through */
00219       if (prep->rows_to_go == cinfo->image_height) {
00220     for (ci = 0; ci < cinfo->num_components; ci++) {
00221       int row;
00222       for (row = 1; row <= cinfo->max_v_samp_factor; row++) {
00223         jcopy_sample_rows(prep->color_buf[ci], 0,
00224                   prep->color_buf[ci], -row,
00225                   1, cinfo->image_width);
00226       }
00227     }
00228       }
00229       *in_row_ctr += numrows;
00230       prep->next_buf_row += numrows;
00231       prep->rows_to_go -= numrows;
00232     } else {
00233       /* Return for more data, unless we are at the bottom of the image. */
00234       if (prep->rows_to_go != 0)
00235     break;
00236       /* When at bottom of image, pad to fill the conversion buffer. */
00237       if (prep->next_buf_row < prep->next_buf_stop) {
00238     for (ci = 0; ci < cinfo->num_components; ci++) {
00239       expand_bottom_edge(prep->color_buf[ci], cinfo->image_width,
00240                  prep->next_buf_row, prep->next_buf_stop);
00241     }
00242     prep->next_buf_row = prep->next_buf_stop;
00243       }
00244     }
00245     /* If we've gotten enough data, downsample a row group. */
00246     if (prep->next_buf_row == prep->next_buf_stop) {
00247       (*cinfo->downsample->downsample) (cinfo,
00248                     prep->color_buf,
00249                     (JDIMENSION) prep->this_row_group,
00250                     output_buf, *out_row_group_ctr);
00251       (*out_row_group_ctr)++;
00252       /* Advance pointers with wraparound as necessary. */
00253       prep->this_row_group += cinfo->max_v_samp_factor;
00254       if (prep->this_row_group >= buf_height)
00255     prep->this_row_group = 0;
00256       if (prep->next_buf_row >= buf_height)
00257     prep->next_buf_row = 0;
00258       prep->next_buf_stop = prep->next_buf_row + cinfo->max_v_samp_factor;
00259     }
00260   }
00261 }
00262 
00263 
00264 /*
00265  * Create the wrapped-around downsampling input buffer needed for context mode.
00266  */
00267 
00268 LOCAL(void)
00269 create_context_buffer (j_compress_ptr cinfo)
00270 {
00271   my_prep_ptr prep = (my_prep_ptr) cinfo->prep;
00272   int rgroup_height = cinfo->max_v_samp_factor;
00273   int ci, i;
00274   jpeg_component_info * compptr;
00275   JSAMPARRAY true_buffer, fake_buffer;
00276 
00277   /* Grab enough space for fake row pointers for all the components;
00278    * we need five row groups' worth of pointers for each component.
00279    */
00280   fake_buffer = (JSAMPARRAY)
00281     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00282                 (cinfo->num_components * 5 * rgroup_height) *
00283                 SIZEOF(JSAMPROW));
00284 
00285   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00286        ci++, compptr++) {
00287     /* Allocate the actual buffer space (3 row groups) for this component.
00288      * We make the buffer wide enough to allow the downsampler to edge-expand
00289      * horizontally within the buffer, if it so chooses.
00290      */
00291     true_buffer = (*cinfo->mem->alloc_sarray)
00292       ((j_common_ptr) cinfo, JPOOL_IMAGE,
00293        (JDIMENSION) (((long) compptr->width_in_blocks *
00294               cinfo->min_DCT_h_scaled_size *
00295               cinfo->max_h_samp_factor) / compptr->h_samp_factor),
00296        (JDIMENSION) (3 * rgroup_height));
00297     /* Copy true buffer row pointers into the middle of the fake row array */
00298     MEMCOPY(fake_buffer + rgroup_height, true_buffer,
00299         3 * rgroup_height * SIZEOF(JSAMPROW));
00300     /* Fill in the above and below wraparound pointers */
00301     for (i = 0; i < rgroup_height; i++) {
00302       fake_buffer[i] = true_buffer[2 * rgroup_height + i];
00303       fake_buffer[4 * rgroup_height + i] = true_buffer[i];
00304     }
00305     prep->color_buf[ci] = fake_buffer + rgroup_height;
00306     fake_buffer += 5 * rgroup_height; /* point to space for next component */
00307   }
00308 }
00309 
00310 #endif /* CONTEXT_ROWS_SUPPORTED */
00311 
00312 
00313 /*
00314  * Initialize preprocessing controller.
00315  */
00316 
00317 GLOBAL(void)
00318 jinit_c_prep_controller (j_compress_ptr cinfo, boolean need_full_buffer)
00319 {
00320   my_prep_ptr prep;
00321   int ci;
00322   jpeg_component_info * compptr;
00323 
00324   if (need_full_buffer)     /* safety check */
00325     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00326 
00327   prep = (my_prep_ptr)
00328     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00329                 SIZEOF(my_prep_controller));
00330   cinfo->prep = (struct jpeg_c_prep_controller *) prep;
00331   prep->pub.start_pass = start_pass_prep;
00332 
00333   /* Allocate the color conversion buffer.
00334    * We make the buffer wide enough to allow the downsampler to edge-expand
00335    * horizontally within the buffer, if it so chooses.
00336    */
00337   if (cinfo->downsample->need_context_rows) {
00338     /* Set up to provide context rows */
00339 #ifdef CONTEXT_ROWS_SUPPORTED
00340     prep->pub.pre_process_data = pre_process_context;
00341     create_context_buffer(cinfo);
00342 #else
00343     ERREXIT(cinfo, JERR_NOT_COMPILED);
00344 #endif
00345   } else {
00346     /* No context, just make it tall enough for one row group */
00347     prep->pub.pre_process_data = pre_process_data;
00348     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
00349      ci++, compptr++) {
00350       prep->color_buf[ci] = (*cinfo->mem->alloc_sarray)
00351     ((j_common_ptr) cinfo, JPOOL_IMAGE,
00352      (JDIMENSION) (((long) compptr->width_in_blocks *
00353             cinfo->min_DCT_h_scaled_size *
00354             cinfo->max_h_samp_factor) / compptr->h_samp_factor),
00355      (JDIMENSION) cinfo->max_v_samp_factor);
00356     }
00357   }
00358 }

Generated on Sun May 27 2012 04:19:24 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.