📄 decoder.c
字号:
set_thresholds(head_scan[0]->alp, head_scan[0]->NEAR, &(head_scan[0]->T1), &(head_scan[0]->T2), &(head_scan[0]->T3)); T1=head_scan[0]->T1; T2=head_scan[0]->T2; T3=head_scan[0]->T3;#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; /* Parse the parameters, initialize */ /* Not yet fully implemented */ bufiinit(); 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]; } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -