home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Black Box 4
/
BlackBox.cdr
/
progc
/
jpeg3.arj
/
JDMCU.C
< prev
next >
Wrap
C/C++ Source or Header
|
1992-01-17
|
6KB
|
220 lines
/*
* jdmcu.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 MCU disassembly routines and quantization descaling.
* These routines are invoked via the disassemble_MCU, reverse_DCT, and
* disassemble_init/term methods.
*/
#include "jinclude.h"
/*
* Quantization descaling and zigzag reordering
*/
/* ZAG[i] is the natural-order position of the i'th element of zigzag order. */
static const short ZAG[DCTSIZE2] = {
0, 1, 8, 16, 9, 2, 3, 10,
17, 24, 32, 25, 18, 11, 4, 5,
12, 19, 26, 33, 40, 48, 41, 34,
27, 20, 13, 6, 7, 14, 21, 28,
35, 42, 49, 56, 57, 50, 43, 36,
29, 22, 15, 23, 30, 37, 44, 51,
58, 59, 52, 45, 38, 31, 39, 46,
53, 60, 61, 54, 47, 55, 62, 63
};
LOCAL void
qdescale_zig (JBLOCK input, JBLOCKROW outputptr, QUANT_TBL_PTR quanttbl)
{
const short * zagptr = ZAG;
short i;
for (i = DCTSIZE2-1; i >= 0; i--) {
(*outputptr)[*zagptr++] = (*input++) * (*quanttbl++);
}
}
/*
* Fetch one MCU row from entropy_decode, build coefficient array.
* This version is used for noninterleaved (single-component) scans.
*/
METHODDEF void
disassemble_noninterleaved_MCU (decompress_info_ptr cinfo,
JBLOCKIMAGE image_data)
{
JBLOCK MCU_data[1];
long mcuindex;
jpeg_component_info * compptr;
QUANT_TBL_PTR quant_ptr;
/* this is pretty easy since there is one component and one block per MCU */
compptr = cinfo->cur_comp_info[0];
quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
/* Fetch the coefficient data */
(*cinfo->methods->entropy_decode) (cinfo, MCU_data);
/* Descale, reorder, and distribute it into the image array */
qdescale_zig(MCU_data[0], image_data[0][0] + mcuindex, quant_ptr);
}
}
/*
* Fetch one MCU row from entropy_decode, build coefficient array.
* This version is used for interleaved (multi-component) scans.
*/
METHODDEF void
disassemble_interleaved_MCU (decompress_info_ptr cinfo,
JBLOCKIMAGE image_data)
{
JBLOCK MCU_data[MAX_BLOCKS_IN_MCU];
long mcuindex;
short blkn, ci, xpos, ypos;
jpeg_component_info * compptr;
QUANT_TBL_PTR quant_ptr;
JBLOCKROW image_ptr;
for (mcuindex = 0; mcuindex < cinfo->MCUs_per_row; mcuindex++) {
/* Fetch the coefficient data */
(*cinfo->methods->entropy_decode) (cinfo, MCU_data);
/* Descale, reorder, and distribute it into the image array */
blkn = 0;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
compptr = cinfo->cur_comp_info[ci];
quant_ptr = cinfo->quant_tbl_ptrs[compptr->quant_tbl_no];
for (ypos = 0; ypos < compptr->MCU_height; ypos++) {
image_ptr = image_data[ci][ypos] + (mcuindex * compptr->MCU_width);
for (xpos = 0; xpos < compptr->MCU_width; xpos++) {
qdescale_zig(MCU_data[blkn], image_ptr, quant_ptr);
image_ptr++;
blkn++;
}
}
}
}
}
/*
* Perform inverse DCT on each block in an MCU row's worth of data;
* output the results into a sample array starting at row start_row.
* NB: start_row can only be nonzero when dealing with a single-component
* scan; otherwise we'd have to pass different offsets for different
* components, since the heights of interleaved MCU rows can vary.
* But the pipeline controller logic is such that this is not necessary.
*/
METHODDEF void
reverse_DCT (decompress_info_ptr cinfo,
JBLOCKIMAGE coeff_data, JSAMPIMAGE output_data, int start_row)
{
DCTBLOCK block;
JBLOCKROW browptr;
JSAMPARRAY srowptr;
long blocksperrow, bi;
short numrows, ri;
short ci;
for (ci = 0; ci < cinfo->comps_in_scan; ci++) {
/* calculate size of an MCU row in this component */
blocksperrow = cinfo->cur_comp_info[ci]->subsampled_width / DCTSIZE;
numrows = cinfo->cur_comp_info[ci]->MCU_height;
/* iterate through all blocks in MCU row */
for (ri = 0; ri < numrows; ri++) {
browptr = coeff_data[ci][ri];
srowptr = output_data[ci] + (ri * DCTSIZE + start_row);
for (bi = 0; bi < blocksperrow; bi++) {
/* copy the data into a local DCTBLOCK. This allows for change of
* representation (if DCTELEM != JCOEF). On 80x86 machines it also
* brings the data back from FAR storage to NEAR storage.
*/
{ register JCOEFPTR elemptr = browptr[bi];
register DCTELEM *localblkptr = block;
register short elem = DCTSIZE2;
while (--elem >= 0)
*localblkptr++ = (DCTELEM) *elemptr++;
}
j_rev_dct(block); /* perform inverse DCT */
/* output the data into the sample array.
* Note change from signed to unsigned representation:
* DCT calculation works with values +-CENTERJSAMPLE,
* but sample arrays always hold 0..MAXJSAMPLE.
* Have to do explicit range-limiting because of quantization errors
* and so forth in the DCT/IDCT phase.
*/
{ register JSAMPROW elemptr;
register DCTELEM *localblkptr = block;
register short elemr, elemc;
register DCTELEM temp;
for (elemr = 0; elemr < DCTSIZE; elemr++) {
elemptr = srowptr[elemr] + (bi * DCTSIZE);
for (elemc = 0; elemc < DCTSIZE; elemc++) {
temp = (*localblkptr++) + CENTERJSAMPLE;
if (temp < 0) temp = 0;
else if (temp > MAXJSAMPLE) temp = MAXJSAMPLE;
*elemptr++ = (JSAMPLE) temp;
}
}
}
}
}
}
}
/*
* Initialize for processing a scan.
*/
METHODDEF void
disassemble_init (decompress_info_ptr cinfo)
{
/* no work for now */
}
/*
* Clean up after a scan.
*/
METHODDEF void
disassemble_term (decompress_info_ptr cinfo)
{
/* no work for now */
}
/*
* The method selection routine for MCU disassembly.
*/
GLOBAL void
jseldmcu (decompress_info_ptr cinfo)
{
if (cinfo->comps_in_scan == 1)
cinfo->methods->disassemble_MCU = disassemble_noninterleaved_MCU;
else
cinfo->methods->disassemble_MCU = disassemble_interleaved_MCU;
cinfo->methods->reverse_DCT = reverse_DCT;
cinfo->methods->disassemble_init = disassemble_init;
cinfo->methods->disassemble_term = disassemble_term;
}