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)
130 unsigned int* maptable;
132 /* No mapping tables used */
133 if(!(head_scan[0]->need_table))
136 unsigned char* line8;
137 line8 = (unsigned char*)safealloc(cols);
139 for (i=0; i< cols; i++)
140 *(line8+i)=(unsigned char)ENDIAN8(*(line+i));
142 fwrite(line8, sizeof(unsigned char), cols, outfile);
146 fwrite(line, sizeof(short), cols, outfile);
149 /* Mapping tables used */
154 /* Write one byte per table entry */
155 if (head_scan[0]->Wt == 1)
157 unsigned char* line8;
158 line8 = (unsigned char*)safealloc(cols); /* If don't have 2, it mallocs over the table? */
160 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
162 for (i=0; i<cols; i++)
165 *(line8+i) = ENDIAN8(maptable[index]);
168 fwrite(line8, sizeof(unsigned char), cols, outfile);
172 /* Write two bytes per table entry */
173 else if (head_scan[0]->Wt == 2)
175 unsigned short* line16;
176 line16 = (unsigned short*)safealloc(cols*2);
178 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
180 for (i=0; i<cols; i++)
183 *(line16+i) = (unsigned short) maptable[index];
186 fwrite(line16, sizeof(short), cols, outfile);
190 /* Write three bytes per table entry */
191 else if (head_scan[0]->Wt == 3)
193 unsigned char* line8_3;
194 line8_3 = (unsigned char*)safealloc(cols*3);
196 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
198 for (i=0; i<cols; i++)
201 *(line8_3 + (i*3)) = (unsigned char) (maptable[index] >> 16);
202 *(line8_3 + (i*3) + 1) = (unsigned char) (maptable[index] >> 8);
203 *(line8_3 + (i*3) + 2) = (unsigned char) (maptable[index]);
206 fwrite(line8_3, sizeof(char), cols*3, outfile);
212 /* Can't do 16 bit index values */
216 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
228 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);
274 void c_swaplines(int i)
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)
293 for (i=0;i<components;i++)
301 /* command line argument parsing */
302 int initialize(int argc, char *argv[])
304 char *infilename = NULL,
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]=(char*)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))
559 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with plane intereleaved mode\n");
565 if ((multi) && (color_mode==PIXEL_INT)) {
566 multi = 0; /* equivalent to specifying -P flag */
569 if ((out_files>1) && (color_mode==PIXEL_INT)) {
570 fprintf(stderr,"ERROR: Pixel interleaved mode uses only 1 output file\n");
574 if ((multi) && (out_files) && (out_files!=components)) {
575 fprintf(stderr,"ERROR: Number of files, %d, for output must be equal to number of image components, %d\n",out_files,components);
579 /* Compute the image size for the different components */
581 c_columns[0]=columns;
583 whose_max_size_rows=0;
590 for(i=0;i<components;i++) {
591 if (samplingx[i]>max_samp_columns) {
592 max_samp_columns=samplingx[i];
593 whose_max_size_columns=i;
595 if (samplingy[i]>max_samp_rows) {
596 max_samp_rows=samplingy[i];
597 whose_max_size_rows=i;
601 c_columns[whose_max_size_columns]=columns;
602 c_rows[whose_max_size_rows]=rows;
604 for(i=0;i<components;i++) {
605 if (i!=whose_max_size_columns)
607 c_columns[i]=c_columns[whose_max_size_columns]*samplingx[i];
608 c_columns[i]/=samplingx[whose_max_size_columns];
610 if (i!=whose_max_size_rows) {
611 c_rows[i]=c_rows[whose_max_size_rows]*samplingy[i];
612 c_rows[i]/=samplingy[whose_max_size_rows];
618 /* msgfile seems to start being used here, let's initialize it here */
619 if ( !msgfile ) msgfile = stdout;
621 if ( outfilename == NULL ) {
626 if ( strcmp(outfilename,"-")==0 ) {
632 if ( (out=fopen(outfilename,"wb")) == NULL ) {
638 for (i=0;i<components;i++)
639 if ( (c_out[i]=fopen(c_outfilename[i],"wb")) == NULL )
641 perror(c_outfilename[i]);
649 /* check that color mode is valid and pick color mode string */
650 switch ( color_mode ) {
653 color_mode_string = plane_int_string;
657 color_mode_string = line_int_string;
661 color_mode_string = pixel_int_string;
665 fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
671 fprintf(msgfile,"%s\n",banner);
676 fprintf(msgfile,"Input file: %s\nOutput file: %s\n",infilename,outfilename);
679 fprintf(msgfile,"Input file: %s\nOutput files: ",infilename);
680 for (i=0;i<components;i++)
681 fprintf(msgfile," %s ",c_outfilename[i]);
682 fprintf(msgfile,"\n");
687 if ( alpha0 != alpha ) {
688 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);
693 ceil_half_alpha = (alpha+1)/2;
698 /* check that alpha is a power of 2 */
699 for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);
700 if ( alpha != (1<<i) ) {
701 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);
708 /* compute auxiliary parameters for near-lossless (globals) */
710 qbeta = (alpha + 2*NEAR + quant-1 )/quant;
712 ceil_half_qbeta = (qbeta+1)/2;
714 alpha1eps = alpha-1+NEAR;
715 fprintf(msgfile,"Near-lossless mode: NEAR = %d beta = %d qbeta = %d\n",NEAR,beta,qbeta);
718 /* compute bits per sample for input symbols */
719 for ( bpp=1; (1L<<bpp)<alpha; bpp++ );
721 /* compute bits per sample for unencoded prediction errors */
723 for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );
727 if ( bpp < 2 ) bpp = 2;
729 /* limit for unary part of Golomb code */
731 limit = 2*(bpp + 8) - qbpp -1;
733 limit = 4*bpp - qbpp - 1;
735 /* print out parameters */
738 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",
739 columns, rows, alpha0, components,
740 color_mode, color_mode_string,
741 T1, T2, T3, RESET,limit);
743 fprintf(msgfile,"Image: cols=");
744 for (i=0;i<components;i++)
745 fprintf(msgfile," %d",c_columns[i]);
746 fprintf(msgfile," rows=");
747 for (i=0;i<components;i++)
748 fprintf(msgfile," %d",c_rows[i]);
749 fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
751 color_mode, color_mode_string,
752 T1, T2, T3,RESET,limit);
757 fprintf(msgfile,"\n");
760 /* Write out the image header for PGM or PPM files */
761 /* Must look at if there are Mapping Tables used */
763 /* No Mapping Tables used */
764 if (!head_scan[0]->need_table)
767 if (components==1) fputs("P5\n", out);
768 else if (components==3) fputs("P6\n", out);
769 else if (components==4) fputs("P7\n", out);
770 else fprintf(out,"P%d\n",10+components);
772 fprintf(out,"%d %d\n", columns, rows);
773 fprintf(out,"%d\n", alpha - 1);
776 for (i=0;i<components;i++) {
777 fputs("P5\n", c_out[i]);
778 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
779 fprintf(c_out[i],"%d\n", alpha - 1);
783 /* Mapping Tables used */
786 /* only 8 bit indexes supported for mapping tables */
789 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
793 /* Mapping Table elements are 1 or 2 bytes */
794 if (head_scan[0]->Wt==1 || head_scan[0]->Wt==2)
797 if (head_scan[0]->Wt==1)
800 alpha_temp = alpha*alpha;
804 if (components==1) fputs("P5\n", out);
805 else if (components==3) fputs("P6\n", out);
806 else if (components==4) fputs("P7\n", out);
807 else fprintf(out,"P%d\n",10+components);
809 fprintf(out,"%d %d\n", columns, rows);
810 fprintf(out,"%d\n", alpha_temp - 1);
813 for (i=0;i<components;i++)
815 fputs("P5\n", c_out[i]);
816 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
817 fprintf(c_out[i],"%d\n", alpha_temp - 1);
821 /* Mapping Table elements are 3 bytes */
822 else if (head_scan[0]->Wt==3)
826 if (components==1) fputs("P6\n", out);
829 fprintf(stderr,"Error : Cannot have a multi-component image and a mapping table with 3 bytes per element.\n");
833 fprintf(out,"%d %d\n", columns, rows);
834 fprintf(out,"%d\n", alpha - 1);
837 for (i=0;i<components;i++)
839 fputs("P6\n", c_out[i]);
840 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
841 fprintf(c_out[i],"%d\n", alpha - 1);
845 /* Mapping Table elements aren't 1 to 3 bytes */
848 fprintf(stderr, "Sorry, mapping tables elements can only be 1 to 3 bytes in this implementation.\n");
854 /* Allocate memory pools. */
855 initbuffers(multi, components);
858 /* return size of the header, in bytes */
867 /* Main loop for decoding files */
869 int main (int argc, char *argv[]) {
870 int n,n_c,n_r,my_i,n_s,mk,seek_return;
872 double t0, t1; /*, get_utime();*/
876 pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
878 local_cscanline = local_pscanline = NULL;
881 /* Parse the parameters, initialize */
882 /* Not yet fully implemented */
884 pos0 = initialize(argc, argv);
887 /* start timer (must be AFTER initialize()) */
891 /* Initialize the scanline buffers */
893 for (n = 0; n <= (columns + 1); ++n)
896 for (n_c=0;n_c<components;n_c++)
897 for (n = 0; n <= (c_columns[n_c] + 1); ++n)
898 c_pscanline[n_c][n] = 0;
900 if ((components>1) && (multi==0))
902 /* OUTPUT PPM file, allocate auxiliary buffers */
903 local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
904 local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
906 local_pscanline = local_scanl0 + LEFTMARGIN-1;
907 local_cscanline = local_scanl1 + LEFTMARGIN-1;
911 for (n_s=0;n_s<number_of_scans;n_s++)
913 /* Repeat prediction/quantization/statistics scanline by scanline,
916 /* Reset Restart Markers for every scan */
919 /* This implementation supports parameters in 1st scan */
922 /* Prepare the quantization LUTs */
926 /* prepare div/mul tables for near-lossless quantization */
927 prepare_qtables(alpha,NEAR);
931 { /* Read further scan headers */
932 seek_return=seek_marker(in,&mk);
933 if (seek_return == EOF)
935 fprintf(stderr,"*** Premature End of File seeking SOS marker\n");
938 if ( seek_return > 2 )
940 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
941 fprintf(msgfile,"*** Added to marker segment count.\n");
946 fprintf(stderr,"Expecting SOS (%04x), got %04x\n",SOS,mk);
949 seek_return = read_jpegls_scan(in,head_scan[n_s]); /* Read the scan header*/
950 if (seek_return == EOF)
952 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
956 if (head_scan[n_s]->shift!=0)
958 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",head_scan[n_s]->shift);
961 if (head_scan[n_s]->NEAR != NEAR)
963 fprintf(stderr,"Got NEAR=%d after NEAR=%d: cannot change parameters between scans in this implementation\n",head_scan[n_s]->NEAR,NEAR);
966 if ((head_scan[n_s]->color_mode != PLANE_INT) || (head_scan[n_s]->comp != 1) ||
967 (head_scan[n_s]->comp_ids[0] != n_s+1))
969 fprintf(stderr,"This implementation supports multiple scans only in PLANE INTERLEAVED mode.\n");
974 /* Initializations for each scan */
977 /* Start from 1st image row */
980 /* Initialize stats arrays */
986 /* Initialize run processing */
987 init_process_run(MAXRUN);
989 if (color_mode==LINE_INT) { /* line int. */
991 /***********************************************************************/
992 /* Line interleaved mode with single file received */
993 /***********************************************************************/
1000 /* 'extend' the edges */
1001 for (n_c=0;n_c<components;n_c++)
1002 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1004 for (n_c=0;n_c<components;n_c++)
1007 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1009 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1010 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1014 local_cscanline=cscanline;
1015 local_pscanline=pscanline;
1018 if ( lossless_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1020 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1026 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1027 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1030 write_one_line(cscanline + components, components*columns, out);
1032 tot_out += components*columns;
1034 /* extend the edges */
1035 for (n_c=0;n_c<components;n_c++)
1036 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1038 /* make the current scanline the previous one */
1041 /* Take out the Restart Markers */
1044 /* Look for restart markers only after a restart interval */
1045 if ((MCUs_counted % restart_interval) == 0)
1048 read_n_bytes(in, 2); /* read the RST marker */
1055 } /* End of while loop for each file line */
1062 /* 'extend' the edges */
1063 for (n_c=0;n_c<components;n_c++)
1064 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1066 for (n_c=0;n_c<components;n_c++)
1069 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1071 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1072 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1076 local_cscanline=cscanline;
1077 local_pscanline=pscanline;
1080 if ( lossy_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1082 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1088 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1089 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1092 write_one_line(cscanline + components, components*columns, out);
1094 tot_out += components*columns;
1096 /* extend the edges */
1097 for (n_c=0;n_c<components;n_c++)
1098 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1100 /* make the current scanline the previous one */
1103 /* Take out the Restart Markers */
1106 /* Look for restart markers only after a restart interval */
1107 if ((MCUs_counted % restart_interval) == 0)
1110 read_n_bytes(in, 2); /* read the RST marker */
1117 } /* End of while loop for each file line */
1121 { /* Multiple files */
1122 /* color_mode==LINE_INT and multi==1 */
1123 /***********************************************************************/
1124 /* Line interleaved mode with multiple files received */
1125 /***********************************************************************/
1132 while (n <= c_rows[whose_max_size_rows])
1134 for (n_c=0;n_c<components;n_c++)
1136 for (n_r=0;n_r<samplingy[n_c];n_r++)
1139 /* 'extend' the edges */
1140 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1142 if ( lossless_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1144 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1149 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1151 tot_out += c_columns[n_c];
1153 /* extend the edges */
1154 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1156 /* make the current scanline the previous one */
1159 } /* End of for loop for each component */
1161 n+=samplingy[whose_max_size_rows];
1163 /* Take out the Restart Markers */
1166 /* Look for restart markers only after a restart interval */
1167 if ((MCUs_counted % restart_interval) == 0)
1170 read_n_bytes(in, 2); /* read the RST marker */
1177 } /* End of while loop for each line */
1182 while (n <= c_rows[whose_max_size_rows])
1184 for (n_c=0;n_c<components;n_c++)
1186 for (n_r=0;n_r<samplingy[n_c];n_r++)
1189 /* 'extend' the edges */
1190 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1192 if ( lossy_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1194 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1199 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1201 tot_out += c_columns[n_c];
1203 /* extend the edges */
1204 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1206 /* make the current scanline the previous one */
1209 } /* End of for loop for each component */
1211 n+=samplingy[whose_max_size_rows];
1213 /* Take out the Restart Markers */
1216 /* Look for restart markers only after a restart interval */
1217 if ((MCUs_counted % restart_interval) == 0)
1220 read_n_bytes(in, 2); /* read the RST marker */
1227 } /* End of while loop for each line */
1230 } /* Closes the else, LINE_INT and multi=1 */
1232 } /* End of part for LINE_INT */
1234 else { /* Non LINE_INT mode */
1235 if (color_mode==PIXEL_INT) {
1236 /***********************************************************************/
1237 /* Pixel interleaved mode with single file received */
1238 /***********************************************************************/
1245 /* 'extend' the edges */
1246 for (n_c=0;n_c<components;n_c++)
1247 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1249 if ( lossless_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1251 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1256 write_one_line(cscanline+components, components*columns, out);
1258 tot_out += components*columns;
1260 /* extend the edges */
1261 for (n_c=0;n_c<components;n_c++)
1262 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1264 /* make the current scanline the previous one */
1267 /* Take out the Restart Markers */
1270 /* Look for restart markers only after a restart interval */
1271 if ((MCUs_counted % restart_interval) == 0)
1274 read_n_bytes(in, 2); /* read the RST marker */
1281 } /* End of line loop for PIXEL_INT */
1289 /* 'extend' the edges */
1290 for (n_c=0;n_c<components;n_c++)
1291 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1293 if ( lossy_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1295 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1300 write_one_line(cscanline+components, components*columns, out);
1302 tot_out += components*columns;
1304 /* extend the edges */
1305 for (n_c=0;n_c<components;n_c++)
1306 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1308 /* make the current scanline the previous one */
1311 /* Take out the Restart Markers */
1314 /* Look for restart markers only after a restart interval */
1315 if ((MCUs_counted % restart_interval) == 0)
1318 read_n_bytes(in, 2); /* read the RST marker */
1325 } /* End of line loop for PIXEL_INT */
1329 /***********************************************************************/
1330 /* Plane interleaved mode */
1331 /***********************************************************************/
1336 while (++n <= c_rows[n_s])
1338 /* 'extend' the edges */
1339 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1341 if (lossless_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1343 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1348 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1350 tot_out += c_columns[n_s];
1352 /* extend the edges */
1353 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1355 /* make the current scanline the previous one */
1358 /* Take out the Restart Markers */
1361 /* Look for restart markers only after a restart interval */
1362 if ((MCUs_counted % restart_interval) == 0)
1365 read_n_bytes(in, 2); /* read the RST marker */
1372 } /* End of line loop in PLANE_INT */
1377 while (++n <= c_rows[n_s])
1379 /* 'extend' the edges */
1380 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1382 if (lossy_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1384 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1389 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1391 tot_out += c_columns[n_s];
1393 /* extend the edges */
1394 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1396 /* make the current scanline the previous one */
1399 /* Take out the Restart Markers */
1402 /* Look for restart markers only after a restart interval */
1403 if ((MCUs_counted % restart_interval) == 0)
1406 read_n_bytes(in, 2); /* read the RST marker */
1413 } /* End of line loop in PLANE_INT */
1415 } /* End of each component for PLANE_INT */
1417 } /* End of non LINE_INT */
1421 } /* End of loop for scans */
1427 seek_return=seek_marker(in,&mk);
1428 if (seek_return==EOF)
1430 fprintf(stderr,"Did not get EOI at end of compressed image\n");
1433 if ( seek_return > 2 )
1435 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
1436 fprintf(msgfile,"*** Added to marker segment count.\n");
1439 pos0 += seek_return;
1442 fprintf(stderr,"In this implementation last marker must be EOI\n");
1446 if (head_scan[0]->need_table)
1447 fprintf(msgfile,"A mapping table was used which had %i entries of %i bytes each.\n",head_scan[0]->MAXTAB, head_scan[0]->Wt);
1450 fprintf(msgfile,"Restart markers were found with a restart interval of %i.\n",restart_interval);
1453 fprintf(msgfile,"Marker segment bytes: %ld\n",pos0);
1455 /* position in input file */
1457 /* tot_in = 8*(pos1-pos0); */
1459 /* size of compressed file read (bits), incl. headers. */
1463 close_process_run();
1464 closebuffers(multi);
1468 fprintf(msgfile,"Total bits in: %ld Symbols out: %ld %5.3f bps\n",
1469 tot_in,tot_out,tot_in/(double)tot_out);
1470 fprintf(msgfile,"Time = %1.3f secs : %1.0f KSymbols/sec\n",t1-t0,
1471 (tot_out)/(1024*(t1-t0)));
1484 fprintf(stderr,"Usage: %s [flags] [infile] [outfile1 [outfile2, ...]]\n\
1487 outfile1 = %s for color image in a single (PPM) output file.\n\
1488 outfile1 = %s for monochrome image in a single (PGM) output file.\n\
1489 outfile[1,2,...] = %s for multiple (PGM) output files \n\
1490 in plane or line interleaved modes.\n",
1491 "locod", "specified JLS file", OUTFILE ".out",
1493 OUTFILE "[1,2,...].out");
1494 fprintf(stderr,"FLAGS:\n\
1495 outfile2, ... : Multiple output specification for plane or line int. mode.\n\
1496 -i<infile> : Alternate input specification, use -i- for stdin.\n\
1497 -o<outfile> : Alternate output specification, use -o- for stdout.\n\
1498 -P : Generate single (.ppm) output file for sample/line int. mode.\n\
1501 -h : Print this help.\n\
1502 *** No spaces allowed between a flag and its argument.\n\
1508 void bad_flag(char *s)
1510 fprintf(stderr,"Bad flag %s\n",s);