diff options
author | Guido Vollbeding <jpeg-info@uc.ag> | 2010-01-10 00:00:00 +0000 |
---|---|---|
committer | DRC <information@libjpeg-turbo.org> | 2015-07-27 13:45:31 -0500 |
commit | 989630f70cf1af69ebfefca8910d1647bf189712 (patch) | |
tree | 37f16073c27b09c69ec95629218a13e219904d4a /jcmaster.c | |
parent | 5996a25e2f50d20d6a8f09830724035b49c3927b (diff) |
The Independent JPEG Group's JPEG software v8
Diffstat (limited to 'jcmaster.c')
-rw-r--r-- | jcmaster.c | 122 |
1 files changed, 97 insertions, 25 deletions
@@ -2,7 +2,7 @@ * jcmaster.c * * Copyright (C) 1991-1997, Thomas G. Lane. - * Modified 2003-2009 by Guido Vollbeding. + * Modified 2003-2010 by Guido Vollbeding. * This file is part of the Independent JPEG Group's software. * For conditions of distribution and use, see the accompanying README file. * @@ -110,8 +110,8 @@ jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo) /* Provide 1/1 scaling */ cinfo->jpeg_width = cinfo->image_width; cinfo->jpeg_height = cinfo->image_height; - cinfo->min_DCT_h_scaled_size = DCTSIZE; - cinfo->min_DCT_v_scaled_size = DCTSIZE; + cinfo->min_DCT_h_scaled_size = 8; + cinfo->min_DCT_v_scaled_size = 8; } else if (cinfo->scale_num * 9 >= cinfo->scale_denom * 8) { /* Provide 8/9 scaling */ cinfo->jpeg_width = (JDIMENSION) @@ -187,11 +187,40 @@ jpeg_calc_jpeg_dimensions (j_compress_ptr cinfo) cinfo->min_DCT_v_scaled_size = DCTSIZE; #endif /* DCT_SCALING_SUPPORTED */ + + cinfo->block_size = DCTSIZE; + cinfo->natural_order = jpeg_natural_order; + cinfo->lim_Se = DCTSIZE2-1; +} + + +LOCAL(void) +jpeg_calc_trans_dimensions (j_compress_ptr cinfo) +{ + if (cinfo->min_DCT_h_scaled_size < 1 || cinfo->min_DCT_h_scaled_size > 16 + || cinfo->min_DCT_h_scaled_size != cinfo->min_DCT_v_scaled_size) + ERREXIT2(cinfo, JERR_BAD_DCTSIZE, + cinfo->min_DCT_h_scaled_size, cinfo->min_DCT_v_scaled_size); + + cinfo->block_size = cinfo->min_DCT_h_scaled_size; + + switch (cinfo->block_size) { + case 2: cinfo->natural_order = jpeg_natural_order2; break; + case 3: cinfo->natural_order = jpeg_natural_order3; break; + case 4: cinfo->natural_order = jpeg_natural_order4; break; + case 5: cinfo->natural_order = jpeg_natural_order5; break; + case 6: cinfo->natural_order = jpeg_natural_order6; break; + case 7: cinfo->natural_order = jpeg_natural_order7; break; + default: cinfo->natural_order = jpeg_natural_order; break; + } + + cinfo->lim_Se = cinfo->block_size < DCTSIZE ? + cinfo->block_size * cinfo->block_size - 1 : DCTSIZE2-1; } LOCAL(void) -initial_setup (j_compress_ptr cinfo) +initial_setup (j_compress_ptr cinfo, boolean transcode_only) /* Do computations that are needed before master selection phase */ { int ci, ssize; @@ -199,11 +228,14 @@ initial_setup (j_compress_ptr cinfo) long samplesperrow; JDIMENSION jd_samplesperrow; - jpeg_calc_jpeg_dimensions(cinfo); + if (transcode_only) + jpeg_calc_trans_dimensions(cinfo); + else + jpeg_calc_jpeg_dimensions(cinfo); /* Sanity check on image dimensions */ - if (cinfo->jpeg_height <= 0 || cinfo->jpeg_width <= 0 - || cinfo->num_components <= 0 || cinfo->input_components <= 0) + if (cinfo->jpeg_height <= 0 || cinfo->jpeg_width <= 0 || + cinfo->num_components <= 0 || cinfo->input_components <= 0) ERREXIT(cinfo, JERR_EMPTY_IMAGE); /* Make sure image isn't bigger than I can handle */ @@ -278,19 +310,19 @@ initial_setup (j_compress_ptr cinfo) /* Size in DCT blocks */ compptr->width_in_blocks = (JDIMENSION) jdiv_round_up((long) cinfo->jpeg_width * (long) compptr->h_samp_factor, - (long) (cinfo->max_h_samp_factor * DCTSIZE)); + (long) (cinfo->max_h_samp_factor * cinfo->block_size)); compptr->height_in_blocks = (JDIMENSION) jdiv_round_up((long) cinfo->jpeg_height * (long) compptr->v_samp_factor, - (long) (cinfo->max_v_samp_factor * DCTSIZE)); + (long) (cinfo->max_v_samp_factor * cinfo->block_size)); /* Size in samples */ compptr->downsampled_width = (JDIMENSION) jdiv_round_up((long) cinfo->jpeg_width * (long) (compptr->h_samp_factor * compptr->DCT_h_scaled_size), - (long) (cinfo->max_h_samp_factor * DCTSIZE)); + (long) (cinfo->max_h_samp_factor * cinfo->block_size)); compptr->downsampled_height = (JDIMENSION) jdiv_round_up((long) cinfo->jpeg_height * (long) (compptr->v_samp_factor * compptr->DCT_v_scaled_size), - (long) (cinfo->max_v_samp_factor * DCTSIZE)); + (long) (cinfo->max_v_samp_factor * cinfo->block_size)); /* Mark component needed (this flag isn't actually used for compression) */ compptr->component_needed = TRUE; } @@ -300,7 +332,7 @@ initial_setup (j_compress_ptr cinfo) */ cinfo->total_iMCU_rows = (JDIMENSION) jdiv_round_up((long) cinfo->jpeg_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); + (long) (cinfo->max_v_samp_factor * cinfo->block_size)); } @@ -440,6 +472,39 @@ validate_script (j_compress_ptr cinfo) } } + +LOCAL(void) +reduce_script (j_compress_ptr cinfo) +/* Adapt scan script for use with reduced block size; + * assume that script has been validated before. + */ +{ + jpeg_scan_info * scanptr; + int idxout, idxin; + + /* Circumvent const declaration for this function */ + scanptr = (jpeg_scan_info *) cinfo->scan_info; + idxout = 0; + + for (idxin = 0; idxin < cinfo->num_scans; idxin++) { + /* After skipping, idxout becomes smaller than idxin */ + if (idxin != idxout) + /* Copy rest of data; + * note we stay in given chunk of allocated memory. + */ + scanptr[idxout] = scanptr[idxin]; + if (scanptr[idxout].Ss > cinfo->lim_Se) + /* Entire scan out of range - skip this entry */ + continue; + if (scanptr[idxout].Se > cinfo->lim_Se) + /* Limit scan to end of block */ + scanptr[idxout].Se = cinfo->lim_Se; + idxout++; + } + + cinfo->num_scans = idxout; +} + #endif /* C_MULTISCAN_FILES_SUPPORTED */ @@ -460,10 +525,13 @@ select_scan_parameters (j_compress_ptr cinfo) cinfo->cur_comp_info[ci] = &cinfo->comp_info[scanptr->component_index[ci]]; } - cinfo->Ss = scanptr->Ss; - cinfo->Se = scanptr->Se; - cinfo->Ah = scanptr->Ah; - cinfo->Al = scanptr->Al; + if (cinfo->progressive_mode) { + cinfo->Ss = scanptr->Ss; + cinfo->Se = scanptr->Se; + cinfo->Ah = scanptr->Ah; + cinfo->Al = scanptr->Al; + return; + } } else #endif @@ -476,11 +544,11 @@ select_scan_parameters (j_compress_ptr cinfo) for (ci = 0; ci < cinfo->num_components; ci++) { cinfo->cur_comp_info[ci] = &cinfo->comp_info[ci]; } - cinfo->Ss = 0; - cinfo->Se = DCTSIZE2-1; - cinfo->Ah = 0; - cinfo->Al = 0; } + cinfo->Ss = 0; + cinfo->Se = cinfo->block_size * cinfo->block_size - 1; + cinfo->Ah = 0; + cinfo->Al = 0; } @@ -528,10 +596,10 @@ per_scan_setup (j_compress_ptr cinfo) /* Overall image size in MCUs */ cinfo->MCUs_per_row = (JDIMENSION) jdiv_round_up((long) cinfo->jpeg_width, - (long) (cinfo->max_h_samp_factor*DCTSIZE)); + (long) (cinfo->max_h_samp_factor * cinfo->block_size)); cinfo->MCU_rows_in_scan = (JDIMENSION) jdiv_round_up((long) cinfo->jpeg_height, - (long) (cinfo->max_v_samp_factor*DCTSIZE)); + (long) (cinfo->max_v_samp_factor * cinfo->block_size)); cinfo->blocks_in_MCU = 0; @@ -734,11 +802,13 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) master->pub.is_last_pass = FALSE; /* Validate parameters, determine derived values */ - initial_setup(cinfo); + initial_setup(cinfo, transcode_only); if (cinfo->scan_info != NULL) { #ifdef C_MULTISCAN_FILES_SUPPORTED validate_script(cinfo); + if (cinfo->block_size < DCTSIZE) + reduce_script(cinfo); #else ERREXIT(cinfo, JERR_NOT_COMPILED); #endif @@ -747,8 +817,10 @@ jinit_c_master_control (j_compress_ptr cinfo, boolean transcode_only) cinfo->num_scans = 1; } - if (cinfo->progressive_mode && cinfo->arith_code == 0) /* TEMPORARY HACK ??? */ - cinfo->optimize_coding = TRUE; /* assume default tables no good for progressive mode */ + if ((cinfo->progressive_mode || cinfo->block_size < DCTSIZE) && + !cinfo->arith_code) /* TEMPORARY HACK ??? */ + /* assume default tables no good for progressive or downscale mode */ + cinfo->optimize_coding = TRUE; /* Initialize my private state */ if (transcode_only) { |