📄 decoder.c
字号:
#ifndef FIXRESET
RESET=head_scan[0]->RES;
#else
if (head_scan[0]->RES != DEFAULT_RESET) {
fprintf(stderr,"ERROR: Version compiled for fixed RESET=%d parameter: got %d\n",DEFAULT_RESET,head_scan[0]->RES);
exit(10);
}
#endif
/* Check to see if lossless or lossy */
if (NEAR == 0)
lossy=FALSE;
else
lossy=TRUE;
/* Check for 16 or 8 bit mode */
if (alpha0 <= MAXA16 && alpha0 > MAXA8)
{
/* 16 bit */
bpp16 = TRUE;
lutmax = LUTMAX16;
}
else if (alpha0 <= MAXA8 && alpha0 >= 1)
{
/* 8 bit */
bpp16 = FALSE;
lutmax = LUTMAX8;
}
else {
fprintf(stderr,"Got alpha = %d\n",alpha0+1);
error("Bad value for alpha. Sorry...\n");
}
check_compatibility(head_frame,head_scan[0],0);
for (i=0;i<components;i++) {
samplingx[i]=head_frame->samplingx[i];
samplingy[i]=head_frame->samplingy[i];
if ((!multi) && ((samplingx[i]!=1) || (samplingy[i]!=1)) && (components>1))
{
fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with subsampled compressed components\n");
exit(10);
}
}
if ((!multi) && (color_mode==PLANE_INT))
if (components>1) {
fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with plane intereleaved mode\n");
exit(10);
}
else multi=1;
if ((multi) && (color_mode==PIXEL_INT)) {
multi = 0; /* equivalent to specifying -P flag */
}
if ((out_files>1) && (color_mode==PIXEL_INT)) {
fprintf(stderr,"ERROR: Pixel interleaved mode uses only 1 output file\n");
exit(10);
}
if ((multi) && (out_files) && (out_files!=components)) {
fprintf(stderr,"ERROR: Number of files, %d%, for output must be equal to number of image components, %d\n",out_files,components);
exit(10);
}
/* Compute the image size for the different components */
if (components==1) {
c_columns[0]=columns;
c_rows[0]=rows;
whose_max_size_rows=0;
samplingy[0]=1;
}
else
{
max_samp_columns=0;
max_samp_rows=0;
for(i=0;i<components;i++) {
if (samplingx[i]>max_samp_columns) {
max_samp_columns=samplingx[i];
whose_max_size_columns=i;
}
if (samplingy[i]>max_samp_rows) {
max_samp_rows=samplingy[i];
whose_max_size_rows=i;
}
}
c_columns[whose_max_size_columns]=columns;
c_rows[whose_max_size_rows]=rows;
for(i=0;i<components;i++) {
if (i!=whose_max_size_columns)
{
c_columns[i]=c_columns[whose_max_size_columns]*samplingx[i];
c_columns[i]/=samplingx[whose_max_size_columns];
}
if (i!=whose_max_size_rows) {
c_rows[i]=c_rows[whose_max_size_rows]*samplingy[i];
c_rows[i]/=samplingy[whose_max_size_rows];
}
}
}
/* Open out file */
if ( outfilename == NULL ) {
usage();
exit(0);
}
else {
if ( strcmp(outfilename,"-")==0 ) {
out = stdout;
msgfile = stderr;
}
else {
if (multi==0) {
if ( (out=fopen(outfilename,"wb")) == NULL ) {
perror(outfilename);
exit(10);
}
}
else
for (i=0;i<components;i++)
if ( (c_out[i]=fopen(c_outfilename[i],"wb")) == NULL )
{
perror(c_outfilename[i]);
exit(10);
}
}
}
/* check that color mode is valid and pick color mode string */
switch ( color_mode ) {
case PLANE_INT:
color_mode_string = plane_int_string;
break;
case LINE_INT:
color_mode_string = line_int_string;
break;
case PIXEL_INT:
color_mode_string = pixel_int_string;
break;
default:
fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
usage();
exit(10);
}
if ( verbose ) {
fprintf(msgfile,"%s\n",banner);
}
if ( verbose ) {
if (!multi) {
fprintf(msgfile,"Input file: %s\nOutput file: %s\n",infilename,outfilename);
}
else {
fprintf(msgfile,"Input file: %s\nOutput files: ",infilename);
for (i=0;i<components;i++)
fprintf(msgfile," %s ",c_outfilename[i]);
fprintf(msgfile,"\n");
}
}
#ifdef FIXALPHA
if ( alpha0 != alpha ) {
fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);
exit(10);
}
#else
alpha = alpha0;
ceil_half_alpha = (alpha+1)/2;
#endif
#ifdef POW2
highmask = -alpha;
/* check that alpha is a power of 2 */
for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);
if ( alpha != (1<<i) ) {
fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);
exit(10);
}
#endif
if (lossy==TRUE)
{
/* compute auxiliary parameters for near-lossless (globals) */
quant = 2*NEAR+1;
qbeta = (alpha + 2*NEAR + quant-1 )/quant;
beta = quant*qbeta;
ceil_half_qbeta = (qbeta+1)/2;
negNEAR = -NEAR;
alpha1eps = alpha-1+NEAR;
fprintf(msgfile,"Near-lossless mode: NEAR = %d beta = %d qbeta = %d\n",NEAR,beta,qbeta);
}
/* compute bits per sample for input symbols */
for ( bpp=1; (1L<<bpp)<alpha; bpp++ );
/* compute bits per sample for unencoded prediction errors */
if (lossy==TRUE)
for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );
else
qbpp = bpp;
if ( bpp < 2 ) bpp = 2;
/* limit for unary part of Golomb code */
if ( bpp < 8 )
limit = 2*(bpp + 8) - qbpp -1;
else
limit = 4*bpp - qbpp - 1;
/* print out parameters */
if ( verbose ) {
if (!multi)
fprintf(msgfile,"Image: cols=%d rows=%d alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
columns, rows, alpha0, components,
color_mode, color_mode_string,
T1, T2, T3, RESET,limit);
else {
fprintf(msgfile,"Image: cols=");
for (i=0;i<components;i++)
fprintf(msgfile," %d",c_columns[i]);
fprintf(msgfile," rows=");
for (i=0;i<components;i++)
fprintf(msgfile," %d",c_rows[i]);
fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
alpha0, components,
color_mode, color_mode_string,
T1, T2, T3,RESET,limit);
}
}
if ( verbose )
fprintf(msgfile,"\n");
/* Write out the image header for PGM or PPM files */
/* Must look at if there are Mapping Tables used */
/* No Mapping Tables used */
if (!head_scan[0]->need_table)
{
if (!multi) {
if (components==1) fputs("P5\n", out);
else if (components==3) fputs("P6\n", out);
else if (components==4) fputs("P7\n", out);
else fprintf(out,"P%d\n",10+components);
fprintf(out,"%d %d\n", columns, rows);
fprintf(out,"%d\n", alpha - 1);
}
else
for (i=0;i<components;i++) {
fputs("P5\n", c_out[i]);
fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
fprintf(c_out[i],"%d\n", alpha - 1);
}
}
/* Mapping Tables used */
else
{
/* only 8 bit indexes supported for mapping tables */
if (bpp16==TRUE)
{
fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
exit(0);
}
/* Mapping Table elements are 1 or 2 bytes */
if (head_scan[0]->Wt==1 || head_scan[0]->Wt==2)
{
int alpha_temp;
if (head_scan[0]->Wt==1)
alpha_temp = alpha;
else
alpha_temp = alpha*alpha;
if (!multi)
{
if (components==1) fputs("P5\n", out);
else if (components==3) fputs("P6\n", out);
else if (components==4) fputs("P7\n", out);
else fprintf(out,"P%d\n",10+components);
fprintf(out,"%d %d\n", columns, rows);
fprintf(out,"%d\n", alpha_temp - 1);
}
else
for (i=0;i<components;i++)
{
fputs("P5\n", c_out[i]);
fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
fprintf(c_out[i],"%d\n", alpha_temp - 1);
}
}
/* Mapping Table elements are 3 bytes */
else if (head_scan[0]->Wt==3)
{
if (!multi)
{
if (components==1) fputs("P6\n", out);
else
{
fprintf(stderr,"Error : Cannot have a multi-component image and a mapping table with 3 bytes per element.\n");
exit(0);
}
fprintf(out,"%d %d\n", columns, rows);
fprintf(out,"%d\n", alpha - 1);
}
else
for (i=0;i<components;i++)
{
fputs("P6\n", c_out[i]);
fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
fprintf(c_out[i],"%d\n", alpha - 1);
}
}
/* Mapping Table elements aren't 1 to 3 bytes */
else
{
fprintf(stderr, "Sorry, mapping tables elements can only be 1 to 3 bytes in this implementation.\n");
exit(0);
}
}
/* Allocate memory pools. */
initbuffers(multi, components);
/* return size of the header, in bytes */
return pos;
}
/* Main loop for decoding files */
int main (int argc, char *argv[]) {
int n,n_c,n_r,my_i,n_s,mk,seek_return;
int found_EOF = 0;
double t0, t1, get_utime();
long pos0, pos1,
tot_in = 0,
tot_out = 0;
pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
int MCUs_counted;
char szArgv[4][256];
msgfile = stdout; // output msg to stdout
/* Parse the parameters, initialize */
/* Not yet fully implemented */
bufiinit();
#ifdef CHIP_C5402
argc = 4;
argv[1]="-P";
argv[2]="F://Workspace//JPEG//jpeg_ls_v2.2//Encoder//lena24b.jls";
argv[3]="-olena.ppm";
#endif
pos0 = initialize(argc, argv);
/* start timer (must be AFTER initialize()) */
t0 = get_utime();
/* Initialize the scanline buffers */
if (!multi)
for (n = 0; n <= (columns + 1); ++n)
pscanline[n] = 0;
else
for (n_c=0;n_c<components;n_c++)
for (n = 0; n <= (c_columns[n_c] + 1); ++n)
c_pscanline[n_c][n] = 0;
if ((components>1) && (multi==0))
{
/* OUTPUT PPM file, allocate auxiliary buffers */
local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
local_pscanline = local_scanl0 + LEFTMARGIN-1;
local_cscanline = local_scanl1 + LEFTMARGIN-1;
}
for (n_s=0;n_s<number_of_scans;n_s++)
{
/* Repeat prediction/quantization/statistics scanline by scanline,
for each scan. */
/* Reset Restart Markers for every scan */
MCUs_counted = 0;
/* This implementation supports parameters in 1st scan */
if (n_s==0)
{
/* Prepare the quantization LUTs */
prepareLUTs();
if (lossy==TRUE)
/* prepare div/mul tables for near-lossless quantization */
prepare_qtables(alpha,NEAR);
}
else
{ /* Read further scan headers */
seek_return=seek_marker(in,&mk);
if (seek_return == EOF)
{
fprintf(stderr,"*** Premature End of File seeking SOS marker\n");
exit(10);
}
if ( seek_return > 2 )
{
fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
fprintf(msgfile,"*** Added to marker segment count.\n");
}
pos0 +=seek_return;
if (mk != SOS)
{
fprintf(stderr,"Expecting SOS (%04x), got %04x\n",SOS,mk);
exit(10);
}
seek_return = read_jpegls_scan(in,head_scan[n_s]); /* Read the scan header*/
if (seek_return == EOF)
{
fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
exit(10);
}
pos0+=seek_return;
if (head_scan[n_s]->shift!=0)
{
fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",head_scan[n_s]->shift);
exit(10);
}
if (head_scan[n_s]->NEAR != NEAR)
{
fprintf(stderr,"Got NEAR=%d after NEAR=%d: cannot change parameters between scans in this implementation\n",head_scan[n_s]->NEAR,NEAR);
exit(10);
}
if ((head_scan[n_s]->color_mode != PLANE_INT) || (head_scan[n_s]->comp != 1) ||
(head_scan[n_s]->comp_ids[0] != n_s+1))
{
fprintf(stderr,"This implementation supports multiple scans only in PLANE INTERLEAVED mode.\n");
exit(10);
}
}
/* Initializations for each scan */
bitiinit();
/* Start from 1st image row */
n=0;
/* Initialize stats arrays */
if (lossy==TRUE)
init_stats(qbeta);
else
init_stats(alpha);
/* Initialize run processing */
init_process_run(MAXRUN);
if (color_mode==LINE_INT) { /* line int. */
if (!multi) {
/***********************************************************************/
/* Line interleaved mode with single file received */
/***********************************************************************/
if (lossy==FALSE)
/* LOSSLESS MODE */
while (++n <= rows)
{
/* 'extend' the edges */
for (n_c=0;n_c<components;n_c++)
cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
for (n_c=0;n_c<components;n_c++)
{
if (components>1)
for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
{
local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -