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 /* define color mode strings */
62 char plane_int_string[] = "plane by plane",
63 line_int_string[] = "line intlv",
64 pixel_int_string[] = "sample intlv";
66 static char banner[]="\n\
67 =============================================\n\
68 SPMG/JPEG-LS DECOMPRESSOR " JPEGLSVERSION "\n\
69 =============================================\n\
70 These programs are Copyright (c) University of British Columbia.\n\
71 All rights reserved. They may be freely redistributed in their\n\
72 entirety provided that this copyright notice is not removed.\n\
73 They may not be sold for profit or incorporated in commercial\n\
74 programs without the written permission of the copyright holder.\n\
75 Each program is provided as is, without any express or implied\n\
76 warranty, without even the warranty of fitness for a particular\n\
79 =========================================================\n\
80 THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:\n\
81 =========================================================\n\
82 (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.\n";
84 pixel *pscanline, *cscanline, *pscanl0, *cscanl0;
85 pixel *c_pscanline[MAX_COMPONENTS], *c_cscanline[MAX_COMPONENTS],
86 *c_pscanl0[MAX_COMPONENTS], *c_cscanl0[MAX_COMPONENTS];
88 jpeg_ls_header *head_frame, *head_scan[MAX_SCANS];
90 int columns, rows, components,
91 samplingx[MAX_COMPONENTS], samplingy[MAX_COMPONENTS];
92 int c_columns[MAX_COMPONENTS], c_rows[MAX_COMPONENTS];
93 int whose_max_size_columns, whose_max_size_rows, number_of_scans;
95 int shift; /* Shift value for sparse images */
96 int got_lse; /* got an LSE marker */
97 int got_table; /* got a mapping table */
98 int got_restart; /* got a restart marker indicatino */
99 int restart_interval; /* the restart interval */
100 int multi; /* if the files are separate */
101 int application_header; /* application bytes in the header */
103 int lossy; /* Indicates if in lossy mode or not */
104 int bpp16; /* Indicates if 16 bits per pixel mode or not */
105 int lutmax; /* lutmax is either 256 or 4501 */
118 int alpha, /* alphabet size */
119 ceil_half_alpha; /* ceil(alpha/2) */
132 /* Write one row of pixel values */
133 inline void write_one_line(pixel* line, int cols, FILE* outfile)
136 unsigned int* maptable;
138 /* No mapping tables used */
139 if(!(head_scan[0]->need_table))
142 unsigned char* line8;
143 line8 = (unsigned char*)safealloc(cols);
145 for (i=0; i< cols; i++)
146 *(line8+i)=(unsigned char)ENDIAN8(*(line+i));
148 fwrite(line8, sizeof(unsigned char), cols, outfile);
152 fwrite(line, sizeof(short), cols, outfile);
155 /* Mapping tables used */
160 /* Write one byte per table entry */
161 if (head_scan[0]->Wt == 1)
163 unsigned char* line8;
164 line8 = (unsigned char*)safealloc(cols); /* If don't have 2, it mallocs over the table? */
166 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
168 for (i=0; i<cols; i++)
171 *(line8+i) = ENDIAN8(maptable[index]);
174 fwrite(line8, sizeof(unsigned char), cols, outfile);
178 /* Write two bytes per table entry */
179 else if (head_scan[0]->Wt == 2)
181 unsigned short* line16;
182 line16 = (unsigned short*)safealloc(cols*2);
184 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
186 for (i=0; i<cols; i++)
189 *(line16+i) = (unsigned short) maptable[index];
192 fwrite(line16, sizeof(short), cols, outfile);
196 /* Write three bytes per table entry */
197 else if (head_scan[0]->Wt == 3)
199 unsigned char* line8_3;
200 line8_3 = (unsigned char*)safealloc(cols*3);
202 maptable = head_scan[0]->TABLE[head_scan[0]->TID];
204 for (i=0; i<cols; i++)
207 *(line8_3 + (i*3)) = (unsigned char) (maptable[index] >> 16);
208 *(line8_3 + (i*3) + 1) = (unsigned char) (maptable[index] >> 8);
209 *(line8_3 + (i*3) + 2) = (unsigned char) (maptable[index]);
212 fwrite(line8_3, sizeof(char), cols*3, outfile);
218 /* Can't do 16 bit index values */
222 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
234 void initbuffers(int multi, int comp)
239 if (multi) /* Output to several files */
241 for (i=0;i<comp;i++) {
243 c_pscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
244 c_cscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
246 /* Adjust scan line pointers taking into account the margins,
247 and also the fact that indexing for scan lines starts from 1
249 c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
250 c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
253 else { /* Output to a single file */
255 pscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
256 cscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
258 /* Adjust scan line pointers taking into account the margins,
259 and also the fact that indexing for scan lines starts from 1
260 (this will probably have to be changed in the future)
262 pscanline = pscanl0 + components*(LEFTMARGIN-1);
263 cscanline = cscanl0 + components*(LEFTMARGIN-1);
276 pscanline = pscanl0 + components*(LEFTMARGIN-1);
277 cscanline = cscanl0 + components*(LEFTMARGIN-1);
280 void c_swaplines(int i)
284 c_pscanl0[i] = c_cscanl0[i];
286 c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
287 c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
290 void closebuffers(int multi)
299 for (i=0;i<components;i++)
307 /* command line argument parsing */
308 int initialize(int argc, char *argv[])
310 char *infilename = NULL;
311 const char *outfilename = OUTFILE ".out";
312 char *c_outfilename[MAX_COMPONENTS],
314 int i, max_samp_columns, max_samp_rows, mk, n_s,
321 int pos; /* position in the file, after the header */
323 for (i=0;i<MAX_COMPONENTS;i++) {
324 c_outfilename[i]=(char*)malloc(strlen(OUTFILE)+20);
325 sprintf(c_outfilename[i],"%s%d.out",OUTFILE,i+1);
329 for ( i=1; i<argc; i++ )
330 if ( argv[i][0] == '-' )
332 switch ( argv[i][1] ) {
335 infilename = argv[i]+2;
340 outfilename = c_outfilename[out_files++] = argv[i]+2;
349 if ( sscanf(argv[i],"-v%d",&verbose) != 1 )
360 infilename = argv[i];
363 else if ( ! gotoutf )
364 outfilename = c_outfilename[out_files++] = argv[i];
368 verbose = 1; /* at least the banner will show */
370 if ((!multi) && (out_files>1)) {
371 fprintf(stderr,"\nERROR: Only 1 output file expected with -P option.\nThis option is valid only for line/pixel interleaved and not subsampled.\n");
376 if ( infilename == NULL ) {
381 if ( strcmp(infilename,"-")==0 )
383 else if ( (in=fopen(infilename,"rb")) == NULL ) {
389 /* Read the compressed image frame header */
392 head_frame = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
394 for (n_s=0;n_s<MAX_SCANS;n_s++) {
395 head_scan[n_s] = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
396 head_scan[n_s]->T1=head_scan[n_s]->T2=head_scan[n_s]->T3=0;
397 head_scan[n_s]->RES = DEFAULT_RESET;
401 seek_return = seek_marker(in,&mk);
402 if (seek_return == EOF) {
403 fprintf(stderr,"*** Premature End of File seeking SOI\n");
409 fprintf(stderr,"Marker %04x found: first marker must be SOI (%04x) in this implementation\n", mk, SOI);
415 seek_return = seek_marker(in,&mk);
416 if (seek_return == EOF) {
417 fprintf(stderr,"*** Premature End of File seeking SOF_LS\n");
421 pos += seek_return; /* Read SOF_LS */
423 fprintf(stderr,"Marker %04x found: second marker must be SOF_LS (%04x) in this implementation\n", mk, SOF_LS);
428 /* Read the frame header (SOF) */
429 seek_return = read_jpegls_frame(in,head_frame);
430 if (seek_return == EOF) {
431 fprintf(stderr,"*** Premature End of File reading frame header\n");
437 head_scan[0]->alp = head_frame->alp; /* default alpha */
440 /* LSE Extension header */
441 /* This version supports only 2 extension headers, and 1 set of
442 parameters for all the scans */
444 head_scan[0]->need_table = 0;
448 seek_return=seek_marker(in, &mk);
449 if (seek_return == EOF) {
450 fprintf(stderr,"*** Premature End of File seeking SOS or LSE marker\n");
459 seek_return = read_jpegls_extmarker(in, head_scan[0]);
460 if (seek_return == EOF) {
461 fprintf(stderr,"*** Premature End of File\n");
469 seek_return = read_jpegls_restartmarker(in, head_scan[0]);
472 restart_interval = head_scan[0]->restart_interval;
480 /* End of extension header */
484 /* Read the scan header*/
485 seek_return = read_jpegls_scan(in,head_scan[0]);
486 if (seek_return == EOF) {
487 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
492 shift=head_scan[0]->shift;
494 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",shift);
498 NEAR=head_scan[0]->NEAR;
499 color_mode=head_scan[0]->color_mode;
500 columns=head_frame->columns;
501 rows=head_frame->rows;
502 alpha0=head_scan[0]->alp;
503 head_frame->alp = alpha0;
504 components=head_frame->comp;
506 if (color_mode==PLANE_INT)
507 number_of_scans=components;
511 set_thresholds(head_scan[0]->alp, head_scan[0]->NEAR, &(head_scan[0]->T1), &(head_scan[0]->T2), &(head_scan[0]->T3));
517 RESET=head_scan[0]->RES;
519 if (head_scan[0]->RES != DEFAULT_RESET) {
520 fprintf(stderr,"ERROR: Version compiled for fixed RESET=%d parameter: got %d\n",DEFAULT_RESET,head_scan[0]->RES);
525 /* Check to see if lossless or lossy */
531 /* Check for 16 or 8 bit mode */
532 if (alpha0 <= MAXA16 && alpha0 > MAXA8)
538 else if (alpha0 <= MAXA8 && alpha0 >= 1)
545 fprintf(stderr,"Got alpha = %d\n",alpha0+1);
546 error("Bad value for alpha. Sorry...\n");
550 check_compatibility(head_frame,head_scan[0],0);
552 for (i=0;i<components;i++) {
553 samplingx[i]=head_frame->samplingx[i];
554 samplingy[i]=head_frame->samplingy[i];
555 if ((!multi) && ((samplingx[i]!=1) || (samplingy[i]!=1)) && (components>1))
557 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with subsampled compressed components\n");
562 if ((!multi) && (color_mode==PLANE_INT))
565 fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with plane intereleaved mode\n");
571 if ((multi) && (color_mode==PIXEL_INT)) {
572 multi = 0; /* equivalent to specifying -P flag */
575 if ((out_files>1) && (color_mode==PIXEL_INT)) {
576 fprintf(stderr,"ERROR: Pixel interleaved mode uses only 1 output file\n");
580 if ((multi) && (out_files) && (out_files!=components)) {
581 fprintf(stderr,"ERROR: Number of files, %d, for output must be equal to number of image components, %d\n",out_files,components);
585 /* Compute the image size for the different components */
587 c_columns[0]=columns;
589 whose_max_size_rows=0;
596 for(i=0;i<components;i++) {
597 if (samplingx[i]>max_samp_columns) {
598 max_samp_columns=samplingx[i];
599 whose_max_size_columns=i;
601 if (samplingy[i]>max_samp_rows) {
602 max_samp_rows=samplingy[i];
603 whose_max_size_rows=i;
607 c_columns[whose_max_size_columns]=columns;
608 c_rows[whose_max_size_rows]=rows;
610 for(i=0;i<components;i++) {
611 if (i!=whose_max_size_columns)
613 c_columns[i]=c_columns[whose_max_size_columns]*samplingx[i];
614 c_columns[i]/=samplingx[whose_max_size_columns];
616 if (i!=whose_max_size_rows) {
617 c_rows[i]=c_rows[whose_max_size_rows]*samplingy[i];
618 c_rows[i]/=samplingy[whose_max_size_rows];
624 /* msgfile seems to start being used here, let's initialize it here */
625 if ( !msgfile ) msgfile = stdout;
627 if ( outfilename == NULL ) {
632 if ( strcmp(outfilename,"-")==0 ) {
638 if ( (out=fopen(outfilename,"wb")) == NULL ) {
644 for (i=0;i<components;i++)
645 if ( (c_out[i]=fopen(c_outfilename[i],"wb")) == NULL )
647 perror(c_outfilename[i]);
655 /* check that color mode is valid and pick color mode string */
656 switch ( color_mode ) {
659 color_mode_string = plane_int_string;
663 color_mode_string = line_int_string;
667 color_mode_string = pixel_int_string;
671 fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
677 fprintf(msgfile,"%s\n",banner);
682 fprintf(msgfile,"Input file: %s\nOutput file: %s\n",infilename,outfilename);
685 fprintf(msgfile,"Input file: %s\nOutput files: ",infilename);
686 for (i=0;i<components;i++)
687 fprintf(msgfile," %s ",c_outfilename[i]);
688 fprintf(msgfile,"\n");
693 if ( alpha0 != alpha ) {
694 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);
699 ceil_half_alpha = (alpha+1)/2;
704 /* check that alpha is a power of 2 */
705 for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);
706 if ( alpha != (1<<i) ) {
707 fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);
714 /* compute auxiliary parameters for near-lossless (globals) */
716 qbeta = (alpha + 2*NEAR + quant-1 )/quant;
718 ceil_half_qbeta = (qbeta+1)/2;
720 alpha1eps = alpha-1+NEAR;
721 fprintf(msgfile,"Near-lossless mode: NEAR = %d beta = %d qbeta = %d\n",NEAR,beta,qbeta);
724 /* compute bits per sample for input symbols */
725 for ( bpp=1; (1L<<bpp)<alpha; bpp++ );
727 /* compute bits per sample for unencoded prediction errors */
729 for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );
733 if ( bpp < 2 ) bpp = 2;
735 /* limit for unary part of Golomb code */
737 limit = 2*(bpp + 8) - qbpp -1;
739 limit = 4*bpp - qbpp - 1;
741 /* print out parameters */
744 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",
745 columns, rows, alpha0, components,
746 color_mode, color_mode_string,
747 T1, T2, T3, RESET,limit);
749 fprintf(msgfile,"Image: cols=");
750 for (i=0;i<components;i++)
751 fprintf(msgfile," %d",c_columns[i]);
752 fprintf(msgfile," rows=");
753 for (i=0;i<components;i++)
754 fprintf(msgfile," %d",c_rows[i]);
755 fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
757 color_mode, color_mode_string,
758 T1, T2, T3,RESET,limit);
763 fprintf(msgfile,"\n");
766 /* Write out the image header for PGM or PPM files */
767 /* Must look at if there are Mapping Tables used */
769 /* No Mapping Tables used */
770 if (!head_scan[0]->need_table)
773 if (components==1) fputs("P5\n", out);
774 else if (components==3) fputs("P6\n", out);
775 else if (components==4) fputs("P7\n", out);
776 else fprintf(out,"P%d\n",10+components);
778 fprintf(out,"%d %d\n", columns, rows);
779 fprintf(out,"%d\n", alpha - 1);
782 for (i=0;i<components;i++) {
783 fputs("P5\n", c_out[i]);
784 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
785 fprintf(c_out[i],"%d\n", alpha - 1);
789 /* Mapping Tables used */
792 /* only 8 bit indexes supported for mapping tables */
795 fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
799 /* Mapping Table elements are 1 or 2 bytes */
800 if (head_scan[0]->Wt==1 || head_scan[0]->Wt==2)
803 if (head_scan[0]->Wt==1)
806 alpha_temp = alpha*alpha;
810 if (components==1) fputs("P5\n", out);
811 else if (components==3) fputs("P6\n", out);
812 else if (components==4) fputs("P7\n", out);
813 else fprintf(out,"P%d\n",10+components);
815 fprintf(out,"%d %d\n", columns, rows);
816 fprintf(out,"%d\n", alpha_temp - 1);
819 for (i=0;i<components;i++)
821 fputs("P5\n", c_out[i]);
822 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
823 fprintf(c_out[i],"%d\n", alpha_temp - 1);
827 /* Mapping Table elements are 3 bytes */
828 else if (head_scan[0]->Wt==3)
832 if (components==1) fputs("P6\n", out);
835 fprintf(stderr,"Error : Cannot have a multi-component image and a mapping table with 3 bytes per element.\n");
839 fprintf(out,"%d %d\n", columns, rows);
840 fprintf(out,"%d\n", alpha - 1);
843 for (i=0;i<components;i++)
845 fputs("P6\n", c_out[i]);
846 fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
847 fprintf(c_out[i],"%d\n", alpha - 1);
851 /* Mapping Table elements aren't 1 to 3 bytes */
854 fprintf(stderr, "Sorry, mapping tables elements can only be 1 to 3 bytes in this implementation.\n");
860 /* Allocate memory pools. */
861 initbuffers(multi, components);
864 /* return size of the header, in bytes */
873 /* Main loop for decoding files */
875 int main (int argc, char *argv[]) {
876 int n,n_c,n_r,my_i,n_s,mk,seek_return;
878 double t0, t1; /*, get_utime();*/
882 pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
884 local_cscanline = local_pscanline = NULL;
887 /* Parse the parameters, initialize */
888 /* Not yet fully implemented */
890 pos0 = initialize(argc, argv);
893 /* start timer (must be AFTER initialize()) */
897 /* Initialize the scanline buffers */
899 for (n = 0; n <= (columns + 1); ++n)
902 for (n_c=0;n_c<components;n_c++)
903 for (n = 0; n <= (c_columns[n_c] + 1); ++n)
904 c_pscanline[n_c][n] = 0;
906 if ((components>1) && (multi==0))
908 /* OUTPUT PPM file, allocate auxiliary buffers */
909 local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
910 local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
912 local_pscanline = local_scanl0 + LEFTMARGIN-1;
913 local_cscanline = local_scanl1 + LEFTMARGIN-1;
917 for (n_s=0;n_s<number_of_scans;n_s++)
919 /* Repeat prediction/quantization/statistics scanline by scanline,
922 /* Reset Restart Markers for every scan */
925 /* This implementation supports parameters in 1st scan */
928 /* Prepare the quantization LUTs */
932 /* prepare div/mul tables for near-lossless quantization */
933 prepare_qtables(alpha,NEAR);
937 { /* Read further scan headers */
938 seek_return=seek_marker(in,&mk);
939 if (seek_return == EOF)
941 fprintf(stderr,"*** Premature End of File seeking SOS marker\n");
944 if ( seek_return > 2 )
946 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
947 fprintf(msgfile,"*** Added to marker segment count.\n");
952 fprintf(stderr,"Expecting SOS (%04x), got %04x\n",SOS,mk);
955 seek_return = read_jpegls_scan(in,head_scan[n_s]); /* Read the scan header*/
956 if (seek_return == EOF)
958 fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
962 if (head_scan[n_s]->shift!=0)
964 fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",head_scan[n_s]->shift);
967 if (head_scan[n_s]->NEAR != NEAR)
969 fprintf(stderr,"Got NEAR=%d after NEAR=%d: cannot change parameters between scans in this implementation\n",head_scan[n_s]->NEAR,NEAR);
972 if ((head_scan[n_s]->color_mode != PLANE_INT) || (head_scan[n_s]->comp != 1) ||
973 (head_scan[n_s]->comp_ids[0] != n_s+1))
975 fprintf(stderr,"This implementation supports multiple scans only in PLANE INTERLEAVED mode.\n");
980 /* Initializations for each scan */
983 /* Start from 1st image row */
986 /* Initialize stats arrays */
992 /* Initialize run processing */
993 init_process_run(MAXRUN);
995 if (color_mode==LINE_INT) { /* line int. */
997 /***********************************************************************/
998 /* Line interleaved mode with single file received */
999 /***********************************************************************/
1006 /* 'extend' the edges */
1007 for (n_c=0;n_c<components;n_c++)
1008 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1010 for (n_c=0;n_c<components;n_c++)
1013 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1015 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1016 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1020 local_cscanline=cscanline;
1021 local_pscanline=pscanline;
1024 if ( lossless_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1026 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1032 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1033 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1036 write_one_line(cscanline + components, components*columns, out);
1038 tot_out += components*columns;
1040 /* extend the edges */
1041 for (n_c=0;n_c<components;n_c++)
1042 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1044 /* make the current scanline the previous one */
1047 /* Take out the Restart Markers */
1050 /* Look for restart markers only after a restart interval */
1051 if ((MCUs_counted % restart_interval) == 0)
1054 read_n_bytes(in, 2); /* read the RST marker */
1061 } /* End of while loop for each file line */
1068 /* 'extend' the edges */
1069 for (n_c=0;n_c<components;n_c++)
1070 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1072 for (n_c=0;n_c<components;n_c++)
1075 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1077 local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
1078 local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
1082 local_cscanline=cscanline;
1083 local_pscanline=pscanline;
1086 if ( lossy_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
1088 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1094 for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
1095 cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
1098 write_one_line(cscanline + components, components*columns, out);
1100 tot_out += components*columns;
1102 /* extend the edges */
1103 for (n_c=0;n_c<components;n_c++)
1104 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1106 /* make the current scanline the previous one */
1109 /* Take out the Restart Markers */
1112 /* Look for restart markers only after a restart interval */
1113 if ((MCUs_counted % restart_interval) == 0)
1116 read_n_bytes(in, 2); /* read the RST marker */
1123 } /* End of while loop for each file line */
1127 { /* Multiple files */
1128 /* color_mode==LINE_INT and multi==1 */
1129 /***********************************************************************/
1130 /* Line interleaved mode with multiple files received */
1131 /***********************************************************************/
1138 while (n <= c_rows[whose_max_size_rows])
1140 for (n_c=0;n_c<components;n_c++)
1142 for (n_r=0;n_r<samplingy[n_c];n_r++)
1145 /* 'extend' the edges */
1146 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1148 if ( lossless_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1150 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1155 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1157 tot_out += c_columns[n_c];
1159 /* extend the edges */
1160 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1162 /* make the current scanline the previous one */
1165 } /* End of for loop for each component */
1167 n+=samplingy[whose_max_size_rows];
1169 /* Take out the Restart Markers */
1172 /* Look for restart markers only after a restart interval */
1173 if ((MCUs_counted % restart_interval) == 0)
1176 read_n_bytes(in, 2); /* read the RST marker */
1183 } /* End of while loop for each line */
1188 while (n <= c_rows[whose_max_size_rows])
1190 for (n_c=0;n_c<components;n_c++)
1192 for (n_r=0;n_r<samplingy[n_c];n_r++)
1195 /* 'extend' the edges */
1196 c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
1198 if ( lossy_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
1200 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1205 write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
1207 tot_out += c_columns[n_c];
1209 /* extend the edges */
1210 c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
1212 /* make the current scanline the previous one */
1215 } /* End of for loop for each component */
1217 n+=samplingy[whose_max_size_rows];
1219 /* Take out the Restart Markers */
1222 /* Look for restart markers only after a restart interval */
1223 if ((MCUs_counted % restart_interval) == 0)
1226 read_n_bytes(in, 2); /* read the RST marker */
1233 } /* End of while loop for each line */
1236 } /* Closes the else, LINE_INT and multi=1 */
1238 } /* End of part for LINE_INT */
1240 else { /* Non LINE_INT mode */
1241 if (color_mode==PIXEL_INT) {
1242 /***********************************************************************/
1243 /* Pixel interleaved mode with single file received */
1244 /***********************************************************************/
1251 /* 'extend' the edges */
1252 for (n_c=0;n_c<components;n_c++)
1253 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1255 if ( lossless_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1257 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1262 write_one_line(cscanline+components, components*columns, out);
1264 tot_out += components*columns;
1266 /* extend the edges */
1267 for (n_c=0;n_c<components;n_c++)
1268 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1270 /* make the current scanline the previous one */
1273 /* Take out the Restart Markers */
1276 /* Look for restart markers only after a restart interval */
1277 if ((MCUs_counted % restart_interval) == 0)
1280 read_n_bytes(in, 2); /* read the RST marker */
1287 } /* End of line loop for PIXEL_INT */
1295 /* 'extend' the edges */
1296 for (n_c=0;n_c<components;n_c++)
1297 cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
1299 if ( lossy_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
1301 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
1306 write_one_line(cscanline+components, components*columns, out);
1308 tot_out += components*columns;
1310 /* extend the edges */
1311 for (n_c=0;n_c<components;n_c++)
1312 cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
1314 /* make the current scanline the previous one */
1317 /* Take out the Restart Markers */
1320 /* Look for restart markers only after a restart interval */
1321 if ((MCUs_counted % restart_interval) == 0)
1324 read_n_bytes(in, 2); /* read the RST marker */
1331 } /* End of line loop for PIXEL_INT */
1335 /***********************************************************************/
1336 /* Plane interleaved mode */
1337 /***********************************************************************/
1342 while (++n <= c_rows[n_s])
1344 /* 'extend' the edges */
1345 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1347 if (lossless_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1349 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1354 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1356 tot_out += c_columns[n_s];
1358 /* extend the edges */
1359 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1361 /* make the current scanline the previous one */
1364 /* Take out the Restart Markers */
1367 /* Look for restart markers only after a restart interval */
1368 if ((MCUs_counted % restart_interval) == 0)
1371 read_n_bytes(in, 2); /* read the RST marker */
1378 } /* End of line loop in PLANE_INT */
1383 while (++n <= c_rows[n_s])
1385 /* 'extend' the edges */
1386 c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
1388 if (lossy_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
1390 fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
1395 write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
1397 tot_out += c_columns[n_s];
1399 /* extend the edges */
1400 c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
1402 /* make the current scanline the previous one */
1405 /* Take out the Restart Markers */
1408 /* Look for restart markers only after a restart interval */
1409 if ((MCUs_counted % restart_interval) == 0)
1412 read_n_bytes(in, 2); /* read the RST marker */
1419 } /* End of line loop in PLANE_INT */
1421 } /* End of each component for PLANE_INT */
1423 } /* End of non LINE_INT */
1427 } /* End of loop for scans */
1433 seek_return=seek_marker(in,&mk);
1434 if (seek_return==EOF)
1436 fprintf(stderr,"Did not get EOI at end of compressed image\n");
1439 if ( seek_return > 2 )
1441 fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
1442 fprintf(msgfile,"*** Added to marker segment count.\n");
1445 pos0 += seek_return;
1448 fprintf(stderr,"In this implementation last marker must be EOI\n");
1452 if (head_scan[0]->need_table)
1453 fprintf(msgfile,"A mapping table was used which had %i entries of %i bytes each.\n",head_scan[0]->MAXTAB, head_scan[0]->Wt);
1456 fprintf(msgfile,"Restart markers were found with a restart interval of %i.\n",restart_interval);
1459 fprintf(msgfile,"Marker segment bytes: %ld\n",pos0);
1461 /* position in input file */
1463 /* tot_in = 8*(pos1-pos0); */
1465 /* size of compressed file read (bits), incl. headers. */
1469 close_process_run();
1470 closebuffers(multi);
1474 fprintf(msgfile,"Total bits in: %ld Symbols out: %ld %5.3f bps\n",
1475 tot_in,tot_out,tot_in/(double)tot_out);
1476 fprintf(msgfile,"Time = %1.3f secs : %1.0f KSymbols/sec\n",t1-t0,
1477 (tot_out)/(1024*(t1-t0)));
1490 fprintf(stderr,"Usage: %s [flags] [infile] [outfile1 [outfile2, ...]]\n\
1493 outfile1 = %s for color image in a single (PPM) output file.\n\
1494 outfile1 = %s for monochrome image in a single (PGM) output file.\n\
1495 outfile[1,2,...] = %s for multiple (PGM) output files \n\
1496 in plane or line interleaved modes.\n",
1497 "locod", "specified JLS file", OUTFILE ".out",
1499 OUTFILE "[1,2,...].out");
1500 fprintf(stderr,"FLAGS:\n\
1501 outfile2, ... : Multiple output specification for plane or line int. mode.\n\
1502 -i<infile> : Alternate input specification, use -i- for stdin.\n\
1503 -o<outfile> : Alternate output specification, use -o- for stdout.\n\
1504 -P : Generate single (.ppm) output file for sample/line int. mode.\n\
1507 -h : Print this help.\n\
1508 *** No spaces allowed between a flag and its argument.\n\
1514 void bad_flag(char *s)
1516 fprintf(stderr,"Bad flag %s\n",s);