home *** CD-ROM | disk | FTP | other *** search
Text File | 1992-03-23 | 53.2 KB | 1,442 lines |
- Newsgroups: comp.sources.misc
- From: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Subject: v29i003: jpeg - JPEG image compression, Part03/18
- Message-ID: <1992Mar24.072645.19578@sparky.imd.sterling.com>
- X-Md4-Signature: d51e614d771008e271e5711a2b601c62
- Date: Tue, 24 Mar 1992 07:26:45 GMT
- Approved: kent@sparky.imd.sterling.com
-
- Submitted-by: jpeg-info@uunet.uu.net (Independent JPEG Group)
- Posting-number: Volume 29, Issue 3
- Archive-name: jpeg/part03
- Environment: UNIX, VMS, MS-DOS, Mac, Amiga, Cray
-
- #! /bin/sh
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: jcdeflts.c jdpipe.c
- # Wrapped by kent@sparky on Mon Mar 23 16:02:41 1992
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 3 (of 18)."'
- if test -f 'jcdeflts.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jcdeflts.c'\"
- else
- echo shar: Extracting \"'jcdeflts.c'\" \(14213 characters\)
- sed "s/^X//" >'jcdeflts.c' <<'END_OF_FILE'
- X/*
- X * jcdeflts.c
- X *
- X * Copyright (C) 1991, 1992, Thomas G. Lane.
- X * This file is part of the Independent JPEG Group's software.
- X * For conditions of distribution and use, see the accompanying README file.
- X *
- X * This file contains optional default-setting code for the JPEG compressor.
- X * User interfaces do not have to use this file, but those that don't use it
- X * must know a lot more about the innards of the JPEG code.
- X */
- X
- X#include "jinclude.h"
- X
- X
- X/* Default do-nothing progress monitoring routine.
- X * This can be overridden by a user interface that wishes to
- X * provide progress monitoring; just set methods->progress_monitor
- X * after j_c_defaults is done. The routine will be called periodically
- X * during the compression process.
- X *
- X * During any one pass, loopcounter increases from 0 up to (not including)
- X * looplimit; the step size is not necessarily 1. Both the step size and
- X * the limit may differ between passes. The expected total number of passes
- X * is in cinfo->total_passes, and the number of passes already completed is
- X * in cinfo->completed_passes. Thus the fraction of work completed may be
- X * estimated as
- X * completed_passes + (loopcounter/looplimit)
- X * ------------------------------------------
- X * total_passes
- X * ignoring the fact that the passes may not be equal amounts of work.
- X */
- X
- XMETHODDEF void
- Xprogress_monitor (compress_info_ptr cinfo, long loopcounter, long looplimit)
- X{
- X /* do nothing */
- X}
- X
- X
- X/*
- X * Table setup routines
- X */
- X
- XLOCAL void
- Xadd_huff_table (compress_info_ptr cinfo,
- X HUFF_TBL **htblptr, const UINT8 *bits, const UINT8 *val)
- X/* Define a Huffman table */
- X{
- X if (*htblptr == NULL)
- X *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
- X
- X memcpy((void *) (*htblptr)->bits, (const void *) bits,
- X SIZEOF((*htblptr)->bits));
- X memcpy((void *) (*htblptr)->huffval, (const void *) val,
- X SIZEOF((*htblptr)->huffval));
- X
- X /* Initialize sent_table FALSE so table will be written to JPEG file.
- X * In an application where we are writing non-interchange JPEG files,
- X * it might be desirable to save space by leaving default Huffman tables
- X * out of the file. To do that, just initialize sent_table = TRUE...
- X */
- X
- X (*htblptr)->sent_table = FALSE;
- X}
- X
- X
- XLOCAL void
- Xstd_huff_tables (compress_info_ptr cinfo)
- X/* Set up the standard Huffman tables (cf. JPEG standard section K.3) */
- X/* IMPORTANT: these are only valid for 8-bit data precision! */
- X{
- X static const UINT8 dc_luminance_bits[17] =
- X { /* 0-base */ 0, 0, 1, 5, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0 };
- X static const UINT8 dc_luminance_val[] =
- X { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
- X
- X static const UINT8 dc_chrominance_bits[17] =
- X { /* 0-base */ 0, 0, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0 };
- X static const UINT8 dc_chrominance_val[] =
- X { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
- X
- X static const UINT8 ac_luminance_bits[17] =
- X { /* 0-base */ 0, 0, 2, 1, 3, 3, 2, 4, 3, 5, 5, 4, 4, 0, 0, 1, 0x7d };
- X static const UINT8 ac_luminance_val[] =
- X { 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12,
- X 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07,
- X 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08,
- X 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0,
- X 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16,
- X 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28,
- X 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39,
- X 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49,
- X 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59,
- X 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69,
- X 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79,
- X 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89,
- X 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98,
- X 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
- X 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6,
- X 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5,
- X 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4,
- X 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2,
- X 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea,
- X 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- X 0xf9, 0xfa };
- X
- X static const UINT8 ac_chrominance_bits[17] =
- X { /* 0-base */ 0, 0, 2, 1, 2, 4, 4, 3, 4, 7, 5, 4, 4, 0, 1, 2, 0x77 };
- X static const UINT8 ac_chrominance_val[] =
- X { 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21,
- X 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71,
- X 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91,
- X 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0,
- X 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34,
- X 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26,
- X 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38,
- X 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48,
- X 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58,
- X 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68,
- X 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78,
- X 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87,
- X 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96,
- X 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5,
- X 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4,
- X 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3,
- X 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2,
- X 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda,
- X 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9,
- X 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8,
- X 0xf9, 0xfa };
- X
- X add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[0],
- X dc_luminance_bits, dc_luminance_val);
- X add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[0],
- X ac_luminance_bits, ac_luminance_val);
- X add_huff_table(cinfo, &cinfo->dc_huff_tbl_ptrs[1],
- X dc_chrominance_bits, dc_chrominance_val);
- X add_huff_table(cinfo, &cinfo->ac_huff_tbl_ptrs[1],
- X ac_chrominance_bits, ac_chrominance_val);
- X}
- X
- X
- X/* This is the sample quantization table given in the JPEG spec section K.1,
- X * but expressed in zigzag order (as are all of our quant. tables).
- X * The spec says that the values given produce "good" quality, and
- X * when divided by 2, "very good" quality. (These two settings are
- X * selected by quality=50 and quality=75 in j_set_quality, below.)
- X */
- X
- X
- Xstatic const QUANT_VAL std_luminance_quant_tbl[DCTSIZE2] = {
- X 16, 11, 12, 14, 12, 10, 16, 14,
- X 13, 14, 18, 17, 16, 19, 24, 40,
- X 26, 24, 22, 22, 24, 49, 35, 37,
- X 29, 40, 58, 51, 61, 60, 57, 51,
- X 56, 55, 64, 72, 92, 78, 64, 68,
- X 87, 69, 55, 56, 80, 109, 81, 87,
- X 95, 98, 103, 104, 103, 62, 77, 113,
- X 121, 112, 100, 120, 92, 101, 103, 99
- X};
- X
- Xstatic const QUANT_VAL std_chrominance_quant_tbl[DCTSIZE2] = {
- X 17, 18, 18, 24, 21, 24, 47, 26,
- X 26, 47, 99, 66, 56, 66, 99, 99,
- X 99, 99, 99, 99, 99, 99, 99, 99,
- X 99, 99, 99, 99, 99, 99, 99, 99,
- X 99, 99, 99, 99, 99, 99, 99, 99,
- X 99, 99, 99, 99, 99, 99, 99, 99,
- X 99, 99, 99, 99, 99, 99, 99, 99,
- X 99, 99, 99, 99, 99, 99, 99, 99
- X};
- X
- X
- XLOCAL void
- Xadd_quant_table (compress_info_ptr cinfo, int which_tbl,
- X const QUANT_VAL *basic_table, int scale_factor,
- X boolean force_baseline)
- X/* Define a quantization table equal to the basic_table times */
- X/* a scale factor (given as a percentage) */
- X{
- X QUANT_TBL_PTR * qtblptr = & cinfo->quant_tbl_ptrs[which_tbl];
- X int i;
- X long temp;
- X
- X if (*qtblptr == NULL)
- X *qtblptr = (QUANT_TBL_PTR) (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
- X
- X for (i = 0; i < DCTSIZE2; i++) {
- X temp = ((long) basic_table[i] * scale_factor + 50L) / 100L;
- X /* limit the values to the valid range */
- X if (temp <= 0L) temp = 1L;
- X#ifdef EIGHT_BIT_SAMPLES
- X if (temp > 32767L) temp = 32767L; /* QUANT_VALs are 'short' */
- X#else
- X if (temp > 65535L) temp = 65535L; /* QUANT_VALs are 'UINT16' */
- X#endif
- X if (force_baseline && temp > 255L)
- X temp = 255L; /* limit to baseline range if requested */
- X (*qtblptr)[i] = (QUANT_VAL) temp;
- X }
- X}
- X
- X
- XGLOBAL void
- Xj_set_quality (compress_info_ptr cinfo, int quality, boolean force_baseline)
- X/* Set or change the 'quality' (quantization) setting. */
- X/* The 'quality' factor should be 0 (terrible) to 100 (very good). */
- X/* Quality 50 corresponds to the JPEG basic tables given above; */
- X/* quality 100 results in no quantization scaling at all. */
- X/* If force_baseline is TRUE, quantization table entries are limited */
- X/* to 0..255 for JPEG baseline compatibility; this is only an issue */
- X/* for quality settings below 24. */
- X{
- X /* Safety limit on quality factor. Convert 0 to 1 to avoid zero divide. */
- X if (quality <= 0) quality = 1;
- X if (quality > 100) quality = 100;
- X
- X /* Convert quality rating to a percentage scaling of the basic tables.
- X * The basic table is used as-is (scaling 100) for a quality of 50.
- X * Qualities 50..100 are converted to scaling percentage 200 - 2*Q;
- X * note that at Q=100 the scaling is 0, which will cause add_quant_table
- X * to make all the table entries 1 (hence, no quantization loss).
- X * Qualities 1..50 are converted to scaling percentage 5000/Q.
- X */
- X if (quality < 50)
- X quality = 5000 / quality;
- X else
- X quality = 200 - quality*2;
- X
- X /* Set up two quantization tables using the specified quality scaling */
- X add_quant_table(cinfo, 0, std_luminance_quant_tbl, quality, force_baseline);
- X add_quant_table(cinfo, 1, std_chrominance_quant_tbl, quality, force_baseline);
- X}
- X
- X
- X
- X/* Default parameter setup for compression.
- X *
- X * User interfaces that don't choose to use this routine must do their
- X * own setup of all these parameters. Alternately, you can call this
- X * to establish defaults and then alter parameters selectively. This
- X * is the recommended approach since, if we add any new parameters,
- X * your code will still work (they'll be set to reasonable defaults).
- X *
- X * See above for the meaning of the 'quality' and 'force_baseline' parameters.
- X * Typically, the application's default quality setting will be passed to this
- X * routine. A later call on j_set_quality() can be used to change to a
- X * user-specified quality setting.
- X *
- X * This routine sets up for a color image; to output a grayscale image,
- X * do this first and call j_monochrome_default() afterwards.
- X * (The latter can be called within c_ui_method_selection, so the
- X * choice can depend on the input file header.)
- X * Note that if you want a JPEG colorspace other than GRAYSCALE or YCbCr,
- X * you should also change the component ID codes, and you should NOT emit
- X * a JFIF header (set write_JFIF_header = FALSE).
- X *
- X * CAUTION: if you want to compress multiple images per run, it's necessary
- X * to call j_c_defaults before *each* call to jpeg_compress, since subsidiary
- X * structures like the Huffman tables are automatically freed during cleanup.
- X */
- X
- XGLOBAL void
- Xj_c_defaults (compress_info_ptr cinfo, int quality, boolean force_baseline)
- X/* NB: the external methods must already be set up. */
- X{
- X short i;
- X jpeg_component_info * compptr;
- X
- X /* Initialize pointers as needed to mark stuff unallocated. */
- X cinfo->comp_info = NULL;
- X for (i = 0; i < NUM_QUANT_TBLS; i++)
- X cinfo->quant_tbl_ptrs[i] = NULL;
- X for (i = 0; i < NUM_HUFF_TBLS; i++) {
- X cinfo->dc_huff_tbl_ptrs[i] = NULL;
- X cinfo->ac_huff_tbl_ptrs[i] = NULL;
- X }
- X
- X cinfo->data_precision = BITS_IN_JSAMPLE; /* default; can be overridden by input_init */
- X cinfo->density_unit = 0; /* Pixel size is unknown by default */
- X cinfo->X_density = 1; /* Pixel aspect ratio is square by default */
- X cinfo->Y_density = 1;
- X
- X cinfo->input_gamma = 1.0; /* no gamma correction by default */
- X
- X /* Prepare three color components; first is luminance which is also usable */
- X /* for grayscale. The others are assumed to be UV or similar chrominance. */
- X cinfo->write_JFIF_header = TRUE;
- X cinfo->jpeg_color_space = CS_YCbCr;
- X cinfo->num_components = 3;
- X cinfo->comp_info = (jpeg_component_info *)
- X (*cinfo->emethods->alloc_small) (4 * SIZEOF(jpeg_component_info));
- X /* Note: we allocate a 4-entry comp_info array so that user interface can
- X * easily change over to CMYK color space if desired.
- X */
- X
- X compptr = &cinfo->comp_info[0];
- X compptr->component_index = 0;
- X compptr->component_id = 1; /* JFIF specifies IDs 1,2,3 */
- X compptr->h_samp_factor = 2; /* default to 2x2 subsamples of chrominance */
- X compptr->v_samp_factor = 2;
- X compptr->quant_tbl_no = 0; /* use tables 0 for luminance */
- X compptr->dc_tbl_no = 0;
- X compptr->ac_tbl_no = 0;
- X
- X compptr = &cinfo->comp_info[1];
- X compptr->component_index = 1;
- X compptr->component_id = 2;
- X compptr->h_samp_factor = 1;
- X compptr->v_samp_factor = 1;
- X compptr->quant_tbl_no = 1; /* use tables 1 for chrominance */
- X compptr->dc_tbl_no = 1;
- X compptr->ac_tbl_no = 1;
- X
- X compptr = &cinfo->comp_info[2];
- X compptr->component_index = 2;
- X compptr->component_id = 3;
- X compptr->h_samp_factor = 1;
- X compptr->v_samp_factor = 1;
- X compptr->quant_tbl_no = 1; /* use tables 1 for chrominance */
- X compptr->dc_tbl_no = 1;
- X compptr->ac_tbl_no = 1;
- X
- X /* Set up two quantization tables using the specified quality scaling */
- X j_set_quality(cinfo, quality, force_baseline);
- X
- X /* Set up two Huffman tables in case user interface wants Huffman coding */
- X std_huff_tables(cinfo);
- X
- X /* Initialize default arithmetic coding conditioning */
- X for (i = 0; i < NUM_ARITH_TBLS; i++) {
- X cinfo->arith_dc_L[i] = 0;
- X cinfo->arith_dc_U[i] = 1;
- X cinfo->arith_ac_K[i] = 5;
- X }
- X
- X /* Use Huffman coding, not arithmetic coding, by default */
- X cinfo->arith_code = FALSE;
- X
- X /* Color images are interleaved by default */
- X cinfo->interleave = TRUE;
- X
- X /* By default, don't do extra passes to optimize entropy coding */
- X cinfo->optimize_coding = FALSE;
- X
- X /* By default, use the simpler non-cosited sampling alignment */
- X cinfo->CCIR601_sampling = FALSE;
- X
- X /* No restart markers */
- X cinfo->restart_interval = 0;
- X
- X /* Install default do-nothing progress monitoring method. */
- X cinfo->methods->progress_monitor = progress_monitor;
- X}
- X
- X
- X
- XGLOBAL void
- Xj_monochrome_default (compress_info_ptr cinfo)
- X/* Change the j_c_defaults() values to emit a monochrome JPEG file. */
- X{
- X jpeg_component_info * compptr;
- X
- X cinfo->jpeg_color_space = CS_GRAYSCALE;
- X cinfo->num_components = 1;
- X /* Set single component to 1x1 subsampling */
- X compptr = &cinfo->comp_info[0];
- X compptr->h_samp_factor = 1;
- X compptr->v_samp_factor = 1;
- X}
- END_OF_FILE
- if test 14213 -ne `wc -c <'jcdeflts.c'`; then
- echo shar: \"'jcdeflts.c'\" unpacked with wrong size!
- fi
- # end of 'jcdeflts.c'
- fi
- if test -f 'jdpipe.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'jdpipe.c'\"
- else
- echo shar: Extracting \"'jdpipe.c'\" \(36733 characters\)
- sed "s/^X//" >'jdpipe.c' <<'END_OF_FILE'
- X/*
- X * jdpipe.c
- X *
- X * Copyright (C) 1991, 1992, Thomas G. Lane.
- X * This file is part of the Independent JPEG Group's software.
- X * For conditions of distribution and use, see the accompanying README file.
- X *
- X * This file contains decompression pipeline controllers.
- X * These routines are invoked via the d_pipeline_controller method.
- X *
- X * There are two basic pipeline controllers. The simpler one handles a
- X * single-scan JPEG file (single component or fully interleaved) with no
- X * color quantization or 1-pass quantization. In this case, the file can
- X * be processed in one top-to-bottom pass. The more complex controller is
- X * used when 2-pass color quantization is requested and/or the JPEG file
- X * has multiple scans (noninterleaved or partially interleaved). In this
- X * case, the entire image must be buffered up in a "big" array.
- X *
- X * If you need to make a minimal implementation, the more complex controller
- X * can be compiled out by disabling the appropriate configuration options.
- X * We don't recommend this, since then you can't handle all legal JPEG files.
- X */
- X
- X#include "jinclude.h"
- X
- X
- X#ifdef MULTISCAN_FILES_SUPPORTED /* wish we could assume ANSI's defined() */
- X#define NEED_COMPLEX_CONTROLLER
- X#else
- X#ifdef QUANT_2PASS_SUPPORTED
- X#define NEED_COMPLEX_CONTROLLER
- X#endif
- X#endif
- X
- X
- X/*
- X * About the data structures:
- X *
- X * The processing chunk size for unsubsampling is referred to in this file as
- X * a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
- X * any component while subsampled, or Vmax (max_v_samp_factor) unsubsampled
- X * rows. In an interleaved scan each MCU row contains exactly DCTSIZE row
- X * groups of each component in the scan. In a noninterleaved scan an MCU row
- X * is one row of blocks, which might not be an integral number of row groups;
- X * therefore, we read in Vk MCU rows to obtain the same amount of data as we'd
- X * have in an interleaved scan.
- X * To provide context for the unsubsampling step, we have to retain the last
- X * two row groups of the previous MCU row while reading in the next MCU row
- X * (or set of Vk MCU rows). To do this without copying data about, we create
- X * a rather strange data structure. Exactly DCTSIZE+2 row groups of samples
- X * are allocated, but we create two different sets of pointers to this array.
- X * The second set swaps the last two pairs of row groups. By working
- X * alternately with the two sets of pointers, we can access the data in the
- X * desired order.
- X *
- X * Cross-block smoothing also needs context above and below the "current" row.
- X * Since this is an optional feature, I've implemented it in a way that is
- X * much simpler but requires more than the minimum amount of memory. We
- X * simply allocate three extra MCU rows worth of coefficient blocks and use
- X * them to "read ahead" one MCU row in the file. For a typical 1000-pixel-wide
- X * image with 2x2,1x1,1x1 sampling, each MCU row is about 50Kb; an 80x86
- X * machine may be unable to apply cross-block smoothing to wider images.
- X */
- X
- X
- X/*
- X * These variables are logically local to the pipeline controller,
- X * but we make them static so that scan_big_image can use them
- X * without having to pass them through the quantization routines.
- X */
- X
- Xstatic int rows_in_mem; /* # of sample rows in full-size buffers */
- X/* Work buffer for data being passed to output module. */
- X/* This has color_out_comps components if not quantizing, */
- X/* but only one component when quantizing. */
- Xstatic JSAMPIMAGE output_workspace;
- X
- X#ifdef NEED_COMPLEX_CONTROLLER
- X/* Full-size image array holding desubsampled, but not color-processed data. */
- Xstatic big_sarray_ptr *fullsize_image;
- Xstatic JSAMPIMAGE fullsize_ptrs; /* workspace for access_big_sarray() result */
- X#endif
- X
- X
- X/*
- X * Utility routines: common code for pipeline controllers
- X */
- X
- XLOCAL void
- Xinterleaved_scan_setup (decompress_info_ptr cinfo)
- X/* Compute all derived info for an interleaved (multi-component) scan */
- X/* On entry, cinfo->comps_in_scan and cinfo->cur_comp_info[] are set up */
- X{
- X short ci, mcublks;
- X jpeg_component_info *compptr;
- X
- X if (cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
- X ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
- X
- X cinfo->MCUs_per_row = (cinfo->image_width
- X + cinfo->max_h_samp_factor*DCTSIZE - 1)
- X / (cinfo->max_h_samp_factor*DCTSIZE);
- X
- X cinfo->MCU_rows_in_scan = (cinfo->image_height
- X + cinfo->max_v_samp_factor*DCTSIZE - 1)
- X / (cinfo->max_v_samp_factor*DCTSIZE);
- X
- X cinfo->blocks_in_MCU = 0;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X compptr = cinfo->cur_comp_info[ci];
- X /* for interleaved scan, sampling factors give # of blocks per component */
- X compptr->MCU_width = compptr->h_samp_factor;
- X compptr->MCU_height = compptr->v_samp_factor;
- X compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
- X /* compute physical dimensions of component */
- X compptr->subsampled_width = jround_up(compptr->true_comp_width,
- X (long) (compptr->MCU_width*DCTSIZE));
- X compptr->subsampled_height = jround_up(compptr->true_comp_height,
- X (long) (compptr->MCU_height*DCTSIZE));
- X /* Sanity check */
- X if (compptr->subsampled_width !=
- X (cinfo->MCUs_per_row * (compptr->MCU_width*DCTSIZE)))
- X ERREXIT(cinfo->emethods, "I'm confused about the image width");
- X /* Prepare array describing MCU composition */
- X mcublks = compptr->MCU_blocks;
- X if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
- X ERREXIT(cinfo->emethods, "Sampling factors too large for interleaved scan");
- X while (mcublks-- > 0) {
- X cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
- X }
- X }
- X
- X (*cinfo->methods->d_per_scan_method_selection) (cinfo);
- X}
- X
- X
- XLOCAL void
- Xnoninterleaved_scan_setup (decompress_info_ptr cinfo)
- X/* Compute all derived info for a noninterleaved (single-component) scan */
- X/* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
- X{
- X jpeg_component_info *compptr = cinfo->cur_comp_info[0];
- X
- X /* for noninterleaved scan, always one block per MCU */
- X compptr->MCU_width = 1;
- X compptr->MCU_height = 1;
- X compptr->MCU_blocks = 1;
- X /* compute physical dimensions of component */
- X compptr->subsampled_width = jround_up(compptr->true_comp_width,
- X (long) DCTSIZE);
- X compptr->subsampled_height = jround_up(compptr->true_comp_height,
- X (long) DCTSIZE);
- X
- X cinfo->MCUs_per_row = compptr->subsampled_width / DCTSIZE;
- X cinfo->MCU_rows_in_scan = compptr->subsampled_height / DCTSIZE;
- X
- X /* Prepare array describing MCU composition */
- X cinfo->blocks_in_MCU = 1;
- X cinfo->MCU_membership[0] = 0;
- X
- X (*cinfo->methods->d_per_scan_method_selection) (cinfo);
- X}
- X
- X
- X
- XLOCAL JSAMPIMAGE
- Xalloc_sampimage (decompress_info_ptr cinfo,
- X int num_comps, long num_rows, long num_cols)
- X/* Allocate an in-memory sample image (all components same size) */
- X{
- X JSAMPIMAGE image;
- X int ci;
- X
- X image = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (num_comps * SIZEOF(JSAMPARRAY));
- X for (ci = 0; ci < num_comps; ci++) {
- X image[ci] = (*cinfo->emethods->alloc_small_sarray) (num_cols, num_rows);
- X }
- X return image;
- X}
- X
- X
- X#if 0 /* this routine not currently needed */
- X
- XLOCAL void
- Xfree_sampimage (decompress_info_ptr cinfo, JSAMPIMAGE image, int num_comps)
- X/* Release a sample image created by alloc_sampimage */
- X{
- X int ci;
- X
- X for (ci = 0; ci < num_comps; ci++) {
- X (*cinfo->emethods->free_small_sarray) (image[ci]);
- X }
- X (*cinfo->emethods->free_small) ((void *) image);
- X}
- X
- X#endif
- X
- X
- XLOCAL JBLOCKIMAGE
- Xalloc_MCU_row (decompress_info_ptr cinfo)
- X/* Allocate one MCU row's worth of coefficient blocks */
- X{
- X JBLOCKIMAGE image;
- X int ci;
- X
- X image = (JBLOCKIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->comps_in_scan * SIZEOF(JBLOCKARRAY));
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X image[ci] = (*cinfo->emethods->alloc_small_barray)
- X (cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE,
- X (long) cinfo->cur_comp_info[ci]->MCU_height);
- X }
- X return image;
- X}
- X
- X
- X#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
- X
- XLOCAL void
- Xfree_MCU_row (decompress_info_ptr cinfo, JBLOCKIMAGE image)
- X/* Release a coefficient block array created by alloc_MCU_row */
- X{
- X int ci;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X (*cinfo->emethods->free_small_barray) (image[ci]);
- X }
- X (*cinfo->emethods->free_small) ((void *) image);
- X}
- X
- X#endif
- X
- X
- XLOCAL void
- Xalloc_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
- X/* Create a subsampled-data buffer having the desired structure */
- X/* (see comments at head of file) */
- X{
- X short ci, vs, i;
- X
- X /* Get top-level space for array pointers */
- X subsampled_data[0] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->comps_in_scan * SIZEOF(JSAMPARRAY));
- X subsampled_data[1] = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->comps_in_scan * SIZEOF(JSAMPARRAY));
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X vs = cinfo->cur_comp_info[ci]->v_samp_factor; /* row group height */
- X /* Allocate the real storage */
- X subsampled_data[0][ci] = (*cinfo->emethods->alloc_small_sarray)
- X (cinfo->cur_comp_info[ci]->subsampled_width,
- X (long) (vs * (DCTSIZE+2)));
- X /* Create space for the scrambled-order pointers */
- X subsampled_data[1][ci] = (JSAMPARRAY) (*cinfo->emethods->alloc_small)
- X (vs * (DCTSIZE+2) * SIZEOF(JSAMPROW));
- X /* Duplicate the first DCTSIZE-2 row groups */
- X for (i = 0; i < vs * (DCTSIZE-2); i++) {
- X subsampled_data[1][ci][i] = subsampled_data[0][ci][i];
- X }
- X /* Copy the last four row groups in swapped order */
- X for (i = 0; i < vs * 2; i++) {
- X subsampled_data[1][ci][vs*DCTSIZE + i] = subsampled_data[0][ci][vs*(DCTSIZE-2) + i];
- X subsampled_data[1][ci][vs*(DCTSIZE-2) + i] = subsampled_data[0][ci][vs*DCTSIZE + i];
- X }
- X }
- X}
- X
- X
- X#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
- X
- XLOCAL void
- Xfree_sampling_buffer (decompress_info_ptr cinfo, JSAMPIMAGE subsampled_data[2])
- X/* Release a sampling buffer created by alloc_sampling_buffer */
- X{
- X short ci;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X /* Free the real storage */
- X (*cinfo->emethods->free_small_sarray) (subsampled_data[0][ci]);
- X /* Free the scrambled-order pointers */
- X (*cinfo->emethods->free_small) ((void *) subsampled_data[1][ci]);
- X }
- X
- X /* Free the top-level space */
- X (*cinfo->emethods->free_small) ((void *) subsampled_data[0]);
- X (*cinfo->emethods->free_small) ((void *) subsampled_data[1]);
- X}
- X
- X#endif
- X
- X
- XLOCAL void
- Xduplicate_row (JSAMPARRAY image_data,
- X long num_cols, int source_row, int num_rows)
- X/* Duplicate the source_row at source_row+1 .. source_row+num_rows */
- X/* This happens only at the bottom of the image, */
- X/* so it needn't be super-efficient */
- X{
- X register int row;
- X
- X for (row = 1; row <= num_rows; row++) {
- X jcopy_sample_rows(image_data, source_row, image_data, source_row + row,
- X 1, num_cols);
- X }
- X}
- X
- X
- XLOCAL void
- Xexpand (decompress_info_ptr cinfo,
- X JSAMPIMAGE subsampled_data, JSAMPIMAGE fullsize_data,
- X long fullsize_width,
- X short above, short current, short below, short out)
- X/* Do unsubsampling expansion of a single row group (of each component). */
- X/* above, current, below are indexes of row groups in subsampled_data; */
- X/* out is the index of the target row group in fullsize_data. */
- X/* Special case: above, below can be -1 to indicate top, bottom of image. */
- X{
- X jpeg_component_info *compptr;
- X JSAMPARRAY above_ptr, below_ptr;
- X JSAMPROW dummy[MAX_SAMP_FACTOR]; /* for subsample expansion at top/bottom */
- X short ci, vs, i;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X compptr = cinfo->cur_comp_info[ci];
- X vs = compptr->v_samp_factor; /* row group height */
- X
- X if (above >= 0)
- X above_ptr = subsampled_data[ci] + above * vs;
- X else {
- X /* Top of image: make a dummy above-context with copies of 1st row */
- X /* We assume current=0 in this case */
- X for (i = 0; i < vs; i++)
- X dummy[i] = subsampled_data[ci][0];
- X above_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
- X }
- X
- X if (below >= 0)
- X below_ptr = subsampled_data[ci] + below * vs;
- X else {
- X /* Bot of image: make a dummy below-context with copies of last row */
- X for (i = 0; i < vs; i++)
- X dummy[i] = subsampled_data[ci][(current+1)*vs-1];
- X below_ptr = (JSAMPARRAY) dummy; /* possible near->far pointer conv */
- X }
- X
- X (*cinfo->methods->unsubsample[ci])
- X (cinfo, (int) ci,
- X compptr->subsampled_width, (int) vs,
- X fullsize_width, (int) cinfo->max_v_samp_factor,
- X above_ptr,
- X subsampled_data[ci] + current * vs,
- X below_ptr,
- X fullsize_data[ci] + out * cinfo->max_v_samp_factor);
- X }
- X}
- X
- X
- XLOCAL void
- Xemit_1pass (decompress_info_ptr cinfo, int num_rows, JSAMPIMAGE fullsize_data,
- X JSAMPARRAY dummy)
- X/* Do color processing and output of num_rows full-size rows. */
- X/* This is not used when doing 2-pass color quantization. */
- X/* The dummy argument simply lets this be called via scan_big_image. */
- X{
- X if (cinfo->quantize_colors) {
- X (*cinfo->methods->color_quantize) (cinfo, num_rows, fullsize_data,
- X output_workspace[0]);
- X } else {
- X (*cinfo->methods->color_convert) (cinfo, num_rows, cinfo->image_width,
- X fullsize_data, output_workspace);
- X }
- X
- X (*cinfo->methods->put_pixel_rows) (cinfo, num_rows, output_workspace);
- X}
- X
- X
- X/*
- X * Support routines for complex controller.
- X */
- X
- X#ifdef NEED_COMPLEX_CONTROLLER
- X
- XMETHODDEF void
- Xscan_big_image (decompress_info_ptr cinfo, quantize_method_ptr quantize_method)
- X/* Apply quantize_method to entire image stored in fullsize_image[]. */
- X/* This is the "iterator" routine used by the 2-pass color quantizer. */
- X/* We also use it directly in some cases. */
- X{
- X long pixel_rows_output;
- X short ci;
- X
- X for (pixel_rows_output = 0; pixel_rows_output < cinfo->image_height;
- X pixel_rows_output += rows_in_mem) {
- X (*cinfo->methods->progress_monitor) (cinfo, pixel_rows_output,
- X cinfo->image_height);
- X /* Realign the big buffers */
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
- X (fullsize_image[ci], pixel_rows_output, FALSE);
- X }
- X /* Let the quantizer have its way with the data.
- X * Note that output_workspace is simply workspace for the quantizer;
- X * when it's ready to output, it must call put_pixel_rows itself.
- X */
- X (*quantize_method) (cinfo,
- X (int) MIN((long) rows_in_mem,
- X cinfo->image_height - pixel_rows_output),
- X fullsize_ptrs, output_workspace[0]);
- X }
- X
- X cinfo->completed_passes++;
- X}
- X
- X#endif /* NEED_COMPLEX_CONTROLLER */
- X
- X
- X/*
- X * Support routines for cross-block smoothing.
- X */
- X
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X
- X
- XLOCAL void
- Xsmooth_mcu_row (decompress_info_ptr cinfo,
- X JBLOCKIMAGE above, JBLOCKIMAGE input, JBLOCKIMAGE below,
- X JBLOCKIMAGE output)
- X/* Apply cross-block smoothing to one MCU row's worth of coefficient blocks. */
- X/* above,below are NULL if at top/bottom of image. */
- X{
- X jpeg_component_info *compptr;
- X short ci, ri, last;
- X JBLOCKROW prev;
- X
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X compptr = cinfo->cur_comp_info[ci];
- X last = compptr->MCU_height - 1;
- X
- X if (above == NULL)
- X prev = NULL;
- X else
- X prev = above[ci][last];
- X
- X for (ri = 0; ri < last; ri++) {
- X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
- X prev, input[ci][ri], input[ci][ri+1],
- X output[ci][ri]);
- X prev = input[ci][ri];
- X }
- X
- X if (below == NULL)
- X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
- X prev, input[ci][last], (JBLOCKROW) NULL,
- X output[ci][last]);
- X else
- X (*cinfo->methods->smooth_coefficients) (cinfo, compptr,
- X prev, input[ci][last], below[ci][0],
- X output[ci][last]);
- X }
- X}
- X
- X
- XLOCAL void
- Xget_smoothed_row (decompress_info_ptr cinfo, JBLOCKIMAGE coeff_data,
- X JBLOCKIMAGE bsmooth[3], int * whichb, long cur_mcu_row)
- X/* Get an MCU row of coefficients, applying cross-block smoothing. */
- X/* The output row is placed in coeff_data. bsmooth and whichb hold */
- X/* working state, and cur_row is needed to check for image top/bottom. */
- X/* This routine just takes care of the buffering logic. */
- X{
- X int prev, cur, next;
- X
- X /* Special case for top of image: need to pre-fetch a row & init whichb */
- X if (cur_mcu_row == 0) {
- X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[0]);
- X if (cinfo->MCU_rows_in_scan > 1) {
- X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[1]);
- X smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], bsmooth[1],
- X coeff_data);
- X } else {
- X smooth_mcu_row(cinfo, (JBLOCKIMAGE) NULL, bsmooth[0], (JBLOCKIMAGE) NULL,
- X coeff_data);
- X }
- X *whichb = 1; /* points to next bsmooth[] element to use */
- X return;
- X }
- X
- X cur = *whichb; /* set up references */
- X prev = (cur == 0 ? 2 : cur - 1);
- X next = (cur == 2 ? 0 : cur + 1);
- X *whichb = next; /* advance whichb for next time */
- X
- X /* Special case for bottom of image: don't read another row */
- X if (cur_mcu_row >= cinfo->MCU_rows_in_scan - 1) {
- X smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], (JBLOCKIMAGE) NULL,
- X coeff_data);
- X return;
- X }
- X
- X /* Normal case: read ahead a new row, smooth the one I got before */
- X (*cinfo->methods->disassemble_MCU) (cinfo, bsmooth[next]);
- X smooth_mcu_row(cinfo, bsmooth[prev], bsmooth[cur], bsmooth[next],
- X coeff_data);
- X}
- X
- X
- X#endif /* BLOCK_SMOOTHING_SUPPORTED */
- X
- X
- X
- X/*
- X * Decompression pipeline controller used for single-scan files
- X * without 2-pass color quantization.
- X */
- X
- XMETHODDEF void
- Xsimple_dcontroller (decompress_info_ptr cinfo)
- X{
- X long fullsize_width; /* # of samples per row in full-size buffers */
- X long cur_mcu_row; /* counts # of MCU rows processed */
- X long pixel_rows_output; /* # of pixel rows actually emitted */
- X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
- X /* Work buffer for dequantized coefficients (IDCT input) */
- X JBLOCKIMAGE coeff_data;
- X /* Work buffer for cross-block smoothing input */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X JBLOCKIMAGE bsmooth[3]; /* this is optional */
- X int whichb;
- X#endif
- X /* Work buffer for subsampled image data (see comments at head of file) */
- X JSAMPIMAGE subsampled_data[2];
- X /* Work buffer for desubsampled data */
- X JSAMPIMAGE fullsize_data;
- X int whichss, ri;
- X short i;
- X
- X /* Compute dimensions of full-size pixel buffers */
- X /* Note these are the same whether interleaved or not. */
- X rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
- X fullsize_width = jround_up(cinfo->image_width,
- X (long) (cinfo->max_h_samp_factor * DCTSIZE));
- X
- X /* Prepare for single scan containing all components */
- X if (cinfo->comps_in_scan == 1) {
- X noninterleaved_scan_setup(cinfo);
- X /* Need to read Vk MCU rows to obtain Vk block rows */
- X mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
- X } else {
- X interleaved_scan_setup(cinfo);
- X /* in an interleaved scan, one MCU row provides Vk block rows */
- X mcu_rows_per_loop = 1;
- X }
- X cinfo->total_passes++;
- X
- X /* Allocate working memory: */
- X /* coeff_data holds a single MCU row of coefficient blocks */
- X coeff_data = alloc_MCU_row(cinfo);
- X /* if doing cross-block smoothing, need extra space for its input */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing) {
- X bsmooth[0] = alloc_MCU_row(cinfo);
- X bsmooth[1] = alloc_MCU_row(cinfo);
- X bsmooth[2] = alloc_MCU_row(cinfo);
- X }
- X#endif
- X /* subsampled_data is sample data before unsubsampling */
- X alloc_sampling_buffer(cinfo, subsampled_data);
- X /* fullsize_data is sample data after unsubsampling */
- X fullsize_data = alloc_sampimage(cinfo, (int) cinfo->num_components,
- X (long) rows_in_mem, fullsize_width);
- X /* output_workspace is the color-processed data */
- X output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
- X (long) rows_in_mem, fullsize_width);
- X
- X /* Tell the memory manager to instantiate big arrays.
- X * We don't need any big arrays in this controller,
- X * but some other module (like the output file writer) may need one.
- X */
- X (*cinfo->emethods->alloc_big_arrays)
- X ((long) 0, /* no more small sarrays */
- X (long) 0, /* no more small barrays */
- X (long) 0); /* no more "medium" objects */
- X /* NB: if quantizer needs any "medium" size objects, it must get them */
- X /* at color_quant_init time */
- X
- X /* Initialize to read scan data */
- X
- X (*cinfo->methods->entropy_decoder_init) (cinfo);
- X (*cinfo->methods->unsubsample_init) (cinfo);
- X (*cinfo->methods->disassemble_init) (cinfo);
- X
- X /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
- X
- X pixel_rows_output = 0;
- X whichss = 1; /* arrange to start with subsampled_data[0] */
- X
- X for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
- X cur_mcu_row += mcu_rows_per_loop) {
- X (*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
- X cinfo->MCU_rows_in_scan);
- X
- X whichss ^= 1; /* switch to other subsample buffer */
- X
- X /* Obtain v_samp_factor block rows of each component in the scan. */
- X /* This is a single MCU row if interleaved, multiple MCU rows if not. */
- X /* In the noninterleaved case there might be fewer than v_samp_factor */
- X /* block rows remaining; if so, pad with copies of the last pixel row */
- X /* so that unsubsampling doesn't have to treat it as a special case. */
- X
- X for (ri = 0; ri < mcu_rows_per_loop; ri++) {
- X if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
- X /* OK to actually read an MCU row. */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing)
- X get_smoothed_row(cinfo, coeff_data,
- X bsmooth, &whichb, cur_mcu_row + ri);
- X else
- X#endif
- X (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
- X
- X (*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
- X subsampled_data[whichss],
- X ri * DCTSIZE);
- X } else {
- X /* Need to pad out with copies of the last subsampled row. */
- X /* This can only happen if there is just one component. */
- X duplicate_row(subsampled_data[whichss][0],
- X cinfo->cur_comp_info[0]->subsampled_width,
- X ri * DCTSIZE - 1, DCTSIZE);
- X }
- X }
- X
- X /* Unsubsample the data */
- X /* First time through is a special case */
- X
- X if (cur_mcu_row) {
- X /* Expand last row group of previous set */
- X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
- X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
- X (short) (DCTSIZE-1));
- X /* and dump the previous set's expanded data */
- X emit_1pass (cinfo, rows_in_mem, fullsize_data, NULL);
- X pixel_rows_output += rows_in_mem;
- X /* Expand first row group of this set */
- X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
- X (short) (DCTSIZE+1), (short) 0, (short) 1,
- X (short) 0);
- X } else {
- X /* Expand first row group with dummy above-context */
- X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
- X (short) (-1), (short) 0, (short) 1,
- X (short) 0);
- X }
- X /* Expand second through next-to-last row groups of this set */
- X for (i = 1; i <= DCTSIZE-2; i++) {
- X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
- X (short) (i-1), (short) i, (short) (i+1),
- X (short) i);
- X }
- X } /* end of outer loop */
- X
- X /* Expand the last row group with dummy below-context */
- X /* Note whichss points to last buffer side used */
- X expand(cinfo, subsampled_data[whichss], fullsize_data, fullsize_width,
- X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
- X (short) (DCTSIZE-1));
- X /* and dump the remaining data (may be less than full height) */
- X emit_1pass (cinfo, (int) (cinfo->image_height - pixel_rows_output),
- X fullsize_data, NULL);
- X
- X /* Clean up after the scan */
- X (*cinfo->methods->disassemble_term) (cinfo);
- X (*cinfo->methods->unsubsample_term) (cinfo);
- X (*cinfo->methods->entropy_decoder_term) (cinfo);
- X (*cinfo->methods->read_scan_trailer) (cinfo);
- X cinfo->completed_passes++;
- X
- X /* Verify that we've seen the whole input file */
- X if ((*cinfo->methods->read_scan_header) (cinfo))
- X ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
- X
- X /* Release working memory */
- X /* (no work -- we let free_all release what's needful) */
- X}
- X
- X
- X/*
- X * Decompression pipeline controller used for multiple-scan files
- X * and/or 2-pass color quantization.
- X *
- X * The current implementation places the "big" buffer at the stage of
- X * desubsampled, non-color-processed data. This is the only place that
- X * makes sense when doing 2-pass quantization. For processing multiple-scan
- X * files without 2-pass quantization, it would be possible to develop another
- X * controller that buffers the subsampled data instead, thus reducing the size
- X * of the temp files (by about a factor of 2 in typical cases). However,
- X * our present unsubsampling logic is dependent on the assumption that
- X * unsubsampling occurs during a scan, so it's much easier to do the
- X * enlargement as the JPEG file is read. This also simplifies life for the
- X * memory manager, which would otherwise have to deal with overlapping
- X * access_big_sarray() requests.
- X * At present it appears that most JPEG files will be single-scan,
- X * so it doesn't seem worthwhile to worry about this optimization.
- X */
- X
- X#ifdef NEED_COMPLEX_CONTROLLER
- X
- XMETHODDEF void
- Xcomplex_dcontroller (decompress_info_ptr cinfo)
- X{
- X long fullsize_width; /* # of samples per row in full-size buffers */
- X long cur_mcu_row; /* counts # of MCU rows processed */
- X long pixel_rows_output; /* # of pixel rows actually emitted */
- X int mcu_rows_per_loop; /* # of MCU rows processed per outer loop */
- X /* Work buffer for dequantized coefficients (IDCT input) */
- X JBLOCKIMAGE coeff_data;
- X /* Work buffer for cross-block smoothing input */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X JBLOCKIMAGE bsmooth[3]; /* this is optional */
- X int whichb;
- X#endif
- X /* Work buffer for subsampled image data (see comments at head of file) */
- X JSAMPIMAGE subsampled_data[2];
- X int whichss, ri;
- X short ci, i;
- X boolean single_scan;
- X
- X /* Compute dimensions of full-size pixel buffers */
- X /* Note these are the same whether interleaved or not. */
- X rows_in_mem = cinfo->max_v_samp_factor * DCTSIZE;
- X fullsize_width = jround_up(cinfo->image_width,
- X (long) (cinfo->max_h_samp_factor * DCTSIZE));
- X
- X /* Allocate all working memory that doesn't depend on scan info */
- X /* output_workspace is the color-processed data */
- X output_workspace = alloc_sampimage(cinfo, (int) cinfo->final_out_comps,
- X (long) rows_in_mem, fullsize_width);
- X
- X /* Get a big image: fullsize_image is sample data after unsubsampling. */
- X fullsize_image = (big_sarray_ptr *) (*cinfo->emethods->alloc_small)
- X (cinfo->num_components * SIZEOF(big_sarray_ptr));
- X for (ci = 0; ci < cinfo->num_components; ci++) {
- X fullsize_image[ci] = (*cinfo->emethods->request_big_sarray)
- X (fullsize_width,
- X jround_up(cinfo->image_height, (long) rows_in_mem),
- X (long) rows_in_mem);
- X }
- X /* Also get an area for pointers to currently accessible chunks */
- X fullsize_ptrs = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
- X (cinfo->num_components * SIZEOF(JSAMPARRAY));
- X
- X /* Tell the memory manager to instantiate big arrays */
- X (*cinfo->emethods->alloc_big_arrays)
- X /* extra sarray space is for subsampled-data buffers: */
- X ((long) (fullsize_width /* max width in samples */
- X * cinfo->max_v_samp_factor*(DCTSIZE+2) /* max height */
- X * cinfo->num_components), /* max components per scan */
- X /* extra barray space is for MCU-row buffers: */
- X (long) ((fullsize_width / DCTSIZE) /* max width in blocks */
- X * cinfo->max_v_samp_factor /* max height */
- X * cinfo->num_components /* max components per scan */
- X * (cinfo->do_block_smoothing ? 4 : 1)),/* how many of these we need */
- X /* no extra "medium"-object space */
- X (long) 0);
- X /* NB: if quantizer needs any "medium" size objects, it must get them */
- X /* at color_quant_init time */
- X
- X /* If file is single-scan, we can do color quantization prescan on-the-fly
- X * during the scan (we must be doing 2-pass quantization, else this method
- X * would not have been selected). If it is multiple scans, we have to make
- X * a separate pass after we've collected all the components. (We could save
- X * some I/O by doing CQ prescan during the last scan, but the extra logic
- X * doesn't seem worth the trouble.)
- X */
- X
- X single_scan = (cinfo->comps_in_scan == cinfo->num_components);
- X
- X /* Account for passes needed (color quantizer adds its passes separately).
- X * If multiscan file, we guess that each component has its own scan,
- X * and increment completed_passes by the number of components in the scan.
- X */
- X
- X if (single_scan)
- X cinfo->total_passes++; /* the single scan */
- X else {
- X cinfo->total_passes += cinfo->num_components; /* guessed # of scans */
- X if (cinfo->two_pass_quantize)
- X cinfo->total_passes++; /* account for separate CQ prescan pass */
- X }
- X if (! cinfo->two_pass_quantize)
- X cinfo->total_passes++; /* count output pass unless quantizer does it */
- X
- X /* Loop over scans in file */
- X
- X do {
- X
- X /* Prepare for this scan */
- X if (cinfo->comps_in_scan == 1) {
- X noninterleaved_scan_setup(cinfo);
- X /* Need to read Vk MCU rows to obtain Vk block rows */
- X mcu_rows_per_loop = cinfo->cur_comp_info[0]->v_samp_factor;
- X } else {
- X interleaved_scan_setup(cinfo);
- X /* in an interleaved scan, one MCU row provides Vk block rows */
- X mcu_rows_per_loop = 1;
- X }
- X
- X /* Allocate scan-local working memory */
- X /* coeff_data holds a single MCU row of coefficient blocks */
- X coeff_data = alloc_MCU_row(cinfo);
- X /* if doing cross-block smoothing, need extra space for its input */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing) {
- X bsmooth[0] = alloc_MCU_row(cinfo);
- X bsmooth[1] = alloc_MCU_row(cinfo);
- X bsmooth[2] = alloc_MCU_row(cinfo);
- X }
- X#endif
- X /* subsampled_data is sample data before unsubsampling */
- X alloc_sampling_buffer(cinfo, subsampled_data);
- X
- X /* line up the big buffers for components in this scan */
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
- X (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
- X (long) 0, TRUE);
- X }
- X
- X /* Initialize to read scan data */
- X
- X (*cinfo->methods->entropy_decoder_init) (cinfo);
- X (*cinfo->methods->unsubsample_init) (cinfo);
- X (*cinfo->methods->disassemble_init) (cinfo);
- X
- X /* Loop over scan's data: rows_in_mem pixel rows are processed per loop */
- X
- X pixel_rows_output = 0;
- X whichss = 1; /* arrange to start with subsampled_data[0] */
- X
- X for (cur_mcu_row = 0; cur_mcu_row < cinfo->MCU_rows_in_scan;
- X cur_mcu_row += mcu_rows_per_loop) {
- X (*cinfo->methods->progress_monitor) (cinfo, cur_mcu_row,
- X cinfo->MCU_rows_in_scan);
- X
- X whichss ^= 1; /* switch to other subsample buffer */
- X
- X /* Obtain v_samp_factor block rows of each component in the scan. */
- X /* This is a single MCU row if interleaved, multiple MCU rows if not. */
- X /* In the noninterleaved case there might be fewer than v_samp_factor */
- X /* block rows remaining; if so, pad with copies of the last pixel row */
- X /* so that unsubsampling doesn't have to treat it as a special case. */
- X
- X for (ri = 0; ri < mcu_rows_per_loop; ri++) {
- X if (cur_mcu_row + ri < cinfo->MCU_rows_in_scan) {
- X /* OK to actually read an MCU row. */
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing)
- X get_smoothed_row(cinfo, coeff_data,
- X bsmooth, &whichb, cur_mcu_row + ri);
- X else
- X#endif
- X (*cinfo->methods->disassemble_MCU) (cinfo, coeff_data);
- X
- X (*cinfo->methods->reverse_DCT) (cinfo, coeff_data,
- X subsampled_data[whichss],
- X ri * DCTSIZE);
- X } else {
- X /* Need to pad out with copies of the last subsampled row. */
- X /* This can only happen if there is just one component. */
- X duplicate_row(subsampled_data[whichss][0],
- X cinfo->cur_comp_info[0]->subsampled_width,
- X ri * DCTSIZE - 1, DCTSIZE);
- X }
- X }
- X
- X /* Unsubsample the data */
- X /* First time through is a special case */
- X
- X if (cur_mcu_row) {
- X /* Expand last row group of previous set */
- X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) DCTSIZE, (short) (DCTSIZE+1), (short) 0,
- X (short) (DCTSIZE-1));
- X /* If single scan, can do color quantization prescan on-the-fly */
- X if (single_scan)
- X (*cinfo->methods->color_quant_prescan) (cinfo, rows_in_mem,
- X fullsize_ptrs,
- X output_workspace[0]);
- X /* Realign the big buffers */
- X pixel_rows_output += rows_in_mem;
- X for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
- X fullsize_ptrs[ci] = (*cinfo->emethods->access_big_sarray)
- X (fullsize_image[cinfo->cur_comp_info[ci]->component_index],
- X pixel_rows_output, TRUE);
- X }
- X /* Expand first row group of this set */
- X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) (DCTSIZE+1), (short) 0, (short) 1,
- X (short) 0);
- X } else {
- X /* Expand first row group with dummy above-context */
- X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) (-1), (short) 0, (short) 1,
- X (short) 0);
- X }
- X /* Expand second through next-to-last row groups of this set */
- X for (i = 1; i <= DCTSIZE-2; i++) {
- X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) (i-1), (short) i, (short) (i+1),
- X (short) i);
- X }
- X } /* end of loop over scan's data */
- X
- X /* Expand the last row group with dummy below-context */
- X /* Note whichss points to last buffer side used */
- X expand(cinfo, subsampled_data[whichss], fullsize_ptrs, fullsize_width,
- X (short) (DCTSIZE-2), (short) (DCTSIZE-1), (short) (-1),
- X (short) (DCTSIZE-1));
- X /* If single scan, finish on-the-fly color quantization prescan */
- X if (single_scan)
- X (*cinfo->methods->color_quant_prescan) (cinfo,
- X (int) (cinfo->image_height - pixel_rows_output),
- X fullsize_ptrs, output_workspace[0]);
- X
- X /* Clean up after the scan */
- X (*cinfo->methods->disassemble_term) (cinfo);
- X (*cinfo->methods->unsubsample_term) (cinfo);
- X (*cinfo->methods->entropy_decoder_term) (cinfo);
- X (*cinfo->methods->read_scan_trailer) (cinfo);
- X if (single_scan)
- X cinfo->completed_passes++;
- X else
- X cinfo->completed_passes += cinfo->comps_in_scan;
- X
- X /* Release scan-local working memory */
- X free_MCU_row(cinfo, coeff_data);
- X#ifdef BLOCK_SMOOTHING_SUPPORTED
- X if (cinfo->do_block_smoothing) {
- X free_MCU_row(cinfo, bsmooth[0]);
- X free_MCU_row(cinfo, bsmooth[1]);
- X free_MCU_row(cinfo, bsmooth[2]);
- X }
- X#endif
- X free_sampling_buffer(cinfo, subsampled_data);
- X
- X /* Repeat if there is another scan */
- X } while ((!single_scan) && (*cinfo->methods->read_scan_header) (cinfo));
- X
- X if (single_scan) {
- X /* If we expected just one scan, make SURE there's just one */
- X if ((*cinfo->methods->read_scan_header) (cinfo))
- X ERREXIT(cinfo->emethods, "Didn't expect more than one scan");
- X /* We did the CQ prescan on-the-fly, so we are all set. */
- X } else {
- X /* For multiple-scan file, do the CQ prescan as a separate pass. */
- X /* The main reason why prescan is passed the output_workspace is */
- X /* so that we can use scan_big_image to call it... */
- X if (cinfo->two_pass_quantize)
- X scan_big_image(cinfo, cinfo->methods->color_quant_prescan);
- X }
- X
- X /* Now that we've collected the data, do color processing and output */
- X if (cinfo->two_pass_quantize)
- X (*cinfo->methods->color_quant_doit) (cinfo, scan_big_image);
- X else
- X scan_big_image(cinfo, emit_1pass);
- X
- X /* Release working memory */
- X /* (no work -- we let free_all release what's needful) */
- X}
- X
- X#endif /* NEED_COMPLEX_CONTROLLER */
- X
- X
- X/*
- X * The method selection routine for decompression pipeline controllers.
- X * Note that at this point we've already read the JPEG header and first SOS,
- X * so we can tell whether the input is one scan or not.
- X */
- X
- XGLOBAL void
- Xjseldpipeline (decompress_info_ptr cinfo)
- X{
- X /* simplify subsequent tests on color quantization */
- X if (! cinfo->quantize_colors)
- X cinfo->two_pass_quantize = FALSE;
- X
- X if (cinfo->comps_in_scan == cinfo->num_components) {
- X /* It's a single-scan file */
- X if (cinfo->two_pass_quantize) {
- X#ifdef NEED_COMPLEX_CONTROLLER
- X cinfo->methods->d_pipeline_controller = complex_dcontroller;
- X#else
- X ERREXIT(cinfo->emethods, "2-pass quantization support was not compiled");
- X#endif
- X } else
- X cinfo->methods->d_pipeline_controller = simple_dcontroller;
- X } else {
- X /* It's a multiple-scan file */
- X#ifdef NEED_COMPLEX_CONTROLLER
- X cinfo->methods->d_pipeline_controller = complex_dcontroller;
- X#else
- X ERREXIT(cinfo->emethods, "Multiple-scan support was not compiled");
- X#endif
- X }
- X}
- END_OF_FILE
- if test 36733 -ne `wc -c <'jdpipe.c'`; then
- echo shar: \"'jdpipe.c'\" unpacked with wrong size!
- fi
- # end of 'jdpipe.c'
- fi
- echo shar: End of archive 3 \(of 18\).
- cp /dev/null ark3isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 18 archives.
- rm -f ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-