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) */
127 /* Write one row of pixel values */
128 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)
234 if (multi) /* Output to several files */
236 for (i=0;i<comp;i++) {
238 c_pscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
239 c_cscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
241 /* Adjust scan line pointers taking into account the margins,
242 and also the fact that indexing for scan lines starts from 1
244 c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
245 c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
248 else { /* Output to a single file */
250 pscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
251 cscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
253 /* Adjust scan line pointers taking into account the margins,
254 and also the fact that indexing for scan lines starts from 1
255 (this will probably have to be changed in the future)
257 pscanline = pscanl0 + components*(LEFTMARGIN-1);
258 cscanline = cscanl0 + components*(LEFTMARGIN-1);
271 pscanline = pscanl0 + components*(LEFTMARGIN-1);
272 cscanline = cscanl0 + components*(LEFTMARGIN-1);
275 void c_swaplines(int i)
279 c_pscanl0[i] = c_cscanl0[i];
281 c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
282 c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
285 void closebuffers(int multi)
294 for (i=0;i<components;i++)
302 /* command line argument parsing */
303 int initialize(int argc, char *argv[])
305 char *infilename = NULL,
306 *outfilename = OUTFILE ".out",
307 *c_outfilename[MAX_COMPONENTS],
309 int i, max_samp_columns, max_samp_rows, mk, n_s,
316 int pos; /* position in the file, after the header */
318 for (i=0;i<MAX_COMPONENTS;i++) {
319 c_outfilename[i]=malloc(strlen(OUTFILE)+20);
320 sprintf(c_outfilename[i],"%s%d.out",OUTFILE,i+1);
324 for ( i=1; i<argc; i++ )
325 if ( argv[i][0] == '-' )
327 switch ( argv[i][1] ) {
330 infilename = argv[i]+2;
335 outfilename = c_outfilename[out_files++] = argv[i]+2;
344 if ( sscanf(argv[i],"-v%d",&verbose) != 1 )
355 infilename = argv[i];
358 else if ( ! gotoutf )
359 outfilename = c_outfilename[out_files++] = argv[i];
363 verbose = 1; /* at least the banner will show */
365 if ((!multi) && (out_files>1)) {
366 fprintf(stderr,"\nERROR: Only 1 output file expected with -P option.\nThis option is valid only for line/pixel interleaved and not subsampled.\n");
371 if ( infilename == NULL ) {
376 if ( strcmp(infilename,"-")==0 )
378 else if ( (in=fopen(infilename,"rb")) == NULL ) {
384 /* Read the compressed image frame header */
387 head_frame = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
389 for (n_s=0;n_s<MAX_SCANS;n_s++) {
390 head_scan[n_s] = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
391 head_scan[n_s]->T1=head_scan[n_s]->T2=head_scan[n_s]->T3=0;
392 head_scan[n_s]->RES = DEFAULT_RESET;
396 seek_return = seek_marker(in,&mk);
397 if (seek_return == EOF) {
398 fprintf(stderr,"*** Premature End of File seeking SOI\n");
404 fprintf(stderr,"Marker %04x found: first marker must be SOI (%04x) in this implementation\n", mk, SOI);
410 seek_return = seek_marker(in,&mk);
411 if (seek_return == EOF) {
412 fprintf(stderr,"*** Premature End of File seeking SOF_LS\n");
416 pos += seek_return; /* Read SOF_LS */
418 fprintf(stderr,"Marker %04x found: second marker must be SOF_LS (%04x) in this implementation\n", mk, SOF_LS);
423 /* Read the frame header (SOF) */
424 seek_return = read_jpegls_frame(in,head_frame);
425 if (seek_return == EOF) {
426 fprintf(stderr,"*** Premature End of File reading frame header\n");
432 head_scan[0]->alp = head_frame->alp; /* default alpha */
435 /* LSE Extension header */
436 /* This version supports only 2 extension headers, and 1 set of
437 parameters for all the scans */
439 head_scan[0]->need_table = 0;
443 seek_return=seek_marker(in, &mk);
444 if (seek_return == EOF) {
445 fprintf(stderr,"*** Premature End of File seeking SOS or LSE marker\n");
454 seek_return = read_jpegls_extmarker(in, head_scan[0]);
455 if (seek_return == EOF) {
456 fprintf(stderr,"*** Premature End of File\n");
464 seek_return = read_jpegls_restartmarker(in, head_scan[0]);
467 restart_interval = head_scan[0]->restart_interval;
475 /* End of extension header */
479 /* Read the scan header*/
480 seek_return = read_jpegls_scan(in,head_scan[0]);
481 if (seek_return == EOF) {
482 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
487 shift=head_scan[0]->shift;
489 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",shift);
493 NEAR=head_scan[0]->NEAR;
494 color_mode=head_scan[0]->color_mode;
495 columns=head_frame->columns;
496 rows=head_frame->rows;
497 alpha0=head_scan[0]->alp;
498 head_frame->alp = alpha0;
499 components=head_frame->comp;
501 if (color_mode==PLANE_INT)
502 number_of_scans=components;
506 set_thresholds(head_scan[0]->alp, head_scan[0]->NEAR, &(head_scan[0]->T1), &(head_scan[0]->T2), &(head_scan[0]->T3));
512 RESET=head_scan[0]->RES;
514 if (head_scan[0]->RES != DEFAULT_RESET) {
515 fprintf(stderr,"ERROR: Version compiled for fixed RESET=%d parameter: got %d\n",DEFAULT_RESET,head_scan[0]->RES);
520 /* Check to see if lossless or lossy */
526 /* Check for 16 or 8 bit mode */
527 if (alpha0 <= MAXA16 && alpha0 > MAXA8)
533 else if (alpha0 <= MAXA8 && alpha0 >= 1)
540 fprintf(stderr,"Got alpha = %d\n",alpha0+1);
541 error("Bad value for alpha. Sorry...\n");
545 check_compatibility(head_frame,head_scan[0],0);
547 for (i=0;i<components;i++) {
548 samplingx[i]=head_frame->samplingx[i];
549 samplingy[i]=head_frame->samplingy[i];
550 if ((!multi) && ((samplingx[i]!=1) || (samplingy[i]!=1)) && (components>1))
552 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with subsampled compressed components\n");
557 if ((!multi) && (color_mode==PLANE_INT))
560 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with plane intereleaved mode\n");
566 if ((multi) && (color_mode==PIXEL_INT)) {
567 multi = 0; /* equivalent to specifying -P flag */
570 if ((out_files>1) && (color_mode==PIXEL_INT)) {
571 fprintf(stderr,"ERROR: Pixel interleaved mode uses only 1 output file\n");
575 if ((multi) && (out_files) && (out_files!=components)) {
576 fprintf(stderr,"ERROR: Number of files, %d, for output must be equal to number of image components, %d\n",out_files,components);
580 /* Compute the image size for the different components */
582 c_columns[0]=columns;
584 whose_max_size_rows=0;
591 for(i=0;i<components;i++) {
592 if (samplingx[i]>max_samp_columns) {
593 max_samp_columns=samplingx[i];
594 whose_max_size_columns=i;
596 if (samplingy[i]>max_samp_rows) {
597 max_samp_rows=samplingy[i];
598 whose_max_size_rows=i;
602 c_columns[whose_max_size_columns]=columns;
603 c_rows[whose_max_size_rows]=rows;
605 for(i=0;i<components;i++) {
606 if (i!=whose_max_size_columns)
608 c_columns[i]=c_columns[whose_max_size_columns]*samplingx[i];
609 c_columns[i]/=samplingx[whose_max_size_columns];
611 if (i!=whose_max_size_rows) {
612 c_rows[i]=c_rows[whose_max_size_rows]*samplingy[i];
613 c_rows[i]/=samplingy[whose_max_size_rows];
619 /* msgfile seems to start being used here, let's initialize it here */
620 if ( !msgfile ) msgfile = stdout;
622 if ( outfilename == NULL ) {
627 if ( strcmp(outfilename,"-")==0 ) {
633 if ( (out=fopen(outfilename,"wb")) == NULL ) {
639 for (i=0;i<components;i++)
640 if ( (c_out[i]=fopen(c_outfilename[i],"wb")) == NULL )
642 perror(c_outfilename[i]);
650 /* check that color mode is valid and pick color mode string */
651 switch ( color_mode ) {
654 color_mode_string = plane_int_string;
658 color_mode_string = line_int_string;
662 color_mode_string = pixel_int_string;
666 fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
672 fprintf(msgfile,"%s\n",banner);
677 fprintf(msgfile,"Input file: %s\nOutput file: %s\n",infilename,outfilename);
680 fprintf(msgfile,"Input file: %s\nOutput files: ",infilename);
681 for (i=0;i<components;i++)
682 fprintf(msgfile," %s ",c_outfilename[i]);
683 fprintf(msgfile,"\n");
688 if ( alpha0 != alpha ) {
689 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);
694 ceil_half_alpha = (alpha+1)/2;
699 /* check that alpha is a power of 2 */
700 for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);
701 if ( alpha != (1<<i) ) {
702 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);
709 /* compute auxiliary parameters for near-lossless (globals) */
711 qbeta = (alpha + 2*NEAR + quant-1 )/quant;
713 ceil_half_qbeta = (qbeta+1)/2;
715 alpha1eps = alpha-1+NEAR;
716 fprintf(msgfile,"Near-lossless mode: NEAR = %d beta = %d qbeta = %d\n",NEAR,beta,qbeta);
719 /* compute bits per sample for input symbols */
720 for ( bpp=1; (1L<<bpp)<alpha; bpp++ );
722 /* compute bits per sample for unencoded prediction errors */
724 for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );
728 if ( bpp < 2 ) bpp = 2;
730 /* limit for unary part of Golomb code */
732 limit = 2*(bpp + 8) - qbpp -1;
734 limit = 4*bpp - qbpp - 1;
736 /* print out parameters */
739 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",
740 columns, rows, alpha0, components,
741 color_mode, color_mode_string,
742 T1, T2, T3, RESET,limit);
744 fprintf(msgfile,"Image: cols=");
745 for (i=0;i<components;i++)
746 fprintf(msgfile," %d",c_columns[i]);
747 fprintf(msgfile," rows=");
748 for (i=0;i<components;i++)
749 fprintf(msgfile," %d",c_rows[i]);
750 fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
752 color_mode, color_mode_string,
753 T1, T2, T3,RESET,limit);
758 fprintf(msgfile,"\n");
761 /* Write out the image header for PGM or PPM files */
762 /* Must look at if there are Mapping Tables used */
764 /* No Mapping Tables used */
765 if (!head_scan[0]->need_table)
768 if (components==1) fputs("P5\n", out);
769 else if (components==3) fputs("P6\n", out);
770 else if (components==4) fputs("P7\n", out);
771 else fprintf(out,"P%d\n",10+components);
773 fprintf(out,"%d %d\n", columns, rows);
774 fprintf(out,"%d\n", alpha - 1);
777 for (i=0;i<components;i++) {
778 fputs("P5\n", c_out[i]);
779 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
780 fprintf(c_out[i],"%d\n", alpha - 1);
784 /* Mapping Tables used */
787 /* only 8 bit indexes supported for mapping tables */
790 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
794 /* Mapping Table elements are 1 or 2 bytes */
795 if (head_scan[0]->Wt==1 || head_scan[0]->Wt==2)
798 if (head_scan[0]->Wt==1)
801 alpha_temp = alpha*alpha;
805 if (components==1) fputs("P5\n", out);
806 else if (components==3) fputs("P6\n", out);
807 else if (components==4) fputs("P7\n", out);
808 else fprintf(out,"P%d\n",10+components);
810 fprintf(out,"%d %d\n", columns, rows);
811 fprintf(out,"%d\n", alpha_temp - 1);
814 for (i=0;i<components;i++)
816 fputs("P5\n", c_out[i]);
817 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
818 fprintf(c_out[i],"%d\n", alpha_temp - 1);
822 /* Mapping Table elements are 3 bytes */
823 else if (head_scan[0]->Wt==3)
827 if (components==1) fputs("P6\n", out);
830 fprintf(stderr,"Error : Cannot have a multi-component image and a mapping table with 3 bytes per element.\n");
834 fprintf(out,"%d %d\n", columns, rows);
835 fprintf(out,"%d\n", alpha - 1);
838 for (i=0;i<components;i++)
840 fputs("P6\n", c_out[i]);
841 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
842 fprintf(c_out[i],"%d\n", alpha - 1);
846 /* Mapping Table elements aren't 1 to 3 bytes */
849 fprintf(stderr, "Sorry, mapping tables elements can only be 1 to 3 bytes in this implementation.\n");
855 /* Allocate memory pools. */
856 initbuffers(multi, components);
859 /* return size of the header, in bytes */
868 /* Main loop for decoding files */
870 int main (int argc, char *argv[]) {
871 int n,n_c,n_r,my_i,n_s,mk,seek_return;
873 double t0, t1; /*, get_utime();*/
877 pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
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.3lf bps\n",
1469 tot_in,tot_out,tot_in/(double)tot_out);
1470 fprintf(msgfile,"Time = %1.3lf secs : %1.0lf 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);