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)=(unsigned char)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]=(char*)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;
879 local_cscanline = local_pscanline = NULL;
882 /* Parse the parameters, initialize */
883 /* Not yet fully implemented */
885 pos0 = initialize(argc, argv);
888 /* start timer (must be AFTER initialize()) */
892 /* Initialize the scanline buffers */
894 for (n = 0; n <= (columns + 1); ++n)
897 for (n_c=0;n_c<components;n_c++)
898 for (n = 0; n <= (c_columns[n_c] + 1); ++n)
899 c_pscanline[n_c][n] = 0;
901 if ((components>1) && (multi==0))
903 /* OUTPUT PPM file, allocate auxiliary buffers */
904 local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
905 local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
907 local_pscanline = local_scanl0 + LEFTMARGIN-1;
908 local_cscanline = local_scanl1 + LEFTMARGIN-1;
912 for (n_s=0;n_s<number_of_scans;n_s++)
914 /* Repeat prediction/quantization/statistics scanline by scanline,
917 /* Reset Restart Markers for every scan */
920 /* This implementation supports parameters in 1st scan */
923 /* Prepare the quantization LUTs */
927 /* prepare div/mul tables for near-lossless quantization */
928 prepare_qtables(alpha,NEAR);
932 { /* Read further scan headers */
933 seek_return=seek_marker(in,&mk);
934 if (seek_return == EOF)
936 fprintf(stderr,"*** Premature End of File seeking SOS marker\n");
939 if ( seek_return > 2 )
941 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
942 fprintf(msgfile,"*** Added to marker segment count.\n");
947 fprintf(stderr,"Expecting SOS (%04x), got %04x\n",SOS,mk);
950 seek_return = read_jpegls_scan(in,head_scan[n_s]); /* Read the scan header*/
951 if (seek_return == EOF)
953 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
957 if (head_scan[n_s]->shift!=0)
959 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",head_scan[n_s]->shift);
962 if (head_scan[n_s]->NEAR != NEAR)
964 fprintf(stderr,"Got NEAR=%d after NEAR=%d: cannot change parameters between scans in this implementation\n",head_scan[n_s]->NEAR,NEAR);
967 if ((head_scan[n_s]->color_mode != PLANE_INT) || (head_scan[n_s]->comp != 1) ||
968 (head_scan[n_s]->comp_ids[0] != n_s+1))
970 fprintf(stderr,"This implementation supports multiple scans only in PLANE INTERLEAVED mode.\n");
975 /* Initializations for each scan */
978 /* Start from 1st image row */
981 /* Initialize stats arrays */
987 /* Initialize run processing */
988 init_process_run(MAXRUN);
990 if (color_mode==LINE_INT) { /* line int. */
992 /***********************************************************************/
993 /* Line interleaved mode with single file received */
994 /***********************************************************************/
1001 /* 'extend' the edges */
1002 for (n_c=0;n_c<components;n_c++)
1003 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1005 for (n_c=0;n_c<components;n_c++)
1008 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1010 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1011 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1015 local_cscanline=cscanline;
1016 local_pscanline=pscanline;
1019 if ( lossless_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1021 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1027 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1028 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1031 write_one_line(cscanline + components, components*columns, out);
1033 tot_out += components*columns;
1035 /* extend the edges */
1036 for (n_c=0;n_c<components;n_c++)
1037 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1039 /* make the current scanline the previous one */
1042 /* Take out the Restart Markers */
1045 /* Look for restart markers only after a restart interval */
1046 if ((MCUs_counted % restart_interval) == 0)
1049 read_n_bytes(in, 2); /* read the RST marker */
1056 } /* End of while loop for each file line */
1063 /* 'extend' the edges */
1064 for (n_c=0;n_c<components;n_c++)
1065 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1067 for (n_c=0;n_c<components;n_c++)
1070 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1072 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1073 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1077 local_cscanline=cscanline;
1078 local_pscanline=pscanline;
1081 if ( lossy_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1083 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1089 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1090 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1093 write_one_line(cscanline + components, components*columns, out);
1095 tot_out += components*columns;
1097 /* extend the edges */
1098 for (n_c=0;n_c<components;n_c++)
1099 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1101 /* make the current scanline the previous one */
1104 /* Take out the Restart Markers */
1107 /* Look for restart markers only after a restart interval */
1108 if ((MCUs_counted % restart_interval) == 0)
1111 read_n_bytes(in, 2); /* read the RST marker */
1118 } /* End of while loop for each file line */
1122 { /* Multiple files */
1123 /* color_mode==LINE_INT and multi==1 */
1124 /***********************************************************************/
1125 /* Line interleaved mode with multiple files received */
1126 /***********************************************************************/
1133 while (n <= c_rows[whose_max_size_rows])
1135 for (n_c=0;n_c<components;n_c++)
1137 for (n_r=0;n_r<samplingy[n_c];n_r++)
1140 /* 'extend' the edges */
1141 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1143 if ( lossless_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1145 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1150 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1152 tot_out += c_columns[n_c];
1154 /* extend the edges */
1155 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1157 /* make the current scanline the previous one */
1160 } /* End of for loop for each component */
1162 n+=samplingy[whose_max_size_rows];
1164 /* Take out the Restart Markers */
1167 /* Look for restart markers only after a restart interval */
1168 if ((MCUs_counted % restart_interval) == 0)
1171 read_n_bytes(in, 2); /* read the RST marker */
1178 } /* End of while loop for each line */
1183 while (n <= c_rows[whose_max_size_rows])
1185 for (n_c=0;n_c<components;n_c++)
1187 for (n_r=0;n_r<samplingy[n_c];n_r++)
1190 /* 'extend' the edges */
1191 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1193 if ( lossy_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1195 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1200 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1202 tot_out += c_columns[n_c];
1204 /* extend the edges */
1205 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1207 /* make the current scanline the previous one */
1210 } /* End of for loop for each component */
1212 n+=samplingy[whose_max_size_rows];
1214 /* Take out the Restart Markers */
1217 /* Look for restart markers only after a restart interval */
1218 if ((MCUs_counted % restart_interval) == 0)
1221 read_n_bytes(in, 2); /* read the RST marker */
1228 } /* End of while loop for each line */
1231 } /* Closes the else, LINE_INT and multi=1 */
1233 } /* End of part for LINE_INT */
1235 else { /* Non LINE_INT mode */
1236 if (color_mode==PIXEL_INT) {
1237 /***********************************************************************/
1238 /* Pixel interleaved mode with single file received */
1239 /***********************************************************************/
1246 /* 'extend' the edges */
1247 for (n_c=0;n_c<components;n_c++)
1248 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1250 if ( lossless_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1252 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1257 write_one_line(cscanline+components, components*columns, out);
1259 tot_out += components*columns;
1261 /* extend the edges */
1262 for (n_c=0;n_c<components;n_c++)
1263 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1265 /* make the current scanline the previous one */
1268 /* Take out the Restart Markers */
1271 /* Look for restart markers only after a restart interval */
1272 if ((MCUs_counted % restart_interval) == 0)
1275 read_n_bytes(in, 2); /* read the RST marker */
1282 } /* End of line loop for PIXEL_INT */
1290 /* 'extend' the edges */
1291 for (n_c=0;n_c<components;n_c++)
1292 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1294 if ( lossy_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1296 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1301 write_one_line(cscanline+components, components*columns, out);
1303 tot_out += components*columns;
1305 /* extend the edges */
1306 for (n_c=0;n_c<components;n_c++)
1307 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1309 /* make the current scanline the previous one */
1312 /* Take out the Restart Markers */
1315 /* Look for restart markers only after a restart interval */
1316 if ((MCUs_counted % restart_interval) == 0)
1319 read_n_bytes(in, 2); /* read the RST marker */
1326 } /* End of line loop for PIXEL_INT */
1330 /***********************************************************************/
1331 /* Plane interleaved mode */
1332 /***********************************************************************/
1337 while (++n <= c_rows[n_s])
1339 /* 'extend' the edges */
1340 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1342 if (lossless_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1344 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1349 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1351 tot_out += c_columns[n_s];
1353 /* extend the edges */
1354 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1356 /* make the current scanline the previous one */
1359 /* Take out the Restart Markers */
1362 /* Look for restart markers only after a restart interval */
1363 if ((MCUs_counted % restart_interval) == 0)
1366 read_n_bytes(in, 2); /* read the RST marker */
1373 } /* End of line loop in PLANE_INT */
1378 while (++n <= c_rows[n_s])
1380 /* 'extend' the edges */
1381 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1383 if (lossy_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1385 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1390 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1392 tot_out += c_columns[n_s];
1394 /* extend the edges */
1395 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1397 /* make the current scanline the previous one */
1400 /* Take out the Restart Markers */
1403 /* Look for restart markers only after a restart interval */
1404 if ((MCUs_counted % restart_interval) == 0)
1407 read_n_bytes(in, 2); /* read the RST marker */
1414 } /* End of line loop in PLANE_INT */
1416 } /* End of each component for PLANE_INT */
1418 } /* End of non LINE_INT */
1422 } /* End of loop for scans */
1428 seek_return=seek_marker(in,&mk);
1429 if (seek_return==EOF)
1431 fprintf(stderr,"Did not get EOI at end of compressed image\n");
1434 if ( seek_return > 2 )
1436 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
1437 fprintf(msgfile,"*** Added to marker segment count.\n");
1440 pos0 += seek_return;
1443 fprintf(stderr,"In this implementation last marker must be EOI\n");
1447 if (head_scan[0]->need_table)
1448 fprintf(msgfile,"A mapping table was used which had %i entries of %i bytes each.\n",head_scan[0]->MAXTAB, head_scan[0]->Wt);
1451 fprintf(msgfile,"Restart markers were found with a restart interval of %i.\n",restart_interval);
1454 fprintf(msgfile,"Marker segment bytes: %ld\n",pos0);
1456 /* position in input file */
1458 /* tot_in = 8*(pos1-pos0); */
1460 /* size of compressed file read (bits), incl. headers. */
1464 close_process_run();
1465 closebuffers(multi);
1469 fprintf(msgfile,"Total bits in: %ld Symbols out: %ld %5.3f bps\n",
1470 tot_in,tot_out,tot_in/(double)tot_out);
1471 fprintf(msgfile,"Time = %1.3f secs : %1.0f KSymbols/sec\n",t1-t0,
1472 (tot_out)/(1024*(t1-t0)));
1485 fprintf(stderr,"Usage: %s [flags] [infile] [outfile1 [outfile2, ...]]\n\
1488 outfile1 = %s for color image in a single (PPM) output file.\n\
1489 outfile1 = %s for monochrome image in a single (PGM) output file.\n\
1490 outfile[1,2,...] = %s for multiple (PGM) output files \n\
1491 in plane or line interleaved modes.\n",
1492 "locod", "specified JLS file", OUTFILE ".out",
1494 OUTFILE "[1,2,...].out");
1495 fprintf(stderr,"FLAGS:\n\
1496 outfile2, ... : Multiple output specification for plane or line int. mode.\n\
1497 -i<infile> : Alternate input specification, use -i- for stdin.\n\
1498 -o<outfile> : Alternate output specification, use -o- for stdout.\n\
1499 -P : Generate single (.ppm) output file for sample/line int. mode.\n\
1502 -h : Print this help.\n\
1503 *** No spaces allowed between a flag and its argument.\n\
1509 void bad_flag(char *s)
1511 fprintf(stderr,"Bad flag %s\n",s);