📄 decompress.c
字号:
/*****************************************************************************/
/* Copyright 1998, Hewlett-Packard Company */
/* All rights reserved */
/* Author: David Taubman */
/* Version: V2.0 */
/* Last Revised: 9/22/98 */
/*****************************************************************************/
#include <local_heap.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#include <limits.h>
#include <assert.h>
#include <line_block_ifc.h>
#include <decompress_config.h>
#define MAX_COMPONENTS 256
/*****************************************************************************/
/* STATIC local_fopen */
/*****************************************************************************/
static FILE *
local_fopen(char *fname, char *mode)
/* Same as `fopen', but accepts `-' to identify std-output or std-input. */
{
if (strcmp(fname,"-") == 0)
{
#ifdef WIN32
if (strchr(mode,'b') != NULL)
{
fprintf(stderr,"The UNIX \"-\" convention for std-input and/or "
"std-output\n should not be used to open binary files on "
"WIN32 platforms!\n");
exit(-1);
}
#endif
if (strchr(mode,'r') != NULL)
return(stdin);
else
return(stdout);
}
return(fopen(fname,mode));
}
/*****************************************************************************/
/* STATIC local_fclose */
/*****************************************************************************/
static void
local_fclose(FILE *fp)
{
if ((fp != stdin) && (fp != stdout) && (fp != stderr))
fclose(fp);
}
/*****************************************************************************/
/* STATIC print_profile_vector */
/*****************************************************************************/
static void
print_profile_vector(int profile, FILE *dest)
{
fprintf(dest,
" Random access [a] : %s\n"
" SNR progressive [sp]: %s\n"
" SNR parsable (scalable) [ss]: %s\n"
" Resolution progressive [rp]: %s\n"
" Resolution parsable (scalable) [rs]: %s\n"
" Component parsable (scalable) [cs]: %s\n",
(profile & PROFILE__RANDOM_ACCESS)?"YES":"NO",
(profile & PROFILE__SNR_PROGRESSIVE)?"YES":"NO",
(profile & PROFILE__SNR_PARSABLE)?"YES":"NO",
(profile & PROFILE__RESOLUTION_PROGRESSIVE)?"YES":"NO",
(profile & PROFILE__RESOLUTION_PARSABLE)?"YES":"NO",
(profile & PROFILE__COMPONENT_PARSABLE)?"YES":"NO");
}
/*****************************************************************************/
/* STATIC print_usage */
/*****************************************************************************/
static void
print_usage(int default_max_components, int default_max_levels,
float default_max_bpp, char *prog_name, FILE *dest)
{
filter_info_ref info;
synthesis_ref synthesis;
dequantizer_ref dequantizer;
decoder_ref decoder;
bitstream_source_ref bitstream;
fprintf(dest,"\n"
"Usage: \"%s args...\",\n"
" where the following arguments are recognized:\n",prog_name);
fprintf(dest,
" -i <input compressed file> (mandatory)\n");
fprintf(dest,
" -o <output image file> (mandatory; PGM or PPM for now)\n");
fprintf(dest,
" -comp <max components> (default = %d)\n",
default_max_components);
fprintf(dest,
" -lev <max transform levels> (default = %d)\n",
default_max_levels);
fprintf(dest,
" -loc <file name for local filter set> "
"(default = built-in filter set)\n"
" -- only if the same argument was used during compression.\n");
fprintf(dest,
" -rate <max rate in bpp> (default = %g)\n",
default_max_bpp);
fprintf(dest,
" -trunc (default = reduce rate by parsing, not truncation)\n");
fprintf(dest,
" -q -- turns off verbose mode.\n");
info = info_creator();
info->print_usage(info,dest);
info->terminate(info);
synthesis = synthesis_creator();
synthesis->print_usage(synthesis,dest);
synthesis->terminate(synthesis);
dequantizer = dequantizer_creator();
dequantizer->print_usage(dequantizer,dest);
decoder = decoder_creator();
decoder->print_usage(decoder,dest);
decoder->terminate(decoder);
bitstream = bitstream_creator();
bitstream->print_usage(bitstream,dest);
bitstream->terminate(bitstream);
fprintf(dest,
" -u [<output file>]\n"
" -- print usage statement & exit. Overrides other args.\n"
" Prints to std-error unless output file given.\n"
" Accepts UNIX \"-\" convention to identify std-output.\n");
}
/*****************************************************************************/
/* STATIC parse_common_arguments */
/*****************************************************************************/
static void
parse_common_arguments(int argc, char *argv[], int *max_components,
int *max_levels, char **local_filter_name,
float *max_bpp, int *truncate, int *verbose)
{
for (argc--, argv++; argc > 0; argc--, argv++)
if (strcmp(*argv,"-comp") == 0)
{
*(argv++) = ""; argc--;
if ((argc == 0) || (sscanf(*argv,"%d",max_components) == 0))
{
fprintf(stderr,"\nThe `-comp' argument requires the number of "
"components!\n");
exit(-1);
}
*argv = "";
}
else if (strcmp(*argv,"-lev") == 0)
{
*(argv++) = ""; argc--;
if ((argc == 0) || (sscanf(*argv,"%d",max_levels) == 0))
{
fprintf(stderr,"\nThe `-lev' argument requires the number of "
"resolution levels!\n");
exit(-1);
}
*argv = "";
}
else if (strcmp(*argv,"-loc") == 0)
{
*(argv++) = ""; argc--;
if ((argc == 0) || (strlen(*argv) <= 1))
{
fprintf(stderr,"\nThe `-loc' argument requires the name of "
"a local filter\n set file; the name must be at least "
"2 characters long!\n");
exit(-1);
}
*local_filter_name = *argv;
*argv = "";
}
else if (strcmp(*argv,"-rate") == 0)
{
*(argv++) = ""; argc--;
if ((argc == 0) || (sscanf(*argv,"%f",max_bpp) == 0))
{
fprintf(stderr,"\nThe `-rate' argument requires the number of "
"bits per pixel!\n");
exit(-1);
}
*argv = "";
}
else if (strcmp(*argv,"-trunc") == 0)
{
*argv = "";
*truncate = 1;
}
else if (strcmp(*argv,"-q") == 0)
{
*argv = "";
*verbose = 0;
}
}
/*****************************************************************************/
/* STATIC check_all_arguments_used */
/*****************************************************************************/
static void
check_all_arguments_used(int argc, char *argv[])
{
int i;
for (i=1; i < argc; i++)
if (*(argv[i]) != '\0')
fprintf(stderr,"\nWarning: The command-line argument, \"%s\", does "
"not\n appear to have been recognized by any object in the "
"decompression system!\n",argv[i]);
}
/*****************************************************************************/
/* STATIC open_output_image_file */
/*****************************************************************************/
static FILE *
open_output_image_file(int argc, char *argv[], int num_rows, int num_cols,
int num_planes)
{
int i;
char *name;
FILE *fp;
for (name=NULL, i=1; i < (argc-1); i++)
if (strcmp(argv[i],"-o") == 0)
{
name = argv[i+1];
argv[i] = argv[i+1] = "";
}
if (name == NULL)
{
fprintf(stderr,"Must supply output file name via `-o' switch!\n");
exit(-1);
}
fp = local_fopen(name,"wb");
if (fp == NULL)
{
fprintf(stderr,"Cannot open output file, \"%s\"!\n",name);
exit(-1);
}
if (num_planes == 1)
fprintf(fp,"P5\n%d %d\n255\n",num_cols,num_rows);
else
{
assert(num_planes == 3);
fprintf(fp,"P6\n%d %d\n255\n",num_cols,num_rows);
}
return(fp);
}
/*****************************************************************************/
/* STATIC write_image_line */
/*****************************************************************************/
static void
write_image_line(ifc_int *buf, FILE *fp, int samples, int components)
{
int c, elts;
ifc_int *sp, val, offset, shift;
unsigned char *dp;
elts = samples * components;
shift = STD_NOMINAL_RANGE_BITS - 8;
offset = (1<<shift)>>1;
sp = buf;
dp = (unsigned char *) buf;
for (c=elts; c > 0; c--)
{
val = *(sp++);
val = (val + offset) >> shift;
val += 128;
if (val & 0x0000FF00)
val = (val<0)?0:255;
*(dp++) = (unsigned char) val;
}
fwrite(buf,1,(size_t) elts,fp);
}
/*****************************************************************************/
/* STATIC read_word */
/*****************************************************************************/
static int
read_word(FILE *fp, int num_bytes)
/* Reads an integer value of length `num_bytes' from the supplied file,
returning the result as an integer. */
{
int result, shift, byte;
for (result=shift=0; num_bytes > 0; num_bytes--, shift += 8)
{
byte = fgetc(fp);
if (byte == EOF)
{
fprintf(stderr,"Compressed file terminated while reading header "
"information!\n");
exit(-1);
}
result += (byte << shift);
}
return(result);
}
/*****************************************************************************/
/* STATIC open_input_bitstream */
/*****************************************************************************/
static FILE *
open_input_bitstream(int argc, char *argv[], int *original_levels,
int *num_levels, int *filter_set, int *filter_flags,
int *coder_profile, int *max_bitplanes,
int *num_components, int component_rows[],
int component_cols[], float component_base_steps[],
int *header_size)
/* Parses the command line arguments to determine the name of the input
file and opens the file, reading the common header in order to recover
critical initialization parameters for the decompressor. The last
argument is used to return the number of header bytes which were read. */
{
int comp, i, tmp, header_bytes, fixed_point_step;
char *name, magic[5];
FILE *fp;
for (name=NULL, i=1; i < (argc-1); i++)
if (strcmp(argv[i],"-i") == 0)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -