1*7dd7cddfSDavid du Colombier /* 2*7dd7cddfSDavid du Colombier * jctrans.c 3*7dd7cddfSDavid du Colombier * 4*7dd7cddfSDavid du Colombier * Copyright (C) 1995-1996, Thomas G. Lane. 5*7dd7cddfSDavid du Colombier * This file is part of the Independent JPEG Group's software. 6*7dd7cddfSDavid du Colombier * For conditions of distribution and use, see the accompanying README file. 7*7dd7cddfSDavid du Colombier * 8*7dd7cddfSDavid du Colombier * This file contains library routines for transcoding compression, 9*7dd7cddfSDavid du Colombier * that is, writing raw DCT coefficient arrays to an output JPEG file. 10*7dd7cddfSDavid du Colombier * The routines in jcapimin.c will also be needed by a transcoder. 11*7dd7cddfSDavid du Colombier */ 12*7dd7cddfSDavid du Colombier 13*7dd7cddfSDavid du Colombier #define JPEG_INTERNALS 14*7dd7cddfSDavid du Colombier #include "jinclude.h" 15*7dd7cddfSDavid du Colombier #include "jpeglib.h" 16*7dd7cddfSDavid du Colombier 17*7dd7cddfSDavid du Colombier 18*7dd7cddfSDavid du Colombier /* Forward declarations */ 19*7dd7cddfSDavid du Colombier LOCAL(void) transencode_master_selection 20*7dd7cddfSDavid du Colombier JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); 21*7dd7cddfSDavid du Colombier LOCAL(void) transencode_coef_controller 22*7dd7cddfSDavid du Colombier JPP((j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays)); 23*7dd7cddfSDavid du Colombier 24*7dd7cddfSDavid du Colombier 25*7dd7cddfSDavid du Colombier /* 26*7dd7cddfSDavid du Colombier * Compression initialization for writing raw-coefficient data. 27*7dd7cddfSDavid du Colombier * Before calling this, all parameters and a data destination must be set up. 28*7dd7cddfSDavid du Colombier * Call jpeg_finish_compress() to actually write the data. 29*7dd7cddfSDavid du Colombier * 30*7dd7cddfSDavid du Colombier * The number of passed virtual arrays must match cinfo->num_components. 31*7dd7cddfSDavid du Colombier * Note that the virtual arrays need not be filled or even realized at 32*7dd7cddfSDavid du Colombier * the time write_coefficients is called; indeed, if the virtual arrays 33*7dd7cddfSDavid du Colombier * were requested from this compression object's memory manager, they 34*7dd7cddfSDavid du Colombier * typically will be realized during this routine and filled afterwards. 35*7dd7cddfSDavid du Colombier */ 36*7dd7cddfSDavid du Colombier 37*7dd7cddfSDavid du Colombier GLOBAL(void) 38*7dd7cddfSDavid du Colombier jpeg_write_coefficients (j_compress_ptr cinfo, jvirt_barray_ptr * coef_arrays) 39*7dd7cddfSDavid du Colombier { 40*7dd7cddfSDavid du Colombier if (cinfo->global_state != CSTATE_START) 41*7dd7cddfSDavid du Colombier ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); 42*7dd7cddfSDavid du Colombier /* Mark all tables to be written */ 43*7dd7cddfSDavid du Colombier jpeg_suppress_tables(cinfo, FALSE); 44*7dd7cddfSDavid du Colombier /* (Re)initialize error mgr and destination modules */ 45*7dd7cddfSDavid du Colombier (*cinfo->err->reset_error_mgr) ((j_common_ptr) cinfo); 46*7dd7cddfSDavid du Colombier (*cinfo->dest->init_destination) (cinfo); 47*7dd7cddfSDavid du Colombier /* Perform master selection of active modules */ 48*7dd7cddfSDavid du Colombier transencode_master_selection(cinfo, coef_arrays); 49*7dd7cddfSDavid du Colombier /* Wait for jpeg_finish_compress() call */ 50*7dd7cddfSDavid du Colombier cinfo->next_scanline = 0; /* so jpeg_write_marker works */ 51*7dd7cddfSDavid du Colombier cinfo->global_state = CSTATE_WRCOEFS; 52*7dd7cddfSDavid du Colombier } 53*7dd7cddfSDavid du Colombier 54*7dd7cddfSDavid du Colombier 55*7dd7cddfSDavid du Colombier /* 56*7dd7cddfSDavid du Colombier * Initialize the compression object with default parameters, 57*7dd7cddfSDavid du Colombier * then copy from the source object all parameters needed for lossless 58*7dd7cddfSDavid du Colombier * transcoding. Parameters that can be varied without loss (such as 59*7dd7cddfSDavid du Colombier * scan script and Huffman optimization) are left in their default states. 60*7dd7cddfSDavid du Colombier */ 61*7dd7cddfSDavid du Colombier 62*7dd7cddfSDavid du Colombier GLOBAL(void) 63*7dd7cddfSDavid du Colombier jpeg_copy_critical_parameters (j_decompress_ptr srcinfo, 64*7dd7cddfSDavid du Colombier j_compress_ptr dstinfo) 65*7dd7cddfSDavid du Colombier { 66*7dd7cddfSDavid du Colombier JQUANT_TBL ** qtblptr; 67*7dd7cddfSDavid du Colombier jpeg_component_info *incomp, *outcomp; 68*7dd7cddfSDavid du Colombier JQUANT_TBL *c_quant, *slot_quant; 69*7dd7cddfSDavid du Colombier int tblno, ci, coefi; 70*7dd7cddfSDavid du Colombier 71*7dd7cddfSDavid du Colombier /* Safety check to ensure start_compress not called yet. */ 72*7dd7cddfSDavid du Colombier if (dstinfo->global_state != CSTATE_START) 73*7dd7cddfSDavid du Colombier ERREXIT1(dstinfo, JERR_BAD_STATE, dstinfo->global_state); 74*7dd7cddfSDavid du Colombier /* Copy fundamental image dimensions */ 75*7dd7cddfSDavid du Colombier dstinfo->image_width = srcinfo->image_width; 76*7dd7cddfSDavid du Colombier dstinfo->image_height = srcinfo->image_height; 77*7dd7cddfSDavid du Colombier dstinfo->input_components = srcinfo->num_components; 78*7dd7cddfSDavid du Colombier dstinfo->in_color_space = srcinfo->jpeg_color_space; 79*7dd7cddfSDavid du Colombier /* Initialize all parameters to default values */ 80*7dd7cddfSDavid du Colombier jpeg_set_defaults(dstinfo); 81*7dd7cddfSDavid du Colombier /* jpeg_set_defaults may choose wrong colorspace, eg YCbCr if input is RGB. 82*7dd7cddfSDavid du Colombier * Fix it to get the right header markers for the image colorspace. 83*7dd7cddfSDavid du Colombier */ 84*7dd7cddfSDavid du Colombier jpeg_set_colorspace(dstinfo, srcinfo->jpeg_color_space); 85*7dd7cddfSDavid du Colombier dstinfo->data_precision = srcinfo->data_precision; 86*7dd7cddfSDavid du Colombier dstinfo->CCIR601_sampling = srcinfo->CCIR601_sampling; 87*7dd7cddfSDavid du Colombier /* Copy the source's quantization tables. */ 88*7dd7cddfSDavid du Colombier for (tblno = 0; tblno < NUM_QUANT_TBLS; tblno++) { 89*7dd7cddfSDavid du Colombier if (srcinfo->quant_tbl_ptrs[tblno] != NULL) { 90*7dd7cddfSDavid du Colombier qtblptr = & dstinfo->quant_tbl_ptrs[tblno]; 91*7dd7cddfSDavid du Colombier if (*qtblptr == NULL) 92*7dd7cddfSDavid du Colombier *qtblptr = jpeg_alloc_quant_table((j_common_ptr) dstinfo); 93*7dd7cddfSDavid du Colombier MEMCOPY((*qtblptr)->quantval, 94*7dd7cddfSDavid du Colombier srcinfo->quant_tbl_ptrs[tblno]->quantval, 95*7dd7cddfSDavid du Colombier SIZEOF((*qtblptr)->quantval)); 96*7dd7cddfSDavid du Colombier (*qtblptr)->sent_table = FALSE; 97*7dd7cddfSDavid du Colombier } 98*7dd7cddfSDavid du Colombier } 99*7dd7cddfSDavid du Colombier /* Copy the source's per-component info. 100*7dd7cddfSDavid du Colombier * Note we assume jpeg_set_defaults has allocated the dest comp_info array. 101*7dd7cddfSDavid du Colombier */ 102*7dd7cddfSDavid du Colombier dstinfo->num_components = srcinfo->num_components; 103*7dd7cddfSDavid du Colombier if (dstinfo->num_components < 1 || dstinfo->num_components > MAX_COMPONENTS) 104*7dd7cddfSDavid du Colombier ERREXIT2(dstinfo, JERR_COMPONENT_COUNT, dstinfo->num_components, 105*7dd7cddfSDavid du Colombier MAX_COMPONENTS); 106*7dd7cddfSDavid du Colombier for (ci = 0, incomp = srcinfo->comp_info, outcomp = dstinfo->comp_info; 107*7dd7cddfSDavid du Colombier ci < dstinfo->num_components; ci++, incomp++, outcomp++) { 108*7dd7cddfSDavid du Colombier outcomp->component_id = incomp->component_id; 109*7dd7cddfSDavid du Colombier outcomp->h_samp_factor = incomp->h_samp_factor; 110*7dd7cddfSDavid du Colombier outcomp->v_samp_factor = incomp->v_samp_factor; 111*7dd7cddfSDavid du Colombier outcomp->quant_tbl_no = incomp->quant_tbl_no; 112*7dd7cddfSDavid du Colombier /* Make sure saved quantization table for component matches the qtable 113*7dd7cddfSDavid du Colombier * slot. If not, the input file re-used this qtable slot. 114*7dd7cddfSDavid du Colombier * IJG encoder currently cannot duplicate this. 115*7dd7cddfSDavid du Colombier */ 116*7dd7cddfSDavid du Colombier tblno = outcomp->quant_tbl_no; 117*7dd7cddfSDavid du Colombier if (tblno < 0 || tblno >= NUM_QUANT_TBLS || 118*7dd7cddfSDavid du Colombier srcinfo->quant_tbl_ptrs[tblno] == NULL) 119*7dd7cddfSDavid du Colombier ERREXIT1(dstinfo, JERR_NO_QUANT_TABLE, tblno); 120*7dd7cddfSDavid du Colombier slot_quant = srcinfo->quant_tbl_ptrs[tblno]; 121*7dd7cddfSDavid du Colombier c_quant = incomp->quant_table; 122*7dd7cddfSDavid du Colombier if (c_quant != NULL) { 123*7dd7cddfSDavid du Colombier for (coefi = 0; coefi < DCTSIZE2; coefi++) { 124*7dd7cddfSDavid du Colombier if (c_quant->quantval[coefi] != slot_quant->quantval[coefi]) 125*7dd7cddfSDavid du Colombier ERREXIT1(dstinfo, JERR_MISMATCHED_QUANT_TABLE, tblno); 126*7dd7cddfSDavid du Colombier } 127*7dd7cddfSDavid du Colombier } 128*7dd7cddfSDavid du Colombier /* Note: we do not copy the source's Huffman table assignments; 129*7dd7cddfSDavid du Colombier * instead we rely on jpeg_set_colorspace to have made a suitable choice. 130*7dd7cddfSDavid du Colombier */ 131*7dd7cddfSDavid du Colombier } 132*7dd7cddfSDavid du Colombier } 133*7dd7cddfSDavid du Colombier 134*7dd7cddfSDavid du Colombier 135*7dd7cddfSDavid du Colombier /* 136*7dd7cddfSDavid du Colombier * Master selection of compression modules for transcoding. 137*7dd7cddfSDavid du Colombier * This substitutes for jcinit.c's initialization of the full compressor. 138*7dd7cddfSDavid du Colombier */ 139*7dd7cddfSDavid du Colombier 140*7dd7cddfSDavid du Colombier LOCAL(void) 141*7dd7cddfSDavid du Colombier transencode_master_selection (j_compress_ptr cinfo, 142*7dd7cddfSDavid du Colombier jvirt_barray_ptr * coef_arrays) 143*7dd7cddfSDavid du Colombier { 144*7dd7cddfSDavid du Colombier /* Although we don't actually use input_components for transcoding, 145*7dd7cddfSDavid du Colombier * jcmaster.c's initial_setup will complain if input_components is 0. 146*7dd7cddfSDavid du Colombier */ 147*7dd7cddfSDavid du Colombier cinfo->input_components = 1; 148*7dd7cddfSDavid du Colombier /* Initialize master control (includes parameter checking/processing) */ 149*7dd7cddfSDavid du Colombier jinit_c_master_control(cinfo, TRUE /* transcode only */); 150*7dd7cddfSDavid du Colombier 151*7dd7cddfSDavid du Colombier /* Entropy encoding: either Huffman or arithmetic coding. */ 152*7dd7cddfSDavid du Colombier if (cinfo->arith_code) { 153*7dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_ARITH_NOTIMPL); 154*7dd7cddfSDavid du Colombier } else { 155*7dd7cddfSDavid du Colombier if (cinfo->progressive_mode) { 156*7dd7cddfSDavid du Colombier #ifdef C_PROGRESSIVE_SUPPORTED 157*7dd7cddfSDavid du Colombier jinit_phuff_encoder(cinfo); 158*7dd7cddfSDavid du Colombier #else 159*7dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_NOT_COMPILED); 160*7dd7cddfSDavid du Colombier #endif 161*7dd7cddfSDavid du Colombier } else 162*7dd7cddfSDavid du Colombier jinit_huff_encoder(cinfo); 163*7dd7cddfSDavid du Colombier } 164*7dd7cddfSDavid du Colombier 165*7dd7cddfSDavid du Colombier /* We need a special coefficient buffer controller. */ 166*7dd7cddfSDavid du Colombier transencode_coef_controller(cinfo, coef_arrays); 167*7dd7cddfSDavid du Colombier 168*7dd7cddfSDavid du Colombier jinit_marker_writer(cinfo); 169*7dd7cddfSDavid du Colombier 170*7dd7cddfSDavid du Colombier /* We can now tell the memory manager to allocate virtual arrays. */ 171*7dd7cddfSDavid du Colombier (*cinfo->mem->realize_virt_arrays) ((j_common_ptr) cinfo); 172*7dd7cddfSDavid du Colombier 173*7dd7cddfSDavid du Colombier /* Write the datastream header (SOI) immediately. 174*7dd7cddfSDavid du Colombier * Frame and scan headers are postponed till later. 175*7dd7cddfSDavid du Colombier * This lets application insert special markers after the SOI. 176*7dd7cddfSDavid du Colombier */ 177*7dd7cddfSDavid du Colombier (*cinfo->marker->write_file_header) (cinfo); 178*7dd7cddfSDavid du Colombier } 179*7dd7cddfSDavid du Colombier 180*7dd7cddfSDavid du Colombier 181*7dd7cddfSDavid du Colombier /* 182*7dd7cddfSDavid du Colombier * The rest of this file is a special implementation of the coefficient 183*7dd7cddfSDavid du Colombier * buffer controller. This is similar to jccoefct.c, but it handles only 184*7dd7cddfSDavid du Colombier * output from presupplied virtual arrays. Furthermore, we generate any 185*7dd7cddfSDavid du Colombier * dummy padding blocks on-the-fly rather than expecting them to be present 186*7dd7cddfSDavid du Colombier * in the arrays. 187*7dd7cddfSDavid du Colombier */ 188*7dd7cddfSDavid du Colombier 189*7dd7cddfSDavid du Colombier /* Private buffer controller object */ 190*7dd7cddfSDavid du Colombier 191*7dd7cddfSDavid du Colombier typedef struct { 192*7dd7cddfSDavid du Colombier struct jpeg_c_coef_controller pub; /* public fields */ 193*7dd7cddfSDavid du Colombier 194*7dd7cddfSDavid du Colombier JDIMENSION iMCU_row_num; /* iMCU row # within image */ 195*7dd7cddfSDavid du Colombier JDIMENSION mcu_ctr; /* counts MCUs processed in current row */ 196*7dd7cddfSDavid du Colombier int MCU_vert_offset; /* counts MCU rows within iMCU row */ 197*7dd7cddfSDavid du Colombier int MCU_rows_per_iMCU_row; /* number of such rows needed */ 198*7dd7cddfSDavid du Colombier 199*7dd7cddfSDavid du Colombier /* Virtual block array for each component. */ 200*7dd7cddfSDavid du Colombier jvirt_barray_ptr * whole_image; 201*7dd7cddfSDavid du Colombier 202*7dd7cddfSDavid du Colombier /* Workspace for constructing dummy blocks at right/bottom edges. */ 203*7dd7cddfSDavid du Colombier JBLOCKROW dummy_buffer[C_MAX_BLOCKS_IN_MCU]; 204*7dd7cddfSDavid du Colombier } my_coef_controller; 205*7dd7cddfSDavid du Colombier 206*7dd7cddfSDavid du Colombier typedef my_coef_controller * my_coef_ptr; 207*7dd7cddfSDavid du Colombier 208*7dd7cddfSDavid du Colombier 209*7dd7cddfSDavid du Colombier LOCAL(void) 210*7dd7cddfSDavid du Colombier start_iMCU_row (j_compress_ptr cinfo) 211*7dd7cddfSDavid du Colombier /* Reset within-iMCU-row counters for a new row */ 212*7dd7cddfSDavid du Colombier { 213*7dd7cddfSDavid du Colombier my_coef_ptr coef = (my_coef_ptr) cinfo->coef; 214*7dd7cddfSDavid du Colombier 215*7dd7cddfSDavid du Colombier /* In an interleaved scan, an MCU row is the same as an iMCU row. 216*7dd7cddfSDavid du Colombier * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows. 217*7dd7cddfSDavid du Colombier * But at the bottom of the image, process only what's left. 218*7dd7cddfSDavid du Colombier */ 219*7dd7cddfSDavid du Colombier if (cinfo->comps_in_scan > 1) { 220*7dd7cddfSDavid du Colombier coef->MCU_rows_per_iMCU_row = 1; 221*7dd7cddfSDavid du Colombier } else { 222*7dd7cddfSDavid du Colombier if (coef->iMCU_row_num < (cinfo->total_iMCU_rows-1)) 223*7dd7cddfSDavid du Colombier coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor; 224*7dd7cddfSDavid du Colombier else 225*7dd7cddfSDavid du Colombier coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height; 226*7dd7cddfSDavid du Colombier } 227*7dd7cddfSDavid du Colombier 228*7dd7cddfSDavid du Colombier coef->mcu_ctr = 0; 229*7dd7cddfSDavid du Colombier coef->MCU_vert_offset = 0; 230*7dd7cddfSDavid du Colombier } 231*7dd7cddfSDavid du Colombier 232*7dd7cddfSDavid du Colombier 233*7dd7cddfSDavid du Colombier /* 234*7dd7cddfSDavid du Colombier * Initialize for a processing pass. 235*7dd7cddfSDavid du Colombier */ 236*7dd7cddfSDavid du Colombier 237*7dd7cddfSDavid du Colombier METHODDEF(void) 238*7dd7cddfSDavid du Colombier start_pass_coef (j_compress_ptr cinfo, J_BUF_MODE pass_mode) 239*7dd7cddfSDavid du Colombier { 240*7dd7cddfSDavid du Colombier my_coef_ptr coef = (my_coef_ptr) cinfo->coef; 241*7dd7cddfSDavid du Colombier 242*7dd7cddfSDavid du Colombier if (pass_mode != JBUF_CRANK_DEST) 243*7dd7cddfSDavid du Colombier ERREXIT(cinfo, JERR_BAD_BUFFER_MODE); 244*7dd7cddfSDavid du Colombier 245*7dd7cddfSDavid du Colombier coef->iMCU_row_num = 0; 246*7dd7cddfSDavid du Colombier start_iMCU_row(cinfo); 247*7dd7cddfSDavid du Colombier } 248*7dd7cddfSDavid du Colombier 249*7dd7cddfSDavid du Colombier 250*7dd7cddfSDavid du Colombier /* 251*7dd7cddfSDavid du Colombier * Process some data. 252*7dd7cddfSDavid du Colombier * We process the equivalent of one fully interleaved MCU row ("iMCU" row) 253*7dd7cddfSDavid du Colombier * per call, ie, v_samp_factor block rows for each component in the scan. 254*7dd7cddfSDavid du Colombier * The data is obtained from the virtual arrays and fed to the entropy coder. 255*7dd7cddfSDavid du Colombier * Returns TRUE if the iMCU row is completed, FALSE if suspended. 256*7dd7cddfSDavid du Colombier * 257*7dd7cddfSDavid du Colombier * NB: input_buf is ignored; it is likely to be a NULL pointer. 258*7dd7cddfSDavid du Colombier */ 259*7dd7cddfSDavid du Colombier 260*7dd7cddfSDavid du Colombier METHODDEF(boolean) 261*7dd7cddfSDavid du Colombier compress_output (j_compress_ptr cinfo, JSAMPIMAGE input_buf) 262*7dd7cddfSDavid du Colombier { 263*7dd7cddfSDavid du Colombier my_coef_ptr coef = (my_coef_ptr) cinfo->coef; 264*7dd7cddfSDavid du Colombier JDIMENSION MCU_col_num; /* index of current MCU within row */ 265*7dd7cddfSDavid du Colombier JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1; 266*7dd7cddfSDavid du Colombier JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1; 267*7dd7cddfSDavid du Colombier int blkn, ci, xindex, yindex, yoffset, blockcnt; 268*7dd7cddfSDavid du Colombier JDIMENSION start_col; 269*7dd7cddfSDavid du Colombier JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN]; 270*7dd7cddfSDavid du Colombier JBLOCKROW MCU_buffer[C_MAX_BLOCKS_IN_MCU]; 271*7dd7cddfSDavid du Colombier JBLOCKROW buffer_ptr; 272*7dd7cddfSDavid du Colombier jpeg_component_info *compptr; 273*7dd7cddfSDavid du Colombier 274*7dd7cddfSDavid du Colombier /* Align the virtual buffers for the components used in this scan. */ 275*7dd7cddfSDavid du Colombier for (ci = 0; ci < cinfo->comps_in_scan; ci++) { 276*7dd7cddfSDavid du Colombier compptr = cinfo->cur_comp_info[ci]; 277*7dd7cddfSDavid du Colombier buffer[ci] = (*cinfo->mem->access_virt_barray) 278*7dd7cddfSDavid du Colombier ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index], 279*7dd7cddfSDavid du Colombier coef->iMCU_row_num * compptr->v_samp_factor, 280*7dd7cddfSDavid du Colombier (JDIMENSION) compptr->v_samp_factor, FALSE); 281*7dd7cddfSDavid du Colombier } 282*7dd7cddfSDavid du Colombier 283*7dd7cddfSDavid du Colombier /* Loop to process one whole iMCU row */ 284*7dd7cddfSDavid du Colombier for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row; 285*7dd7cddfSDavid du Colombier yoffset++) { 286*7dd7cddfSDavid du Colombier for (MCU_col_num = coef->mcu_ctr; MCU_col_num < cinfo->MCUs_per_row; 287*7dd7cddfSDavid du Colombier MCU_col_num++) { 288*7dd7cddfSDavid du Colombier /* Construct list of pointers to DCT blocks belonging to this MCU */ 289*7dd7cddfSDavid du Colombier blkn = 0; /* index of current DCT block within MCU */ 290*7dd7cddfSDavid du Colombier for (ci = 0; ci < cinfo->comps_in_scan; ci++) { 291*7dd7cddfSDavid du Colombier compptr = cinfo->cur_comp_info[ci]; 292*7dd7cddfSDavid du Colombier start_col = MCU_col_num * compptr->MCU_width; 293*7dd7cddfSDavid du Colombier blockcnt = (MCU_col_num < last_MCU_col) ? compptr->MCU_width 294*7dd7cddfSDavid du Colombier : compptr->last_col_width; 295*7dd7cddfSDavid du Colombier for (yindex = 0; yindex < compptr->MCU_height; yindex++) { 296*7dd7cddfSDavid du Colombier if (coef->iMCU_row_num < last_iMCU_row || 297*7dd7cddfSDavid du Colombier yindex+yoffset < compptr->last_row_height) { 298*7dd7cddfSDavid du Colombier /* Fill in pointers to real blocks in this row */ 299*7dd7cddfSDavid du Colombier buffer_ptr = buffer[ci][yindex+yoffset] + start_col; 300*7dd7cddfSDavid du Colombier for (xindex = 0; xindex < blockcnt; xindex++) 301*7dd7cddfSDavid du Colombier MCU_buffer[blkn++] = buffer_ptr++; 302*7dd7cddfSDavid du Colombier } else { 303*7dd7cddfSDavid du Colombier /* At bottom of image, need a whole row of dummy blocks */ 304*7dd7cddfSDavid du Colombier xindex = 0; 305*7dd7cddfSDavid du Colombier } 306*7dd7cddfSDavid du Colombier /* Fill in any dummy blocks needed in this row. 307*7dd7cddfSDavid du Colombier * Dummy blocks are filled in the same way as in jccoefct.c: 308*7dd7cddfSDavid du Colombier * all zeroes in the AC entries, DC entries equal to previous 309*7dd7cddfSDavid du Colombier * block's DC value. The init routine has already zeroed the 310*7dd7cddfSDavid du Colombier * AC entries, so we need only set the DC entries correctly. 311*7dd7cddfSDavid du Colombier */ 312*7dd7cddfSDavid du Colombier for (; xindex < compptr->MCU_width; xindex++) { 313*7dd7cddfSDavid du Colombier MCU_buffer[blkn] = coef->dummy_buffer[blkn]; 314*7dd7cddfSDavid du Colombier MCU_buffer[blkn][0][0] = MCU_buffer[blkn-1][0][0]; 315*7dd7cddfSDavid du Colombier blkn++; 316*7dd7cddfSDavid du Colombier } 317*7dd7cddfSDavid du Colombier } 318*7dd7cddfSDavid du Colombier } 319*7dd7cddfSDavid du Colombier /* Try to write the MCU. */ 320*7dd7cddfSDavid du Colombier if (! (*cinfo->entropy->encode_mcu) (cinfo, MCU_buffer)) { 321*7dd7cddfSDavid du Colombier /* Suspension forced; update state counters and exit */ 322*7dd7cddfSDavid du Colombier coef->MCU_vert_offset = yoffset; 323*7dd7cddfSDavid du Colombier coef->mcu_ctr = MCU_col_num; 324*7dd7cddfSDavid du Colombier return FALSE; 325*7dd7cddfSDavid du Colombier } 326*7dd7cddfSDavid du Colombier } 327*7dd7cddfSDavid du Colombier /* Completed an MCU row, but perhaps not an iMCU row */ 328*7dd7cddfSDavid du Colombier coef->mcu_ctr = 0; 329*7dd7cddfSDavid du Colombier } 330*7dd7cddfSDavid du Colombier /* Completed the iMCU row, advance counters for next one */ 331*7dd7cddfSDavid du Colombier coef->iMCU_row_num++; 332*7dd7cddfSDavid du Colombier start_iMCU_row(cinfo); 333*7dd7cddfSDavid du Colombier return TRUE; 334*7dd7cddfSDavid du Colombier } 335*7dd7cddfSDavid du Colombier 336*7dd7cddfSDavid du Colombier 337*7dd7cddfSDavid du Colombier /* 338*7dd7cddfSDavid du Colombier * Initialize coefficient buffer controller. 339*7dd7cddfSDavid du Colombier * 340*7dd7cddfSDavid du Colombier * Each passed coefficient array must be the right size for that 341*7dd7cddfSDavid du Colombier * coefficient: width_in_blocks wide and height_in_blocks high, 342*7dd7cddfSDavid du Colombier * with unitheight at least v_samp_factor. 343*7dd7cddfSDavid du Colombier */ 344*7dd7cddfSDavid du Colombier 345*7dd7cddfSDavid du Colombier LOCAL(void) 346*7dd7cddfSDavid du Colombier transencode_coef_controller (j_compress_ptr cinfo, 347*7dd7cddfSDavid du Colombier jvirt_barray_ptr * coef_arrays) 348*7dd7cddfSDavid du Colombier { 349*7dd7cddfSDavid du Colombier my_coef_ptr coef; 350*7dd7cddfSDavid du Colombier JBLOCKROW buffer; 351*7dd7cddfSDavid du Colombier int i; 352*7dd7cddfSDavid du Colombier 353*7dd7cddfSDavid du Colombier coef = (my_coef_ptr) 354*7dd7cddfSDavid du Colombier (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE, 355*7dd7cddfSDavid du Colombier SIZEOF(my_coef_controller)); 356*7dd7cddfSDavid du Colombier cinfo->coef = (struct jpeg_c_coef_controller *) coef; 357*7dd7cddfSDavid du Colombier coef->pub.start_pass = start_pass_coef; 358*7dd7cddfSDavid du Colombier coef->pub.compress_data = compress_output; 359*7dd7cddfSDavid du Colombier 360*7dd7cddfSDavid du Colombier /* Save pointer to virtual arrays */ 361*7dd7cddfSDavid du Colombier coef->whole_image = coef_arrays; 362*7dd7cddfSDavid du Colombier 363*7dd7cddfSDavid du Colombier /* Allocate and pre-zero space for dummy DCT blocks. */ 364*7dd7cddfSDavid du Colombier buffer = (JBLOCKROW) 365*7dd7cddfSDavid du Colombier (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE, 366*7dd7cddfSDavid du Colombier C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); 367*7dd7cddfSDavid du Colombier jzero_far((void FAR *) buffer, C_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK)); 368*7dd7cddfSDavid du Colombier for (i = 0; i < C_MAX_BLOCKS_IN_MCU; i++) { 369*7dd7cddfSDavid du Colombier coef->dummy_buffer[i] = buffer + i; 370*7dd7cddfSDavid du Colombier } 371*7dd7cddfSDavid du Colombier } 372