xref: /plan9/sys/src/cmd/gs/jpeg/jdcoefct.c (revision 593dc095aefb2a85c828727bbfa9da139a49bdf4)
17dd7cddfSDavid du Colombier /*
27dd7cddfSDavid du Colombier  * jdcoefct.c
37dd7cddfSDavid du Colombier  *
4*593dc095SDavid du Colombier  * Copyright (C) 1994-1997, Thomas G. Lane.
57dd7cddfSDavid du Colombier  * This file is part of the Independent JPEG Group's software.
67dd7cddfSDavid du Colombier  * For conditions of distribution and use, see the accompanying README file.
77dd7cddfSDavid du Colombier  *
87dd7cddfSDavid du Colombier  * This file contains the coefficient buffer controller for decompression.
97dd7cddfSDavid du Colombier  * This controller is the top level of the JPEG decompressor proper.
107dd7cddfSDavid du Colombier  * The coefficient buffer lies between entropy decoding and inverse-DCT steps.
117dd7cddfSDavid du Colombier  *
127dd7cddfSDavid du Colombier  * In buffered-image mode, this controller is the interface between
137dd7cddfSDavid du Colombier  * input-oriented processing and output-oriented processing.
147dd7cddfSDavid du Colombier  * Also, the input side (only) is used when reading a file for transcoding.
157dd7cddfSDavid du Colombier  */
167dd7cddfSDavid du Colombier 
177dd7cddfSDavid du Colombier #define JPEG_INTERNALS
187dd7cddfSDavid du Colombier #include "jinclude.h"
197dd7cddfSDavid du Colombier #include "jpeglib.h"
207dd7cddfSDavid du Colombier 
217dd7cddfSDavid du Colombier /* Block smoothing is only applicable for progressive JPEG, so: */
227dd7cddfSDavid du Colombier #ifndef D_PROGRESSIVE_SUPPORTED
237dd7cddfSDavid du Colombier #undef BLOCK_SMOOTHING_SUPPORTED
247dd7cddfSDavid du Colombier #endif
257dd7cddfSDavid du Colombier 
267dd7cddfSDavid du Colombier /* Private buffer controller object */
277dd7cddfSDavid du Colombier 
287dd7cddfSDavid du Colombier typedef struct {
297dd7cddfSDavid du Colombier   struct jpeg_d_coef_controller pub; /* public fields */
307dd7cddfSDavid du Colombier 
317dd7cddfSDavid du Colombier   /* These variables keep track of the current location of the input side. */
327dd7cddfSDavid du Colombier   /* cinfo->input_iMCU_row is also used for this. */
337dd7cddfSDavid du Colombier   JDIMENSION MCU_ctr;		/* counts MCUs processed in current row */
347dd7cddfSDavid du Colombier   int MCU_vert_offset;		/* counts MCU rows within iMCU row */
357dd7cddfSDavid du Colombier   int MCU_rows_per_iMCU_row;	/* number of such rows needed */
367dd7cddfSDavid du Colombier 
377dd7cddfSDavid du Colombier   /* The output side's location is represented by cinfo->output_iMCU_row. */
387dd7cddfSDavid du Colombier 
397dd7cddfSDavid du Colombier   /* In single-pass modes, it's sufficient to buffer just one MCU.
407dd7cddfSDavid du Colombier    * We allocate a workspace of D_MAX_BLOCKS_IN_MCU coefficient blocks,
417dd7cddfSDavid du Colombier    * and let the entropy decoder write into that workspace each time.
427dd7cddfSDavid du Colombier    * (On 80x86, the workspace is FAR even though it's not really very big;
437dd7cddfSDavid du Colombier    * this is to keep the module interfaces unchanged when a large coefficient
447dd7cddfSDavid du Colombier    * buffer is necessary.)
457dd7cddfSDavid du Colombier    * In multi-pass modes, this array points to the current MCU's blocks
467dd7cddfSDavid du Colombier    * within the virtual arrays; it is used only by the input side.
477dd7cddfSDavid du Colombier    */
487dd7cddfSDavid du Colombier   JBLOCKROW MCU_buffer[D_MAX_BLOCKS_IN_MCU];
497dd7cddfSDavid du Colombier 
507dd7cddfSDavid du Colombier #ifdef D_MULTISCAN_FILES_SUPPORTED
517dd7cddfSDavid du Colombier   /* In multi-pass modes, we need a virtual block array for each component. */
527dd7cddfSDavid du Colombier   jvirt_barray_ptr whole_image[MAX_COMPONENTS];
537dd7cddfSDavid du Colombier #endif
547dd7cddfSDavid du Colombier 
557dd7cddfSDavid du Colombier #ifdef BLOCK_SMOOTHING_SUPPORTED
567dd7cddfSDavid du Colombier   /* When doing block smoothing, we latch coefficient Al values here */
577dd7cddfSDavid du Colombier   int * coef_bits_latch;
587dd7cddfSDavid du Colombier #define SAVED_COEFS  6		/* we save coef_bits[0..5] */
597dd7cddfSDavid du Colombier #endif
607dd7cddfSDavid du Colombier } my_coef_controller;
617dd7cddfSDavid du Colombier 
627dd7cddfSDavid du Colombier typedef my_coef_controller * my_coef_ptr;
637dd7cddfSDavid du Colombier 
647dd7cddfSDavid du Colombier /* Forward declarations */
657dd7cddfSDavid du Colombier METHODDEF(int) decompress_onepass
667dd7cddfSDavid du Colombier 	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
677dd7cddfSDavid du Colombier #ifdef D_MULTISCAN_FILES_SUPPORTED
687dd7cddfSDavid du Colombier METHODDEF(int) decompress_data
697dd7cddfSDavid du Colombier 	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
707dd7cddfSDavid du Colombier #endif
717dd7cddfSDavid du Colombier #ifdef BLOCK_SMOOTHING_SUPPORTED
727dd7cddfSDavid du Colombier LOCAL(boolean) smoothing_ok JPP((j_decompress_ptr cinfo));
737dd7cddfSDavid du Colombier METHODDEF(int) decompress_smooth_data
747dd7cddfSDavid du Colombier 	JPP((j_decompress_ptr cinfo, JSAMPIMAGE output_buf));
757dd7cddfSDavid du Colombier #endif
767dd7cddfSDavid du Colombier 
777dd7cddfSDavid du Colombier 
787dd7cddfSDavid du Colombier LOCAL(void)
start_iMCU_row(j_decompress_ptr cinfo)797dd7cddfSDavid du Colombier start_iMCU_row (j_decompress_ptr cinfo)
807dd7cddfSDavid du Colombier /* Reset within-iMCU-row counters for a new row (input side) */
817dd7cddfSDavid du Colombier {
827dd7cddfSDavid du Colombier   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
837dd7cddfSDavid du Colombier 
847dd7cddfSDavid du Colombier   /* In an interleaved scan, an MCU row is the same as an iMCU row.
857dd7cddfSDavid du Colombier    * In a noninterleaved scan, an iMCU row has v_samp_factor MCU rows.
867dd7cddfSDavid du Colombier    * But at the bottom of the image, process only what's left.
877dd7cddfSDavid du Colombier    */
887dd7cddfSDavid du Colombier   if (cinfo->comps_in_scan > 1) {
897dd7cddfSDavid du Colombier     coef->MCU_rows_per_iMCU_row = 1;
907dd7cddfSDavid du Colombier   } else {
917dd7cddfSDavid du Colombier     if (cinfo->input_iMCU_row < (cinfo->total_iMCU_rows-1))
927dd7cddfSDavid du Colombier       coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->v_samp_factor;
937dd7cddfSDavid du Colombier     else
947dd7cddfSDavid du Colombier       coef->MCU_rows_per_iMCU_row = cinfo->cur_comp_info[0]->last_row_height;
957dd7cddfSDavid du Colombier   }
967dd7cddfSDavid du Colombier 
977dd7cddfSDavid du Colombier   coef->MCU_ctr = 0;
987dd7cddfSDavid du Colombier   coef->MCU_vert_offset = 0;
997dd7cddfSDavid du Colombier }
1007dd7cddfSDavid du Colombier 
1017dd7cddfSDavid du Colombier 
1027dd7cddfSDavid du Colombier /*
1037dd7cddfSDavid du Colombier  * Initialize for an input processing pass.
1047dd7cddfSDavid du Colombier  */
1057dd7cddfSDavid du Colombier 
1067dd7cddfSDavid du Colombier METHODDEF(void)
start_input_pass(j_decompress_ptr cinfo)1077dd7cddfSDavid du Colombier start_input_pass (j_decompress_ptr cinfo)
1087dd7cddfSDavid du Colombier {
1097dd7cddfSDavid du Colombier   cinfo->input_iMCU_row = 0;
1107dd7cddfSDavid du Colombier   start_iMCU_row(cinfo);
1117dd7cddfSDavid du Colombier }
1127dd7cddfSDavid du Colombier 
1137dd7cddfSDavid du Colombier 
1147dd7cddfSDavid du Colombier /*
1157dd7cddfSDavid du Colombier  * Initialize for an output processing pass.
1167dd7cddfSDavid du Colombier  */
1177dd7cddfSDavid du Colombier 
1187dd7cddfSDavid du Colombier METHODDEF(void)
start_output_pass(j_decompress_ptr cinfo)1197dd7cddfSDavid du Colombier start_output_pass (j_decompress_ptr cinfo)
1207dd7cddfSDavid du Colombier {
1217dd7cddfSDavid du Colombier #ifdef BLOCK_SMOOTHING_SUPPORTED
1227dd7cddfSDavid du Colombier   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
1237dd7cddfSDavid du Colombier 
1247dd7cddfSDavid du Colombier   /* If multipass, check to see whether to use block smoothing on this pass */
1257dd7cddfSDavid du Colombier   if (coef->pub.coef_arrays != NULL) {
1267dd7cddfSDavid du Colombier     if (cinfo->do_block_smoothing && smoothing_ok(cinfo))
1277dd7cddfSDavid du Colombier       coef->pub.decompress_data = decompress_smooth_data;
1287dd7cddfSDavid du Colombier     else
1297dd7cddfSDavid du Colombier       coef->pub.decompress_data = decompress_data;
1307dd7cddfSDavid du Colombier   }
1317dd7cddfSDavid du Colombier #endif
1327dd7cddfSDavid du Colombier   cinfo->output_iMCU_row = 0;
1337dd7cddfSDavid du Colombier }
1347dd7cddfSDavid du Colombier 
1357dd7cddfSDavid du Colombier 
1367dd7cddfSDavid du Colombier /*
1377dd7cddfSDavid du Colombier  * Decompress and return some data in the single-pass case.
1387dd7cddfSDavid du Colombier  * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
1397dd7cddfSDavid du Colombier  * Input and output must run in lockstep since we have only a one-MCU buffer.
1407dd7cddfSDavid du Colombier  * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
1417dd7cddfSDavid du Colombier  *
142*593dc095SDavid du Colombier  * NB: output_buf contains a plane for each component in image,
143*593dc095SDavid du Colombier  * which we index according to the component's SOF position.
1447dd7cddfSDavid du Colombier  */
1457dd7cddfSDavid du Colombier 
1467dd7cddfSDavid du Colombier METHODDEF(int)
decompress_onepass(j_decompress_ptr cinfo,JSAMPIMAGE output_buf)1477dd7cddfSDavid du Colombier decompress_onepass (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
1487dd7cddfSDavid du Colombier {
1497dd7cddfSDavid du Colombier   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
1507dd7cddfSDavid du Colombier   JDIMENSION MCU_col_num;	/* index of current MCU within row */
1517dd7cddfSDavid du Colombier   JDIMENSION last_MCU_col = cinfo->MCUs_per_row - 1;
1527dd7cddfSDavid du Colombier   JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
1537dd7cddfSDavid du Colombier   int blkn, ci, xindex, yindex, yoffset, useful_width;
1547dd7cddfSDavid du Colombier   JSAMPARRAY output_ptr;
1557dd7cddfSDavid du Colombier   JDIMENSION start_col, output_col;
1567dd7cddfSDavid du Colombier   jpeg_component_info *compptr;
1577dd7cddfSDavid du Colombier   inverse_DCT_method_ptr inverse_DCT;
1587dd7cddfSDavid du Colombier 
1597dd7cddfSDavid du Colombier   /* Loop to process as much as one whole iMCU row */
1607dd7cddfSDavid du Colombier   for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
1617dd7cddfSDavid du Colombier        yoffset++) {
1627dd7cddfSDavid du Colombier     for (MCU_col_num = coef->MCU_ctr; MCU_col_num <= last_MCU_col;
1637dd7cddfSDavid du Colombier 	 MCU_col_num++) {
1647dd7cddfSDavid du Colombier       /* Try to fetch an MCU.  Entropy decoder expects buffer to be zeroed. */
1657dd7cddfSDavid du Colombier       jzero_far((void FAR *) coef->MCU_buffer[0],
1667dd7cddfSDavid du Colombier 		(size_t) (cinfo->blocks_in_MCU * SIZEOF(JBLOCK)));
1677dd7cddfSDavid du Colombier       if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
1687dd7cddfSDavid du Colombier 	/* Suspension forced; update state counters and exit */
1697dd7cddfSDavid du Colombier 	coef->MCU_vert_offset = yoffset;
1707dd7cddfSDavid du Colombier 	coef->MCU_ctr = MCU_col_num;
1717dd7cddfSDavid du Colombier 	return JPEG_SUSPENDED;
1727dd7cddfSDavid du Colombier       }
1737dd7cddfSDavid du Colombier       /* Determine where data should go in output_buf and do the IDCT thing.
1747dd7cddfSDavid du Colombier        * We skip dummy blocks at the right and bottom edges (but blkn gets
1757dd7cddfSDavid du Colombier        * incremented past them!).  Note the inner loop relies on having
1767dd7cddfSDavid du Colombier        * allocated the MCU_buffer[] blocks sequentially.
1777dd7cddfSDavid du Colombier        */
1787dd7cddfSDavid du Colombier       blkn = 0;			/* index of current DCT block within MCU */
1797dd7cddfSDavid du Colombier       for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
1807dd7cddfSDavid du Colombier 	compptr = cinfo->cur_comp_info[ci];
1817dd7cddfSDavid du Colombier 	/* Don't bother to IDCT an uninteresting component. */
1827dd7cddfSDavid du Colombier 	if (! compptr->component_needed) {
1837dd7cddfSDavid du Colombier 	  blkn += compptr->MCU_blocks;
1847dd7cddfSDavid du Colombier 	  continue;
1857dd7cddfSDavid du Colombier 	}
1867dd7cddfSDavid du Colombier 	inverse_DCT = cinfo->idct->inverse_DCT[compptr->component_index];
1877dd7cddfSDavid du Colombier 	useful_width = (MCU_col_num < last_MCU_col) ? compptr->MCU_width
1887dd7cddfSDavid du Colombier 						    : compptr->last_col_width;
189*593dc095SDavid du Colombier 	output_ptr = output_buf[compptr->component_index] +
190*593dc095SDavid du Colombier 	  yoffset * compptr->DCT_scaled_size;
1917dd7cddfSDavid du Colombier 	start_col = MCU_col_num * compptr->MCU_sample_width;
1927dd7cddfSDavid du Colombier 	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
1937dd7cddfSDavid du Colombier 	  if (cinfo->input_iMCU_row < last_iMCU_row ||
1947dd7cddfSDavid du Colombier 	      yoffset+yindex < compptr->last_row_height) {
1957dd7cddfSDavid du Colombier 	    output_col = start_col;
1967dd7cddfSDavid du Colombier 	    for (xindex = 0; xindex < useful_width; xindex++) {
1977dd7cddfSDavid du Colombier 	      (*inverse_DCT) (cinfo, compptr,
1987dd7cddfSDavid du Colombier 			      (JCOEFPTR) coef->MCU_buffer[blkn+xindex],
1997dd7cddfSDavid du Colombier 			      output_ptr, output_col);
2007dd7cddfSDavid du Colombier 	      output_col += compptr->DCT_scaled_size;
2017dd7cddfSDavid du Colombier 	    }
2027dd7cddfSDavid du Colombier 	  }
2037dd7cddfSDavid du Colombier 	  blkn += compptr->MCU_width;
2047dd7cddfSDavid du Colombier 	  output_ptr += compptr->DCT_scaled_size;
2057dd7cddfSDavid du Colombier 	}
2067dd7cddfSDavid du Colombier       }
2077dd7cddfSDavid du Colombier     }
2087dd7cddfSDavid du Colombier     /* Completed an MCU row, but perhaps not an iMCU row */
2097dd7cddfSDavid du Colombier     coef->MCU_ctr = 0;
2107dd7cddfSDavid du Colombier   }
2117dd7cddfSDavid du Colombier   /* Completed the iMCU row, advance counters for next one */
2127dd7cddfSDavid du Colombier   cinfo->output_iMCU_row++;
2137dd7cddfSDavid du Colombier   if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
2147dd7cddfSDavid du Colombier     start_iMCU_row(cinfo);
2157dd7cddfSDavid du Colombier     return JPEG_ROW_COMPLETED;
2167dd7cddfSDavid du Colombier   }
2177dd7cddfSDavid du Colombier   /* Completed the scan */
2187dd7cddfSDavid du Colombier   (*cinfo->inputctl->finish_input_pass) (cinfo);
2197dd7cddfSDavid du Colombier   return JPEG_SCAN_COMPLETED;
2207dd7cddfSDavid du Colombier }
2217dd7cddfSDavid du Colombier 
2227dd7cddfSDavid du Colombier 
2237dd7cddfSDavid du Colombier /*
2247dd7cddfSDavid du Colombier  * Dummy consume-input routine for single-pass operation.
2257dd7cddfSDavid du Colombier  */
2267dd7cddfSDavid du Colombier 
2277dd7cddfSDavid du Colombier METHODDEF(int)
dummy_consume_data(j_decompress_ptr cinfo)2287dd7cddfSDavid du Colombier dummy_consume_data (j_decompress_ptr cinfo)
2297dd7cddfSDavid du Colombier {
2307dd7cddfSDavid du Colombier   return JPEG_SUSPENDED;	/* Always indicate nothing was done */
2317dd7cddfSDavid du Colombier }
2327dd7cddfSDavid du Colombier 
2337dd7cddfSDavid du Colombier 
2347dd7cddfSDavid du Colombier #ifdef D_MULTISCAN_FILES_SUPPORTED
2357dd7cddfSDavid du Colombier 
2367dd7cddfSDavid du Colombier /*
2377dd7cddfSDavid du Colombier  * Consume input data and store it in the full-image coefficient buffer.
2387dd7cddfSDavid du Colombier  * We read as much as one fully interleaved MCU row ("iMCU" row) per call,
2397dd7cddfSDavid du Colombier  * ie, v_samp_factor block rows for each component in the scan.
2407dd7cddfSDavid du Colombier  * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
2417dd7cddfSDavid du Colombier  */
2427dd7cddfSDavid du Colombier 
2437dd7cddfSDavid du Colombier METHODDEF(int)
consume_data(j_decompress_ptr cinfo)2447dd7cddfSDavid du Colombier consume_data (j_decompress_ptr cinfo)
2457dd7cddfSDavid du Colombier {
2467dd7cddfSDavid du Colombier   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
2477dd7cddfSDavid du Colombier   JDIMENSION MCU_col_num;	/* index of current MCU within row */
2487dd7cddfSDavid du Colombier   int blkn, ci, xindex, yindex, yoffset;
2497dd7cddfSDavid du Colombier   JDIMENSION start_col;
2507dd7cddfSDavid du Colombier   JBLOCKARRAY buffer[MAX_COMPS_IN_SCAN];
2517dd7cddfSDavid du Colombier   JBLOCKROW buffer_ptr;
2527dd7cddfSDavid du Colombier   jpeg_component_info *compptr;
2537dd7cddfSDavid du Colombier 
2547dd7cddfSDavid du Colombier   /* Align the virtual buffers for the components used in this scan. */
2557dd7cddfSDavid du Colombier   for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
2567dd7cddfSDavid du Colombier     compptr = cinfo->cur_comp_info[ci];
2577dd7cddfSDavid du Colombier     buffer[ci] = (*cinfo->mem->access_virt_barray)
2587dd7cddfSDavid du Colombier       ((j_common_ptr) cinfo, coef->whole_image[compptr->component_index],
2597dd7cddfSDavid du Colombier        cinfo->input_iMCU_row * compptr->v_samp_factor,
2607dd7cddfSDavid du Colombier        (JDIMENSION) compptr->v_samp_factor, TRUE);
2617dd7cddfSDavid du Colombier     /* Note: entropy decoder expects buffer to be zeroed,
2627dd7cddfSDavid du Colombier      * but this is handled automatically by the memory manager
2637dd7cddfSDavid du Colombier      * because we requested a pre-zeroed array.
2647dd7cddfSDavid du Colombier      */
2657dd7cddfSDavid du Colombier   }
2667dd7cddfSDavid du Colombier 
2677dd7cddfSDavid du Colombier   /* Loop to process one whole iMCU row */
2687dd7cddfSDavid du Colombier   for (yoffset = coef->MCU_vert_offset; yoffset < coef->MCU_rows_per_iMCU_row;
2697dd7cddfSDavid du Colombier        yoffset++) {
2707dd7cddfSDavid du Colombier     for (MCU_col_num = coef->MCU_ctr; MCU_col_num < cinfo->MCUs_per_row;
2717dd7cddfSDavid du Colombier 	 MCU_col_num++) {
2727dd7cddfSDavid du Colombier       /* Construct list of pointers to DCT blocks belonging to this MCU */
2737dd7cddfSDavid du Colombier       blkn = 0;			/* index of current DCT block within MCU */
2747dd7cddfSDavid du Colombier       for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
2757dd7cddfSDavid du Colombier 	compptr = cinfo->cur_comp_info[ci];
2767dd7cddfSDavid du Colombier 	start_col = MCU_col_num * compptr->MCU_width;
2777dd7cddfSDavid du Colombier 	for (yindex = 0; yindex < compptr->MCU_height; yindex++) {
2787dd7cddfSDavid du Colombier 	  buffer_ptr = buffer[ci][yindex+yoffset] + start_col;
2797dd7cddfSDavid du Colombier 	  for (xindex = 0; xindex < compptr->MCU_width; xindex++) {
2807dd7cddfSDavid du Colombier 	    coef->MCU_buffer[blkn++] = buffer_ptr++;
2817dd7cddfSDavid du Colombier 	  }
2827dd7cddfSDavid du Colombier 	}
2837dd7cddfSDavid du Colombier       }
2847dd7cddfSDavid du Colombier       /* Try to fetch the MCU. */
2857dd7cddfSDavid du Colombier       if (! (*cinfo->entropy->decode_mcu) (cinfo, coef->MCU_buffer)) {
2867dd7cddfSDavid du Colombier 	/* Suspension forced; update state counters and exit */
2877dd7cddfSDavid du Colombier 	coef->MCU_vert_offset = yoffset;
2887dd7cddfSDavid du Colombier 	coef->MCU_ctr = MCU_col_num;
2897dd7cddfSDavid du Colombier 	return JPEG_SUSPENDED;
2907dd7cddfSDavid du Colombier       }
2917dd7cddfSDavid du Colombier     }
2927dd7cddfSDavid du Colombier     /* Completed an MCU row, but perhaps not an iMCU row */
2937dd7cddfSDavid du Colombier     coef->MCU_ctr = 0;
2947dd7cddfSDavid du Colombier   }
2957dd7cddfSDavid du Colombier   /* Completed the iMCU row, advance counters for next one */
2967dd7cddfSDavid du Colombier   if (++(cinfo->input_iMCU_row) < cinfo->total_iMCU_rows) {
2977dd7cddfSDavid du Colombier     start_iMCU_row(cinfo);
2987dd7cddfSDavid du Colombier     return JPEG_ROW_COMPLETED;
2997dd7cddfSDavid du Colombier   }
3007dd7cddfSDavid du Colombier   /* Completed the scan */
3017dd7cddfSDavid du Colombier   (*cinfo->inputctl->finish_input_pass) (cinfo);
3027dd7cddfSDavid du Colombier   return JPEG_SCAN_COMPLETED;
3037dd7cddfSDavid du Colombier }
3047dd7cddfSDavid du Colombier 
3057dd7cddfSDavid du Colombier 
3067dd7cddfSDavid du Colombier /*
3077dd7cddfSDavid du Colombier  * Decompress and return some data in the multi-pass case.
3087dd7cddfSDavid du Colombier  * Always attempts to emit one fully interleaved MCU row ("iMCU" row).
3097dd7cddfSDavid du Colombier  * Return value is JPEG_ROW_COMPLETED, JPEG_SCAN_COMPLETED, or JPEG_SUSPENDED.
3107dd7cddfSDavid du Colombier  *
3117dd7cddfSDavid du Colombier  * NB: output_buf contains a plane for each component in image.
3127dd7cddfSDavid du Colombier  */
3137dd7cddfSDavid du Colombier 
3147dd7cddfSDavid du Colombier METHODDEF(int)
decompress_data(j_decompress_ptr cinfo,JSAMPIMAGE output_buf)3157dd7cddfSDavid du Colombier decompress_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
3167dd7cddfSDavid du Colombier {
3177dd7cddfSDavid du Colombier   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
3187dd7cddfSDavid du Colombier   JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
3197dd7cddfSDavid du Colombier   JDIMENSION block_num;
3207dd7cddfSDavid du Colombier   int ci, block_row, block_rows;
3217dd7cddfSDavid du Colombier   JBLOCKARRAY buffer;
3227dd7cddfSDavid du Colombier   JBLOCKROW buffer_ptr;
3237dd7cddfSDavid du Colombier   JSAMPARRAY output_ptr;
3247dd7cddfSDavid du Colombier   JDIMENSION output_col;
3257dd7cddfSDavid du Colombier   jpeg_component_info *compptr;
3267dd7cddfSDavid du Colombier   inverse_DCT_method_ptr inverse_DCT;
3277dd7cddfSDavid du Colombier 
3287dd7cddfSDavid du Colombier   /* Force some input to be done if we are getting ahead of the input. */
3297dd7cddfSDavid du Colombier   while (cinfo->input_scan_number < cinfo->output_scan_number ||
3307dd7cddfSDavid du Colombier 	 (cinfo->input_scan_number == cinfo->output_scan_number &&
3317dd7cddfSDavid du Colombier 	  cinfo->input_iMCU_row <= cinfo->output_iMCU_row)) {
3327dd7cddfSDavid du Colombier     if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
3337dd7cddfSDavid du Colombier       return JPEG_SUSPENDED;
3347dd7cddfSDavid du Colombier   }
3357dd7cddfSDavid du Colombier 
3367dd7cddfSDavid du Colombier   /* OK, output from the virtual arrays. */
3377dd7cddfSDavid du Colombier   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
3387dd7cddfSDavid du Colombier        ci++, compptr++) {
3397dd7cddfSDavid du Colombier     /* Don't bother to IDCT an uninteresting component. */
3407dd7cddfSDavid du Colombier     if (! compptr->component_needed)
3417dd7cddfSDavid du Colombier       continue;
3427dd7cddfSDavid du Colombier     /* Align the virtual buffer for this component. */
3437dd7cddfSDavid du Colombier     buffer = (*cinfo->mem->access_virt_barray)
3447dd7cddfSDavid du Colombier       ((j_common_ptr) cinfo, coef->whole_image[ci],
3457dd7cddfSDavid du Colombier        cinfo->output_iMCU_row * compptr->v_samp_factor,
3467dd7cddfSDavid du Colombier        (JDIMENSION) compptr->v_samp_factor, FALSE);
3477dd7cddfSDavid du Colombier     /* Count non-dummy DCT block rows in this iMCU row. */
3487dd7cddfSDavid du Colombier     if (cinfo->output_iMCU_row < last_iMCU_row)
3497dd7cddfSDavid du Colombier       block_rows = compptr->v_samp_factor;
3507dd7cddfSDavid du Colombier     else {
3517dd7cddfSDavid du Colombier       /* NB: can't use last_row_height here; it is input-side-dependent! */
3527dd7cddfSDavid du Colombier       block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
3537dd7cddfSDavid du Colombier       if (block_rows == 0) block_rows = compptr->v_samp_factor;
3547dd7cddfSDavid du Colombier     }
3557dd7cddfSDavid du Colombier     inverse_DCT = cinfo->idct->inverse_DCT[ci];
3567dd7cddfSDavid du Colombier     output_ptr = output_buf[ci];
3577dd7cddfSDavid du Colombier     /* Loop over all DCT blocks to be processed. */
3587dd7cddfSDavid du Colombier     for (block_row = 0; block_row < block_rows; block_row++) {
3597dd7cddfSDavid du Colombier       buffer_ptr = buffer[block_row];
3607dd7cddfSDavid du Colombier       output_col = 0;
3617dd7cddfSDavid du Colombier       for (block_num = 0; block_num < compptr->width_in_blocks; block_num++) {
3627dd7cddfSDavid du Colombier 	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) buffer_ptr,
3637dd7cddfSDavid du Colombier 			output_ptr, output_col);
3647dd7cddfSDavid du Colombier 	buffer_ptr++;
3657dd7cddfSDavid du Colombier 	output_col += compptr->DCT_scaled_size;
3667dd7cddfSDavid du Colombier       }
3677dd7cddfSDavid du Colombier       output_ptr += compptr->DCT_scaled_size;
3687dd7cddfSDavid du Colombier     }
3697dd7cddfSDavid du Colombier   }
3707dd7cddfSDavid du Colombier 
3717dd7cddfSDavid du Colombier   if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
3727dd7cddfSDavid du Colombier     return JPEG_ROW_COMPLETED;
3737dd7cddfSDavid du Colombier   return JPEG_SCAN_COMPLETED;
3747dd7cddfSDavid du Colombier }
3757dd7cddfSDavid du Colombier 
3767dd7cddfSDavid du Colombier #endif /* D_MULTISCAN_FILES_SUPPORTED */
3777dd7cddfSDavid du Colombier 
3787dd7cddfSDavid du Colombier 
3797dd7cddfSDavid du Colombier #ifdef BLOCK_SMOOTHING_SUPPORTED
3807dd7cddfSDavid du Colombier 
3817dd7cddfSDavid du Colombier /*
3827dd7cddfSDavid du Colombier  * This code applies interblock smoothing as described by section K.8
3837dd7cddfSDavid du Colombier  * of the JPEG standard: the first 5 AC coefficients are estimated from
3847dd7cddfSDavid du Colombier  * the DC values of a DCT block and its 8 neighboring blocks.
3857dd7cddfSDavid du Colombier  * We apply smoothing only for progressive JPEG decoding, and only if
3867dd7cddfSDavid du Colombier  * the coefficients it can estimate are not yet known to full precision.
3877dd7cddfSDavid du Colombier  */
3887dd7cddfSDavid du Colombier 
3897dd7cddfSDavid du Colombier /* Natural-order array positions of the first 5 zigzag-order coefficients */
3907dd7cddfSDavid du Colombier #define Q01_POS  1
3917dd7cddfSDavid du Colombier #define Q10_POS  8
3927dd7cddfSDavid du Colombier #define Q20_POS  16
3937dd7cddfSDavid du Colombier #define Q11_POS  9
3947dd7cddfSDavid du Colombier #define Q02_POS  2
3957dd7cddfSDavid du Colombier 
3967dd7cddfSDavid du Colombier /*
3977dd7cddfSDavid du Colombier  * Determine whether block smoothing is applicable and safe.
3987dd7cddfSDavid du Colombier  * We also latch the current states of the coef_bits[] entries for the
3997dd7cddfSDavid du Colombier  * AC coefficients; otherwise, if the input side of the decompressor
4007dd7cddfSDavid du Colombier  * advances into a new scan, we might think the coefficients are known
4017dd7cddfSDavid du Colombier  * more accurately than they really are.
4027dd7cddfSDavid du Colombier  */
4037dd7cddfSDavid du Colombier 
4047dd7cddfSDavid du Colombier LOCAL(boolean)
smoothing_ok(j_decompress_ptr cinfo)4057dd7cddfSDavid du Colombier smoothing_ok (j_decompress_ptr cinfo)
4067dd7cddfSDavid du Colombier {
4077dd7cddfSDavid du Colombier   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
4087dd7cddfSDavid du Colombier   boolean smoothing_useful = FALSE;
4097dd7cddfSDavid du Colombier   int ci, coefi;
4107dd7cddfSDavid du Colombier   jpeg_component_info *compptr;
4117dd7cddfSDavid du Colombier   JQUANT_TBL * qtable;
4127dd7cddfSDavid du Colombier   int * coef_bits;
4137dd7cddfSDavid du Colombier   int * coef_bits_latch;
4147dd7cddfSDavid du Colombier 
4157dd7cddfSDavid du Colombier   if (! cinfo->progressive_mode || cinfo->coef_bits == NULL)
4167dd7cddfSDavid du Colombier     return FALSE;
4177dd7cddfSDavid du Colombier 
4187dd7cddfSDavid du Colombier   /* Allocate latch area if not already done */
4197dd7cddfSDavid du Colombier   if (coef->coef_bits_latch == NULL)
4207dd7cddfSDavid du Colombier     coef->coef_bits_latch = (int *)
4217dd7cddfSDavid du Colombier       (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
4227dd7cddfSDavid du Colombier 				  cinfo->num_components *
4237dd7cddfSDavid du Colombier 				  (SAVED_COEFS * SIZEOF(int)));
4247dd7cddfSDavid du Colombier   coef_bits_latch = coef->coef_bits_latch;
4257dd7cddfSDavid du Colombier 
4267dd7cddfSDavid du Colombier   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
4277dd7cddfSDavid du Colombier        ci++, compptr++) {
4287dd7cddfSDavid du Colombier     /* All components' quantization values must already be latched. */
4297dd7cddfSDavid du Colombier     if ((qtable = compptr->quant_table) == NULL)
4307dd7cddfSDavid du Colombier       return FALSE;
4317dd7cddfSDavid du Colombier     /* Verify DC & first 5 AC quantizers are nonzero to avoid zero-divide. */
4327dd7cddfSDavid du Colombier     if (qtable->quantval[0] == 0 ||
4337dd7cddfSDavid du Colombier 	qtable->quantval[Q01_POS] == 0 ||
4347dd7cddfSDavid du Colombier 	qtable->quantval[Q10_POS] == 0 ||
4357dd7cddfSDavid du Colombier 	qtable->quantval[Q20_POS] == 0 ||
4367dd7cddfSDavid du Colombier 	qtable->quantval[Q11_POS] == 0 ||
4377dd7cddfSDavid du Colombier 	qtable->quantval[Q02_POS] == 0)
4387dd7cddfSDavid du Colombier       return FALSE;
4397dd7cddfSDavid du Colombier     /* DC values must be at least partly known for all components. */
4407dd7cddfSDavid du Colombier     coef_bits = cinfo->coef_bits[ci];
4417dd7cddfSDavid du Colombier     if (coef_bits[0] < 0)
4427dd7cddfSDavid du Colombier       return FALSE;
4437dd7cddfSDavid du Colombier     /* Block smoothing is helpful if some AC coefficients remain inaccurate. */
4447dd7cddfSDavid du Colombier     for (coefi = 1; coefi <= 5; coefi++) {
4457dd7cddfSDavid du Colombier       coef_bits_latch[coefi] = coef_bits[coefi];
4467dd7cddfSDavid du Colombier       if (coef_bits[coefi] != 0)
4477dd7cddfSDavid du Colombier 	smoothing_useful = TRUE;
4487dd7cddfSDavid du Colombier     }
4497dd7cddfSDavid du Colombier     coef_bits_latch += SAVED_COEFS;
4507dd7cddfSDavid du Colombier   }
4517dd7cddfSDavid du Colombier 
4527dd7cddfSDavid du Colombier   return smoothing_useful;
4537dd7cddfSDavid du Colombier }
4547dd7cddfSDavid du Colombier 
4557dd7cddfSDavid du Colombier 
4567dd7cddfSDavid du Colombier /*
4577dd7cddfSDavid du Colombier  * Variant of decompress_data for use when doing block smoothing.
4587dd7cddfSDavid du Colombier  */
4597dd7cddfSDavid du Colombier 
4607dd7cddfSDavid du Colombier METHODDEF(int)
decompress_smooth_data(j_decompress_ptr cinfo,JSAMPIMAGE output_buf)4617dd7cddfSDavid du Colombier decompress_smooth_data (j_decompress_ptr cinfo, JSAMPIMAGE output_buf)
4627dd7cddfSDavid du Colombier {
4637dd7cddfSDavid du Colombier   my_coef_ptr coef = (my_coef_ptr) cinfo->coef;
4647dd7cddfSDavid du Colombier   JDIMENSION last_iMCU_row = cinfo->total_iMCU_rows - 1;
4657dd7cddfSDavid du Colombier   JDIMENSION block_num, last_block_column;
4667dd7cddfSDavid du Colombier   int ci, block_row, block_rows, access_rows;
4677dd7cddfSDavid du Colombier   JBLOCKARRAY buffer;
4687dd7cddfSDavid du Colombier   JBLOCKROW buffer_ptr, prev_block_row, next_block_row;
4697dd7cddfSDavid du Colombier   JSAMPARRAY output_ptr;
4707dd7cddfSDavid du Colombier   JDIMENSION output_col;
4717dd7cddfSDavid du Colombier   jpeg_component_info *compptr;
4727dd7cddfSDavid du Colombier   inverse_DCT_method_ptr inverse_DCT;
4737dd7cddfSDavid du Colombier   boolean first_row, last_row;
4747dd7cddfSDavid du Colombier   JBLOCK workspace;
4757dd7cddfSDavid du Colombier   int *coef_bits;
4767dd7cddfSDavid du Colombier   JQUANT_TBL *quanttbl;
4777dd7cddfSDavid du Colombier   INT32 Q00,Q01,Q02,Q10,Q11,Q20, num;
4787dd7cddfSDavid du Colombier   int DC1,DC2,DC3,DC4,DC5,DC6,DC7,DC8,DC9;
4797dd7cddfSDavid du Colombier   int Al, pred;
4807dd7cddfSDavid du Colombier 
4817dd7cddfSDavid du Colombier   /* Force some input to be done if we are getting ahead of the input. */
4827dd7cddfSDavid du Colombier   while (cinfo->input_scan_number <= cinfo->output_scan_number &&
4837dd7cddfSDavid du Colombier 	 ! cinfo->inputctl->eoi_reached) {
4847dd7cddfSDavid du Colombier     if (cinfo->input_scan_number == cinfo->output_scan_number) {
4857dd7cddfSDavid du Colombier       /* If input is working on current scan, we ordinarily want it to
4867dd7cddfSDavid du Colombier        * have completed the current row.  But if input scan is DC,
4877dd7cddfSDavid du Colombier        * we want it to keep one row ahead so that next block row's DC
4887dd7cddfSDavid du Colombier        * values are up to date.
4897dd7cddfSDavid du Colombier        */
4907dd7cddfSDavid du Colombier       JDIMENSION delta = (cinfo->Ss == 0) ? 1 : 0;
4917dd7cddfSDavid du Colombier       if (cinfo->input_iMCU_row > cinfo->output_iMCU_row+delta)
4927dd7cddfSDavid du Colombier 	break;
4937dd7cddfSDavid du Colombier     }
4947dd7cddfSDavid du Colombier     if ((*cinfo->inputctl->consume_input)(cinfo) == JPEG_SUSPENDED)
4957dd7cddfSDavid du Colombier       return JPEG_SUSPENDED;
4967dd7cddfSDavid du Colombier   }
4977dd7cddfSDavid du Colombier 
4987dd7cddfSDavid du Colombier   /* OK, output from the virtual arrays. */
4997dd7cddfSDavid du Colombier   for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
5007dd7cddfSDavid du Colombier        ci++, compptr++) {
5017dd7cddfSDavid du Colombier     /* Don't bother to IDCT an uninteresting component. */
5027dd7cddfSDavid du Colombier     if (! compptr->component_needed)
5037dd7cddfSDavid du Colombier       continue;
5047dd7cddfSDavid du Colombier     /* Count non-dummy DCT block rows in this iMCU row. */
5057dd7cddfSDavid du Colombier     if (cinfo->output_iMCU_row < last_iMCU_row) {
5067dd7cddfSDavid du Colombier       block_rows = compptr->v_samp_factor;
5077dd7cddfSDavid du Colombier       access_rows = block_rows * 2; /* this and next iMCU row */
5087dd7cddfSDavid du Colombier       last_row = FALSE;
5097dd7cddfSDavid du Colombier     } else {
5107dd7cddfSDavid du Colombier       /* NB: can't use last_row_height here; it is input-side-dependent! */
5117dd7cddfSDavid du Colombier       block_rows = (int) (compptr->height_in_blocks % compptr->v_samp_factor);
5127dd7cddfSDavid du Colombier       if (block_rows == 0) block_rows = compptr->v_samp_factor;
5137dd7cddfSDavid du Colombier       access_rows = block_rows; /* this iMCU row only */
5147dd7cddfSDavid du Colombier       last_row = TRUE;
5157dd7cddfSDavid du Colombier     }
5167dd7cddfSDavid du Colombier     /* Align the virtual buffer for this component. */
5177dd7cddfSDavid du Colombier     if (cinfo->output_iMCU_row > 0) {
5187dd7cddfSDavid du Colombier       access_rows += compptr->v_samp_factor; /* prior iMCU row too */
5197dd7cddfSDavid du Colombier       buffer = (*cinfo->mem->access_virt_barray)
5207dd7cddfSDavid du Colombier 	((j_common_ptr) cinfo, coef->whole_image[ci],
5217dd7cddfSDavid du Colombier 	 (cinfo->output_iMCU_row - 1) * compptr->v_samp_factor,
5227dd7cddfSDavid du Colombier 	 (JDIMENSION) access_rows, FALSE);
5237dd7cddfSDavid du Colombier       buffer += compptr->v_samp_factor;	/* point to current iMCU row */
5247dd7cddfSDavid du Colombier       first_row = FALSE;
5257dd7cddfSDavid du Colombier     } else {
5267dd7cddfSDavid du Colombier       buffer = (*cinfo->mem->access_virt_barray)
5277dd7cddfSDavid du Colombier 	((j_common_ptr) cinfo, coef->whole_image[ci],
5287dd7cddfSDavid du Colombier 	 (JDIMENSION) 0, (JDIMENSION) access_rows, FALSE);
5297dd7cddfSDavid du Colombier       first_row = TRUE;
5307dd7cddfSDavid du Colombier     }
5317dd7cddfSDavid du Colombier     /* Fetch component-dependent info */
5327dd7cddfSDavid du Colombier     coef_bits = coef->coef_bits_latch + (ci * SAVED_COEFS);
5337dd7cddfSDavid du Colombier     quanttbl = compptr->quant_table;
5347dd7cddfSDavid du Colombier     Q00 = quanttbl->quantval[0];
5357dd7cddfSDavid du Colombier     Q01 = quanttbl->quantval[Q01_POS];
5367dd7cddfSDavid du Colombier     Q10 = quanttbl->quantval[Q10_POS];
5377dd7cddfSDavid du Colombier     Q20 = quanttbl->quantval[Q20_POS];
5387dd7cddfSDavid du Colombier     Q11 = quanttbl->quantval[Q11_POS];
5397dd7cddfSDavid du Colombier     Q02 = quanttbl->quantval[Q02_POS];
5407dd7cddfSDavid du Colombier     inverse_DCT = cinfo->idct->inverse_DCT[ci];
5417dd7cddfSDavid du Colombier     output_ptr = output_buf[ci];
5427dd7cddfSDavid du Colombier     /* Loop over all DCT blocks to be processed. */
5437dd7cddfSDavid du Colombier     for (block_row = 0; block_row < block_rows; block_row++) {
5447dd7cddfSDavid du Colombier       buffer_ptr = buffer[block_row];
5457dd7cddfSDavid du Colombier       if (first_row && block_row == 0)
5467dd7cddfSDavid du Colombier 	prev_block_row = buffer_ptr;
5477dd7cddfSDavid du Colombier       else
5487dd7cddfSDavid du Colombier 	prev_block_row = buffer[block_row-1];
5497dd7cddfSDavid du Colombier       if (last_row && block_row == block_rows-1)
5507dd7cddfSDavid du Colombier 	next_block_row = buffer_ptr;
5517dd7cddfSDavid du Colombier       else
5527dd7cddfSDavid du Colombier 	next_block_row = buffer[block_row+1];
5537dd7cddfSDavid du Colombier       /* We fetch the surrounding DC values using a sliding-register approach.
5547dd7cddfSDavid du Colombier        * Initialize all nine here so as to do the right thing on narrow pics.
5557dd7cddfSDavid du Colombier        */
5567dd7cddfSDavid du Colombier       DC1 = DC2 = DC3 = (int) prev_block_row[0][0];
5577dd7cddfSDavid du Colombier       DC4 = DC5 = DC6 = (int) buffer_ptr[0][0];
5587dd7cddfSDavid du Colombier       DC7 = DC8 = DC9 = (int) next_block_row[0][0];
5597dd7cddfSDavid du Colombier       output_col = 0;
5607dd7cddfSDavid du Colombier       last_block_column = compptr->width_in_blocks - 1;
5617dd7cddfSDavid du Colombier       for (block_num = 0; block_num <= last_block_column; block_num++) {
5627dd7cddfSDavid du Colombier 	/* Fetch current DCT block into workspace so we can modify it. */
5637dd7cddfSDavid du Colombier 	jcopy_block_row(buffer_ptr, (JBLOCKROW) workspace, (JDIMENSION) 1);
5647dd7cddfSDavid du Colombier 	/* Update DC values */
5657dd7cddfSDavid du Colombier 	if (block_num < last_block_column) {
5667dd7cddfSDavid du Colombier 	  DC3 = (int) prev_block_row[1][0];
5677dd7cddfSDavid du Colombier 	  DC6 = (int) buffer_ptr[1][0];
5687dd7cddfSDavid du Colombier 	  DC9 = (int) next_block_row[1][0];
5697dd7cddfSDavid du Colombier 	}
5707dd7cddfSDavid du Colombier 	/* Compute coefficient estimates per K.8.
5717dd7cddfSDavid du Colombier 	 * An estimate is applied only if coefficient is still zero,
5727dd7cddfSDavid du Colombier 	 * and is not known to be fully accurate.
5737dd7cddfSDavid du Colombier 	 */
5747dd7cddfSDavid du Colombier 	/* AC01 */
5757dd7cddfSDavid du Colombier 	if ((Al=coef_bits[1]) != 0 && workspace[1] == 0) {
5767dd7cddfSDavid du Colombier 	  num = 36 * Q00 * (DC4 - DC6);
5777dd7cddfSDavid du Colombier 	  if (num >= 0) {
5787dd7cddfSDavid du Colombier 	    pred = (int) (((Q01<<7) + num) / (Q01<<8));
5797dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
5807dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
5817dd7cddfSDavid du Colombier 	  } else {
5827dd7cddfSDavid du Colombier 	    pred = (int) (((Q01<<7) - num) / (Q01<<8));
5837dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
5847dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
5857dd7cddfSDavid du Colombier 	    pred = -pred;
5867dd7cddfSDavid du Colombier 	  }
5877dd7cddfSDavid du Colombier 	  workspace[1] = (JCOEF) pred;
5887dd7cddfSDavid du Colombier 	}
5897dd7cddfSDavid du Colombier 	/* AC10 */
5907dd7cddfSDavid du Colombier 	if ((Al=coef_bits[2]) != 0 && workspace[8] == 0) {
5917dd7cddfSDavid du Colombier 	  num = 36 * Q00 * (DC2 - DC8);
5927dd7cddfSDavid du Colombier 	  if (num >= 0) {
5937dd7cddfSDavid du Colombier 	    pred = (int) (((Q10<<7) + num) / (Q10<<8));
5947dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
5957dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
5967dd7cddfSDavid du Colombier 	  } else {
5977dd7cddfSDavid du Colombier 	    pred = (int) (((Q10<<7) - num) / (Q10<<8));
5987dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
5997dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
6007dd7cddfSDavid du Colombier 	    pred = -pred;
6017dd7cddfSDavid du Colombier 	  }
6027dd7cddfSDavid du Colombier 	  workspace[8] = (JCOEF) pred;
6037dd7cddfSDavid du Colombier 	}
6047dd7cddfSDavid du Colombier 	/* AC20 */
6057dd7cddfSDavid du Colombier 	if ((Al=coef_bits[3]) != 0 && workspace[16] == 0) {
6067dd7cddfSDavid du Colombier 	  num = 9 * Q00 * (DC2 + DC8 - 2*DC5);
6077dd7cddfSDavid du Colombier 	  if (num >= 0) {
6087dd7cddfSDavid du Colombier 	    pred = (int) (((Q20<<7) + num) / (Q20<<8));
6097dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
6107dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
6117dd7cddfSDavid du Colombier 	  } else {
6127dd7cddfSDavid du Colombier 	    pred = (int) (((Q20<<7) - num) / (Q20<<8));
6137dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
6147dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
6157dd7cddfSDavid du Colombier 	    pred = -pred;
6167dd7cddfSDavid du Colombier 	  }
6177dd7cddfSDavid du Colombier 	  workspace[16] = (JCOEF) pred;
6187dd7cddfSDavid du Colombier 	}
6197dd7cddfSDavid du Colombier 	/* AC11 */
6207dd7cddfSDavid du Colombier 	if ((Al=coef_bits[4]) != 0 && workspace[9] == 0) {
6217dd7cddfSDavid du Colombier 	  num = 5 * Q00 * (DC1 - DC3 - DC7 + DC9);
6227dd7cddfSDavid du Colombier 	  if (num >= 0) {
6237dd7cddfSDavid du Colombier 	    pred = (int) (((Q11<<7) + num) / (Q11<<8));
6247dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
6257dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
6267dd7cddfSDavid du Colombier 	  } else {
6277dd7cddfSDavid du Colombier 	    pred = (int) (((Q11<<7) - num) / (Q11<<8));
6287dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
6297dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
6307dd7cddfSDavid du Colombier 	    pred = -pred;
6317dd7cddfSDavid du Colombier 	  }
6327dd7cddfSDavid du Colombier 	  workspace[9] = (JCOEF) pred;
6337dd7cddfSDavid du Colombier 	}
6347dd7cddfSDavid du Colombier 	/* AC02 */
6357dd7cddfSDavid du Colombier 	if ((Al=coef_bits[5]) != 0 && workspace[2] == 0) {
6367dd7cddfSDavid du Colombier 	  num = 9 * Q00 * (DC4 + DC6 - 2*DC5);
6377dd7cddfSDavid du Colombier 	  if (num >= 0) {
6387dd7cddfSDavid du Colombier 	    pred = (int) (((Q02<<7) + num) / (Q02<<8));
6397dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
6407dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
6417dd7cddfSDavid du Colombier 	  } else {
6427dd7cddfSDavid du Colombier 	    pred = (int) (((Q02<<7) - num) / (Q02<<8));
6437dd7cddfSDavid du Colombier 	    if (Al > 0 && pred >= (1<<Al))
6447dd7cddfSDavid du Colombier 	      pred = (1<<Al)-1;
6457dd7cddfSDavid du Colombier 	    pred = -pred;
6467dd7cddfSDavid du Colombier 	  }
6477dd7cddfSDavid du Colombier 	  workspace[2] = (JCOEF) pred;
6487dd7cddfSDavid du Colombier 	}
6497dd7cddfSDavid du Colombier 	/* OK, do the IDCT */
6507dd7cddfSDavid du Colombier 	(*inverse_DCT) (cinfo, compptr, (JCOEFPTR) workspace,
6517dd7cddfSDavid du Colombier 			output_ptr, output_col);
6527dd7cddfSDavid du Colombier 	/* Advance for next column */
6537dd7cddfSDavid du Colombier 	DC1 = DC2; DC2 = DC3;
6547dd7cddfSDavid du Colombier 	DC4 = DC5; DC5 = DC6;
6557dd7cddfSDavid du Colombier 	DC7 = DC8; DC8 = DC9;
6567dd7cddfSDavid du Colombier 	buffer_ptr++, prev_block_row++, next_block_row++;
6577dd7cddfSDavid du Colombier 	output_col += compptr->DCT_scaled_size;
6587dd7cddfSDavid du Colombier       }
6597dd7cddfSDavid du Colombier       output_ptr += compptr->DCT_scaled_size;
6607dd7cddfSDavid du Colombier     }
6617dd7cddfSDavid du Colombier   }
6627dd7cddfSDavid du Colombier 
6637dd7cddfSDavid du Colombier   if (++(cinfo->output_iMCU_row) < cinfo->total_iMCU_rows)
6647dd7cddfSDavid du Colombier     return JPEG_ROW_COMPLETED;
6657dd7cddfSDavid du Colombier   return JPEG_SCAN_COMPLETED;
6667dd7cddfSDavid du Colombier }
6677dd7cddfSDavid du Colombier 
6687dd7cddfSDavid du Colombier #endif /* BLOCK_SMOOTHING_SUPPORTED */
6697dd7cddfSDavid du Colombier 
6707dd7cddfSDavid du Colombier 
6717dd7cddfSDavid du Colombier /*
6727dd7cddfSDavid du Colombier  * Initialize coefficient buffer controller.
6737dd7cddfSDavid du Colombier  */
6747dd7cddfSDavid du Colombier 
6757dd7cddfSDavid du Colombier GLOBAL(void)
jinit_d_coef_controller(j_decompress_ptr cinfo,boolean need_full_buffer)6767dd7cddfSDavid du Colombier jinit_d_coef_controller (j_decompress_ptr cinfo, boolean need_full_buffer)
6777dd7cddfSDavid du Colombier {
6787dd7cddfSDavid du Colombier   my_coef_ptr coef;
6797dd7cddfSDavid du Colombier 
6807dd7cddfSDavid du Colombier   coef = (my_coef_ptr)
6817dd7cddfSDavid du Colombier     (*cinfo->mem->alloc_small) ((j_common_ptr) cinfo, JPOOL_IMAGE,
6827dd7cddfSDavid du Colombier 				SIZEOF(my_coef_controller));
6837dd7cddfSDavid du Colombier   cinfo->coef = (struct jpeg_d_coef_controller *) coef;
6847dd7cddfSDavid du Colombier   coef->pub.start_input_pass = start_input_pass;
6857dd7cddfSDavid du Colombier   coef->pub.start_output_pass = start_output_pass;
6867dd7cddfSDavid du Colombier #ifdef BLOCK_SMOOTHING_SUPPORTED
6877dd7cddfSDavid du Colombier   coef->coef_bits_latch = NULL;
6887dd7cddfSDavid du Colombier #endif
6897dd7cddfSDavid du Colombier 
6907dd7cddfSDavid du Colombier   /* Create the coefficient buffer. */
6917dd7cddfSDavid du Colombier   if (need_full_buffer) {
6927dd7cddfSDavid du Colombier #ifdef D_MULTISCAN_FILES_SUPPORTED
6937dd7cddfSDavid du Colombier     /* Allocate a full-image virtual array for each component, */
6947dd7cddfSDavid du Colombier     /* padded to a multiple of samp_factor DCT blocks in each direction. */
6957dd7cddfSDavid du Colombier     /* Note we ask for a pre-zeroed array. */
6967dd7cddfSDavid du Colombier     int ci, access_rows;
6977dd7cddfSDavid du Colombier     jpeg_component_info *compptr;
6987dd7cddfSDavid du Colombier 
6997dd7cddfSDavid du Colombier     for (ci = 0, compptr = cinfo->comp_info; ci < cinfo->num_components;
7007dd7cddfSDavid du Colombier 	 ci++, compptr++) {
7017dd7cddfSDavid du Colombier       access_rows = compptr->v_samp_factor;
7027dd7cddfSDavid du Colombier #ifdef BLOCK_SMOOTHING_SUPPORTED
7037dd7cddfSDavid du Colombier       /* If block smoothing could be used, need a bigger window */
7047dd7cddfSDavid du Colombier       if (cinfo->progressive_mode)
7057dd7cddfSDavid du Colombier 	access_rows *= 3;
7067dd7cddfSDavid du Colombier #endif
7077dd7cddfSDavid du Colombier       coef->whole_image[ci] = (*cinfo->mem->request_virt_barray)
7087dd7cddfSDavid du Colombier 	((j_common_ptr) cinfo, JPOOL_IMAGE, TRUE,
7097dd7cddfSDavid du Colombier 	 (JDIMENSION) jround_up((long) compptr->width_in_blocks,
7107dd7cddfSDavid du Colombier 				(long) compptr->h_samp_factor),
7117dd7cddfSDavid du Colombier 	 (JDIMENSION) jround_up((long) compptr->height_in_blocks,
7127dd7cddfSDavid du Colombier 				(long) compptr->v_samp_factor),
7137dd7cddfSDavid du Colombier 	 (JDIMENSION) access_rows);
7147dd7cddfSDavid du Colombier     }
7157dd7cddfSDavid du Colombier     coef->pub.consume_data = consume_data;
7167dd7cddfSDavid du Colombier     coef->pub.decompress_data = decompress_data;
7177dd7cddfSDavid du Colombier     coef->pub.coef_arrays = coef->whole_image; /* link to virtual arrays */
7187dd7cddfSDavid du Colombier #else
7197dd7cddfSDavid du Colombier     ERREXIT(cinfo, JERR_NOT_COMPILED);
7207dd7cddfSDavid du Colombier #endif
7217dd7cddfSDavid du Colombier   } else {
7227dd7cddfSDavid du Colombier     /* We only need a single-MCU buffer. */
7237dd7cddfSDavid du Colombier     JBLOCKROW buffer;
7247dd7cddfSDavid du Colombier     int i;
7257dd7cddfSDavid du Colombier 
7267dd7cddfSDavid du Colombier     buffer = (JBLOCKROW)
7277dd7cddfSDavid du Colombier       (*cinfo->mem->alloc_large) ((j_common_ptr) cinfo, JPOOL_IMAGE,
7287dd7cddfSDavid du Colombier 				  D_MAX_BLOCKS_IN_MCU * SIZEOF(JBLOCK));
7297dd7cddfSDavid du Colombier     for (i = 0; i < D_MAX_BLOCKS_IN_MCU; i++) {
7307dd7cddfSDavid du Colombier       coef->MCU_buffer[i] = buffer + i;
7317dd7cddfSDavid du Colombier     }
7327dd7cddfSDavid du Colombier     coef->pub.consume_data = dummy_consume_data;
7337dd7cddfSDavid du Colombier     coef->pub.decompress_data = decompress_onepass;
7347dd7cddfSDavid du Colombier     coef->pub.coef_arrays = NULL; /* flag for no virtual arrays */
7357dd7cddfSDavid du Colombier   }
7367dd7cddfSDavid du Colombier }
737