home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 2
/
FFMCD02.bin
/
new
/
gfx
/
edit
/
tsmorph
/
jpeg_ls
/
jdpipe.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-21
|
38KB
|
1,049 lines
/*
* jdpipe.c
*
* Copyright (C) 1991, 1992, Thomas G. Lane.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains decompression pipeline controllers.
* These routines are invoked via the d_pipeline_controller method.
*
* There are two basic pipeline controllers. The simpler one handles a
* single-scan JPEG file (single component or fully interleaved) with no
* color quantization or 1-pass quantization. In this case, the file can
* be processed in one top-to-bottom pass. The more complex controller is
* used when 2-pass color quantization is requested and/or the JPEG file
* has multiple scans (noninterleaved or partially interleaved). In this
* case, the entire image must be buffered up in a "big" array.
*
* If you need to make a minimal implementation, the more complex controller
* can be compiled out by disabling the appropriate configuration options.
* We don't recommend this, since then you can't handle all legal JPEG files.
*/
#include "jinclude.h"
#ifdef D_MULTISCAN_FILES_SUPPORTED /* wish we could assume ANSI's defined() */
#define NEED_COMPLEX_CONTROLLER
#else
#ifdef QUANT_2PASS_SUPPORTED
#define NEED_COMPLEX_CONTROLLER
#endif
#endif
/*
* About the data structures:
*
* The processing chunk size for upsampling is referred to in this file as
* a "row group": a row group is defined as Vk (v_samp_factor) sample rows of
* any component while downsampled, or Vmax (max_v_samp_factor) unsubsampled
* rows. In an interleaved scan each MCU row contains exactly DCTSIZE row
* groups of each component in the scan. In a noninterleaved scan an MCU row
* is one row of blocks, which might not be an integral number of row groups;
* therefore, we read in Vk MCU rows to obtain the same amount of data as we'd
* have in an interleaved scan.
* To provide context for the upsampling step, we have to retain the last
* two row groups of the previous MCU row while reading in the next MCU row
* (or set of Vk MCU rows). To do this without copying data about, we create
* a rather strange data structure. Exactly DCTSIZE+2 row groups of samples
* are allocated, but we create two different sets of pointers to this array.
* The second set swaps the last two pairs of row groups. By working
* alternately with the two sets of pointers, we can access the data in the
* desired order.
*
* Cross-block smoothing also needs context above and below the "current" row.
* Since this is an optional feature, I've implemented it in a way that is
* much simpler but requires more than the minimum amount of memory. We
* simply allocate three extra MCU rows worth of coefficient blocks and use
* them to "read ahead" one MCU row in the file. For a typical 1000-pixel-wide
* image with 2x2,1x1,1x1 sampling, each MCU row is about 50Kb; an 80x86
* machine may be unable to apply cross-block smoothing to wider images.
*/
/*
* These variables are logically local to the pipeline controller,
* but we make them static so that scan_big_image can use them
* without having to pass them through the quantization routines.
*/
static int rows_in_mem; /* # of sample rows in full-size buffers */
/* Work buffer for data being passed to output module. */
/* This has color_out_comps components if not quantizing, */
/* but only one component when quantizing. */
static JSAMPIMAGE output_workspace;
#ifdef NEED_COMPLEX_CONTROLLER
/* Full-size image array holding upsampled, but not color-processed data. */
static big_sarray_ptr *fullsize_image;
static JSAMPIMAGE fullsize_ptrs; /* workspace for access_big_sarray() result */
#endif
/*
* Utility routines: common code for pipeline controllers
*/
LOCAL void
interleaved_scan_setup (decompress_info_ptr cinfo)
/* Compute all derived info for an interleaved (multi-component) scan */
/* On entry, cinfo->comps_in_scan and cinfo->cur_comp_info[] are set up */
{
short ci, mcublks;
jpeg_component_info *compptr;
if (cinfo->comps_in_scan > MAX_COMPS_IN_SCAN)
ERREXIT(cinfo->emethods, "Too many components for interleaved scan");
cinfo->MCUs_per_row = (cinfo->image_width
+ cinfo->max_h_samp_factor*DCTSIZE - 1)
/ (cinfo->max_h_samp_factor*DCTSIZE);
cinfo->MCU_rows_in_scan = (cinfo->image_height
+ cinfo->max_v_samp_factor*DCTSIZE - 1)
/ (cinfo->max_v_samp_factor*DCTSIZE);
cinfo->blocks_in_MCU = 0;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
/* for interleaved scan, sampling factors give # of blocks per component */
compptr->MCU_width = compptr->h_samp_factor;
compptr->MCU_height = compptr->v_samp_factor;
compptr->MCU_blocks = compptr->MCU_width * compptr->MCU_height;
/* compute physical dimensions of component */
compptr->downsampled_width = jround_up(compptr->true_comp_width,
(long) (compptr->MCU_width*DCTSIZE));
compptr->downsampled_height = jround_up(compptr->true_comp_height,
(long) (compptr->MCU_height*DCTSIZE));
/* Sanity check */
if (compptr->downsampled_width !=
(cinfo->MCUs_per_row * (compptr->MCU_width*DCTSIZE)))
ERREXIT(cinfo->emethods, "I'm confused about the image width");
/* Prepare array describing MCU composition */
mcublks = compptr->MCU_blocks;
if (cinfo->blocks_in_MCU + mcublks > MAX_BLOCKS_IN_MCU)
ERREXIT(cinfo->emethods, "Sampling factors too large for interleaved scan");
while (mcublks-- > 0) {
cinfo->MCU_membership[cinfo->blocks_in_MCU++] = ci;
}
}
(*cinfo->methods->d_per_scan_method_selection) (cinfo);
}
LOCAL void
noninterleaved_scan_setup (decompress_info_ptr cinfo)
/* Compute all derived info for a noninterleaved (single-component) scan */
/* On entry, cinfo->comps_in_scan = 1 and cinfo->cur_comp_info[0] is set up */
{
jpeg_component_info *compptr = cinfo->cur_comp_info[0];
/* for noninterleaved scan, always one block per MCU */
compptr->MCU_width = 1;
compptr->MCU_height = 1;
compptr->MCU_blocks = 1;
/* compute physical dimensions of component */
compptr->downsampled_width = jround_up(compptr->true_comp_width,
(long) DCTSIZE);
compptr->downsampled_height = jround_up(compptr->true_comp_height,
(long) DCTSIZE);
cinfo->MCUs_per_row = compptr->downsampled_width / DCTSIZE;
cinfo->MCU_rows_in_scan = compptr->downsampled_height / DCTSIZE;
/* Prepare array describing MCU composition */
cinfo->blocks_in_MCU = 1;
cinfo->MCU_membership[0] = 0;
(*cinfo->methods->d_per_scan_method_selection) (cinfo);
}
LOCAL JSAMPIMAGE
alloc_sampimage (decompress_info_ptr cinfo,
int num_comps, long num_rows, long num_cols)
/* Allocate an in-memory sample image (all components same size) */
{
JSAMPIMAGE image;
int ci;
image = (JSAMPIMAGE) (*cinfo->emethods->alloc_small)
(num_comps * SIZEOF(JSAMPARRAY));
for (ci = 0; ci < num_comps; ci++) {
image[ci] = (*cinfo->emethods->alloc_small_sarray) (num_cols, num_rows);
}
return image;
}
#if 0 /* this routine not currently needed */
LOCAL void
free_sampimage (decompress_info_ptr cinfo, JSAMPIMAGE image, int num_comps)
/* Release a sample image created by alloc_sampimage */
{
int ci;
for (ci = 0; ci < num_comps; ci++) {
(*cinfo->emethods->free_small_sarray) (image[ci]);
}
(*cinfo->emethods->free_small) ((void *) image);
}
#endif
LOCAL JBLOCKIMAGE
alloc_MCU_row (decompress_info_ptr cinfo)
/* Allocate one MCU row's worth of coefficient blocks */
{
JBLOCKIMAGE image;
int ci;
image = (JBLOCKIMAGE) (*cinfo->emethods->alloc_small)
(cinfo->comps_in_scan * SIZEOF(JBLOCKARRAY));
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
image[ci] = (*cinfo->emethods->alloc_small_barray)
(cinfo->cur_comp_info[ci]->downsampled_width / DCTSIZE,
(long) cinfo->cur_comp_info[ci]->MCU_height);
}
return image;
}
#ifdef NEED_COMPLEX_CONTROLLER /* not used by simple controller */
LOCAL void
free_MCU_row (decompress_info_ptr cinfo, JBLOCKIMAGE image)
/* Release a coefficient block array created by alloc_MCU_row */
{
int ci;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
(*ci