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

jctrans.c
Go to the documentation of this file.
00001 /*
00002  * jctrans.c
00003  *
00004  * Copyright (C) 1995-1998, Thomas G. Lane.
00005  * Modified 2000-2009 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 library routines for transcoding compression,
00010  * that is, writing raw DCT coefficient arrays to an output JPEG file.
00011  * The routines in jcapimin.c will also be needed by a transcoder.
00012  */
00013 
00014 #define JPEG_INTERNALS
00015 #include "jinclude.h"
00016 #include "jpeglib.h"
00017 
00018 
00019 /* Forward declarations */
00020 LOCAL(void) transencode_master_selection
00021     JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
00022 LOCAL(void) transencode_coef_controller
00023     JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays));
00024 
00025 
00026 /*
00027  * Compression initialization for writing raw-coefficient data.
00028  * Before calling this, all parameters and a data destination must be set up.
00029  * Call jpeg_finish_compress() to actually write the data.
00030  *
00031  * The number of passed virtual arrays must match cinfo->num_components.
00032  * Note that the virtual arrays need not be filled or even realized at
00033  * the time write_coefficients is called; indeed, if the virtual arrays
00034  * were requested from this compression object's memory manager, they
00035  * typically will be realized during this routine and filled afterwards.
00036  */
00037 
00038 GLOBAL(void)
00039 jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)
00040 {
00041   if (cinfo->global_state != CSTATE_START)
00042     ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state);
00043   /* Mark all tables to be written */
00044   jpeg_suppress_tables(cinfo, FALSE);
00045   /* (Re)initialize error mgr and destination modules */
00046   (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo);
00047   (*cinfo->dest->init_destination) (cinfo);
00048   /* Perform master selection of active modules */
00049   transencode_master_selection(cinfo, coef_arrays);
00050   /* Wait for jpeg_finish_compress() call */
00051   cinfo->next_scanline = 0; /* so jpeg_write_marker works */
00052   cinfo->global_state = CSTATE_WRCOEFS;
00053 }
00054 
00055 
00056 /*
00057  * Initialize the compression object with default parameters,
00058  * then copy from the source object all parameters needed for lossless
00059  * transcoding.  Parameters that can be varied without loss (such as
00060  * scan script and Huffman optimization) are left in their default states.
00061  */
00062 
00063 GLOBAL(void)
00064 jpeg_copy_critical_parameters (j_decompress_ptr srcinfo,
00065                    j_compress_ptr dstinfo)
00066 {
00067   JQUANT_TBL ** qtblptr;
00068   jpeg_component_info *incomp, *outcomp;
00069   JQUANT_TBL *c_quant, *slot_quant;
00070   int tblno, ci, coefi;
00071 
00072   /* Safety check to ensure start_compress not called yet. */
00073   if (dstinfo->global_state != CSTATE_START)
00074     ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state);
00075   /* Copy fundamental image dimensions */
00076   dstinfo->image_width = srcinfo->image_width;
00077   dstinfo->image_height = srcinfo->image_height;
00078   dstinfo->input_components = srcinfo->num_components;
00079   dstinfo->in_color_space = srcinfo->jpeg_color_space;
00080   dstinfo->jpeg_width = srcinfo->output_width;
00081   dstinfo->jpeg_height = srcinfo->output_height;
00082   dstinfo->min_DCT_h_scaled_size = srcinfo->min_DCT_h_scaled_size;
00083   dstinfo->min_DCT_v_scaled_size = srcinfo->min_DCT_v_scaled_size;
00084   /* Initialize all parameters to default values */
00085   jpeg_set_defaults(dstinfo);
00086   /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB.
00087    * Fix it to get the right header markers for the image colorspace.
00088    */
00089   jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space);
00090   dstinfo->data_precision = srcinfo->data_precision;
00091   dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling;
00092   /* Copy the source's quantization tables. */
00093   for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) {
00094     if (srcinfo->quant_tbl_ptrs[tblno] != NULL) {
00095       qtblptr = & dstinfo->quant_tbl_ptrs[tblno];
00096       if (*qtblptr == NULL)
00097     *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo);
00098       MEMCOPY((*qtblptr)->quantval,
00099           srcinfo->quant_tbl_ptrs[tblno]->quantval,
00100           SIZEOF((*qtblptr)->quantval));
00101       (*qtblptr)->sent_table = FALSE;
00102     }
00103   }
00104   /* Copy the source's per-component info.
00105    * Note we assume jpeg_set_defaults has allocated the dest comp_info array.
00106    */
00107   dstinfo->num_components = srcinfo->num_components;
00108   if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS)
00109     ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components,
00110          MAX_COMPONENTS);
00111   for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info;
00112        ci < dstinfo->num_components; ci++, incomp++, outcomp++) {
00113     outcomp->component_id = incomp->component_id;
00114     outcomp->h_samp_factor = incomp->h_samp_factor;
00115     outcomp->v_samp_factor = incomp->v_samp_factor;
00116     outcomp->quant_tbl_no = incomp->quant_tbl_no;
00117     /* Make sure saved quantization table for component matches the qtable
00118      * slot.  If not, the input file re-used this qtable slot.
00119      * IJG encoder currently cannot duplicate this.
00120      */
00121     tblno = outcomp->quant_tbl_no;
00122     if (tblno < 0 || tblno >= NUM_QUANT_TBLS ||
00123     srcinfo->quant_tbl_ptrs[tblno] == NULL)
00124       ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno);
00125     slot_quant = srcinfo->quant_tbl_ptrs[tblno];
00126     c_quant = incomp->quant_table;
00127     if (c_quant != NULL) {
00128       for (coefi = 0; coefi < DCTSIZE2; coefi++) {
00129     if (c_quant->quantval[coefi] != slot_quant->quantval[coefi])
00130       ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno);
00131       }
00132     }
00133     /* Note: we do not copy the source's Huffman table assignments;
00134      * instead we rely on jpeg_set_colorspace to have made a suitable choice.
00135      */
00136   }
00137   /* Also copy JFIF version and resolution information, if available.
00138    * Strictly speaking this isn't "critical" info, but it's nearly
00139    * always appropriate to copy it if available.  In particular,
00140    * if the application chooses to copy JFIF 1.02 extension markers from
00141    * the source file, we need to copy the version to make sure we don't
00142    * emit a file that has 1.02 extensions but a claimed version of 1.01.
00143    * We will *not*, however, copy version info from mislabeled "2.01" files.
00144    */
00145   if (srcinfo->saw_JFIF_marker) {
00146     if (srcinfo->JFIF_major_version == 1) {
00147       dstinfo->JFIF_major_version = srcinfo->JFIF_major_version;
00148       dstinfo->JFIF_minor_version = srcinfo->JFIF_minor_version;
00149     }
00150     dstinfo->density_unit = srcinfo->density_unit;
00151     dstinfo->X_density = srcinfo->X_density;
00152     dstinfo->Y_density = srcinfo->Y_density;
00153   }
00154 }
00155 
00156 
00157 /*
00158  * Master selection of compression modules for transcoding.
00159  * This substitutes for jcinit.c's initialization of the full compressor.
00160  */
00161 
00162 LOCAL(void)
00163 transencode_master_selection (j_compress_ptr cinfo,
00164                   jvirt_barray_ptr * coef_arrays)
00165 {
00166   /* Initialize master control (includes parameter checking/processing) */
00167   jinit_c_master_control(cinfo, TRUE /* transcode only */);
00168 
00169   /* Entropy encoding: either Huffman or arithmetic coding. */
00170   if (cinfo->arith_code)
00171     jinit_arith_encoder(cinfo);
00172   else {
00173     jinit_huff_encoder(cinfo);
00174   }
00175 
00176   /* We need a special coefficient buffer controller. */
00177   transencode_coef_controller(cinfo, coef_arrays);
00178 
00179   jinit_marker_writer(cinfo);
00180 
00181   /* We can now tell the memory manager to allocate virtual arrays. */
00182   (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo);
00183 
00184   /* Write the datastream header (SOI, JFIF) immediately.
00185    * Frame and scan headers are postponed till later.
00186    * This lets application insert special markers after the SOI.
00187    */
00188   (*cinfo->marker->write_file_header) (cinfo);
00189 }
00190 
00191 
00192 /*
00193  * The rest of this file is a special implementation of the coefficient
00194  * buffer controller.  This is similar to jccoefct.c, but it handles only
00195  * output from presupplied virtual arrays.  Furthermore, we generate any
00196  * dummy padding blocks on-the-fly rather than expecting them to be present
00197  * in the arrays.
00198  */
00199 
00200 /* Private buffer controller object */
00201 
00202 typedef struct {
00203   struct jpeg_c_coef_controller pub; /* public fields */
00204 
00205   JDIMENSION iMCU_row_num;  /* iMCU row # within image */
00206   JDIMENSION mcu_ctr;       /* counts MCUs processed in current row */
00207   int MCU_vert_offset;      /* counts MCU rows within iMCU row */
00208   int MCU_rows_per_iMCU_row;    /* number of such rows needed */
00209 
00210   /* Virtual block array for each component. */
00211   jvirt_barray_ptr * whole_image;
00212 
00213   /* Workspace for constructing dummy blocks at right/bottom edges. */
00214   JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU];
00215 } my_coef_controller;
00216 
00217 typedef my_coef_controller * my_coef_ptr;
00218 
00219 
00220 LOCAL(void)
00221 start_iMCU_row (j_compress_ptr cinfo)
00222 /* Reset within-iMCU-row counters for a new row */
00223 {
00224   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
00225 
00226   /* In an interleaved scan, an MCU row is the same as an iMCU row.
00227    * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
00228    * But at the bottom of the image, process only what's left.
00229    */
00230   if (cinfo->comps_in_scan > 1) {
00231     coef->MCU_rows_per_iMCU_row = 1;
00232   } else {
00233     if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1))
00234       coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
00235     else
00236       coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
00237   }
00238 
00239   coef->mcu_ctr = 0;
00240   coef->MCU_vert_offset = 0;
00241 }
00242 
00243 
00244 /*
00245  * Initialize for a processing pass.
00246  */
00247 
00248 METHODDEF(void)
00249 start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode)
00250 {
00251   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
00252 
00253   if (pass_mode != JBUF_CRANK_DEST)
00254     ERREXIT(cinfo, JERR_BAD_BUFFER_MODE);
00255 
00256   coef->iMCU_row_num = 0;
00257   start_iMCU_row(cinfo);
00258 }
00259 
00260 
00261 /*
00262  * Process some data.
00263  * We process the equivalent of one fully interleaved MCU row ("iMCU" row)
00264  * per call, ie, v_samp_factor block rows for each component in the scan.
00265  * The data is obtained from the virtual arrays and fed to the entropy coder.
00266  * Returns TRUE if the iMCU row is completed, FALSE if suspended.
00267  *
00268  * NB: input_buf is ignored; it is likely to be a NULL pointer.
00269  */
00270 
00271 METHODDEF(boolean)
00272 compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf)
00273 {
00274   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
00275   JDIMENSION MCU_col_num;   /* index of current MCU within row */
00276   JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
00277   JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
00278   int blkn, ci, xindex, yindex, yoffset, blockcnt;
00279   JDIMENSION start_col;
00280   JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
00281   JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU];
00282   JBLOCKROW buffer_ptr;
00283   jpeg_component_info *compptr;
00284 
00285   /* Align the virtual buffers for the components used in this scan. */
00286   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00287     compptr = cinfo->cur_comp_info[ci];
00288     buffer[ci] = (*cinfo->mem->access_virt_barray)
00289       ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
00290        coef->iMCU_row_num * compptr->v_samp_factor,
00291        (JDIMENSION) compptr->v_samp_factor, FALSE);
00292   }
00293 
00294   /* Loop to process one whole iMCU row */
00295   for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
00296        yoffset++) {
00297     for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row;
00298      MCU_col_num++) {
00299       /* Construct list of pointers to DCT blocks belonging to this MCU */
00300       blkn = 0;         /* index of current DCT block within MCU */
00301       for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
00302     compptr = cinfo->cur_comp_info[ci];
00303     start_col = MCU_col_num * compptr->MCU_width;
00304     blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
00305                         : compptr->last_col_width;
00306     for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
00307       if (coef->iMCU_row_num < last_iMCU_row ||
00308           yindex+yoffset < compptr->last_row_height) {
00309         /* Fill in pointers to real blocks in this row */
00310         buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
00311         for (xindex = 0; xindex < blockcnt; xindex++)
00312           MCU_buffer[blkn++] = buffer_ptr++;
00313       } else {
00314         /* At bottom of image, need a whole row of dummy blocks */
00315         xindex = 0;
00316       }
00317       /* Fill in any dummy blocks needed in this row.
00318        * Dummy blocks are filled in the same way as in jccoefct.c:
00319        * all zeroes in the AC entries, DC entries equal to previous
00320        * block's DC value.  The init routine has already zeroed the
00321        * AC entries, so we need only set the DC entries correctly.
00322        */
00323       for (; xindex < compptr->MCU_width; xindex++) {
00324         MCU_buffer[blkn] = coef->dummy_buffer[blkn];
00325         MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0];
00326         blkn++;
00327       }
00328     }
00329       }
00330       /* Try to write the MCU. */
00331       if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) {
00332     /* Suspension forced; update state counters and exit */
00333     coef->MCU_vert_offset = yoffset;
00334     coef->mcu_ctr = MCU_col_num;
00335     return FALSE;
00336       }
00337     }
00338     /* Completed an MCU row, but perhaps not an iMCU row */
00339     coef->mcu_ctr = 0;
00340   }
00341   /* Completed the iMCU row, advance counters for next one */
00342   coef->iMCU_row_num++;
00343   start_iMCU_row(cinfo);
00344   return TRUE;
00345 }
00346 
00347 
00348 /*
00349  * Initialize coefficient buffer controller.
00350  *
00351  * Each passed coefficient array must be the right size for that
00352  * coefficient: width_in_blocks wide and height_in_blocks high,
00353  * with unitheight at least v_samp_factor.
00354  */
00355 
00356 LOCAL(void)
00357 transencode_coef_controller (j_compress_ptr cinfo,
00358                  jvirt_barray_ptr * coef_arrays)
00359 {
00360   my_coef_ptr coef;
00361   JBLOCKROW buffer;
00362   int i;
00363 
00364   coef = (my_coef_ptr)
00365     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00366                 SIZEOF(my_coef_controller));
00367   cinfo->coef = (struct jpeg_c_coef_controller *) coef;
00368   coef->pub.start_pass = start_pass_coef;
00369   coef->pub.compress_data = compress_output;
00370 
00371   /* Save pointer to virtual arrays */
00372   coef->whole_image = coef_arrays;
00373 
00374   /* Allocate and pre-zero space for dummy DCT blocks. */
00375   buffer = (JBLOCKROW)
00376     (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
00377                 C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
00378   jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
00379   for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) {
00380     coef->dummy_buffer[i] = buffer + i;
00381   }
00382 }

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.