diff options
author | Joseph Wen <josephwen@google.com> | 2010-08-20 18:42:27 +0800 |
---|---|---|
committer | Joseph Wen <josephwen@google.com> | 2010-08-23 17:13:55 +0800 |
commit | cc66ecf44d1407039b05ffd7b3342389f95c17b7 (patch) | |
tree | 2fd8321368159d17aa35fe6311e7cfe5cfc356d6 | |
parent | f5b94eebe742df1a9bb3941fc0a0ec0137e936ef (diff) | |
download | jpeg-cc66ecf44d1407039b05ffd7b3342389f95c17b7.tar.gz |
Fix a bug related to tile based decoding
When the sample size is larger than 1.
The calculation of image's height and width should be rounding up not down.
Change-Id: I6c2ad1f630d1f8f9392594887e23f294ecde2352
-rw-r--r-- | jdapistd.c | 35 | ||||
-rw-r--r-- | jdcoefct.c | 5 | ||||
-rw-r--r-- | jdhuff.c | 1 | ||||
-rw-r--r-- | jdmaster.c | 9 | ||||
-rw-r--r-- | jpeglib.h | 4 |
5 files changed, 28 insertions, 26 deletions
@@ -204,7 +204,8 @@ jpeg_read_scanlines (j_decompress_ptr cinfo, JSAMPARRAY scanlines, * Initialize the jpeg decoder to decompressing a rectangle with size of (width, height) * and its upper-left corner located at (start_x, start_y). * Align start_x and start_y to multiplies of iMCU width and height, respectively. - * Also, the new reader position will be returned in (start_x, start_y). + * Also, the new reader position and sampled image size will be returned in + * (start_x, start_y) and (width, height), respectively. */ GLOBAL(void) @@ -217,15 +218,15 @@ jpeg_init_read_tile_scanline(j_decompress_ptr cinfo, huffman_index *index, int row_offset = *start_y / lines_per_iMCU_row; int col_left_boundary = ((*start_x / lines_per_iMCU_col) / index->MCU_sample_size) * index->MCU_sample_size; - int col_right_boundary = (*start_x + *width + lines_per_iMCU_col - 1) - / lines_per_iMCU_col; + int col_right_boundary = + jdiv_round_up(*start_x + *width, lines_per_iMCU_col); *height = (*start_y - row_offset * lines_per_iMCU_row) + *height; *start_x = col_left_boundary * lines_per_iMCU_col; *start_y = row_offset * lines_per_iMCU_row; - cinfo->image_width = jmin(cinfo->original_image_width - - col_left_boundary * lines_per_iMCU_col, - (col_right_boundary - col_left_boundary) * lines_per_iMCU_col); + cinfo->image_width = jmin(cinfo->original_image_width, + col_right_boundary * lines_per_iMCU_col) - + col_left_boundary * lines_per_iMCU_col; cinfo->input_iMCU_row = row_offset; cinfo->output_iMCU_row = row_offset; @@ -239,10 +240,11 @@ jpeg_init_read_tile_scanline(j_decompress_ptr cinfo, huffman_index *index, else jpeg_decompress_per_scan_setup(cinfo); - int sampleSize = cinfo->image_width / cinfo->output_width; - *height /= sampleSize; + int sample_size = DCTSIZE / cinfo->min_DCT_scaled_size; + + *height = jdiv_round_up(*height, sample_size); *width = cinfo->output_width; - cinfo->output_scanline = lines_per_iMCU_row * row_offset / sampleSize; + cinfo->output_scanline = lines_per_iMCU_row * row_offset / sample_size; cinfo->inputctl->consume_input = cinfo->coef->consume_data; cinfo->inputctl->consume_input_build_huffman_index = cinfo->coef->consume_data_build_huffman_index; @@ -265,24 +267,23 @@ jpeg_init_read_tile_scanline(j_decompress_ptr cinfo, huffman_index *index, GLOBAL(JDIMENSION) jpeg_read_tile_scanline (j_decompress_ptr cinfo, huffman_index *index, - JSAMPARRAY scanlines, int start_x, int start_y, int width, int height) + JSAMPARRAY scanlines) { // Calculates the boundary of iMCU int lines_per_iMCU_row = cinfo->max_v_samp_factor * DCTSIZE; int lines_per_iMCU_col = cinfo->max_h_samp_factor * DCTSIZE; - int col_left_boundary = ((start_x / lines_per_iMCU_col) - / index->MCU_sample_size) * index->MCU_sample_size; - int sampleSize = cinfo->image_width / cinfo->output_width; - int row_ctr = 0; + int sample_size = DCTSIZE / cinfo->min_DCT_scaled_size; + JDIMENSION row_ctr = 0; if (cinfo->progressive_mode) { (*cinfo->main->process_data) (cinfo, scanlines, &row_ctr, 1); } else { - if (cinfo->output_scanline % (lines_per_iMCU_row / sampleSize) == 0) { + if (cinfo->output_scanline % (lines_per_iMCU_row / sample_size) == 0) { // Set the read head to the next iMCU row int iMCU_row_offset = cinfo->output_scanline / - (lines_per_iMCU_row / sampleSize); - int offset_data_col_position = col_left_boundary / index->MCU_sample_size; + (lines_per_iMCU_row / sample_size); + int offset_data_col_position = cinfo->coef->MCU_column_left_boundary / + index->MCU_sample_size; huffman_offset_data offset_data = index->scan[0].offset[iMCU_row_offset][offset_data_col_position]; (*cinfo->entropy->configure_huffman_decoder) (cinfo, offset_data); @@ -272,10 +272,9 @@ consume_data (j_decompress_ptr cinfo) unsigned int MCUs_per_row = cinfo->MCUs_per_row; #ifdef ANDROID_TILE_BASED_DECODE if (cinfo->tile_decode) { - MCUs_per_row = + MCUs_per_row = jmin(MCUs_per_row, (cinfo->coef->column_right_boundary - cinfo->coef->column_left_boundary) - * cinfo->entropy->index->MCU_sample_size * cinfo->max_h_samp_factor; - MCUs_per_row = jmin(MCUs_per_row, cinfo->MCUs_per_row); + * cinfo->entropy->index->MCU_sample_size * cinfo->max_h_samp_factor); } #endif @@ -519,6 +519,7 @@ jpeg_configure_huffman_decoder(j_decompress_ptr cinfo, int blkn, i; cinfo->restart_interval = 0; + cinfo->unread_marker = 0; unsigned int byte_offset = bitstream_offset >> LOG_TWO_BIT_BUF_SIZE; unsigned int bit_in_bit_buffer = @@ -103,9 +103,12 @@ jpeg_calc_output_dimensions (j_decompress_ptr cinfo) #endif /* Prevent application from calling me at wrong times */ - // FIXME - //if (cinfo->global_state != DSTATE_READY) - // ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); +#if ANDROID_TILE_BASED_DECODE + // Tile based decoding may call this function several times. + if (!cinfo->tile_decode) +#endif + if (cinfo->global_state != DSTATE_READY) + ERREXIT1(cinfo, JERR_BAD_STATE, cinfo->global_state); #ifdef IDCT_SCALING_SUPPORTED @@ -1043,9 +1043,7 @@ EXTERN(JDIMENSION) jpeg_read_scanlines_from JPP((j_decompress_ptr cinfo, JDIMENSION max_lines)); EXTERN(JDIMENSION) jpeg_read_tile_scanline JPP((j_decompress_ptr cinfo, huffman_index *index, - JSAMPARRAY scanlines, - int start_x, int start_y, - int width, int height)); + JSAMPARRAY scanlines)); EXTERN(void) jpeg_init_read_tile_scanline JPP((j_decompress_ptr cinfo, huffman_index *index, int *start_x, int *start_y, |