📄 decompress.c
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company */
/* All rights reserved */
/* File: "decompress.c" */
/* Description: Invocation environment for decompression. */
/* Author: David Taubman */
/* Affiliation: Hewlett-Packard and */
/* The University of New South Wales, Australia */
/* Version: VM8.5 */
/* Last Revised: 11 September, 2000 */
/*****************************************************************************/
/*****************************************************************************/
/* Modified to incorporate optional entropy coder */
/* Copyright 1999 Science Applications International Corporation (SAIC). */
/* All Rights Reserved for modified parts. */
/*****************************************************************************/
/*****************************************************************************/
/* Modified by David Taubman to support arbitrary reference points for the */
/* transform and the various regular partitions, so as to facilitate */
/* cropping and geometric transformations in the compressed domain and to */
/* enable full support for CRF's single-sample overlap Wavelet transform, */
/* as originally documented in Seoul. Changes are too numerous to flag */
/* individually within the code. Changes copyrighted by HP with all rights */
/* reserved for the modified parts. */
/*****************************************************************************/
/*****************************************************************************/
/* Modified by David Taubman to support interface modifications, arbitrary */
/* changes in coding parameters from component to component and from tile */
/* to tile, to support the full generality of PART-1 of the JPEG2000 */
/* standard, and to support most anticipated generality of PART-2. Changes */
/* are too numerous to flag individually within the code, which in some */
/* places has been completely rewritten. All changes copyrighted by HP with */
/* all rights reserved for the modified parts. */
/*****************************************************************************/
/*****************************************************************************/
/* Modified by David Taubman to allow overlapping tiles. Changes */
/* copyrighted by HP with all rights reserved for the modified parts. */
/*****************************************************************************/
/*****************************************************************************/
/* Modified by David Taubman to implement changes in Tokyo between CD and */
/* FCD for Part-1 of the standard. Copyrighted by HP with all rights */
/* reserved for the modified parts. */
/*****************************************************************************/
/*****************************************************************************/
/* Modified for general offset and scalar quantization. */
/* Copyright 2000 The MITRE Corporation. */
/* All Rights Reserved for modified parts. */
/*****************************************************************************/
/*****************************************************************************/
/* Compilation directives involving "_WIN32" added by David Taubman to avoid */
/* problems caused by EKC raw image I/O code. */
/*****************************************************************************/
/*****************************************************************************/
/* Compilation problems caused by EKC raw image I/O code should hopefully be */
/* fixed. Therefore, compilation directives involving "_WIN32" added by */
/* David Taubman have been taken out. */
/*****************************************************************************/
/*****************************************************************************/
/* Modified by Jianxin Wei, Australian Defence Force Academy (ADFA) */
/* to implement the Odd Tile-Size Low-Pass First Convention (OTLPF_CONVENTION)*/
/* Copyright 2000 University of New South Wales, Australia. */
/* All rights reserved for modified parts. */
/*****************************************************************************/
#include <local_services.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <ifc.h>
#include <image_io.h>
#include <markers.h>
#include "decompress_local.h"
/* STOP: THERE SHOULD HARDLY EVER BE ANY REASON TO CHANGE THIS FILE.
IF YOU ARE ABOUT TO DO SO THEN YOU HAVE PROBABLY NOT UNDERSTOOD
THE MODULAR PRINCIPLES BEHIND VM3A. */
/* ========================================================================= */
/* -------------------------- Internal Functions --------------------------- */
/* ========================================================================= */
/*****************************************************************************/
/* STATIC adjust_tile_dims */
/*****************************************************************************/
static void
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
adjust_tile_dims(canvas_dims_ptr dims, int level_reduction,
reverse_info_ref info, int tnum, int otlpf_convention)
{
int xnum, ynum, factor, twidth, hor_offset, vert_offset, hor_subsampling, vert_subsampling;
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
int ax, ay, bx, by;
ax = dims->left_col; bx = ax + dims->cols;
ay = dims->top_row; by = ay + dims->rows;
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
if(otlpf_convention)
{
info->get_fixed_tile_info(info, 0,
tnum, &xnum, &ynum, NULL,
&hor_subsampling, &vert_subsampling,
&hor_offset, &vert_offset, NULL, NULL,NULL);
factor = 1 << level_reduction;
twidth = (bx - ax + factor -1)/factor;
ax = info->new_otlpf_sub_band(0, ax, factor, xnum, hor_offset, hor_subsampling);
bx = ax + twidth;
twidth = (by - ay + factor -1)/factor;
ay = info->new_otlpf_sub_band(0, ay, factor, ynum, vert_offset, vert_subsampling);
by = ay + twidth;
}
else
{
ax = 1+((ax-1)>>level_reduction); ay = 1+((ay-1)>>level_reduction);
bx = 1+((bx-1)>>level_reduction); by = 1+((by-1)>>level_reduction);
}
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
dims->left_col = ax; dims->top_row = ay;
dims->cols = bx - ax; dims->rows = by - ay;
}
/*****************************************************************************/
/* STATIC get_output_dims */
/*****************************************************************************/
static int
get_output_dims(reverse_info_ref info, int components,
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
int otlpf_convention,
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
int level_reduction, canvas_dims_ptr dims)
{
int n, tnum=0, xnum, ynum; /* TJF: =0 to avoid warnings */
canvas_dims tmp_dims;
for (n=0; n < components; n++)
{
dims[n].rows = dims[n].cols = 0;
tnum = 0;
/* MITRE General Offset/SQ Begin */
while (info->get_fixed_tile_info(info,n,tnum,&xnum,&ynum,&tmp_dims,
NULL,NULL,NULL,NULL,NULL,NULL,NULL))
/* MITRE General Offset/SQ End */
{
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
adjust_tile_dims(&tmp_dims, level_reduction, info, tnum, otlpf_convention);
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
if (xnum == 0)
dims[n].rows += tmp_dims.rows;
if (ynum == 0)
dims[n].cols += tmp_dims.cols;
tnum++;
}
}
return(tnum);
}
/*****************************************************************************/
/* STATIC get_image_row */
/*****************************************************************************/
static ifc_int *
get_image_row(dec_component_info_ptr component, int idx)
/* This function returns a pointer to an image row buffer whose
location, relative to the start of the current vertical tile
partition is given by `idx'. Legal values of `idx' may range from
-1 through to `component->tile_rows', since there may be an overlap
of up to 1 row at the top or bottom of the tile partition. The
caller will usually proceed to write data into the row buffer, but
may accumulate data into the buffer if it is known to contain
existing samples from an overlap. The image data will not be written
to an actual file until the `release_image_row' function is called. */
{
int r;
assert((idx >= -1) && (idx <= component->tile_rows));
idx -= component->min_buffer_row_idx;
assert(idx >= 0);
while ((r = component->num_buffer_rows) <= idx)
{
component->num_buffer_rows++;
if (component->num_buffer_rows > component->max_buffer_rows)
{
component->max_buffer_rows++;
component->buffer = (ifc_int **)
local_realloc(component->buffer,
sizeof(ifc_int *)*component->max_buffer_rows);
component->buffer[r] = (ifc_int *)
local_malloc(INVOCATION_MEM_KEY,sizeof(ifc_int)*component->cols);
}
}
return(component->buffer[idx]);
}
/*****************************************************************************/
/* STATIC release_image_row */
/*****************************************************************************/
static void
release_image_row(dec_component_info_ptr component, int comp_idx,
int idx, image_writer_ref writer)
/* This function is called when we can be sure that the indicated image
row will not be accessed again. By assumption, none of the preceding
rows will be accessed again either. The row itself is identified
relative to the start of the current vertical tile partition, so the
`idx' value may be negative. If the row is not currently in the buffer
then no action is taken; otherwise, the row is flushed from the buffer
to the `writer' object. */
{
int r, k;
ifc_int *tmp;
idx -= component->min_buffer_row_idx;
assert(idx < component->num_buffer_rows);
for (r=0; r <= idx; r++)
{ /* Release row `r'. */
component->min_buffer_row_idx++;
component->num_buffer_rows--;
tmp = component->buffer[0];
for (k=0; k < component->num_buffer_rows; k++)
component->buffer[k] = component->buffer[k+1];
component->buffer[k] = tmp;
writer->push_line(writer,tmp,comp_idx,component->cols);
}
}
/*****************************************************************************/
/* STATIC decompress_and_write_the_image */
/*****************************************************************************/
static void
decompress_and_write_the_image(reverse_info_ref info,
image_writer_ref writer,
component_demix_ref demixer,
int num_components,
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
int otlpf_convention,
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
int level_reduction)
{
dec_component_info_ptr comps;
int n, k, max_rows, max_cols, precision, done;
int tnum, xnum, ynum;
int tiles_across=0, tiles_down=0; /* TJF: =0 to avoid warnings */
ifc_int *buf, *work;
/* Initialize component information structures with basic details first. */
comps = (dec_component_info_ptr)
local_malloc(INVOCATION_MEM_KEY,sizeof(dec_component_info)*num_components);
max_rows = max_cols = 0;
for (n=0; n < num_components; n++)
{
canvas_dims dims;
tnum = 0;
tiles_across = tiles_down = 0;
/* MITRE General Offset/SQ Begin */ /* Begin Aerospace MCT mods */
while (info->get_fixed_tile_info(info,n,tnum,&xnum,&ynum,&dims,
NULL,NULL,NULL,NULL,NULL,&precision,NULL))
/* MITRE General Offset/SQ End */ /* End Aerospace MCT mods */
{
/* OTLPF_CONVENTION begin; JX Wei ADFA, WJ Zeng Sharp */
adjust_tile_dims(&dims, level_reduction, info, tnum, otlpf_convention);
/* OTLPF_CONVENTION end; JX Wei ADFA, WJ Zeng Sharp */
if (xnum == 0)
{ comps[n].rows += dims.rows; tiles_down++; }
if (ynum == 0)
{ comps[n].cols += dims.cols; tiles_across++; }
if (dims.cols > max_cols)
max_cols = dims.cols;
tnum++;
}
if (comps[n].rows > max_rows)
max_rows = comps[n].rows;
comps[n].max_buffer_rows = 1;
comps[n].buffer = (ifc_int **)
local_malloc(INVOCATION_MEM_KEY,sizeof(ifc_int *));
comps[n].buffer[0] = (ifc_int *)
local_malloc(INVOCATION_MEM_KEY,sizeof(ifc_int)*comps[n].cols);
comps[n].tile_bottom_ovlp = (int *)
local_malloc(INVOCATION_MEM_KEY,sizeof(int)*tiles_across);
}
work = (ifc_int *)
local_malloc(INVOCATION_MEM_KEY,sizeof(ifc_int)*(max_cols+2));
/* Now set the relative line processing rates for the components to
maximize locality in row accesses from multiple component images. */
for (n=0; n < num_components; n++)
comps[n].line_rate = ((float)(comps[n].rows)) / ((float) max_rows);
/* Now walk through the tiles in scan-line order. */
for (tnum=0, ynum=0; ynum < tiles_down; ynum++)
{
for (n=0; n < num_components; n++)
{ /* Set up new vertical tile partition. */
if (ynum == 0)
{
comps[n].min_buffer_row_idx = 0;
comps[n].num_buffer_rows = 0;
}
else
comps[n].min_buffer_row_idx -= comps[n].tile_rows;
comps[n].row_offset = 0;
comps[n].last_right_ovlp = 0;
}
for (xnum=0; xnum < tiles_across; xnum++, tnum++)
{
/* Set up tile-specific parameters. */
/*Begin Aerospace MCT mods (TSW) */
int multicomp_xform;
/* End Aerospace MCT mods */
for (n=0; n < num_components; n++)
{
canvas_dims fix_dims, var_dims;
int downshift; /* MITRE */
double dc_offset; /* MITRE */
/* MITRE General Offset/SQ Begin */ /*Begin Aerospace MCT mods (TSW) */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -