1 /* SPMG/JPEG-LS IMPLEMENTATION V.2.1
2 =====================================
3 These programs are Copyright (c) University of British Columbia. All right reserved.
4 They may be freely redistributed in their entirety provided that this copyright
5 notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
6 COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
7 Each program is provided as is, without any express or implied warranty,
8 without even the warranty of fitness for a particular purpose.
10 =========================================================
11 THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
12 =========================================================
14 LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
15 -------------------------------------------------------------------------------
16 (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
17 HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
18 COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
19 RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
20 BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
21 ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
22 OF THIS LICENSING AGREEMENT.
23 YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
24 FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
25 INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
26 SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
27 TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
28 YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
29 OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
30 HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
31 SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
32 THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
33 THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
34 FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
35 IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
36 MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
37 HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
38 OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
39 -------------------------------------------------------------------------------
42 /* decoder.c --- the main module, argument parsing, file I/O
44 * Initial code by Alex Jakulin, Aug. 1995
46 * Modified and optimized: Gadiel Seroussi, October 1995
48 * Color Enhancement: Guillermo Sapiro, August 1996
50 * Modified and added Restart marker and input tables by:
51 * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
62 #define PGMNAME PGMPREFIX "d"
63 #define EPGMNAME PGMPREFIX "e"
65 /* define color mode strings */
66 char plane_int_string[] = "plane by plane",
67 line_int_string[] = "line intlv",
68 pixel_int_string[] = "sample intlv";
70 static char banner[]="\n\
71 =============================================\n\
72 SPMG/JPEG-LS DECOMPRESSOR " JPEGLSVERSION "\n\
73 =============================================\n\
74 These programs are Copyright (c) University of British Columbia.\n\
75 All rights reserved. They may be freely redistributed in their\n\
76 entirety provided that this copyright notice is not removed.\n\
77 They may not be sold for profit or incorporated in commercial\n\
78 programs without the written permission of the copyright holder.\n\
79 Each program is provided as is, without any express or implied\n\
80 warranty, without even the warranty of fitness for a particular\n\
83 =========================================================\n\
84 THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:\n\
85 =========================================================\n\
86 (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.\n";
88 pixel *pscanline, *cscanline, *pscanl0, *cscanl0;
89 pixel *c_pscanline[MAX_COMPONENTS], *c_cscanline[MAX_COMPONENTS],
90 *c_pscanl0[MAX_COMPONENTS], *c_cscanl0[MAX_COMPONENTS];
92 jpeg_ls_header *head_frame, *head_scan[MAX_SCANS];
94 int columns, rows, components,
95 samplingx[MAX_COMPONENTS], samplingy[MAX_COMPONENTS];
96 int c_columns[MAX_COMPONENTS], c_rows[MAX_COMPONENTS];
97 int whose_max_size_columns, whose_max_size_rows, number_of_scans;
99 int shift; /* Shift value for sparse images */
100 int got_lse; /* got an LSE marker */
101 int got_table; /* got a mapping table */
102 int got_restart; /* got a restart marker indicatino */
103 int restart_interval; /* the restart interval */
104 int multi; /* if the files are separate */
105 int application_header; /* application bytes in the header */
107 int lossy; /* Indicates if in lossy mode or not */
108 int bpp16; /* Indicates if 16 bits per pixel mode or not */
109 int lutmax; /* lutmax is either 256 or 4501 */
120 int alpha, /* alphabet size */
121 ceil_half_alpha; /* ceil(alpha/2) */
131 /* Write one row of pixel values */
132 inline void write_one_line(pixel* line, int cols, FILE* outfile)
135 unsigned int* maptable;
137 /* No mapping tables used */
138 if(!(head_scan[0]->need_table))
141 unsigned char* line8;
142 line8 = (unsigned char*)safealloc(cols);
144 for (i=0; i< cols; i++)
145 *(line8+i)=(unsigned char)ENDIAN8(*(line+i));
147 fwrite(line8, sizeof(unsigned char), cols, outfile);
151 fwrite(line, sizeof(short), cols, outfile);
154 /* Mapping tables used */
159 /* Write one byte per table entry */
160 if (head_scan[0]->Wt == 1)
162 unsigned char* line8;
163 line8 = (unsigned char*)safealloc(cols); /* If don't have 2, it mallocs over the table? */
165 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
167 for (i=0; i<cols; i++)
170 *(line8+i) = ENDIAN8(maptable[index]);
173 fwrite(line8, sizeof(unsigned char), cols, outfile);
177 /* Write two bytes per table entry */
178 else if (head_scan[0]->Wt == 2)
180 unsigned short* line16;
181 line16 = (unsigned short*)safealloc(cols*2);
183 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
185 for (i=0; i<cols; i++)
188 *(line16+i) = (unsigned short) maptable[index];
191 fwrite(line16, sizeof(short), cols, outfile);
195 /* Write three bytes per table entry */
196 else if (head_scan[0]->Wt == 3)
198 unsigned char* line8_3;
199 line8_3 = (unsigned char*)safealloc(cols*3);
201 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
203 for (i=0; i<cols; i++)
206 *(line8_3 + (i*3)) = (unsigned char) (maptable[index] >> 16);
207 *(line8_3 + (i*3) + 1) = (unsigned char) (maptable[index] >> 8);
208 *(line8_3 + (i*3) + 2) = (unsigned char) (maptable[index]);
211 fwrite(line8_3, sizeof(char), cols*3, outfile);
217 /* Can't do 16 bit index values */
221 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
233 void initbuffers(int multi, int comp)
238 if (multi) /* Output to several files */
240 for (i=0;i<comp;i++) {
242 c_pscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
243 c_cscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
245 /* Adjust scan line pointers taking into account the margins,
246 and also the fact that indexing for scan lines starts from 1
248 c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
249 c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
252 else { /* Output to a single file */
254 pscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
255 cscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
257 /* Adjust scan line pointers taking into account the margins,
258 and also the fact that indexing for scan lines starts from 1
259 (this will probably have to be changed in the future)
261 pscanline = pscanl0 + components*(LEFTMARGIN-1);
262 cscanline = cscanl0 + components*(LEFTMARGIN-1);
275 pscanline = pscanl0 + components*(LEFTMARGIN-1);
276 cscanline = cscanl0 + components*(LEFTMARGIN-1);
279 void c_swaplines(int i)
283 c_pscanl0[i] = c_cscanl0[i];
285 c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
286 c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
289 void closebuffers(int multi)
298 for (i=0;i<components;i++)
306 /* command line argument parsing */
307 int initialize(int argc, char *argv[])
309 char *infilename = NULL;
310 const char *outfilename = OUTFILE ".out";
311 char *c_outfilename[MAX_COMPONENTS],
313 int i, max_samp_columns, max_samp_rows, mk, n_s,
320 int pos; /* position in the file, after the header */
322 for (i=0;i<MAX_COMPONENTS;i++) {
323 c_outfilename[i]=(char*)malloc(strlen(OUTFILE)+20);
324 sprintf(c_outfilename[i],"%s%d.out",OUTFILE,i+1);
328 for ( i=1; i<argc; i++ )
329 if ( argv[i][0] == '-' )
331 switch ( argv[i][1] ) {
334 infilename = argv[i]+2;
339 outfilename = c_outfilename[out_files++] = argv[i]+2;
348 if ( sscanf(argv[i],"-v%d",&verbose) != 1 )
359 infilename = argv[i];
362 else if ( ! gotoutf )
363 outfilename = c_outfilename[out_files++] = argv[i];
367 verbose = 1; /* at least the banner will show */
369 if ((!multi) && (out_files>1)) {
370 fprintf(stderr,"\nERROR: Only 1 output file expected with -P option.\nThis option is valid only for line/pixel interleaved and not subsampled.\n");
375 if ( infilename == NULL ) {
380 if ( strcmp(infilename,"-")==0 )
382 else if ( (in=fopen(infilename,"rb")) == NULL ) {
388 /* Read the compressed image frame header */
391 head_frame = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
393 for (n_s=0;n_s<MAX_SCANS;n_s++) {
394 head_scan[n_s] = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
395 head_scan[n_s]->T1=head_scan[n_s]->T2=head_scan[n_s]->T3=0;
396 head_scan[n_s]->RES = DEFAULT_RESET;
400 seek_return = seek_marker(in,&mk);
401 if (seek_return == EOF) {
402 fprintf(stderr,"*** Premature End of File seeking SOI\n");
408 fprintf(stderr,"Marker %04x found: first marker must be SOI (%04x) in this implementation\n", mk, SOI);
414 seek_return = seek_marker(in,&mk);
415 if (seek_return == EOF) {
416 fprintf(stderr,"*** Premature End of File seeking SOF_LS\n");
420 pos += seek_return; /* Read SOF_LS */
422 fprintf(stderr,"Marker %04x found: second marker must be SOF_LS (%04x) in this implementation\n", mk, SOF_LS);
427 /* Read the frame header (SOF) */
428 seek_return = read_jpegls_frame(in,head_frame);
429 if (seek_return == EOF) {
430 fprintf(stderr,"*** Premature End of File reading frame header\n");
436 head_scan[0]->alp = head_frame->alp; /* default alpha */
439 /* LSE Extension header */
440 /* This version supports only 2 extension headers, and 1 set of
441 parameters for all the scans */
443 head_scan[0]->need_table = 0;
447 seek_return=seek_marker(in, &mk);
448 if (seek_return == EOF) {
449 fprintf(stderr,"*** Premature End of File seeking SOS or LSE marker\n");
458 seek_return = read_jpegls_extmarker(in, head_scan[0]);
459 if (seek_return == EOF) {
460 fprintf(stderr,"*** Premature End of File\n");
468 seek_return = read_jpegls_restartmarker(in, head_scan[0]);
471 restart_interval = head_scan[0]->restart_interval;
479 /* End of extension header */
483 /* Read the scan header*/
484 seek_return = read_jpegls_scan(in,head_scan[0]);
485 if (seek_return == EOF) {
486 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
491 shift=head_scan[0]->shift;
493 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",shift);
497 NEAR=head_scan[0]->NEAR;
498 color_mode=head_scan[0]->color_mode;
499 columns=head_frame->columns;
500 rows=head_frame->rows;
501 alpha0=head_scan[0]->alp;
502 head_frame->alp = alpha0;
503 components=head_frame->comp;
505 if (color_mode==PLANE_INT)
506 number_of_scans=components;
510 set_thresholds(head_scan[0]->alp, head_scan[0]->NEAR, &(head_scan[0]->T1), &(head_scan[0]->T2), &(head_scan[0]->T3));
516 RESET=head_scan[0]->RES;
518 if (head_scan[0]->RES != DEFAULT_RESET) {
519 fprintf(stderr,"ERROR: Version compiled for fixed RESET=%d parameter: got %d\n",DEFAULT_RESET,head_scan[0]->RES);
524 /* Check to see if lossless or lossy */
530 /* Check for 16 or 8 bit mode */
531 if (alpha0 <= MAXA16 && alpha0 > MAXA8)
537 else if (alpha0 <= MAXA8 && alpha0 >= 1)
544 fprintf(stderr,"Got alpha = %d\n",alpha0+1);
545 error("Bad value for alpha. Sorry...\n");
549 check_compatibility(head_frame,head_scan[0],0);
551 for (i=0;i<components;i++) {
552 samplingx[i]=head_frame->samplingx[i];
553 samplingy[i]=head_frame->samplingy[i];
554 if ((!multi) && ((samplingx[i]!=1) || (samplingy[i]!=1)) && (components>1))
556 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with subsampled compressed components\n");
561 if ((!multi) && (color_mode==PLANE_INT))
564 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with plane intereleaved mode\n");
570 if ((multi) && (color_mode==PIXEL_INT)) {
571 multi = 0; /* equivalent to specifying -P flag */
574 if ((out_files>1) && (color_mode==PIXEL_INT)) {
575 fprintf(stderr,"ERROR: Pixel interleaved mode uses only 1 output file\n");
579 if ((multi) && (out_files) && (out_files!=components)) {
580 fprintf(stderr,"ERROR: Number of files, %d, for output must be equal to number of image components, %d\n",out_files,components);
584 /* Compute the image size for the different components */
586 c_columns[0]=columns;
588 whose_max_size_rows=0;
595 for(i=0;i<components;i++) {
596 if (samplingx[i]>max_samp_columns) {
597 max_samp_columns=samplingx[i];
598 whose_max_size_columns=i;
600 if (samplingy[i]>max_samp_rows) {
601 max_samp_rows=samplingy[i];
602 whose_max_size_rows=i;
606 c_columns[whose_max_size_columns]=columns;
607 c_rows[whose_max_size_rows]=rows;
609 for(i=0;i<components;i++) {
610 if (i!=whose_max_size_columns)
612 c_columns[i]=c_columns[whose_max_size_columns]*samplingx[i];
613 c_columns[i]/=samplingx[whose_max_size_columns];
615 if (i!=whose_max_size_rows) {
616 c_rows[i]=c_rows[whose_max_size_rows]*samplingy[i];
617 c_rows[i]/=samplingy[whose_max_size_rows];
623 /* msgfile seems to start being used here, let's initialize it here */
624 if ( !msgfile ) msgfile = stdout;
626 if ( outfilename == NULL ) {
631 if ( strcmp(outfilename,"-")==0 ) {
637 if ( (out=fopen(outfilename,"wb")) == NULL ) {
643 for (i=0;i<components;i++)
644 if ( (c_out[i]=fopen(c_outfilename[i],"wb")) == NULL )
646 perror(c_outfilename[i]);
654 /* check that color mode is valid and pick color mode string */
655 switch ( color_mode ) {
658 color_mode_string = plane_int_string;
662 color_mode_string = line_int_string;
666 color_mode_string = pixel_int_string;
670 fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
676 fprintf(msgfile,"%s\n",banner);
681 fprintf(msgfile,"Input file: %s\nOutput file: %s\n",infilename,outfilename);
684 fprintf(msgfile,"Input file: %s\nOutput files: ",infilename);
685 for (i=0;i<components;i++)
686 fprintf(msgfile," %s ",c_outfilename[i]);
687 fprintf(msgfile,"\n");
692 if ( alpha0 != alpha ) {
693 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);
698 ceil_half_alpha = (alpha+1)/2;
703 /* check that alpha is a power of 2 */
704 for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);
705 if ( alpha != (1<<i) ) {
706 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);
713 /* compute auxiliary parameters for near-lossless (globals) */
715 qbeta = (alpha + 2*NEAR + quant-1 )/quant;
717 ceil_half_qbeta = (qbeta+1)/2;
719 alpha1eps = alpha-1+NEAR;
720 fprintf(msgfile,"Near-lossless mode: NEAR = %d beta = %d qbeta = %d\n",NEAR,beta,qbeta);
723 /* compute bits per sample for input symbols */
724 for ( bpp=1; (1L<<bpp)<alpha; bpp++ );
726 /* compute bits per sample for unencoded prediction errors */
728 for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );
732 if ( bpp < 2 ) bpp = 2;
734 /* limit for unary part of Golomb code */
736 limit = 2*(bpp + 8) - qbpp -1;
738 limit = 4*bpp - qbpp - 1;
740 /* print out parameters */
743 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",
744 columns, rows, alpha0, components,
745 color_mode, color_mode_string,
746 T1, T2, T3, RESET,limit);
748 fprintf(msgfile,"Image: cols=");
749 for (i=0;i<components;i++)
750 fprintf(msgfile," %d",c_columns[i]);
751 fprintf(msgfile," rows=");
752 for (i=0;i<components;i++)
753 fprintf(msgfile," %d",c_rows[i]);
754 fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
756 color_mode, color_mode_string,
757 T1, T2, T3,RESET,limit);
762 fprintf(msgfile,"\n");
765 /* Write out the image header for PGM or PPM files */
766 /* Must look at if there are Mapping Tables used */
768 /* No Mapping Tables used */
769 if (!head_scan[0]->need_table)
772 if (components==1) fputs("P5\n", out);
773 else if (components==3) fputs("P6\n", out);
774 else if (components==4) fputs("P7\n", out);
775 else fprintf(out,"P%d\n",10+components);
777 fprintf(out,"%d %d\n", columns, rows);
778 fprintf(out,"%d\n", alpha - 1);
781 for (i=0;i<components;i++) {
782 fputs("P5\n", c_out[i]);
783 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
784 fprintf(c_out[i],"%d\n", alpha - 1);
788 /* Mapping Tables used */
791 /* only 8 bit indexes supported for mapping tables */
794 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
798 /* Mapping Table elements are 1 or 2 bytes */
799 if (head_scan[0]->Wt==1 || head_scan[0]->Wt==2)
802 if (head_scan[0]->Wt==1)
805 alpha_temp = alpha*alpha;
809 if (components==1) fputs("P5\n", out);
810 else if (components==3) fputs("P6\n", out);
811 else if (components==4) fputs("P7\n", out);
812 else fprintf(out,"P%d\n",10+components);
814 fprintf(out,"%d %d\n", columns, rows);
815 fprintf(out,"%d\n", alpha_temp - 1);
818 for (i=0;i<components;i++)
820 fputs("P5\n", c_out[i]);
821 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
822 fprintf(c_out[i],"%d\n", alpha_temp - 1);
826 /* Mapping Table elements are 3 bytes */
827 else if (head_scan[0]->Wt==3)
831 if (components==1) fputs("P6\n", out);
834 fprintf(stderr,"Error : Cannot have a multi-component image and a mapping table with 3 bytes per element.\n");
838 fprintf(out,"%d %d\n", columns, rows);
839 fprintf(out,"%d\n", alpha - 1);
842 for (i=0;i<components;i++)
844 fputs("P6\n", c_out[i]);
845 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
846 fprintf(c_out[i],"%d\n", alpha - 1);
850 /* Mapping Table elements aren't 1 to 3 bytes */
853 fprintf(stderr, "Sorry, mapping tables elements can only be 1 to 3 bytes in this implementation.\n");
859 /* Allocate memory pools. */
860 initbuffers(multi, components);
863 /* return size of the header, in bytes */
872 /* Main loop for decoding files */
874 int main (int argc, char *argv[]) {
875 int n,n_c,n_r,my_i,n_s,mk,seek_return;
877 double t0, t1; /*, get_utime();*/
881 pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
883 local_cscanline = local_pscanline = NULL;
886 /* Parse the parameters, initialize */
887 /* Not yet fully implemented */
889 pos0 = initialize(argc, argv);
892 /* start timer (must be AFTER initialize()) */
896 /* Initialize the scanline buffers */
898 for (n = 0; n <= (columns + 1); ++n)
901 for (n_c=0;n_c<components;n_c++)
902 for (n = 0; n <= (c_columns[n_c] + 1); ++n)
903 c_pscanline[n_c][n] = 0;
905 if ((components>1) && (multi==0))
907 /* OUTPUT PPM file, allocate auxiliary buffers */
908 local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
909 local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
911 local_pscanline = local_scanl0 + LEFTMARGIN-1;
912 local_cscanline = local_scanl1 + LEFTMARGIN-1;
916 for (n_s=0;n_s<number_of_scans;n_s++)
918 /* Repeat prediction/quantization/statistics scanline by scanline,
921 /* Reset Restart Markers for every scan */
924 /* This implementation supports parameters in 1st scan */
927 /* Prepare the quantization LUTs */
931 /* prepare div/mul tables for near-lossless quantization */
932 prepare_qtables(alpha,NEAR);
936 { /* Read further scan headers */
937 seek_return=seek_marker(in,&mk);
938 if (seek_return == EOF)
940 fprintf(stderr,"*** Premature End of File seeking SOS marker\n");
943 if ( seek_return > 2 )
945 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
946 fprintf(msgfile,"*** Added to marker segment count.\n");
951 fprintf(stderr,"Expecting SOS (%04x), got %04x\n",SOS,mk);
954 seek_return = read_jpegls_scan(in,head_scan[n_s]); /* Read the scan header*/
955 if (seek_return == EOF)
957 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
961 if (head_scan[n_s]->shift!=0)
963 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",head_scan[n_s]->shift);
966 if (head_scan[n_s]->NEAR != NEAR)
968 fprintf(stderr,"Got NEAR=%d after NEAR=%d: cannot change parameters between scans in this implementation\n",head_scan[n_s]->NEAR,NEAR);
971 if ((head_scan[n_s]->color_mode != PLANE_INT) || (head_scan[n_s]->comp != 1) ||
972 (head_scan[n_s]->comp_ids[0] != n_s+1))
974 fprintf(stderr,"This implementation supports multiple scans only in PLANE INTERLEAVED mode.\n");
979 /* Initializations for each scan */
982 /* Start from 1st image row */
985 /* Initialize stats arrays */
991 /* Initialize run processing */
992 init_process_run(MAXRUN);
994 if (color_mode==LINE_INT) { /* line int. */
996 /***********************************************************************/
997 /* Line interleaved mode with single file received */
998 /***********************************************************************/
1005 /* 'extend' the edges */
1006 for (n_c=0;n_c<components;n_c++)
1007 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1009 for (n_c=0;n_c<components;n_c++)
1012 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1014 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1015 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1019 local_cscanline=cscanline;
1020 local_pscanline=pscanline;
1023 if ( lossless_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1025 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1031 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1032 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1035 write_one_line(cscanline + components, components*columns, out);
1037 tot_out += components*columns;
1039 /* extend the edges */
1040 for (n_c=0;n_c<components;n_c++)
1041 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1043 /* make the current scanline the previous one */
1046 /* Take out the Restart Markers */
1049 /* Look for restart markers only after a restart interval */
1050 if ((MCUs_counted % restart_interval) == 0)
1053 read_n_bytes(in, 2); /* read the RST marker */
1060 } /* End of while loop for each file line */
1067 /* 'extend' the edges */
1068 for (n_c=0;n_c<components;n_c++)
1069 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1071 for (n_c=0;n_c<components;n_c++)
1074 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1076 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1077 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1081 local_cscanline=cscanline;
1082 local_pscanline=pscanline;
1085 if ( lossy_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1087 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1093 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1094 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1097 write_one_line(cscanline + components, components*columns, out);
1099 tot_out += components*columns;
1101 /* extend the edges */
1102 for (n_c=0;n_c<components;n_c++)
1103 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1105 /* make the current scanline the previous one */
1108 /* Take out the Restart Markers */
1111 /* Look for restart markers only after a restart interval */
1112 if ((MCUs_counted % restart_interval) == 0)
1115 read_n_bytes(in, 2); /* read the RST marker */
1122 } /* End of while loop for each file line */
1126 { /* Multiple files */
1127 /* color_mode==LINE_INT and multi==1 */
1128 /***********************************************************************/
1129 /* Line interleaved mode with multiple files received */
1130 /***********************************************************************/
1137 while (n <= c_rows[whose_max_size_rows])
1139 for (n_c=0;n_c<components;n_c++)
1141 for (n_r=0;n_r<samplingy[n_c];n_r++)
1144 /* 'extend' the edges */
1145 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1147 if ( lossless_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1149 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1154 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1156 tot_out += c_columns[n_c];
1158 /* extend the edges */
1159 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1161 /* make the current scanline the previous one */
1164 } /* End of for loop for each component */
1166 n+=samplingy[whose_max_size_rows];
1168 /* Take out the Restart Markers */
1171 /* Look for restart markers only after a restart interval */
1172 if ((MCUs_counted % restart_interval) == 0)
1175 read_n_bytes(in, 2); /* read the RST marker */
1182 } /* End of while loop for each line */
1187 while (n <= c_rows[whose_max_size_rows])
1189 for (n_c=0;n_c<components;n_c++)
1191 for (n_r=0;n_r<samplingy[n_c];n_r++)
1194 /* 'extend' the edges */
1195 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1197 if ( lossy_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1199 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1204 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1206 tot_out += c_columns[n_c];
1208 /* extend the edges */
1209 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1211 /* make the current scanline the previous one */
1214 } /* End of for loop for each component */
1216 n+=samplingy[whose_max_size_rows];
1218 /* Take out the Restart Markers */
1221 /* Look for restart markers only after a restart interval */
1222 if ((MCUs_counted % restart_interval) == 0)
1225 read_n_bytes(in, 2); /* read the RST marker */
1232 } /* End of while loop for each line */
1235 } /* Closes the else, LINE_INT and multi=1 */
1237 } /* End of part for LINE_INT */
1239 else { /* Non LINE_INT mode */
1240 if (color_mode==PIXEL_INT) {
1241 /***********************************************************************/
1242 /* Pixel interleaved mode with single file received */
1243 /***********************************************************************/
1250 /* 'extend' the edges */
1251 for (n_c=0;n_c<components;n_c++)
1252 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1254 if ( lossless_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1256 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1261 write_one_line(cscanline+components, components*columns, out);
1263 tot_out += components*columns;
1265 /* extend the edges */
1266 for (n_c=0;n_c<components;n_c++)
1267 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1269 /* make the current scanline the previous one */
1272 /* Take out the Restart Markers */
1275 /* Look for restart markers only after a restart interval */
1276 if ((MCUs_counted % restart_interval) == 0)
1279 read_n_bytes(in, 2); /* read the RST marker */
1286 } /* End of line loop for PIXEL_INT */
1294 /* 'extend' the edges */
1295 for (n_c=0;n_c<components;n_c++)
1296 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1298 if ( lossy_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1300 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1305 write_one_line(cscanline+components, components*columns, out);
1307 tot_out += components*columns;
1309 /* extend the edges */
1310 for (n_c=0;n_c<components;n_c++)
1311 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1313 /* make the current scanline the previous one */
1316 /* Take out the Restart Markers */
1319 /* Look for restart markers only after a restart interval */
1320 if ((MCUs_counted % restart_interval) == 0)
1323 read_n_bytes(in, 2); /* read the RST marker */
1330 } /* End of line loop for PIXEL_INT */
1334 /***********************************************************************/
1335 /* Plane interleaved mode */
1336 /***********************************************************************/
1341 while (++n <= c_rows[n_s])
1343 /* 'extend' the edges */
1344 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1346 if (lossless_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1348 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1353 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1355 tot_out += c_columns[n_s];
1357 /* extend the edges */
1358 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1360 /* make the current scanline the previous one */
1363 /* Take out the Restart Markers */
1366 /* Look for restart markers only after a restart interval */
1367 if ((MCUs_counted % restart_interval) == 0)
1370 read_n_bytes(in, 2); /* read the RST marker */
1377 } /* End of line loop in PLANE_INT */
1382 while (++n <= c_rows[n_s])
1384 /* 'extend' the edges */
1385 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1387 if (lossy_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1389 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1394 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1396 tot_out += c_columns[n_s];
1398 /* extend the edges */
1399 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1401 /* make the current scanline the previous one */
1404 /* Take out the Restart Markers */
1407 /* Look for restart markers only after a restart interval */
1408 if ((MCUs_counted % restart_interval) == 0)
1411 read_n_bytes(in, 2); /* read the RST marker */
1418 } /* End of line loop in PLANE_INT */
1420 } /* End of each component for PLANE_INT */
1422 } /* End of non LINE_INT */
1426 } /* End of loop for scans */
1432 seek_return=seek_marker(in,&mk);
1433 if (seek_return==EOF)
1435 fprintf(stderr,"Did not get EOI at end of compressed image\n");
1438 if ( seek_return > 2 )
1440 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
1441 fprintf(msgfile,"*** Added to marker segment count.\n");
1444 pos0 += seek_return;
1447 fprintf(stderr,"In this implementation last marker must be EOI\n");
1451 if (head_scan[0]->need_table)
1452 fprintf(msgfile,"A mapping table was used which had %d entries of %g bytes each.\n",head_scan[0]->MAXTAB, head_scan[0]->Wt);
1455 fprintf(msgfile,"Restart markers were found with a restart interval of %i.\n",restart_interval);
1458 fprintf(msgfile,"Marker segment bytes: %ld\n",pos0);
1460 /* position in input file */
1462 /* tot_in = 8*(pos1-pos0); */
1464 /* size of compressed file read (bits), incl. headers. */
1468 close_process_run();
1469 closebuffers(multi);
1473 fprintf(msgfile,"Total bits in: %ld Symbols out: %ld %5.3f bps\n",
1474 tot_in,tot_out,tot_in/(double)tot_out);
1475 fprintf(msgfile,"Time = %1.3f secs : %1.0f KSymbols/sec\n",t1-t0,
1476 (tot_out)/(1024*(t1-t0)));
1489 fprintf(stderr,"Usage: %s [flags] [infile] [outfile1 [outfile2, ...]]\n\
1492 outfile1 = %s for color image in a single (PPM) output file.\n\
1493 outfile1 = %s for monochrome image in a single (PGM) output file.\n\
1494 outfile[1,2,...] = %s for multiple (PGM) output files \n\
1495 in plane or line interleaved modes.\n",
1496 "locod", "specified JLS file", OUTFILE ".out",
1498 OUTFILE "[1,2,...].out");
1499 fprintf(stderr,"FLAGS:\n\
1500 outfile2, ... : Multiple output specification for plane or line int. mode.\n\
1501 -i<infile> : Alternate input specification, use -i- for stdin.\n\
1502 -o<outfile> : Alternate output specification, use -o- for stdout.\n\
1503 -P : Generate single (.ppm) output file for sample/line int. mode.\n\
1506 -h : Print this help.\n\
1507 *** No spaces allowed between a flag and its argument.\n\
1513 void bad_flag(char *s)
1515 fprintf(stderr,"Bad flag %s\n",s);