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
58 #define PGMNAME PGMPREFIX "d"
59 #define EPGMNAME PGMPREFIX "e"
61 static char *banner="\n\
62 =============================================\n\
63 SPMG/JPEG-LS DECOMPRESSOR " JPEGLSVERSION "\n\
64 =============================================\n\
65 These programs are Copyright (c) University of British Columbia.\n\
66 All rights reserved. They may be freely redistributed in their\n\
67 entirety provided that this copyright notice is not removed.\n\
68 They may not be sold for profit or incorporated in commercial\n\
69 programs without the written permission of the copyright holder.\n\
70 Each program is provided as is, without any express or implied\n\
71 warranty, without even the warranty of fitness for a particular\n\
74 =========================================================\n\
75 THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:\n\
76 =========================================================\n\
77 (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.\n";
79 pixel *pscanline, *cscanline, *pscanl0, *cscanl0;
80 pixel *c_pscanline[MAX_COMPONENTS], *c_cscanline[MAX_COMPONENTS],
81 *c_pscanl0[MAX_COMPONENTS], *c_cscanl0[MAX_COMPONENTS];
83 jpeg_ls_header *head_frame, *head_scan[MAX_SCANS];
85 int columns, rows, components,
86 samplingx[MAX_COMPONENTS], samplingy[MAX_COMPONENTS];
87 int c_columns[MAX_COMPONENTS], c_rows[MAX_COMPONENTS];
88 int whose_max_size_columns, whose_max_size_rows, number_of_scans;
90 int shift; /* Shift value for sparse images */
91 int got_lse; /* got an LSE marker */
92 int got_table; /* got a mapping table */
93 int got_restart; /* got a restart marker indicatino */
94 int restart_interval; /* the restart interval */
95 int multi; /* if the files are separate */
96 int application_header; /* application bytes in the header */
98 int lossy; /* Indicates if in lossy mode or not */
99 int bpp16; /* Indicates if 16 bits per pixel mode or not */
100 int lutmax; /* lutmax is either 256 or 4501 */
113 int alpha, /* alphabet size */
114 ceil_half_alpha; /* ceil(alpha/2) */
126 /* Write one row of pixel values */
127 inline void write_one_line(pixel* line, int cols, FILE* outfile)
131 unsigned int* maptable;
133 /* No mapping tables used */
134 if(!(head_scan[0]->need_table))
137 unsigned char* line8;
138 line8 = (unsigned char*)safealloc(cols);
140 for (i=0; i< cols; i++)
141 *(line8+i)=ENDIAN8(*(line+i));
143 fwrite(line8, sizeof(unsigned char), cols, outfile);
147 fwrite(line, sizeof(short), cols, outfile);
150 /* Mapping tables used */
155 /* Write one byte per table entry */
156 if (head_scan[0]->Wt == 1)
158 unsigned char* line8;
159 line8 = (unsigned char*)safealloc(cols); /* If don't have 2, it mallocs over the table? */
161 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
163 for (i=0; i<cols; i++)
166 *(line8+i) = ENDIAN8(maptable[index]);
169 fwrite(line8, sizeof(unsigned char), cols, outfile);
173 /* Write two bytes per table entry */
174 else if (head_scan[0]->Wt == 2)
176 unsigned short* line16;
177 line16 = (unsigned short*)safealloc(cols*2);
179 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
181 for (i=0; i<cols; i++)
184 *(line16+i) = (unsigned short) maptable[index];
187 fwrite(line16, sizeof(short), cols, outfile);
191 /* Write three bytes per table entry */
192 else if (head_scan[0]->Wt == 3)
194 unsigned char* line8_3;
195 line8_3 = (unsigned char*)safealloc(cols*3);
197 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
199 for (i=0; i<cols; i++)
202 *(line8_3 + (i*3)) = (unsigned char) (maptable[index] >> 16);
203 *(line8_3 + (i*3) + 1) = (unsigned char) (maptable[index] >> 8);
204 *(line8_3 + (i*3) + 2) = (unsigned char) (maptable[index]);
207 fwrite(line8_3, sizeof(char), cols*3, outfile);
213 /* Can't do 16 bit index values */
217 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
229 void initbuffers(int multi, int comp) {
233 if (multi) /* Output to several files */
235 for (i=0;i<comp;i++) {
237 c_pscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
238 c_cscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
240 /* Adjust scan line pointers taking into account the margins,
241 and also the fact that indexing for scan lines starts from 1
243 c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
244 c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
247 else { /* Output to a single file */
249 pscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
250 cscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
252 /* Adjust scan line pointers taking into account the margins,
253 and also the fact that indexing for scan lines starts from 1
254 (this will probably have to be changed in the future)
256 pscanline = pscanl0 + components*(LEFTMARGIN-1);
257 cscanline = cscanl0 + components*(LEFTMARGIN-1);
270 pscanline = pscanl0 + components*(LEFTMARGIN-1);
271 cscanline = cscanl0 + components*(LEFTMARGIN-1);
278 c_pscanl0[i] = c_cscanl0[i];
280 c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
281 c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
284 void closebuffers(int multi) {
292 for (i=0;i<components;i++)
302 int initialize(int argc, char *argv[]) {
303 char line[256],tmp_char[1],
305 *outfilename = OUTFILE ".out",
306 *c_outfilename[MAX_COMPONENTS],
308 int i, max_samp_columns, max_samp_rows, mk, n_s,
315 int pos; /* position in the file, after the header */
317 for (i=0;i<MAX_COMPONENTS;i++) {
318 c_outfilename[i]=malloc(strlen(OUTFILE)+20);
319 sprintf(c_outfilename[i],"%s%d.out",OUTFILE,i+1);
323 for ( i=1; i<argc; i++ )
324 if ( argv[i][0] == '-' )
326 switch ( argv[i][1] ) {
329 infilename = argv[i]+2;
334 outfilename = c_outfilename[out_files++] = argv[i]+2;
343 if ( sscanf(argv[i],"-v%d",&verbose) != 1 )
354 infilename = argv[i];
357 else if ( ! gotoutf )
358 outfilename = c_outfilename[out_files++] = argv[i];
362 verbose = 1; /* at least the banner will show */
364 if ((!multi) && (out_files>1)) {
365 fprintf(stderr,"\nERROR: Only 1 output file expected with -P option.\nThis option is valid only for line/pixel interleaved and not subsampled.\n");
370 if ( infilename == NULL ) {
375 if ( strcmp(infilename,"-")==0 )
377 else if ( (in=fopen(infilename,"rb")) == NULL ) {
383 /* Read the compressed image frame header */
386 head_frame = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
388 for (n_s=0;n_s<MAX_SCANS;n_s++) {
389 head_scan[n_s] = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
390 head_scan[n_s]->T1=head_scan[n_s]->T2=head_scan[n_s]->T3=0;
391 head_scan[n_s]->RES = DEFAULT_RESET;
395 seek_return = seek_marker(in,&mk);
396 if (seek_return == EOF) {
397 fprintf(stderr,"*** Premature End of File seeking SOI\n");
403 fprintf(stderr,"Marker %04x found: first marker must be SOI (%04x) in this implementation\n", mk, SOI);
409 seek_return = seek_marker(in,&mk);
410 if (seek_return == EOF) {
411 fprintf(stderr,"*** Premature End of File seeking SOF_LS\n");
415 pos += seek_return; /* Read SOF_LS */
417 fprintf(stderr,"Marker %04x found: second marker must be SOF_LS (%04x) in this implementation\n", mk, SOF_LS);
422 /* Read the frame header (SOF) */
423 seek_return = read_jpegls_frame(in,head_frame);
424 if (seek_return == EOF) {
425 fprintf(stderr,"*** Premature End of File reading frame header\n");
431 head_scan[0]->alp = head_frame->alp; /* default alpha */
434 /* LSE Extension header */
435 /* This version supports only 2 extension headers, and 1 set of
436 parameters for all the scans */
438 head_scan[0]->need_table = 0;
442 seek_return=seek_marker(in, &mk);
443 if (seek_return == EOF) {
444 fprintf(stderr,"*** Premature End of File seeking SOS or LSE marker\n");
453 seek_return = read_jpegls_extmarker(in, head_scan[0]);
454 if (seek_return == EOF) {
455 fprintf(stderr,"*** Premature End of File\n");
463 seek_return = read_jpegls_restartmarker(in, head_scan[0]);
466 restart_interval = head_scan[0]->restart_interval;
474 /* End of extension header */
478 /* Read the scan header*/
479 seek_return = read_jpegls_scan(in,head_scan[0]);
480 if (seek_return == EOF) {
481 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
486 shift=head_scan[0]->shift;
488 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",shift);
492 NEAR=head_scan[0]->NEAR;
493 color_mode=head_scan[0]->color_mode;
494 columns=head_frame->columns;
495 rows=head_frame->rows;
496 alpha0=head_scan[0]->alp;
497 head_frame->alp = alpha0;
498 components=head_frame->comp;
500 if (color_mode==PLANE_INT)
501 number_of_scans=components;
505 set_thresholds(head_scan[0]->alp, head_scan[0]->NEAR, &(head_scan[0]->T1), &(head_scan[0]->T2), &(head_scan[0]->T3));
511 RESET=head_scan[0]->RES;
513 if (head_scan[0]->RES != DEFAULT_RESET) {
514 fprintf(stderr,"ERROR: Version compiled for fixed RESET=%d parameter: got %d\n",DEFAULT_RESET,head_scan[0]->RES);
519 /* Check to see if lossless or lossy */
525 /* Check for 16 or 8 bit mode */
526 if (alpha0 <= MAXA16 && alpha0 > MAXA8)
532 else if (alpha0 <= MAXA8 && alpha0 >= 1)
539 fprintf(stderr,"Got alpha = %d\n",alpha0+1);
540 error("Bad value for alpha. Sorry...\n");
544 check_compatibility(head_frame,head_scan[0],0);
546 for (i=0;i<components;i++) {
547 samplingx[i]=head_frame->samplingx[i];
548 samplingy[i]=head_frame->samplingy[i];
549 if ((!multi) && ((samplingx[i]!=1) || (samplingy[i]!=1)) && (components>1))
551 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with subsampled compressed components\n");
556 if ((!multi) && (color_mode==PLANE_INT))
558 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with plane intereleaved mode\n");
563 if ((multi) && (color_mode==PIXEL_INT)) {
564 multi = 0; /* equivalent to specifying -P flag */
567 if ((out_files>1) && (color_mode==PIXEL_INT)) {
568 fprintf(stderr,"ERROR: Pixel interleaved mode uses only 1 output file\n");
572 if ((multi) && (out_files) && (out_files!=components)) {
573 fprintf(stderr,"ERROR: Number of files, %d%, for output must be equal to number of image components, %d\n",out_files,components);
577 /* Compute the image size for the different components */
579 c_columns[0]=columns;
581 whose_max_size_rows=0;
588 for(i=0;i<components;i++) {
589 if (samplingx[i]>max_samp_columns) {
590 max_samp_columns=samplingx[i];
591 whose_max_size_columns=i;
593 if (samplingy[i]>max_samp_rows) {
594 max_samp_rows=samplingy[i];
595 whose_max_size_rows=i;
599 c_columns[whose_max_size_columns]=columns;
600 c_rows[whose_max_size_rows]=rows;
602 for(i=0;i<components;i++) {
603 if (i!=whose_max_size_columns)
605 c_columns[i]=c_columns[whose_max_size_columns]*samplingx[i];
606 c_columns[i]/=samplingx[whose_max_size_columns];
608 if (i!=whose_max_size_rows) {
609 c_rows[i]=c_rows[whose_max_size_rows]*samplingy[i];
610 c_rows[i]/=samplingy[whose_max_size_rows];
617 if ( outfilename == NULL ) {
622 if ( strcmp(outfilename,"-")==0 ) {
628 if ( (out=fopen(outfilename,"wb")) == NULL ) {
634 for (i=0;i<components;i++)
635 if ( (c_out[i]=fopen(c_outfilename[i],"wb")) == NULL )
637 perror(c_outfilename[i]);
645 /* check that color mode is valid and pick color mode string */
646 switch ( color_mode ) {
649 color_mode_string = plane_int_string;
653 color_mode_string = line_int_string;
657 color_mode_string = pixel_int_string;
661 fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
667 fprintf(msgfile,"%s\n",banner);
672 fprintf(msgfile,"Input file: %s\nOutput file: %s\n",infilename,outfilename);
675 fprintf(msgfile,"Input file: %s\nOutput files: ",infilename);
676 for (i=0;i<components;i++)
677 fprintf(msgfile," %s ",c_outfilename[i]);
678 fprintf(msgfile,"\n");
683 if ( alpha0 != alpha ) {
684 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);
689 ceil_half_alpha = (alpha+1)/2;
694 /* check that alpha is a power of 2 */
695 for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);
696 if ( alpha != (1<<i) ) {
697 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);
704 /* compute auxiliary parameters for near-lossless (globals) */
706 qbeta = (alpha + 2*NEAR + quant-1 )/quant;
708 ceil_half_qbeta = (qbeta+1)/2;
710 alpha1eps = alpha-1+NEAR;
711 fprintf(msgfile,"Near-lossless mode: NEAR = %d beta = %d qbeta = %d\n",NEAR,beta,qbeta);
714 /* compute bits per sample for input symbols */
715 for ( bpp=1; (1L<<bpp)<alpha; bpp++ );
717 /* compute bits per sample for unencoded prediction errors */
719 for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );
723 if ( bpp < 2 ) bpp = 2;
725 /* limit for unary part of Golomb code */
727 limit = 2*(bpp + 8) - qbpp -1;
729 limit = 4*bpp - qbpp - 1;
731 /* print out parameters */
734 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",
735 columns, rows, alpha0, components,
736 color_mode, color_mode_string,
737 T1, T2, T3, RESET,limit);
739 fprintf(msgfile,"Image: cols=");
740 for (i=0;i<components;i++)
741 fprintf(msgfile," %d",c_columns[i]);
742 fprintf(msgfile," rows=");
743 for (i=0;i<components;i++)
744 fprintf(msgfile," %d",c_rows[i]);
745 fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
747 color_mode, color_mode_string,
748 T1, T2, T3,RESET,limit);
753 fprintf(msgfile,"\n");
756 /* Write out the image header for PGM or PPM files */
757 /* Must look at if there are Mapping Tables used */
759 /* No Mapping Tables used */
760 if (!head_scan[0]->need_table)
763 if (components==1) fputs("P5\n", out);
764 else if (components==3) fputs("P6\n", out);
765 else if (components==4) fputs("P7\n", out);
766 else fprintf(out,"P%d\n",10+components);
768 fprintf(out,"%d %d\n", columns, rows);
769 fprintf(out,"%d\n", alpha - 1);
772 for (i=0;i<components;i++) {
773 fputs("P5\n", c_out[i]);
774 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
775 fprintf(c_out[i],"%d\n", alpha - 1);
779 /* Mapping Tables used */
782 /* only 8 bit indexes supported for mapping tables */
785 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
789 /* Mapping Table elements are 1 or 2 bytes */
790 if (head_scan[0]->Wt==1 || head_scan[0]->Wt==2)
793 if (head_scan[0]->Wt==1)
796 alpha_temp = alpha*alpha;
800 if (components==1) fputs("P5\n", out);
801 else if (components==3) fputs("P6\n", out);
802 else if (components==4) fputs("P7\n", out);
803 else fprintf(out,"P%d\n",10+components);
805 fprintf(out,"%d %d\n", columns, rows);
806 fprintf(out,"%d\n", alpha_temp - 1);
809 for (i=0;i<components;i++)
811 fputs("P5\n", c_out[i]);
812 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
813 fprintf(c_out[i],"%d\n", alpha_temp - 1);
817 /* Mapping Table elements are 3 bytes */
818 else if (head_scan[0]->Wt==3)
822 if (components==1) fputs("P6\n", out);
825 fprintf(stderr,"Error : Cannot have a multi-component image and a mapping table with 3 bytes per element.\n");
829 fprintf(out,"%d %d\n", columns, rows);
830 fprintf(out,"%d\n", alpha - 1);
833 for (i=0;i<components;i++)
835 fputs("P6\n", c_out[i]);
836 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
837 fprintf(c_out[i],"%d\n", alpha - 1);
841 /* Mapping Table elements aren't 1 to 3 bytes */
844 fprintf(stderr, "Sorry, mapping tables elements can only be 1 to 3 bytes in this implementation.\n");
850 /* Allocate memory pools. */
851 initbuffers(multi, components);
854 /* return size of the header, in bytes */
863 /* Main loop for decoding files */
865 int main (int argc, char *argv[]) {
866 int n,n_c,n_r,my_i,n_s,mk,seek_return;
868 double t0, t1, get_utime();
872 pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
876 /* Parse the parameters, initialize */
877 /* Not yet fully implemented */
879 pos0 = initialize(argc, argv);
882 /* start timer (must be AFTER initialize()) */
886 /* Initialize the scanline buffers */
888 for (n = 0; n <= (columns + 1); ++n)
891 for (n_c=0;n_c<components;n_c++)
892 for (n = 0; n <= (c_columns[n_c] + 1); ++n)
893 c_pscanline[n_c][n] = 0;
895 if ((components>1) && (multi==0))
897 /* OUTPUT PPM file, allocate auxiliary buffers */
898 local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
899 local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
901 local_pscanline = local_scanl0 + LEFTMARGIN-1;
902 local_cscanline = local_scanl1 + LEFTMARGIN-1;
906 for (n_s=0;n_s<number_of_scans;n_s++)
908 /* Repeat prediction/quantization/statistics scanline by scanline,
911 /* Reset Restart Markers for every scan */
914 /* This implementation supports parameters in 1st scan */
917 /* Prepare the quantization LUTs */
921 /* prepare div/mul tables for near-lossless quantization */
922 prepare_qtables(alpha,NEAR);
926 { /* Read further scan headers */
927 seek_return=seek_marker(in,&mk);
928 if (seek_return == EOF)
930 fprintf(stderr,"*** Premature End of File seeking SOS marker\n");
933 if ( seek_return > 2 )
935 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
936 fprintf(msgfile,"*** Added to marker segment count.\n");
941 fprintf(stderr,"Expecting SOS (%04x), got %04x\n",SOS,mk);
944 seek_return = read_jpegls_scan(in,head_scan[n_s]); /* Read the scan header*/
945 if (seek_return == EOF)
947 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
951 if (head_scan[n_s]->shift!=0)
953 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",head_scan[n_s]->shift);
956 if (head_scan[n_s]->NEAR != NEAR)
958 fprintf(stderr,"Got NEAR=%d after NEAR=%d: cannot change parameters between scans in this implementation\n",head_scan[n_s]->NEAR,NEAR);
961 if ((head_scan[n_s]->color_mode != PLANE_INT) || (head_scan[n_s]->comp != 1) ||
962 (head_scan[n_s]->comp_ids[0] != n_s+1))
964 fprintf(stderr,"This implementation supports multiple scans only in PLANE INTERLEAVED mode.\n");
969 /* Initializations for each scan */
972 /* Start from 1st image row */
975 /* Initialize stats arrays */
981 /* Initialize run processing */
982 init_process_run(MAXRUN);
984 if (color_mode==LINE_INT) { /* line int. */
986 /***********************************************************************/
987 /* Line interleaved mode with single file received */
988 /***********************************************************************/
995 /* 'extend' the edges */
996 for (n_c=0;n_c<components;n_c++)
997 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
999 for (n_c=0;n_c<components;n_c++)
1002 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1004 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1005 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1009 local_cscanline=cscanline;
1010 local_pscanline=pscanline;
1013 if ( lossless_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1015 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1021 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1022 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1025 write_one_line(cscanline + components, components*columns, out);
1027 tot_out += components*columns;
1029 /* extend the edges */
1030 for (n_c=0;n_c<components;n_c++)
1031 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1033 /* make the current scanline the previous one */
1036 /* Take out the Restart Markers */
1039 /* Look for restart markers only after a restart interval */
1040 if ((MCUs_counted % restart_interval) == 0)
1043 read_n_bytes(in, 2); /* read the RST marker */
1050 } /* End of while loop for each file line */
1057 /* 'extend' the edges */
1058 for (n_c=0;n_c<components;n_c++)
1059 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1061 for (n_c=0;n_c<components;n_c++)
1064 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1066 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1067 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1071 local_cscanline=cscanline;
1072 local_pscanline=pscanline;
1075 if ( lossy_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1077 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1083 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1084 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1087 write_one_line(cscanline + components, components*columns, out);
1089 tot_out += components*columns;
1091 /* extend the edges */
1092 for (n_c=0;n_c<components;n_c++)
1093 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1095 /* make the current scanline the previous one */
1098 /* Take out the Restart Markers */
1101 /* Look for restart markers only after a restart interval */
1102 if ((MCUs_counted % restart_interval) == 0)
1105 read_n_bytes(in, 2); /* read the RST marker */
1112 } /* End of while loop for each file line */
1116 { /* Multiple files */
1117 /* color_mode==LINE_INT and multi==1 */
1118 /***********************************************************************/
1119 /* Line interleaved mode with multiple files received */
1120 /***********************************************************************/
1127 while (n <= c_rows[whose_max_size_rows])
1129 for (n_c=0;n_c<components;n_c++)
1131 for (n_r=0;n_r<samplingy[n_c];n_r++)
1134 /* 'extend' the edges */
1135 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1137 if ( lossless_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1139 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1144 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1146 tot_out += c_columns[n_c];
1148 /* extend the edges */
1149 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1151 /* make the current scanline the previous one */
1154 } /* End of for loop for each component */
1156 n+=samplingy[whose_max_size_rows];
1158 /* Take out the Restart Markers */
1161 /* Look for restart markers only after a restart interval */
1162 if ((MCUs_counted % restart_interval) == 0)
1165 read_n_bytes(in, 2); /* read the RST marker */
1172 } /* End of while loop for each line */
1177 while (n <= c_rows[whose_max_size_rows])
1179 for (n_c=0;n_c<components;n_c++)
1181 for (n_r=0;n_r<samplingy[n_c];n_r++)
1184 /* 'extend' the edges */
1185 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1187 if ( lossy_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1189 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1194 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1196 tot_out += c_columns[n_c];
1198 /* extend the edges */
1199 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1201 /* make the current scanline the previous one */
1204 } /* End of for loop for each component */
1206 n+=samplingy[whose_max_size_rows];
1208 /* Take out the Restart Markers */
1211 /* Look for restart markers only after a restart interval */
1212 if ((MCUs_counted % restart_interval) == 0)
1215 read_n_bytes(in, 2); /* read the RST marker */
1222 } /* End of while loop for each line */
1225 } /* Closes the else, LINE_INT and multi=1 */
1227 } /* End of part for LINE_INT */
1229 else { /* Non LINE_INT mode */
1230 if (color_mode==PIXEL_INT) {
1231 /***********************************************************************/
1232 /* Pixel interleaved mode with single file received */
1233 /***********************************************************************/
1240 /* 'extend' the edges */
1241 for (n_c=0;n_c<components;n_c++)
1242 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1244 if ( lossless_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1246 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1251 write_one_line(cscanline+components, components*columns, out);
1253 tot_out += components*columns;
1255 /* extend the edges */
1256 for (n_c=0;n_c<components;n_c++)
1257 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1259 /* make the current scanline the previous one */
1262 /* Take out the Restart Markers */
1265 /* Look for restart markers only after a restart interval */
1266 if ((MCUs_counted % restart_interval) == 0)
1269 read_n_bytes(in, 2); /* read the RST marker */
1276 } /* End of line loop for PIXEL_INT */
1284 /* 'extend' the edges */
1285 for (n_c=0;n_c<components;n_c++)
1286 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1288 if ( lossy_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1290 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1295 write_one_line(cscanline+components, components*columns, out);
1297 tot_out += components*columns;
1299 /* extend the edges */
1300 for (n_c=0;n_c<components;n_c++)
1301 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1303 /* make the current scanline the previous one */
1306 /* Take out the Restart Markers */
1309 /* Look for restart markers only after a restart interval */
1310 if ((MCUs_counted % restart_interval) == 0)
1313 read_n_bytes(in, 2); /* read the RST marker */
1320 } /* End of line loop for PIXEL_INT */
1324 /***********************************************************************/
1325 /* Plane interleaved mode */
1326 /***********************************************************************/
1331 while (++n <= c_rows[n_s])
1333 /* 'extend' the edges */
1334 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1336 if (lossless_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1338 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1343 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1345 tot_out += c_columns[n_s];
1347 /* extend the edges */
1348 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1350 /* make the current scanline the previous one */
1353 /* Take out the Restart Markers */
1356 /* Look for restart markers only after a restart interval */
1357 if ((MCUs_counted % restart_interval) == 0)
1360 read_n_bytes(in, 2); /* read the RST marker */
1367 } /* End of line loop in PLANE_INT */
1372 while (++n <= c_rows[n_s])
1374 /* 'extend' the edges */
1375 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1377 if (lossy_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1379 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1384 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1386 tot_out += c_columns[n_s];
1388 /* extend the edges */
1389 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1391 /* make the current scanline the previous one */
1394 /* Take out the Restart Markers */
1397 /* Look for restart markers only after a restart interval */
1398 if ((MCUs_counted % restart_interval) == 0)
1401 read_n_bytes(in, 2); /* read the RST marker */
1408 } /* End of line loop in PLANE_INT */
1410 } /* End of each component for PLANE_INT */
1412 } /* End of non LINE_INT */
1416 } /* End of loop for scans */
1422 seek_return=seek_marker(in,&mk);
1423 if (seek_return==EOF)
1425 fprintf(stderr,"Did not get EOI at end of compressed image\n");
1428 if ( seek_return > 2 )
1430 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
1431 fprintf(msgfile,"*** Added to marker segment count.\n");
1434 pos0 += seek_return;
1437 fprintf(stderr,"In this implementation last marker must be EOI\n");
1441 if (head_scan[0]->need_table)
1442 fprintf(msgfile,"A mapping table was used which had %i entries of %i bytes each.\n",head_scan[0]->MAXTAB, head_scan[0]->Wt);
1445 fprintf(msgfile,"Restart markers were found with a restart interval of %i.\n",restart_interval);
1448 fprintf(msgfile,"Marker segment bytes: %ld\n",pos0);
1450 /* position in input file */
1452 /* tot_in = 8*(pos1-pos0); */
1454 /* size of compressed file read (bits), incl. headers. */
1458 close_process_run();
1459 closebuffers(multi);
1463 fprintf(msgfile,"Total bits in: %ld Symbols out: %ld %5.3lf bps\n",
1464 tot_in,tot_out,tot_in/(double)tot_out);
1465 fprintf(msgfile,"Time = %1.3lf secs : %1.0lf KSymbols/sec\n",t1-t0,
1466 (tot_out)/(1024*(t1-t0)));
1479 fprintf(stderr,"Usage: %s [flags] [infile] [outfile1 [outfile2, ...]]\n\
1482 outfile1 = %s for color image in a single (PPM) output file.\n\
1483 outfile1 = %s for monochrome image in a single (PGM) output file.\n\
1484 outfile[1,2,...] = %s for multiple (PGM) output files \n\
1485 in plane or line interleaved modes.\n",
1486 "locod", "specified JLS file", OUTFILE ".out",
1488 OUTFILE "[1,2,...].out");
1489 fprintf(stderr,"FLAGS:\n\
1490 outfile2, ... : Multiple output specification for plane or line int. mode.\n\
1491 -i<infile> : Alternate input specification, use -i- for stdin.\n\
1492 -o<outfile> : Alternate output specification, use -o- for stdout.\n\
1493 -P : Generate single (.ppm) output file for sample/line int. mode.\n\
1496 -h : Print this help.\n\
1497 *** No spaces allowed between a flag and its argument.\n\
1505 fprintf(stderr,"Bad flag %s\n",s);