--- /dev/null
+PROJECT(GDCMJPEGLS)
+
+SUBDIRS(Decoder
+ # Encoder
+ )
--- /dev/null
+#CC=cc
+#PKGNAME=loco
+#OPTFLAGS= -Aa $(CFL) -DBIG_ENDIAN
+
+#CFLAGS = $(OPTFLAGS) $(VFL) $(DFL) -DPGMPREFIX=\"$(PREFIX)\" -DMELCODE -DEXTERNDISTRIB -Dinline="" -DNDEBUG
+
+#LNKFLAGS = -lm
+
+SET(GDCMJPEGLS_SRCS
+ global.c
+ jpegmark.c
+ initialize.c
+ decoder.c
+ lossless_d.c
+ lossy_d.c
+ bitio.c
+ melcode.c)
+
+ADD_LIBRARY(gdcmjpegls ${GDCMJPEGLS_SRCS})
+
+#INCL = global.h jpegmark.h bitio.h
+
+#EOBJS = global.o jpegmark.o initialize.o decoder.o lossless_d.o lossy_d.o bitio.o melcode.o
+
+#loco:
+# $(MAKE) -$(MAKEFLAGS) VFL="" PREFIX="loco" codec
+#
+#DECODER = $(PREFIX)d
+#
+#codec: $(DECODER)
+#
+#jpegmark.o: jpegmark.c jpegmark.h bitio.h global.h
+#
+#global.o: global.h global.c
+#
+#initialize.o: initialize.c bitio.h global.h
+#
+#lossless_d.o: global.h lossless_d.c bitio.h
+#
+#lossy_d.o: global.h lossy_d.c bitio.h
+#
+#decoder.o: decoder.c jpegmark.c global.h
+#
+#bitio.o: bitio.c bitio.h global.h
+#
+#melcode.o: melcode.c bitio.h global.h
+#
+#
+#$(DECODER): $(EOBJS)
+# $(CC) $(CFLAGS) -o $@ $(EOBJS) $(LNKFLAGS)
+#
+#lint:
+# lint $(SRCS)
+#clean:
+# -rm -f *.o core loco* *.out
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/*
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include "global.h"
+#include "bitio.h"
+
+
+extern int zeroLUT[]; /* lookup table to find number of leading zeroes */
+
+extern FILE *in, *out;
+
+byte negbuff[BUFSIZE+4]; /* byte I/O buffer, allowing for 4 "negative"
+ locations */
+
+/*
+ 'buff' is defined as 'rawbuff+4' in bitio.h, so that buff[-4]..buff[-1]
+ are well defined. Those locations are used to "return" data to
+ the byte buffer when flushing the input bit buffer .
+ */
+
+
+int fp; /* index into byte buffer */
+int truebufsize; /* true size of byte buffer ( <= BUFSIZE) */
+int foundeof;
+
+int zeroLUT[256]; /* table to find out number of leading zeros */
+
+
+/* BIT I/O variables */
+dword reg; /* BIT buffer for input/output */
+int bits; /* number of bits free in bit buffer (on output) */
+ /* (number of bits free)-8 in bit buffer (on input)*/
+
+
+/****************************************************************************
+ * INPUT ROUTINES
+ * note: some routines are implemented as preprocessor macros. See bitio.h.
+ ****************************************************************************/
+
+
+void bufiinit(FILE *fil) {
+ /* argument is ignored */
+ fp = BUFSIZE;
+ truebufsize = 0;
+ foundeof = 0;
+}
+
+
+byte fillinbuff(FILE *fil)
+{
+ int i;
+
+ /* remember 4 last bytes of current buffer (for "undo") */
+ for ( i=-4; i<0; i++ )
+ buff[i] = buff[fp+i];
+ truebufsize = fread(buff, 1, BUFSIZE, fil);
+ if ( truebufsize < BUFSIZE )
+ {
+ if ( truebufsize <= 0 )
+ {
+ if ( foundeof )
+ { /* second attempt to read past EOF */
+ fprintf(stderr,"*** Premature EOF in compressed file\n");
+ exit(10);
+ }
+ else
+ {
+ /* One attempt to read past EOF is OK */
+ foundeof = 1;
+ }
+ }
+ /* fill buffer with zeros */
+ memset(buff+truebufsize, 0, (BUFSIZE-truebufsize)*sizeof(*buff));
+ }
+
+ fp = 1;
+ return buff[0];
+}
+
+
+/* Initializes the bit input routines */
+void bitiinit() {
+ bits = reg = 0;
+ fillbuffer(24);
+}
+
+
+/*
+ Flush the input bit buffer TO A BYTE BOUNDARY. Return unused whole
+ bytes to the byte buffer
+ */
+void bitiflush() {
+ int filled,
+ discard,
+ dbytes,
+ i, k, treg;
+ byte *bp;
+
+ filled = 24 - bits; /* how many bits at the MS part of reg
+ have unused data. These correspond to
+ at most filled+2 bits from the input
+ stream, as at most 2 '0' bits might have
+ been dropped by marker processing */
+
+ dbytes = (filled+2)/8; /* the coorrect number of bytes we need to
+ "unget" is either dbytes or dbytes-1 */
+ /* this solution is more general than what is required here: it
+ will work correctly even if the end of a scan is not followed
+ by a marker, as will necessarily be the case with the standard JPEG
+ format */
+ for ( ; ; dbytes-- )
+ {
+ bp = buff + fp - dbytes; /* back-in the buffer */
+ treg = k = 0;
+ for ( i=0; i<dbytes; i++ )
+ {
+ if ( bp[i-1]==0xff && (bp[i]&0x80)==0 )
+ {
+ treg |= bp[i] << (BITBUFSIZE-7-k);
+ k += 7;
+ }
+ else
+ {
+ treg |= bp[i] << (BITBUFSIZE-8-k);
+ k += 8;
+ }
+ }
+
+ if ( k <= filled )
+ break;
+ }
+ /* check consistency */
+ if ( filled-k > 7 ) {
+ fprintf(stderr,"bitiflush: inconsistent bits=%d filled=%d k=%d\n",bits,filled,k);
+ exit(10);
+ }
+ discard = filled-k;
+ if ( treg != (reg<<discard) ) {
+ fprintf(stderr,"bitiflush: inconsistent bits=%d discard=%d reg=%08x treg=%08x\n",bits, discard, reg, treg);
+ exit(10);
+ }
+ if ( reg & (((1<<discard)-1)<<(BITBUFSIZE-discard)) )
+ fprintf(stderr,"bitiflush: Warning: discarding nonzero bits; reg=%08x bits=%d discard=%d\n",reg,bits,discard);
+
+ fp -= dbytes; /* do the unget */
+ if ( buff[fp-1]==0xff && buff[fp]==0 ) fp++;
+
+ bits = 0;
+ reg = 0;
+}
+
+
+
+
+/* Unpad zeros from byte length */
+void unpadzeros()
+{
+ int z;
+
+ z = bits % 8;
+
+ if (bits!=24)
+ {
+ reg = (reg << z);
+ bits = bits + z;
+ }
+
+
+}
+
+
+
+
+/* creates the bit counting look-up table. */
+void createzeroLUT()
+{
+ int i, j, k, l;
+
+ j = k = 1; l = 8;
+ for (i = 0; i < 256; ++i) {
+ zeroLUT[i] = l;
+ --k;
+ if (k == 0) {
+ k = j;
+ --l;
+ j *= 2;
+ }
+ }
+}
+
+
+
+#ifdef IOFXNS
+/* if using functions instead of macros */
+dword
+getbits(int no)
+{
+ register dword temp;
+
+ assert(no > 0 && no <= 18);
+ temp = reg >> (32 - no);
+ fillbuffer(no);
+ return temp;
+}
+# define GETBITS(n) getbits(n)
+#else
+/* see GETBITS(x,n) in bitio.h */
+#endif
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* bitio.h --- for I/O routines
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#ifndef BITIO_H
+#define BITIO_H
+
+#include "global.h"
+
+/* BYTE I/O variables */
+#define BUFSIZE ((16*1024)-4) /* Size of input BYTE buffer */
+extern int fp; /* index into byte buffer */
+extern int truebufsize; /* true size of byte buffer ( <= BUFSIZE) */
+extern byte negbuff[]; /* the buffer */
+#define buff (negbuff+4)
+
+
+/* BIT I/O variables */
+extern dword reg; /* BIT buffer for input/output */
+extern int bits; /* number of bits free in bit buffer (on output) */
+ /* (number of bits free)-8 in bit buffer (on input)*/
+#define BITBUFSIZE (8*sizeof(reg))
+
+extern int zeroLUT[]; /* lookup table to find number of leading zeroes */
+
+extern FILE *in, *out;
+
+
+#define mygetc(fil) ((fp >= BUFSIZE) ? (fillinbuff(fil)) : (buff[fp++]))
+#define myungetc(x,fil) (buff[--fp]=x)
+#define myfeof(fil) ((fp >= truebufsize) && feof(fil))
+
+
+extern void bufiinit(FILE *fil);
+
+extern byte fillinbuff(FILE *fil);
+
+
+
+/* loads more data in the input buffer (inline code )*/
+#define fillbuffer(no) { \
+ byte x; \
+ \
+ assert(no+bits <= 24); \
+ reg <<= no; \
+ bits += no; \
+ while (bits >= 0) { \
+ x = mygetc(in); \
+ if ( x == 0xff ) { \
+ if ( bits < 8 ) { \
+ myungetc(0xff, in); \
+ break; \
+ } \
+ else { \
+ x = mygetc(in); \
+ if ( !(x & 0x80) ) { /* non-marker: drop 0 */ \
+ reg |= (0xff << bits) | ((x & 0x7f)<<(bits-7));\
+ bits -= 15; \
+ } \
+ else { \
+ /* marker: hope we know what we're doing */\
+ /* the "1" bit following ff is NOT dropped */\
+ reg |= (0xff << bits) | (x <<(bits-8));\
+ bits -= 16; \
+ } \
+ continue; \
+ } \
+ } \
+ reg |= x << bits; \
+ bits -= 8; \
+ } \
+}
+
+#define FILLBUFFER(n) fillbuffer(n)
+
+
+/* Initializes the bit input routines */
+extern void bitiinit();
+
+
+/* creates the bit counting look-up table. */
+extern void createzeroLUT();
+
+
+#ifdef IOFXNS
+extern dword getbits(int no);
+# define GETBITS(n) getbits(n)
+#else
+# define GETBITS(x, n)\
+ { x = reg >> (32 - (n));\
+ FILLBUFFER(n);\
+ }
+#endif
+
+
+
+#endif /* BITIO_H */
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All right reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* decoder.c --- the main module, argument parsing, file I/O
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include "global.h"
+#include <string.h>
+#include "jpegmark.h"
+
+#define PGMNAME PGMPREFIX "d"
+#define EPGMNAME PGMPREFIX "e"
+
+static char *banner="\n\
+=============================================\n\
+SPMG/JPEG-LS DECOMPRESSOR " JPEGLSVERSION "\n\
+=============================================\n\
+These programs are Copyright (c) University of British Columbia.\n\
+All rights reserved. They may be freely redistributed in their\n\
+entirety provided that this copyright notice is not removed.\n\
+They may not be sold for profit or incorporated in commercial\n\
+programs without the written permission of the copyright holder.\n\
+Each program is provided as is, without any express or implied\n\
+warranty, without even the warranty of fitness for a particular\n\
+purpose.\n\
+\n\
+=========================================================\n\
+THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:\n\
+=========================================================\n\
+(c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.\n";
+
+pixel *pscanline, *cscanline, *pscanl0, *cscanl0;
+pixel *c_pscanline[MAX_COMPONENTS], *c_cscanline[MAX_COMPONENTS],
+ *c_pscanl0[MAX_COMPONENTS], *c_cscanl0[MAX_COMPONENTS];
+
+jpeg_ls_header *head_frame, *head_scan[MAX_SCANS];
+
+int columns, rows, components,
+ samplingx[MAX_COMPONENTS], samplingy[MAX_COMPONENTS];
+int c_columns[MAX_COMPONENTS], c_rows[MAX_COMPONENTS];
+int whose_max_size_columns, whose_max_size_rows, number_of_scans;
+int color_mode;
+int shift; /* Shift value for sparse images */
+int got_lse; /* got an LSE marker */
+int got_table; /* got a mapping table */
+int got_restart; /* got a restart marker indicatino */
+int restart_interval; /* the restart interval */
+int multi; /* if the files are separate */
+int application_header; /* application bytes in the header */
+
+int lossy; /* Indicates if in lossy mode or not */
+int bpp16; /* Indicates if 16 bits per pixel mode or not */
+int lutmax; /* lutmax is either 256 or 4501 */
+
+
+
+
+/* reset */
+#ifndef FIXRESET
+int RESET;
+#endif
+
+
+/* alphabet size */
+#ifndef FIXALPHA
+int alpha, /* alphabet size */
+ ceil_half_alpha; /* ceil(alpha/2) */
+#endif
+
+#ifdef POW2
+int highmask;
+#endif
+
+
+
+
+
+
+/* Write one row of pixel values */
+inline void write_one_line(pixel* line, int cols, FILE* outfile)
+{
+
+ int i, index;
+ unsigned int* maptable;
+
+ /* No mapping tables used */
+ if(!(head_scan[0]->need_table))
+ if (bpp16==FALSE)
+ {
+ unsigned char* line8;
+ line8 = (unsigned char*)safealloc(cols);
+
+ for (i=0; i< cols; i++)
+ *(line8+i)=ENDIAN8(*(line+i));
+
+ fwrite(line8, sizeof(unsigned char), cols, outfile);
+
+ free(line8);
+ } else {
+ fwrite(line, sizeof(short), cols, outfile);
+ }
+
+ /* Mapping tables used */
+ else
+ {
+ if (bpp16==FALSE)
+ {
+ /* Write one byte per table entry */
+ if (head_scan[0]->Wt == 1)
+ {
+ unsigned char* line8;
+ line8 = (unsigned char*)safealloc(cols); /* If don't have 2, it mallocs over the table? */
+
+ maptable = head_scan[0]->TABLE[head_scan[0]->TID];
+
+ for (i=0; i<cols; i++)
+ {
+ index = *(line+i);
+ *(line8+i) = ENDIAN8(maptable[index]);
+ }
+
+ fwrite(line8, sizeof(unsigned char), cols, outfile);
+
+ free(line8);
+ }
+ /* Write two bytes per table entry */
+ else if (head_scan[0]->Wt == 2)
+ {
+ unsigned short* line16;
+ line16 = (unsigned short*)safealloc(cols*2);
+
+ maptable = head_scan[0]->TABLE[head_scan[0]->TID];
+
+ for (i=0; i<cols; i++)
+ {
+ index = *(line+i);
+ *(line16+i) = (unsigned short) maptable[index];
+ }
+
+ fwrite(line16, sizeof(short), cols, outfile);
+
+ free(line16);
+ }
+ /* Write three bytes per table entry */
+ else if (head_scan[0]->Wt == 3)
+ {
+ unsigned char* line8_3;
+ line8_3 = (unsigned char*)safealloc(cols*3);
+
+ maptable = head_scan[0]->TABLE[head_scan[0]->TID];
+
+ for (i=0; i<cols; i++)
+ {
+ index = *(line+i);
+ *(line8_3 + (i*3)) = (unsigned char) (maptable[index] >> 16);
+ *(line8_3 + (i*3) + 1) = (unsigned char) (maptable[index] >> 8);
+ *(line8_3 + (i*3) + 2) = (unsigned char) (maptable[index]);
+ }
+
+ fwrite(line8_3, sizeof(char), cols*3, outfile);
+
+ free(line8_3);
+ }
+
+
+ /* Can't do 16 bit index values */
+ }
+ else
+ {
+ fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
+ exit(0);
+ }
+ }
+
+
+}
+
+
+
+
+
+void initbuffers(int multi, int comp) {
+
+ int i;
+
+ if (multi) /* Output to several files */
+
+ for (i=0;i<comp;i++) {
+
+ c_pscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
+ c_cscanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
+
+ /* Adjust scan line pointers taking into account the margins,
+ and also the fact that indexing for scan lines starts from 1
+ */
+ c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
+ c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
+ }
+
+ else { /* Output to a single file */
+
+ pscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
+ cscanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
+
+ /* Adjust scan line pointers taking into account the margins,
+ and also the fact that indexing for scan lines starts from 1
+ (this will probably have to be changed in the future)
+ */
+ pscanline = pscanl0 + components*(LEFTMARGIN-1);
+ cscanline = cscanl0 + components*(LEFTMARGIN-1);
+ }
+
+ createzeroLUT();
+
+}
+
+swaplines()
+{
+ pixel *temp;
+ temp = pscanl0;
+ pscanl0 = cscanl0;
+ cscanl0 = temp;
+ pscanline = pscanl0 + components*(LEFTMARGIN-1);
+ cscanline = cscanl0 + components*(LEFTMARGIN-1);
+}
+
+c_swaplines(int i)
+{
+ pixel *temp;
+ temp = c_pscanl0[i];
+ c_pscanl0[i] = c_cscanl0[i];
+ c_cscanl0[i] = temp;
+ c_pscanline[i] = c_pscanl0[i] + (LEFTMARGIN-1);
+ c_cscanline[i] = c_cscanl0[i] + (LEFTMARGIN-1);
+}
+
+void closebuffers(int multi) {
+
+ int i;
+
+ fclose(in);
+ if (multi==0)
+ fclose(out);
+ else
+ for (i=0;i<components;i++)
+ fclose(c_out[i]);
+
+ free(pscanl0);
+ free(cscanl0);
+}
+
+
+
+
+int initialize(int argc, char *argv[]) {
+ char line[256],tmp_char[1],
+ *infilename = NULL,
+ *outfilename = OUTFILE ".out",
+ *c_outfilename[MAX_COMPONENTS],
+ *color_mode_string;
+ int i, max_samp_columns, max_samp_rows, mk, n_s,
+ end_of_seek=0,
+ seek_return,
+ alpha0,
+ gotinf = 0,
+ gotoutf = 0,
+ out_files=0;
+ int pos; /* position in the file, after the header */
+
+ for (i=0;i<MAX_COMPONENTS;i++) {
+ c_outfilename[i]=malloc(strlen(OUTFILE)+20);
+ sprintf(c_outfilename[i],"%s%d.out",OUTFILE,i+1);
+ }
+
+ multi=1;
+ for ( i=1; i<argc; i++ )
+ if ( argv[i][0] == '-' )
+ {
+ switch ( argv[i][1] ) {
+
+ case 'i':
+ infilename = argv[i]+2;
+ gotinf = 1;
+ break;
+
+ case 'o':
+ outfilename = c_outfilename[out_files++] = argv[i]+2;
+ gotoutf = 1;
+ break;
+
+ case 'P':
+ multi=0;
+ break;
+
+ case 'v':
+ if ( sscanf(argv[i],"-v%d",&verbose) != 1 )
+ verbose=2;
+ break;
+
+ default:
+ usage();
+ exit(0);
+ }
+ }
+ else {
+ if ( ! gotinf ) {
+ infilename = argv[i];
+ gotinf = 1;
+ }
+ else if ( ! gotoutf )
+ outfilename = c_outfilename[out_files++] = argv[i];
+ }
+
+ if ( verbose < 1 )
+ verbose = 1; /* at least the banner will show */
+
+ if ((!multi) && (out_files>1)) {
+ fprintf(stderr,"\nERROR: Only 1 output file expected with -P option.\nThis option is valid only for line/pixel interleaved and not subsampled.\n");
+ exit(10);
+ }
+
+ /* Open in file */
+ if ( infilename == NULL ) {
+ usage();
+ exit(0);
+ }
+ else {
+ if ( strcmp(infilename,"-")==0 )
+ in = stdin;
+ else if ( (in=fopen(infilename,"rb")) == NULL ) {
+ perror(infilename);
+ exit(10);
+ }
+ }
+
+ /* Read the compressed image frame header */
+ bufiinit(in);
+
+ head_frame = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
+
+ for (n_s=0;n_s<MAX_SCANS;n_s++) {
+ head_scan[n_s] = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
+ head_scan[n_s]->T1=head_scan[n_s]->T2=head_scan[n_s]->T3=0;
+ head_scan[n_s]->RES = DEFAULT_RESET;
+ }
+
+ /* Read SOI */
+ seek_return = seek_marker(in,&mk);
+ if (seek_return == EOF) {
+ fprintf(stderr,"*** Premature End of File seeking SOI\n");
+ exit(10);
+ }
+ else {
+ pos = seek_return;
+ if (mk != SOI) {
+ fprintf(stderr,"Marker %04x found: first marker must be SOI (%04x) in this implementation\n", mk, SOI);
+ exit(10);
+ }
+ }
+
+ /* Read SOF_LS */
+ seek_return = seek_marker(in,&mk);
+ if (seek_return == EOF) {
+ fprintf(stderr,"*** Premature End of File seeking SOF_LS\n");
+ exit(10);
+ }
+ else {
+ pos += seek_return; /* Read SOF_LS */
+ if (mk != SOF_LS) {
+ fprintf(stderr,"Marker %04x found: second marker must be SOF_LS (%04x) in this implementation\n", mk, SOF_LS);
+ exit(10);
+ }
+ }
+
+ /* Read the frame header (SOF) */
+ seek_return = read_jpegls_frame(in,head_frame);
+ if (seek_return == EOF) {
+ fprintf(stderr,"*** Premature End of File reading frame header\n");
+ exit(10);
+ }
+ else
+ pos += seek_return;
+
+ head_scan[0]->alp = head_frame->alp; /* default alpha */
+
+
+ /* LSE Extension header */
+ /* This version supports only 2 extension headers, and 1 set of
+ parameters for all the scans */
+ got_lse = 0;
+ head_scan[0]->need_table = 0;
+
+ while (!end_of_seek)
+ {
+ seek_return=seek_marker(in, &mk);
+ if (seek_return == EOF) {
+ fprintf(stderr,"*** Premature End of File seeking SOS or LSE marker\n");
+ exit(10);
+ }
+ pos +=seek_return;
+
+
+ switch(mk)
+ {
+ case LSE:
+ seek_return = read_jpegls_extmarker(in, head_scan[0]);
+ if (seek_return == EOF) {
+ fprintf(stderr,"*** Premature End of File\n");
+ exit(10);
+ }
+ pos += seek_return;
+ got_lse = 1;
+ break;
+
+ case DRI:
+ seek_return = read_jpegls_restartmarker(in, head_scan[0]);
+ pos += seek_return;
+ got_restart = 1;
+ restart_interval = head_scan[0]->restart_interval;
+ break;
+
+ case SOS:
+ end_of_seek=1;
+ break;
+ }
+ }
+ /* End of extension header */
+
+
+
+ /* Read the scan header*/
+ seek_return = read_jpegls_scan(in,head_scan[0]);
+ if (seek_return == EOF) {
+ fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
+ exit(10);
+ }
+ pos+=seek_return;
+
+ shift=head_scan[0]->shift;
+ if (shift!=0) {
+ fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",shift);
+ exit(10);
+ }
+
+ NEAR=head_scan[0]->NEAR;
+ color_mode=head_scan[0]->color_mode;
+ columns=head_frame->columns;
+ rows=head_frame->rows;
+ alpha0=head_scan[0]->alp;
+ head_frame->alp = alpha0;
+ components=head_frame->comp;
+
+ if (color_mode==PLANE_INT)
+ number_of_scans=components;
+ else
+ number_of_scans=1;
+
+ set_thresholds(head_scan[0]->alp, head_scan[0]->NEAR, &(head_scan[0]->T1), &(head_scan[0]->T2), &(head_scan[0]->T3));
+ T1=head_scan[0]->T1;
+ T2=head_scan[0]->T2;
+ T3=head_scan[0]->T3;
+
+#ifndef FIXRESET
+ RESET=head_scan[0]->RES;
+#else
+ if (head_scan[0]->RES != DEFAULT_RESET) {
+ fprintf(stderr,"ERROR: Version compiled for fixed RESET=%d parameter: got %d\n",DEFAULT_RESET,head_scan[0]->RES);
+ exit(10);
+ }
+#endif
+
+ /* Check to see if lossless or lossy */
+ if (NEAR == 0)
+ lossy=FALSE;
+ else
+ lossy=TRUE;
+
+ /* Check for 16 or 8 bit mode */
+ if (alpha0 <= MAXA16 && alpha0 > MAXA8)
+ {
+ /* 16 bit */
+ bpp16 = TRUE;
+ lutmax = LUTMAX16;
+ }
+ else if (alpha0 <= MAXA8 && alpha0 >= 1)
+ {
+ /* 8 bit */
+ bpp16 = FALSE;
+ lutmax = LUTMAX8;
+ }
+ else {
+ fprintf(stderr,"Got alpha = %d\n",alpha0+1);
+ error("Bad value for alpha. Sorry...\n");
+ }
+
+
+ check_compatibility(head_frame,head_scan[0],0);
+
+ for (i=0;i<components;i++) {
+ samplingx[i]=head_frame->samplingx[i];
+ samplingy[i]=head_frame->samplingy[i];
+ if ((!multi) && ((samplingx[i]!=1) || (samplingy[i]!=1)) && (components>1))
+ {
+ fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with subsampled compressed components\n");
+ exit(10);
+ }
+ }
+
+ if ((!multi) && (color_mode==PLANE_INT))
+ if (components>1) {
+ fprintf(stderr,"\nERROR: Cannot use -P (PPM output) with plane intereleaved mode\n");
+ exit(10);
+ }
+ else multi=1;
+
+ if ((multi) && (color_mode==PIXEL_INT)) {
+ multi = 0; /* equivalent to specifying -P flag */
+ }
+
+ if ((out_files>1) && (color_mode==PIXEL_INT)) {
+ fprintf(stderr,"ERROR: Pixel interleaved mode uses only 1 output file\n");
+ exit(10);
+ }
+
+ if ((multi) && (out_files) && (out_files!=components)) {
+ fprintf(stderr,"ERROR: Number of files, %d%, for output must be equal to number of image components, %d\n",out_files,components);
+ exit(10);
+ }
+
+ /* Compute the image size for the different components */
+ if (components==1) {
+ c_columns[0]=columns;
+ c_rows[0]=rows;
+ whose_max_size_rows=0;
+ samplingy[0]=1;
+ }
+ else
+ {
+ max_samp_columns=0;
+ max_samp_rows=0;
+ for(i=0;i<components;i++) {
+ if (samplingx[i]>max_samp_columns) {
+ max_samp_columns=samplingx[i];
+ whose_max_size_columns=i;
+ }
+ if (samplingy[i]>max_samp_rows) {
+ max_samp_rows=samplingy[i];
+ whose_max_size_rows=i;
+ }
+ }
+
+ c_columns[whose_max_size_columns]=columns;
+ c_rows[whose_max_size_rows]=rows;
+
+ for(i=0;i<components;i++) {
+ if (i!=whose_max_size_columns)
+ {
+ c_columns[i]=c_columns[whose_max_size_columns]*samplingx[i];
+ c_columns[i]/=samplingx[whose_max_size_columns];
+ }
+ if (i!=whose_max_size_rows) {
+ c_rows[i]=c_rows[whose_max_size_rows]*samplingy[i];
+ c_rows[i]/=samplingy[whose_max_size_rows];
+ }
+ }
+ }
+
+
+ /* Open out file */
+ if ( outfilename == NULL ) {
+ usage();
+ exit(0);
+ }
+ else {
+ if ( strcmp(outfilename,"-")==0 ) {
+ out = stdout;
+ msgfile = stderr;
+ }
+ else {
+ if (multi==0) {
+ if ( (out=fopen(outfilename,"wb")) == NULL ) {
+ perror(outfilename);
+ exit(10);
+ }
+ }
+ else
+ for (i=0;i<components;i++)
+ if ( (c_out[i]=fopen(c_outfilename[i],"wb")) == NULL )
+ {
+ perror(c_outfilename[i]);
+ exit(10);
+ }
+
+ }
+ }
+
+
+ /* check that color mode is valid and pick color mode string */
+ switch ( color_mode ) {
+
+ case PLANE_INT:
+ color_mode_string = plane_int_string;
+ break;
+
+ case LINE_INT:
+ color_mode_string = line_int_string;
+ break;
+
+ case PIXEL_INT:
+ color_mode_string = pixel_int_string;
+ break;
+
+ default:
+ fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
+ usage();
+ exit(10);
+ }
+
+ if ( verbose ) {
+ fprintf(msgfile,"%s\n",banner);
+ }
+
+ if ( verbose ) {
+ if (!multi) {
+ fprintf(msgfile,"Input file: %s\nOutput file: %s\n",infilename,outfilename);
+ }
+ else {
+ fprintf(msgfile,"Input file: %s\nOutput files: ",infilename);
+ for (i=0;i<components;i++)
+ fprintf(msgfile," %s ",c_outfilename[i]);
+ fprintf(msgfile,"\n");
+ }
+ }
+
+#ifdef FIXALPHA
+ if ( alpha0 != alpha ) {
+ fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);
+ exit(10);
+ }
+#else
+ alpha = alpha0;
+ ceil_half_alpha = (alpha+1)/2;
+#endif
+
+#ifdef POW2
+ highmask = -alpha;
+/* check that alpha is a power of 2 */
+ for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);
+ if ( alpha != (1<<i) ) {
+ fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);
+ exit(10);
+ }
+#endif
+
+ if (lossy==TRUE)
+ {
+ /* compute auxiliary parameters for near-lossless (globals) */
+ quant = 2*NEAR+1;
+ qbeta = (alpha + 2*NEAR + quant-1 )/quant;
+ beta = quant*qbeta;
+ ceil_half_qbeta = (qbeta+1)/2;
+ negNEAR = -NEAR;
+ alpha1eps = alpha-1+NEAR;
+ fprintf(msgfile,"Near-lossless mode: NEAR = %d beta = %d qbeta = %d\n",NEAR,beta,qbeta);
+ }
+
+ /* compute bits per sample for input symbols */
+ for ( bpp=1; (1L<<bpp)<alpha; bpp++ );
+
+ /* compute bits per sample for unencoded prediction errors */
+ if (lossy==TRUE)
+ for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );
+ else
+ qbpp = bpp;
+
+ if ( bpp < 2 ) bpp = 2;
+
+ /* limit for unary part of Golomb code */
+ if ( bpp < 8 )
+ limit = 2*(bpp + 8) - qbpp -1;
+ else
+ limit = 4*bpp - qbpp - 1;
+
+ /* print out parameters */
+ if ( verbose ) {
+ if (!multi)
+ 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",
+ columns, rows, alpha0, components,
+ color_mode, color_mode_string,
+ T1, T2, T3, RESET,limit);
+ else {
+ fprintf(msgfile,"Image: cols=");
+ for (i=0;i<components;i++)
+ fprintf(msgfile," %d",c_columns[i]);
+ fprintf(msgfile," rows=");
+ for (i=0;i<components;i++)
+ fprintf(msgfile," %d",c_rows[i]);
+ fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)\nParameters: Ta=%d Tb=%d Tc=%d RESET=%d limit=%d",
+ alpha0, components,
+ color_mode, color_mode_string,
+ T1, T2, T3,RESET,limit);
+ }
+ }
+
+ if ( verbose )
+ fprintf(msgfile,"\n");
+
+
+ /* Write out the image header for PGM or PPM files */
+ /* Must look at if there are Mapping Tables used */
+
+ /* No Mapping Tables used */
+ if (!head_scan[0]->need_table)
+ {
+ if (!multi) {
+ if (components==1) fputs("P5\n", out);
+ else if (components==3) fputs("P6\n", out);
+ else if (components==4) fputs("P7\n", out);
+ else fprintf(out,"P%d\n",10+components);
+
+ fprintf(out,"%d %d\n", columns, rows);
+ fprintf(out,"%d\n", alpha - 1);
+ }
+ else
+ for (i=0;i<components;i++) {
+ fputs("P5\n", c_out[i]);
+ fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
+ fprintf(c_out[i],"%d\n", alpha - 1);
+ }
+ }
+
+ /* Mapping Tables used */
+ else
+ {
+ /* only 8 bit indexes supported for mapping tables */
+ if (bpp16==TRUE)
+ {
+ fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
+ exit(0);
+ }
+
+ /* Mapping Table elements are 1 or 2 bytes */
+ if (head_scan[0]->Wt==1 || head_scan[0]->Wt==2)
+ {
+ int alpha_temp;
+ if (head_scan[0]->Wt==1)
+ alpha_temp = alpha;
+ else
+ alpha_temp = alpha*alpha;
+
+ if (!multi)
+ {
+ if (components==1) fputs("P5\n", out);
+ else if (components==3) fputs("P6\n", out);
+ else if (components==4) fputs("P7\n", out);
+ else fprintf(out,"P%d\n",10+components);
+
+ fprintf(out,"%d %d\n", columns, rows);
+ fprintf(out,"%d\n", alpha_temp - 1);
+ }
+ else
+ for (i=0;i<components;i++)
+ {
+ fputs("P5\n", c_out[i]);
+ fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
+ fprintf(c_out[i],"%d\n", alpha_temp - 1);
+ }
+ }
+
+ /* Mapping Table elements are 3 bytes */
+ else if (head_scan[0]->Wt==3)
+ {
+ if (!multi)
+ {
+ if (components==1) fputs("P6\n", out);
+ else
+ {
+ fprintf(stderr,"Error : Cannot have a multi-component image and a mapping table with 3 bytes per element.\n");
+ exit(0);
+ }
+
+ fprintf(out,"%d %d\n", columns, rows);
+ fprintf(out,"%d\n", alpha - 1);
+ }
+ else
+ for (i=0;i<components;i++)
+ {
+ fputs("P6\n", c_out[i]);
+ fprintf(c_out[i],"%d %d\n", c_columns[i], c_rows[i]);
+ fprintf(c_out[i],"%d\n", alpha - 1);
+ }
+ }
+
+ /* Mapping Table elements aren't 1 to 3 bytes */
+ else
+ {
+ fprintf(stderr, "Sorry, mapping tables elements can only be 1 to 3 bytes in this implementation.\n");
+ exit(0);
+ }
+ }
+
+
+ /* Allocate memory pools. */
+ initbuffers(multi, components);
+
+
+ /* return size of the header, in bytes */
+ return pos;
+
+}
+
+
+
+
+
+/* Main loop for decoding files */
+
+int main (int argc, char *argv[]) {
+ int n,n_c,n_r,my_i,n_s,mk,seek_return;
+ int found_EOF = 0;
+ double t0, t1, get_utime();
+ long pos0, pos1,
+ tot_in = 0,
+ tot_out = 0;
+ pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
+ int MCUs_counted;
+
+
+ /* Parse the parameters, initialize */
+ /* Not yet fully implemented */
+ bufiinit();
+ pos0 = initialize(argc, argv);
+
+
+ /* start timer (must be AFTER initialize()) */
+ t0 = get_utime();
+
+
+ /* Initialize the scanline buffers */
+ if (!multi)
+ for (n = 0; n <= (columns + 1); ++n)
+ pscanline[n] = 0;
+ else
+ for (n_c=0;n_c<components;n_c++)
+ for (n = 0; n <= (c_columns[n_c] + 1); ++n)
+ c_pscanline[n_c][n] = 0;
+
+ if ((components>1) && (multi==0))
+ {
+ /* OUTPUT PPM file, allocate auxiliary buffers */
+ local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
+ local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof (pixel) );
+
+ local_pscanline = local_scanl0 + LEFTMARGIN-1;
+ local_cscanline = local_scanl1 + LEFTMARGIN-1;
+ }
+
+
+ for (n_s=0;n_s<number_of_scans;n_s++)
+ {
+ /* Repeat prediction/quantization/statistics scanline by scanline,
+ for each scan. */
+
+ /* Reset Restart Markers for every scan */
+ MCUs_counted = 0;
+
+ /* This implementation supports parameters in 1st scan */
+ if (n_s==0)
+ {
+ /* Prepare the quantization LUTs */
+ prepareLUTs();
+
+ if (lossy==TRUE)
+ /* prepare div/mul tables for near-lossless quantization */
+ prepare_qtables(alpha,NEAR);
+
+ }
+ else
+ { /* Read further scan headers */
+ seek_return=seek_marker(in,&mk);
+ if (seek_return == EOF)
+ {
+ fprintf(stderr,"*** Premature End of File seeking SOS marker\n");
+ exit(10);
+ }
+ if ( seek_return > 2 )
+ {
+ fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
+ fprintf(msgfile,"*** Added to marker segment count.\n");
+ }
+ pos0 +=seek_return;
+ if (mk != SOS)
+ {
+ fprintf(stderr,"Expecting SOS (%04x), got %04x\n",SOS,mk);
+ exit(10);
+ }
+ seek_return = read_jpegls_scan(in,head_scan[n_s]); /* Read the scan header*/
+ if (seek_return == EOF)
+ {
+ fprintf(stderr,"*** Premature End of File reading scan marker segment\n");
+ exit(10);
+ }
+ pos0+=seek_return;
+ if (head_scan[n_s]->shift!=0)
+ {
+ fprintf(stderr,"Got shift = %d != 0 : not implemented.\n",head_scan[n_s]->shift);
+ exit(10);
+ }
+ if (head_scan[n_s]->NEAR != NEAR)
+ {
+ fprintf(stderr,"Got NEAR=%d after NEAR=%d: cannot change parameters between scans in this implementation\n",head_scan[n_s]->NEAR,NEAR);
+ exit(10);
+ }
+ if ((head_scan[n_s]->color_mode != PLANE_INT) || (head_scan[n_s]->comp != 1) ||
+ (head_scan[n_s]->comp_ids[0] != n_s+1))
+ {
+ fprintf(stderr,"This implementation supports multiple scans only in PLANE INTERLEAVED mode.\n");
+ exit(10);
+ }
+ }
+
+ /* Initializations for each scan */
+ bitiinit();
+
+ /* Start from 1st image row */
+ n=0;
+
+ /* Initialize stats arrays */
+ if (lossy==TRUE)
+ init_stats(qbeta);
+ else
+ init_stats(alpha);
+
+ /* Initialize run processing */
+ init_process_run(MAXRUN);
+
+ if (color_mode==LINE_INT) { /* line int. */
+ if (!multi) {
+/***********************************************************************/
+/* Line interleaved mode with single file received */
+/***********************************************************************/
+
+ if (lossy==FALSE)
+
+ /* LOSSLESS MODE */
+ while (++n <= rows)
+ {
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
+
+ for (n_c=0;n_c<components;n_c++)
+ {
+ if (components>1)
+ for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
+ {
+ local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
+ local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
+ }
+ else
+ {
+ local_cscanline=cscanline;
+ local_pscanline=pscanline;
+ }
+
+ if ( lossless_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
+ {
+ fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
+ found_EOF = 1;
+ break;
+ }
+
+ if (components>1)
+ for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
+ cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
+ }
+
+ write_one_line(cscanline + components, components*columns, out);
+
+ tot_out += components*columns;
+
+ /* extend the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
+
+ /* make the current scanline the previous one */
+ swaplines();
+
+ /* Take out the Restart Markers */
+ if (got_restart)
+ {
+ /* Look for restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitiflush();
+ read_n_bytes(in, 2); /* read the RST marker */
+ bitiinit();
+ }
+ MCUs_counted++;
+
+ }
+
+ } /* End of while loop for each file line */
+
+ else
+
+ /* LOSSY MODE */
+ while (++n <= rows)
+ {
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
+
+ for (n_c=0;n_c<components;n_c++)
+ {
+ if (components>1)
+ for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
+ {
+ local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
+ local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
+ }
+ else
+ {
+ local_cscanline=cscanline;
+ local_pscanline=pscanline;
+ }
+
+ if ( lossy_undoscanline(local_pscanline, local_cscanline, columns, n_c ) != 0 )
+ {
+ fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
+ found_EOF = 1;
+ break;
+ }
+
+ if (components>1)
+ for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
+ cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
+ }
+
+ write_one_line(cscanline + components, components*columns, out);
+
+ tot_out += components*columns;
+
+ /* extend the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
+
+ /* make the current scanline the previous one */
+ swaplines();
+
+ /* Take out the Restart Markers */
+ if (got_restart)
+ {
+ /* Look for restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitiflush();
+ read_n_bytes(in, 2); /* read the RST marker */
+ bitiinit();
+ }
+ MCUs_counted++;
+
+ }
+
+ } /* End of while loop for each file line */
+
+ }
+ else
+ { /* Multiple files */
+ /* color_mode==LINE_INT and multi==1 */
+/***********************************************************************/
+/* Line interleaved mode with multiple files received */
+/***********************************************************************/
+
+ n++;
+
+ if (lossy==FALSE)
+
+ /* LOSSLESS MODE */
+ while (n <= c_rows[whose_max_size_rows])
+ {
+ for (n_c=0;n_c<components;n_c++)
+ {
+ for (n_r=0;n_r<samplingy[n_c];n_r++)
+ {
+
+ /* 'extend' the edges */
+ c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
+
+ if ( lossless_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
+ {
+ fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
+ found_EOF = 1;
+ break;
+ }
+
+ write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
+
+ tot_out += c_columns[n_c];
+
+ /* extend the edges */
+ c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
+
+ /* make the current scanline the previous one */
+ c_swaplines(n_c);
+ }
+ } /* End of for loop for each component */
+
+ n+=samplingy[whose_max_size_rows];
+
+ /* Take out the Restart Markers */
+ if (got_restart)
+ {
+ /* Look for restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitiflush();
+ read_n_bytes(in, 2); /* read the RST marker */
+ bitiinit();
+ }
+ MCUs_counted++;
+
+ }
+
+ } /* End of while loop for each line */
+
+ else
+
+ /* LOSSY MODE */
+ while (n <= c_rows[whose_max_size_rows])
+ {
+ for (n_c=0;n_c<components;n_c++)
+ {
+ for (n_r=0;n_r<samplingy[n_c];n_r++)
+ {
+
+ /* 'extend' the edges */
+ c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
+
+ if ( lossy_undoscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c], n_c ) != 0 )
+ {
+ fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
+ found_EOF = 1;
+ break;
+ }
+
+ write_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_out[n_c]);
+
+ tot_out += c_columns[n_c];
+
+ /* extend the edges */
+ c_cscanline[n_c][c_columns[n_c]+1] = c_cscanline[n_c][c_columns[n_c]];
+
+ /* make the current scanline the previous one */
+ c_swaplines(n_c);
+ }
+ } /* End of for loop for each component */
+
+ n+=samplingy[whose_max_size_rows];
+
+ /* Take out the Restart Markers */
+ if (got_restart)
+ {
+ /* Look for restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitiflush();
+ read_n_bytes(in, 2); /* read the RST marker */
+ bitiinit();
+ }
+ MCUs_counted++;
+
+ }
+
+ } /* End of while loop for each line */
+
+
+ } /* Closes the else, LINE_INT and multi=1 */
+
+ } /* End of part for LINE_INT */
+
+ else { /* Non LINE_INT mode */
+ if (color_mode==PIXEL_INT) {
+/***********************************************************************/
+/* Pixel interleaved mode with single file received */
+/***********************************************************************/
+
+ if (lossy==FALSE)
+
+ /* LOSSLESS MODE */
+ while (++n <= rows)
+ {
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
+
+ if ( lossless_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
+ {
+ fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
+ found_EOF = 1;
+ break;
+ }
+
+ write_one_line(cscanline+components, components*columns, out);
+
+ tot_out += components*columns;
+
+ /* extend the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
+
+ /* make the current scanline the previous one */
+ swaplines();
+
+ /* Take out the Restart Markers */
+ if (got_restart)
+ {
+ /* Look for restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitiflush();
+ read_n_bytes(in, 2); /* read the RST marker */
+ bitiinit();
+ }
+ MCUs_counted++;
+
+ }
+
+ } /* End of line loop for PIXEL_INT */
+
+
+ else
+
+ /* LOSSY MODE */
+ while (++n <= rows)
+ {
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
+
+ if ( lossy_undoscanline_pixel(pscanline, cscanline, components*columns) != 0 )
+ {
+ fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows,n-1);
+ found_EOF = 1;
+ break;
+ }
+
+ write_one_line(cscanline+components, components*columns, out);
+
+ tot_out += components*columns;
+
+ /* extend the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
+
+ /* make the current scanline the previous one */
+ swaplines();
+
+ /* Take out the Restart Markers */
+ if (got_restart)
+ {
+ /* Look for restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitiflush();
+ read_n_bytes(in, 2); /* read the RST marker */
+ bitiinit();
+ }
+ MCUs_counted++;
+
+ }
+
+ } /* End of line loop for PIXEL_INT */
+
+ }
+ else {
+/***********************************************************************/
+/* Plane interleaved mode */
+/***********************************************************************/
+
+ if (lossy==FALSE)
+
+ /* LOSSLESS MODE */
+ while (++n <= c_rows[n_s])
+ {
+ /* 'extend' the edges */
+ c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
+
+ if (lossless_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
+ {
+ fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
+ found_EOF = 1;
+ break;
+ }
+
+ write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
+
+ tot_out += c_columns[n_s];
+
+ /* extend the edges */
+ c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
+
+ /* make the current scanline the previous one */
+ c_swaplines(n_s);
+
+ /* Take out the Restart Markers */
+ if (got_restart)
+ {
+ /* Look for restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitiflush();
+ read_n_bytes(in, 2); /* read the RST marker */
+ bitiinit();
+ }
+ MCUs_counted++;
+
+ }
+
+ } /* End of line loop in PLANE_INT */
+
+ else
+
+ /* LOSSY MODE */
+ while (++n <= c_rows[n_s])
+ {
+ /* 'extend' the edges */
+ c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
+
+ if (lossy_undoscanline(c_pscanline[n_s], c_cscanline[n_s], c_columns[n_s], n_s ) != 0 )
+ {
+ fprintf(stderr,"*** Premature EOF: expected %d rows, got %d\n",rows, n-1);
+ found_EOF = 1;
+ break;
+ }
+
+ write_one_line(c_cscanline[n_s]+1, c_columns[n_s], c_out[n_s]);
+
+ tot_out += c_columns[n_s];
+
+ /* extend the edges */
+ c_cscanline[n_s][c_columns[n_s]+1] = c_cscanline[n_s][c_columns[n_s]];
+
+ /* make the current scanline the previous one */
+ c_swaplines(n_s);
+
+ /* Take out the Restart Markers */
+ if (got_restart)
+ {
+ /* Look for restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitiflush();
+ read_n_bytes(in, 2); /* read the RST marker */
+ bitiinit();
+ }
+ MCUs_counted++;
+
+ }
+
+ } /* End of line loop in PLANE_INT */
+
+ } /* End of each component for PLANE_INT */
+
+ } /* End of non LINE_INT */
+
+ bitiflush();
+
+ } /* End of loop for scans */
+
+
+ mk = 0;
+
+ /* Read EOI */
+ seek_return=seek_marker(in,&mk);
+ if (seek_return==EOF)
+ {
+ fprintf(stderr,"Did not get EOI at end of compressed image\n");
+ exit(10);
+ }
+ if ( seek_return > 2 )
+ {
+ fprintf(msgfile,"*** WARNING: %d extra bytes between end of scan and next marker.\n",seek_return-2);
+ fprintf(msgfile,"*** Added to marker segment count.\n");
+ }
+
+ pos0 += seek_return;
+ if (mk != EOI)
+ {
+ fprintf(stderr,"In this implementation last marker must be EOI\n");
+ exit(10);
+ }
+
+ if (head_scan[0]->need_table)
+ fprintf(msgfile,"A mapping table was used which had %i entries of %i bytes each.\n",head_scan[0]->MAXTAB, head_scan[0]->Wt);
+
+ if (got_restart)
+ fprintf(msgfile,"Restart markers were found with a restart interval of %i.\n",restart_interval);
+
+ if ( verbose )
+ fprintf(msgfile,"Marker segment bytes: %ld\n",pos0);
+
+ /* position in input file */
+ pos1 = ftell(in);
+ /* tot_in = 8*(pos1-pos0); */
+
+ /* size of compressed file read (bits), incl. headers. */
+ tot_in = 8*pos1;
+
+ /* Close down */
+ close_process_run();
+ closebuffers(multi);
+
+
+ t1 = get_utime();
+ fprintf(msgfile,"Total bits in: %ld Symbols out: %ld %5.3lf bps\n",
+ tot_in,tot_out,tot_in/(double)tot_out);
+ fprintf(msgfile,"Time = %1.3lf secs : %1.0lf KSymbols/sec\n",t1-t0,
+ (tot_out)/(1024*(t1-t0)));
+
+ if ( found_EOF )
+ exit(0);
+ else
+ return 1;
+}
+
+
+
+
+usage()
+{
+ fprintf(stderr,"Usage: %s [flags] [infile] [outfile1 [outfile2, ...]]\n\
+DEFAULTS:\n\
+infile = %s.\n\
+outfile1 = %s for color image in a single (PPM) output file.\n\
+outfile1 = %s for monochrome image in a single (PGM) output file.\n\
+outfile[1,2,...] = %s for multiple (PGM) output files \n\
+ in plane or line interleaved modes.\n",
+ "locod", "specified JLS file", OUTFILE ".out",
+ OUTFILE "1.out",
+ OUTFILE "[1,2,...].out");
+fprintf(stderr,"FLAGS:\n\
+outfile2, ... : Multiple output specification for plane or line int. mode.\n\
+-i<infile> : Alternate input specification, use -i- for stdin.\n\
+-o<outfile> : Alternate output specification, use -o- for stdout.\n\
+-P : Generate single (.ppm) output file for sample/line int. mode.\n\
+");
+ fprintf(stderr,"\
+-h : Print this help.\n\
+*** No spaces allowed between a flag and its argument.\n\
+");
+
+}
+
+
+bad_flag(char *s)
+{
+ fprintf(stderr,"Bad flag %s\n",s);
+ usage();
+ exit(10);
+}
+
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* global.c --- support and portability routines: error handling, safe memory
+ * management, etc.
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995 - ...
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <time.h>
+#include "global.h"
+
+
+
+char *disclaimer = "\
+This program is Copyright (c) University of British Columbia.\n\
+All rights reserved. It may be freely redistributed in its\n\
+entirety provided that this copyright notice is not removed.\n\
+It may not be sold for profit or incorporated in commercial programs\n\
+without the written permission of the copyright holder.\n\
+";
+
+
+
+/* I/O files */
+FILE *in, *out;
+FILE *c_in[MAX_COMPONENTS];
+FILE *c_out[MAX_COMPONENTS];
+FILE *msgfile = stdout;
+
+/* Context quantization thresholds - initially unset */
+int T3 = -1,
+ T2 = -1,
+ T1 = -1,
+ Ta = -1;
+
+
+int verbose = 1; /* verbosity level */
+int nopause = 0; /* whether to pause the legal notice or not */
+int nolegal = 0; /* whether to print the legal notice or not */
+
+
+/* parameters for LOSSY images */
+int quant, /* quantization = 2*NEAR+1 */
+ beta, /* size of extended alphabet */
+ qbeta, /* size of quantized alphabet */
+ ceil_half_qbeta, /* ceil(qbeta/2) */
+ negNEAR, /* -NEAR */
+ alpha1eps; /* alpha-1+NEAR */
+
+int NEAR = DEF_NEAR; /* loss tolerance per symbol, fixed at 0 for lossless */
+int bpp, /* bits per sample */
+ qbpp, /* bits per sample for quantized prediction errors */
+ limit, /* limit for unary part of Golomb code */
+ limit_reduce; /* reduction on above for EOR states */
+
+
+/* define color mode strings */
+char *plane_int_string = "plane by plane",
+ *line_int_string = "line intlv",
+ *pixel_int_string = "sample intlv";
+
+
+/* function to print out error messages */
+void error(char *msg) {
+ fprintf(stderr, msg);
+ exit(-1);
+}
+
+
+/* function to safely call malloc */
+void *safealloc(size_t size) {
+ void *temp;
+
+ temp = malloc(size);
+ if (temp == NULL)
+ error("\nsafealloc: Out of memory. Aborting...\n");
+ return temp;
+}
+
+
+/* function to safely call calloc **/
+void *safecalloc(size_t numels, size_t size) {
+ void *temp;
+
+ temp = calloc(numels, size);
+ if (temp == NULL)
+ error("\nsafecalloc: Out of memory. Aborting...\n");
+ return temp;
+}
+
+
+/*
+ * TIMING ROUTINES
+ */
+
+
+double get_utime()
+{
+ clock_t c;
+
+ return (double)clock()/CLOCKS_PER_SEC;
+}
+
+
+/* Set thresholds to default unless specified by header: */
+set_thresholds(int alfa, int NEAR, int *T1p, int *T2p, int *T3p)
+{
+ int lambda,
+ ilambda = 256/alfa,
+ quant = 2*NEAR+1,
+ T1 = *T1p,
+ T2 = *T2p,
+ T3 = *T3p;
+
+ if (alfa<4096)
+ lambda = (alfa+127)/256;
+ else
+ lambda = (4096+127)/256;
+
+
+
+ if ( T1 <= 0 ) {
+ /* compute lossless default */
+ if ( lambda )
+ T1 = lambda*(BASIC_T1 - 2) + 2;
+ else { /* alphabet < 8 bits */
+ T1 = BASIC_T1/ilambda;
+ if ( T1 < 2 ) T1 = 2;
+ }
+ /* adjust for lossy */
+ T1 += 3*NEAR;
+
+ /* check that the default threshold is in bounds */
+ if ( T1 < NEAR+1 || T1 > (alfa-1) )
+ T1 = NEAR+1; /* eliminates the threshold */
+ }
+ if ( T2 <= 0 ) {
+ /* compute lossless default */
+ if ( lambda )
+ T2 = lambda*(BASIC_T2 - 3) + 3;
+ else {
+ T2 = BASIC_T2/ilambda;
+ if ( T2 < 3 ) T2 = 3;
+ }
+ /* adjust for lossy */
+ T2 += 5*NEAR;
+
+ /* check that the default threshold is in bounds */
+ if ( T2 < T1 || T2 > (alfa-1) )
+ T2 = T1; /* eliminates the threshold */
+ }
+ if ( T3 <= 0 ) {
+ /* compute lossless default */
+ if ( lambda )
+ T3 = lambda*(BASIC_T3 - 4) + 4;
+ else {
+ T3 = BASIC_T3/ilambda;
+ if ( T3 < 4 ) T3 = 4;
+ }
+ /* adjust for lossy */
+ T3 += 7*NEAR;
+
+ /* check that the default threshold is in bounds */
+ if ( T3 < T2 || T3 > (alfa-1) )
+ T3 = T2; /* eliminates the threshold */
+ }
+
+ *T1p = T1;
+ *T2p = T2;
+ *T3p = T3;
+ return 0;
+}
+
+
+
+
+/* We first check compatibility with JPEG-LS, then with this implementation */
+
+void check_compatibility(jpeg_ls_header *head_frame, jpeg_ls_header *head_scan, int n_s)
+{
+
+ int number_of_scans,i;
+ int maxreset;
+
+/* Check implemented color modes */
+ if ((head_scan->color_mode>PIXEL_INT)) {
+ fprintf(stderr,"Color mode %d not supported\n",head_scan->color_mode);
+ exit(10);
+ }
+
+ if (head_scan->color_mode==PLANE_INT)
+ number_of_scans=head_frame->comp;
+ else
+ number_of_scans=1;
+
+
+/* Test standard compatibility */
+
+ if (head_frame->columns<=0 || head_frame->rows <=0) {
+ fprintf(stderr,"Image size must be positive for this implementation.\n");
+ exit(10);
+ }
+
+ if (head_frame->alp<4) {
+ fprintf(stderr,"Alphabet size must be >= 4, got %d\n",head_frame->alp);
+ exit(10);
+ }
+
+
+ if (head_scan->T1>head_scan->T2 || head_scan->T2>head_scan->T3 ||
+ head_scan->T1<head_scan->NEAR+1 || head_scan->T3>=head_scan->alp ) {
+ fprintf(stderr,"Bad thresholds: must be %d <= Ta <= Tb <= Tc <= %d\n",
+ head_scan->NEAR+1,head_scan->alp-1);
+ exit(10);
+ }
+
+ if (head_frame->comp>255) {
+ fprintf(stderr,"Too many components (must be less than 255)\n");
+ exit(10);
+ }
+
+ if (head_scan->NEAR>=head_scan->alp) {
+ fprintf(stderr,"Error for near-lossless must be smaller than alphabet (%d), got %d",head_scan->alp,head_scan->NEAR);
+ exit(10);
+ }
+
+ /*
+ if (head_scan->RES < MINRESET || head_scan->RES >= head_scan->alp ) {
+ fprintf(stderr,"Reset parameter must be between %d and %d\n",
+ MINRESET, head_scan->alp-1);
+ exit(10);
+ }
+ */
+
+ maxreset = (head_scan->alp >= 256)? (head_scan->alp-1):255;
+
+ if (head_scan->RES < MINRESET || head_scan->RES > maxreset ) {
+ fprintf(stderr,"Reset parameter must be between %d and %d\n",
+ MINRESET, head_scan->alp-1);
+ exit(10);
+ }
+
+ for (i=0;i<head_frame->comp;i++)
+ if (head_frame->comp_ids[i] != (i+1)) {
+ fprintf(stderr,"Components id in frame not compatible with this implementation.\n");
+ exit(10);
+ }
+
+ if (number_of_scans == 1) {
+ if (head_frame->comp != head_scan->comp) {
+ fprintf(stderr,"In this implementation, when single scan, all components must be in the scan.\n");
+ exit(10);
+ }
+ for (i=0;i<head_frame->comp;i++)
+ if (head_scan->comp_ids[i] != (i+1)) {
+ fprintf(stderr,"Components id in single scan not compatible with this implementation.\n");
+ exit(10);
+ }
+
+ }
+ else {
+ if (head_scan->comp != 1) {
+ fprintf(stderr,"Only 1 component per scan for plane interleaved mode\n");
+ exit(10);
+ }
+ if (head_scan->comp_ids[0] != (n_s+1)) {
+ fprintf(stderr,"Components id in multiple scan not compatible with this implementation.\n");
+ exit(10);
+ }
+
+ }
+}
+
+
+/* for writing disclaimer to command line in DOS */
+
+char *ttyfilename = "CON";
+
+#define PAUSE 20
+
+fprint_disclaimer(FILE *fp, int nopause)
+{
+ char *p0, *p1;
+ FILE *ttyf;
+ int i, c;
+
+ nopause = nopause | !isatty(fileno(fp));
+
+ if ( !nopause && (ttyf=fopen(ttyfilename,"r"))==NULL ) {
+ nopause = 1;
+ }
+
+ for ( i=1, p0=disclaimer; ; i++ ) {
+ if ( !(*p0) ) break;
+ if ( !nopause && i%PAUSE==0 ) {
+ fflush(fp);
+ fprintf(stderr, "--- (press RETURN to continue) ---");
+ fflush(stderr);
+ c = getc(ttyf);
+ }
+ for ( p1=p0; (*p1 != '\n') && (*p1 != 0); p1++ );
+ *p1 = 0;
+ fprintf(fp,"%s\n",p0);
+ p0 = p1+1;
+ }
+ fprintf(fp,"\n"); fflush(fp);
+ if ( !nopause) fclose(ttyf);
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* global.h --- prototypes for functions and global variables
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 10e6
+#endif
+
+/*#define NDEBUG*/
+#define POW2
+#define FIXAPLHA
+#define FIXRESET
+
+
+/* TRUE and FALSE values */
+#define TRUE 1
+#define FALSE 0
+
+
+/* Version number */
+#define JPEGLSVERSION "V.2.1"
+
+/* Maximal number of components in the implementation*/
+#define MAX_COMPONENTS 6
+#define MAX_SCANS MAX_COMPONENTS
+
+
+/* For 1st component of plane interl. mode */
+#define FIRST 1
+
+
+/* Different colour modes */
+#define PLANE_INT 0
+#define LINE_INT 1
+#define PIXEL_INT 2
+
+#define DEFAULT_COLOR_MODE LINE_INT
+
+extern char *plane_int_string,
+ *line_int_string,
+ *pixel_int_string;
+
+
+#define BIG_ENDIAN 1
+
+typedef struct jpeg_ls {
+
+ int columns, /* The number of columns */
+ rows, /* Number of rows */
+ alp, /* alphabet size (Max+1) , 2 bytes*/
+ comp, /* number of components, 1 byte */
+ NEAR, /* near-lossless error, 1 byte */
+ color_mode, /* indicates the color mode , 1 byte */
+ need_lse, /* Indicates non-default parameters */
+ need_table, /* Indicates use of mapping table */
+ need_restart, /* Indicates use of restart markers */
+ restart_interval, /* The number of MCU's between restart markers */
+ shift, /* for sparse images, 1 byte */
+ T1,T2,T3, /* Thresholds, 2 bytes each */
+ RES, /* reset value for counters, 2 bytes */
+ samplingx[MAX_COMPONENTS], /* col. sampling rates 1 byte each*/
+ samplingy[MAX_COMPONENTS], /* row sampling rates */
+ comp_ids[MAX_COMPONENTS], /* component id's */
+ acc_size, /* 1 byte */
+ adds[MAX_COMPONENTS]; /* size given by acc_size */
+ unsigned int TID, /* Table ID, 1 byte */
+ MAXTAB, /* Maximum table index value */
+ Wt, /* Width of each table entry, 1 byte */
+ *TABLE[MAX_COMPONENTS]; /* The table(s) for each component */
+
+} jpeg_ls_header;
+
+extern int components;
+extern int sampling[MAX_COMPONENTS];
+
+#define NAME_LENGTH 40
+
+/* Output file names */
+#define OUTFILE "outfile"
+#define COMPSUFFIX ".out"
+
+
+/* Define max and min macros */
+#ifndef max
+#define max(a,b) (((a)>=(b))?(a):(b))
+#define min(a,b) (((a)<=(b))?(a):(b))
+#endif
+
+
+/****** Constants */
+
+/* margins for scan lines */
+#define LEFTMARGIN 2
+#define RIGHTMARGIN 1
+
+
+extern char *disclaimer;
+
+
+/* alphabet size */
+#define MAXA8 (256)
+#define MAXA16 (65536)
+#define LUTMAX8 (256)
+#define LUTMAX16 (4501)
+
+
+#ifdef FIXALPHA
+# ifndef alpha
+# define alpha 256
+# endif
+# define highmask (-(alpha))
+# ifndef POW2
+# define POW2
+# endif
+# if (alpha!=2) && (alpha!=4) && (alpha!=8) && (alpha!=16) && (alpha!=32) &&\
+ (alpha!=64) && ( alpha!=128) && (alpha!=256) && (alpha!=512) &&\
+ (alpha!=1024) && ( alpha!=2048) && (alpha!=4096) && (alpha!=8192) &&\
+ (alpha!=16384) && ( alpha!=32768) && (alpha!=65536)
+# error "Fixed alpha must be a power of 2"
+# endif
+# define ceil_half_alpha (alpha/2)
+#else
+extern int alpha; /* alphabet size */
+extern int ceil_half_alpha; /* ceil(alpha/2) */
+extern int highmask; /* for powers of 2, a mask for high bits */
+#endif
+
+
+
+extern int bpp, /* bits per sample */
+ qbpp, /* bits per sample for quantized prediction errors */
+ limit, /* limit for unary part of Golomb code */
+ limit_reduce; /* reduction on above for EOR states */
+
+
+#define DEF_NEAR 0
+
+/* for LOSSY mode */
+extern int quant,
+ beta,
+ qbeta,
+ ceil_half_qbeta,
+ negNEAR,
+ alpha1eps;
+
+/* loss tolerance */
+extern int NEAR;
+
+
+/* Quantization threshold basic defaults */
+/* These are the defaults for LOSSLESS, 8 bpp. Defaults for other
+ cases are derived from these basic values */
+#define BASIC_T1 3
+#define BASIC_T2 7
+#define BASIC_T3 21
+#define BASIC_Ta 5
+
+#define CREGIONS (9) /* quantization regions for d-a, a-c, c-b */
+
+/* run-length treshold */
+#ifndef MAXRUN
+# define MAXRUN (64)
+#endif
+
+#define EOLINE 1
+#define NOEOLINE 0
+
+/* number of different contexts */
+#define CONTEXTS1 (CREGIONS*CREGIONS*CREGIONS)
+
+#define CONTEXTS ((CONTEXTS1+1)/2) /* all regions, with symmetric merging */
+
+
+/* Mandatory for JPEG-LS: */
+#define CLAMP
+#define CLAMPB
+#define CLAMPC
+
+
+#define MAX_C 127
+#define MIN_C -128
+
+
+#define MAXCODE (N_R_L_ERROR)
+
+
+/* Number of end-of-run contexts */
+#define EOR_CONTEXTS 2
+
+
+/* Total number of contexts */
+#define TOT_CONTEXTS (CONTEXTS + EOR_CONTEXTS)
+
+
+/* index of first end-of-run context */
+#define EOR_0 (CONTEXTS)
+
+
+/* index of run state */
+#define RUNSTATE 0
+
+
+
+/*** offsets */
+
+/* The longest code the bit IO can facilitate */
+#define MAXCODELEN 24
+
+/* The stat initialization values */
+#define INITNSTAT 1
+#define MIN_INITABSTAT 2 /* min init value for abstat[] */
+#define INITABSLACK 6 /* init value for abstat is roughly
+ 2^(bpp-INITABSLACK) but not less than above */
+#define INITBIASTAT 0
+
+/* Limit for unary code */
+#define LIMIT 23
+
+/* reset values */
+#define DEFAULT_RESET 64
+#define MINRESET 3
+
+#ifdef FIXRESET
+# ifndef RESET
+# define RESET DEFAULT_RESET
+# endif
+#else
+extern int RESET;
+#endif
+
+#define reset RESET /* reset threshold */
+
+#define RESRUN 256
+
+
+/****** Type prototypes */
+
+/* Portability types */
+typedef unsigned char byte;
+typedef unsigned short word;
+typedef unsigned long dword;
+
+typedef unsigned short pixel;
+
+
+
+/****** Global variables prototypes */
+
+extern FILE *in, *out, *msgfile;
+extern FILE *c_in[MAX_COMPONENTS];
+extern FILE *c_out[MAX_COMPONENTS];
+extern int inhandle;
+extern int T1, T2, T3, Ta;
+extern int verbose,
+ nopause,
+ nolegal;
+
+extern int bpp16;
+extern int lossy;
+
+
+/* for look-up tables */
+extern int alpha;
+extern int vLUT[3][2 * LUTMAX16];
+extern int lutmax;
+extern int classmap[CONTEXTS1];
+extern int *qdiv0, *qdiv, /* quantization table (division via look-up) */
+ *qmul0, *qmul; /* dequantization table */
+
+/* statistics tables */
+extern int N[TOT_CONTEXTS],
+ A[TOT_CONTEXTS],
+ B[TOT_CONTEXTS],
+ C[TOT_CONTEXTS];
+
+
+/****** Function prototypes */
+
+/* global.c */
+void error(char *msg);
+void *safealloc(size_t size);
+void *safecalloc(size_t numels, size_t size);
+
+/* scanline.c */
+void prepareLUTs();
+void init_stats(int);
+void doscanline(pixel *psl, pixel *sl, int no, int color);
+int undoscanline(pixel *psl, pixel *sl, int no, int color);
+void doscanline_pixel(pixel *psl, pixel *sl, int no);
+int undoscanline_pixel(pixel *psl, pixel *sl, int no);
+
+/* bitio.c */
+void bitiinit();
+void bitflush();
+void createzeroLUT();
+void buffinit(FILE *);
+
+/* melcode.c */
+void init_process_run(int);
+void close_process_run();
+int process_run_dec(int,int);
+
+/* initialize.c */
+void prepareLUTs();
+void prepare_qtables(int, int);
+void init_stats(int);
+
+#ifdef BIG_ENDIAN
+# define ENDIAN8(x) (x)
+# define ENDIAN16(x) (x)
+#else
+# define ENDIAN8(x) (x&0x000000ff)
+# define ENDIAN16(x) ( ((x>>8)|(x<<8)) & 0x0000ffff)
+#endif
+
+/* ENDIAN function to fix endian of PCs (for 8 bit pixels)
+#define ENDIAN8(x) (x&0x000000ff)*/
+
+
+/* ENDIAN function to fix endian of PCs (for 16 bit pixels)
+#define ENDIAN16(x) ( ((x>>8)|(x<<8)) & 0x0000ffff )*/
+
+
+
+
+/* clipping macro */
+#ifdef POW2
+# define clip(x,alpha) \
+ if ( x & highmask ) {\
+ if(x < 0) \
+ x = 0;\
+ else \
+ x = alpha - 1;\
+ }
+#else
+# define clip(x,alpha) \
+ if(x < 0) \
+ x = 0; \
+ else if (x >= alpha) \
+ x = alpha - 1;
+#endif /* POW2 */
+
+
+
+/* macro to predict Px */
+#define predict(Rb, Ra, Rc) \
+{ \
+ register pixel minx; \
+ register pixel maxx; \
+ \
+ if (Rb > Ra) { \
+ minx = Ra; \
+ maxx = Rb; \
+ } else { \
+ maxx = Ra; \
+ minx = Rb; \
+ } \
+ if (Rc >= maxx) \
+ Px = minx; \
+ else if (Rc <= minx) \
+ Px = maxx; \
+ else \
+ Px = Ra + Rb - Rc; \
+}
+
+
+#endif
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* initialize.c --- functions to initialize look up tables
+ * and statistics tables
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "global.h"
+#include "bitio.h"
+
+
+
+int vLUT[3][2 * LUTMAX16];
+
+int classmap[CONTEXTS1];
+
+int *qdiv0, *qdiv, /* quantization table (division via look-up) */
+ *qmul0, *qmul; /* dequantization table */
+
+int N[TOT_CONTEXTS],
+ A[TOT_CONTEXTS],
+ B[TOT_CONTEXTS],
+ C[TOT_CONTEXTS];
+
+
+
+/* Setup Look Up Tables for quantized gradient merging */
+void prepareLUTs()
+{
+ int i, j, idx, lmax;
+ byte k;
+
+ lmax = min(alpha,lutmax);
+
+ /* implementation limitation: */
+ if ( T3 > lmax-1 ) {
+ fprintf(stderr,"Sorry, current implementation does not support threshold T3 > %d, got %d\n",lmax-1,T3);
+ exit(10);
+ }
+
+
+ /* Build classification tables (lossless or lossy) */
+
+ if (lossy==FALSE) {
+
+ for (i = -lmax + 1; i < lmax; i++) {
+
+ if ( i <= -T3 ) /* ...... -T3 */
+ idx = 7;
+ else if ( i <= -T2 ) /* -(T3-1) ... -T2 */
+ idx = 5;
+ else if ( i <= -T1 ) /* -(T2-1) ... -T1 */
+ idx = 3;
+
+ else if ( i <= -1 ) /* -(T1-1) ... -1 */
+ idx = 1;
+ else if ( i == 0 ) /* just 0 */
+ idx = 0;
+
+ else if ( i < T1 ) /* 1 ... T1-1 */
+ idx = 2;
+ else if ( i < T2 ) /* T1 ... T2-1 */
+ idx = 4;
+ else if ( i < T3 ) /* T2 ... T3-1 */
+ idx = 6;
+ else /* T3 ... */
+ idx = 8;
+
+ vLUT[0][i + lutmax] = CREGIONS * CREGIONS * idx;
+ vLUT[1][i + lutmax] = CREGIONS * idx;
+ vLUT[2][i + lutmax] = idx;
+ }
+
+ } else {
+
+ for (i = -lmax + 1; i < lmax; i++) {
+
+ if ( NEAR >= (alpha-1) )
+ idx = 0; /* degenerate case, regardless of thresholds */
+ else
+
+ if ( i <= -T3 ) /* ...... -T3 */
+ idx = 7;
+ else if ( i <= -T2 ) /* -(T3-1) ... -T2 */
+ idx = 5;
+ else if ( i <= -T1 ) /* -(T2-1) ... -T1 */
+ idx = 3;
+
+ else if ( i <= -NEAR-1 ) /* -(T1-1) ... -NEAR-1 */
+ idx = 1;
+ else if ( i <= NEAR ) /* within NEAR of 0 */
+ idx = 0;
+
+ else if ( i < T1 ) /* 1 ... T1-1 */
+ idx = 2;
+ else if ( i < T2 ) /* T1 ... T2-1 */
+ idx = 4;
+ else if ( i < T3 ) /* T2 ... T3-1 */
+ idx = 6;
+ else /* T3 ... */
+ idx = 8;
+
+ vLUT[0][i + lutmax] = CREGIONS * CREGIONS * idx;
+ vLUT[1][i + lutmax] = CREGIONS * idx;
+ vLUT[2][i + lutmax] = idx;
+ }
+
+ }
+
+
+ /* prepare context mapping table (symmetric context merging) */
+ classmap[0] = 0;
+ for ( i=1, j=0; i<CONTEXTS1; i++) {
+ int q1, q2, q3, n1=0, n2=0, n3=0, ineg, sgn;
+
+ if(classmap[i])
+ continue;
+
+ q1 = i/(CREGIONS*CREGIONS); /* first digit */
+ q2 = (i/CREGIONS)%CREGIONS; /* second digit */
+ q3 = i%CREGIONS; /* third digit */
+
+ if((q1%2)||(q1==0 && (q2%2))||(q1==0 && q2==0 && (q3%2)))
+ sgn = -1;
+ else
+ sgn = 1;
+
+ /* compute negative context */
+ if(q1) n1 = q1 + ((q1%2) ? 1 : -1);
+ if(q2) n2 = q2 + ((q2%2) ? 1 : -1);
+ if(q3) n3 = q3 + ((q3%2) ? 1 : -1);
+
+ ineg = (n1*CREGIONS+n2)*CREGIONS+n3;
+ j++ ; /* next class number */
+ classmap[i] = sgn*j;
+ classmap[ineg] = -sgn*j;
+
+ }
+
+}
+
+
+
+
+
+
+/* prepare quantization tables for near-lossless quantization */
+void prepare_qtables(int absize, int NEAR)
+{
+ int diff, qdiff;
+ int beta, quant;
+
+ quant = 2*NEAR+1;
+ beta = absize;
+
+ if ( (qdiv0 = (int *)calloc(2*absize-1,sizeof(int)))==NULL ) {
+ perror("qdiv table");
+ exit(10);
+ }
+ qdiv = qdiv0+absize-1;
+
+ if ( (qmul0 = (int *)calloc(2*beta-1,sizeof(int)))==NULL ) {
+ perror("qmul table");
+ exit(10);
+ }
+ qmul = qmul0+beta-1;
+
+ for ( diff = -(absize-1); diff<absize; diff++ ) {
+ if ( diff<0 )
+ qdiff = - ( (NEAR-diff)/quant );
+ else
+ qdiff = ( NEAR + diff )/quant;
+ qdiv[diff] = qdiff;
+ }
+ for ( qdiff = -(beta-1); qdiff<beta; qdiff++ ) {
+ diff = quant*qdiff;
+ qmul[qdiff] = diff;
+ }
+}
+
+
+
+
+/* Initialize A[], B[], C[], and N[] arrays */
+void init_stats(int absize)
+{
+
+ int i, initabstat, slack;
+
+ slack = 1<<INITABSLACK;
+ initabstat = (absize + slack/2)/slack;
+ if ( initabstat < MIN_INITABSTAT ) initabstat = MIN_INITABSTAT;
+
+ /* do the statistics initialization */
+ for (i = 0; i < TOT_CONTEXTS; ++i) {
+ C[i]= B[i] = 0;
+ N[i] = INITNSTAT;
+ A[i] = initabstat;
+ }
+}
+
+
+
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* jpegmark.c --- for JPEG markers
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+
+#include <stdio.h>
+#include "global.h"
+#include "jpegmark.h"
+
+#ifdef BUFINPUT
+# include "bitio.h"
+#else
+# define mygetc(in) (getc(in))
+# define myfeof(in) (feof(in))
+#endif
+
+void
+check_range(int param, char *name, int low, int high)
+{
+ if ( param < low || param > high ) {
+ fprintf(stderr,"Allowed range for %s is [%d..%d]: got %d\n",
+ name, low, high, param);
+ exit(10);
+ }
+}
+
+/*
+ *
+ * Marker output functions
+ *
+ */
+
+int
+write_n_bytes(FILE *out, int value, int n)
+{
+
+ int l;
+
+
+ if (n>4) {
+ fprintf(stderr,"write_n_bytes: Only 32 bits variables supported.\n");
+ exit(10);
+ }
+
+
+#ifdef BIG_ENDIAN
+ for (l=n-1;l>=0;l--) {
+ if ( putc((value>>(8*l))&0x000000FF,out) == EOF )
+ return EOF;
+ }
+#else /* little endian */
+ for (l=0;l<n;l++) {
+ if ( putc((value&0x000000FF),out) == EOF )
+ return EOF;
+ value >>= 8;
+ }
+#endif
+ return n;
+
+}
+
+int
+write_2_bytes(FILE *out, int value)
+{
+ return write_n_bytes(out,value,2);
+}
+
+int
+write_marker(FILE *out, int marker)
+/* Write a two-byte marker (just the marker identifier) */
+{
+ write_n_bytes(out, marker, 2);
+ return 2;
+}
+
+int
+write_jpegls_frame(FILE *out, jpeg_ls_header *jp)
+{
+ int i, marker_len,
+ bpp, ct = 0;
+
+ ct += write_marker(out, SOF_LS); /* write JPEG-LS frame marker */
+
+ check_range(jp->comp, "frame components", 1, 255);
+ marker_len = 8 + 3*jp->comp;
+
+ ct += write_n_bytes(out, marker_len, 2); /* write marker length */
+
+ for ( bpp=1; (1L<<bpp)<jp->alp; bpp++ );
+
+ ct += write_n_bytes(out, bpp, 1); /* write bits/sample */
+
+ /* current implementation only supports up to 64K samples in
+ either direction. Also, they must be specified in the frame header */
+ check_range(jp->rows, "rows", 1, 65535);
+ check_range(jp->columns, "columns", 1, 65535);
+
+ ct += write_n_bytes(out, jp->rows, 2); /* write number of rows */
+ ct += write_n_bytes(out, jp->columns, 2); /* write number of cols */
+
+ ct += write_n_bytes(out, jp->comp, 1);
+
+ /* now write a triplet of bytes per component */
+ for ( i=0; i<jp->comp; i++ ) {
+ int sx = jp->samplingx[i],
+ sy = jp->samplingy[i];
+
+ check_range(sx,"sampling(x)",1,4);
+ check_range(sy,"sampling(y)",1,4);
+ ct += write_n_bytes(out, jp->comp_ids[i], 1); /* component identifier */
+ ct += write_n_bytes(out, (sx<<4)|sy, 1); /* sampling rates */
+ ct += write_n_bytes(out, 0, 1); /* Tq unused */
+ }
+ return ct;
+}
+
+int
+write_jpegls_scan(FILE *out, jpeg_ls_header *jp)
+{
+ int i, marker_len, ct=0;
+
+ ct += write_marker(out, SOS); /* write JPEG-LS scan marker */
+
+ check_range(jp->comp, "scan components", 1, 4);
+
+ if ( jp->comp == 1 && jp->color_mode != PLANE_INT) {
+ fprintf(stderr,"Interleave for 1 component must be PLANE_INT: got %d\n",
+ jp->color_mode);
+ exit(10);
+ }
+
+ if ( jp->comp >1 && jp->color_mode == 0 ) {
+ fprintf(stderr,"Interleave for multi-component scan must be nonzero: got %d\n",
+ jp->color_mode);
+ exit(10);
+ }
+
+ marker_len = 6 + 2*jp->comp;
+
+ ct += write_n_bytes(out, marker_len, 2); /* write marker length */
+ ct += write_n_bytes(out, jp->comp, 1); /* # of components for the scan */
+
+ /* write 2 bytes per component */
+ for ( i=0; i<jp->comp; i++ ) {
+ ct += write_n_bytes(out, jp->comp_ids[i], 1); /* component identifier */
+ ct += write_n_bytes(out, 0, 1); /* no tables in this implementation */
+ }
+
+ check_range(jp->NEAR, "NEAR", 0, 255);
+ ct += write_n_bytes(out, jp->NEAR, 1);
+
+ check_range(jp->color_mode,"INTERLEAVE", 0, 2);
+ ct += write_n_bytes(out, jp->color_mode, 1);
+
+ check_range(jp->shift, "SHIFT", 0, 15);
+ ct += write_n_bytes(out, jp->shift, 1);
+
+ return ct;
+}
+
+
+int
+write_jpegls_extmarker(FILE *out, jpeg_ls_header *jp)
+{
+ int marker_len, ct=0;
+
+ ct += write_marker(out, LSE); /* write JPEG-LS extended marker id */
+
+ ct += write_n_bytes(out, 13, 2); /* marker length */
+ ct += write_n_bytes(out, LSE_PARAMS, 1); /* ext marker id */
+ ct += write_n_bytes(out, jp->alp-1, 2); /* MAXVAL */
+ ct += write_n_bytes(out, jp->T1, 2);
+ ct += write_n_bytes(out, jp->T2, 2);
+ ct += write_n_bytes(out, jp->T3, 2);
+ ct += write_n_bytes(out, jp->RES, 2);
+ return ct;
+}
+
+
+/*
+ *
+ * Marker input functions
+ *
+ */
+
+int
+seek_marker(FILE *in, int *mkp )
+/* Seeks a marker in the input stream. Returns the marker head, or EOF */
+{
+ int c, c2, ct=0;
+ while ( (c=mygetc(in)) != EOF ) {
+ ct ++;
+ if ( c == 0xFF ) {
+ if ( (c2=mygetc(in)) == EOF )
+ return EOF;
+ ct ++;
+ if ( c2 & 0x80 ) {
+ *mkp = (c<<8)|c2;
+ return ct;
+ }
+ }
+ }
+ return EOF;
+}
+
+
+unsigned int
+read_n_bytes(FILE *in, int n)
+/* reads n bytes (0 <= n <= 4) from the input stream */
+{
+ unsigned int m = 0;
+ int i;
+
+ for ( i=0; i<n; i++ )
+ m = (m << 8) | mygetc(in);
+ return m;
+
+}
+
+int
+read_marker(FILE *in, int *mkp)
+/* reads a marker from the next two bytes in the input stream */
+{
+ unsigned int m, ct=0;
+
+ m = read_n_bytes(in, 2);
+ if ( feof(in) ) return EOF;
+ if ( (m & 0xFF00) != 0xFF00 ) {
+ fprintf(stderr,"read_marker: Expected marker, got %04x\n",m);
+ exit(10);
+ }
+ *mkp = m;
+ return 2;
+}
+
+int
+read_jpegls_frame(FILE *in, jpeg_ls_header *jp)
+/* reads the JPEG-LS frame marker (not including marker head) */
+{
+ int i,
+ marker_len,
+ bpp,
+ tq,
+ comp,
+ ct = 0;
+
+ /* Read Marker Length */
+ marker_len = read_n_bytes(in, 2);
+ ct += 2;
+
+ /* Read the bits per pixel */
+ bpp = read_n_bytes(in, 1);
+ ct ++;
+
+ check_range(bpp,"bpp",2,16);
+ jp->alp = 1<<bpp;
+
+ /* Read the rows and columns */
+ jp->rows = read_n_bytes(in, 2);
+ ct += 2;
+ jp->columns = read_n_bytes(in, 2);
+ ct += 2;
+
+ /* Read component information */
+ comp = read_n_bytes(in, 1);
+ ct += 1;
+ check_range(comp,"COMP",1,255);
+ jp->comp = comp;
+
+ for ( i=0; i<comp; i++ )
+ {
+ int sx, sy, cid;
+
+ cid = read_n_bytes(in, 1);
+ ct += 1;
+ sx = read_n_bytes(in, 1);
+ ct += 1;
+ tq = read_n_bytes(in, 1);
+ ct += 1;
+ check_range(tq,"Tq",0,0);
+ sy = sx & 0x0f;
+ sx >>= 4;
+ check_range(sx, "sampling(x)", 1, 4);
+ check_range(sy, "sampling(y)", 1, 4);
+ jp->samplingx[i] = sx;
+ jp->samplingy[i] = sy;
+ jp->comp_ids[i] = cid;
+ }
+
+ /* Check for errors */
+ if ( myfeof(in) )
+ {
+ fprintf(stderr,"read_jpegls_frame: EOF while reading frame marker\n");
+ return EOF;
+ }
+ if ( marker_len != 8 + 3*comp )
+ {
+ fprintf(stderr,"read_jpegls_frame: inconsistent marker length: expected %d, got %d\n",marker_len, 8 + 3*comp);
+ exit(10);
+ }
+
+ return ct;
+}
+
+
+
+/* reads the JPEG-LS scan marker (not including marker head) */
+int read_jpegls_scan(FILE *in, jpeg_ls_header *jp)
+{
+ int i, marker_len,
+ comp, ct=0;
+
+
+ marker_len = read_n_bytes(in, 2);
+ ct += 2;
+
+ comp = read_n_bytes(in, 1);
+ ct += 1;
+ check_range(comp, "scan components", 1, 4);
+
+ jp->comp = comp;
+
+ /* read 2 bytes per component */
+ for ( i=0; i<comp; i++ ) {
+ int cid, tm;
+
+ cid = read_n_bytes(in, 1); /* component identifier */
+ ct += 1;
+ tm = read_n_bytes(in, 1); /* table identifier */
+ ct += 1;
+
+ if ( tm ) {
+ fprintf(stderr,"read_jpegls_scan: found nonzero table identifier, not supported\n");
+ exit(10);
+ }
+ jp->comp_ids[i] = cid;
+ }
+
+ jp->NEAR = read_n_bytes(in, 1);
+ ct += 1;
+ check_range(jp->NEAR,"NEAR", 0, 255);
+
+ jp->color_mode = read_n_bytes(in, 1);
+ ct += 1;
+ check_range(jp->color_mode, "INTERLEAVE", 0, 2);
+
+ if ( jp->comp == 1 && jp->color_mode != 0 ) {
+ /*
+ fprintf(stderr,"Interleave for 1 component must be 0: got %d\n",
+ jp->color_mode);
+ */
+
+ /* ignore interleave value, set to 0 */
+ jp->color_mode = 0;
+ }
+
+ if ( jp->comp >1 && jp->color_mode == 0 ) {
+ fprintf(stderr,"Interleave for multi-component scan must be nonzero: got %d\n",
+ jp->color_mode);
+ exit(10);
+ }
+
+
+ jp->shift = read_n_bytes(in, 1);
+ ct += 1;
+ check_range(jp->shift, "SHIFT", 0, 15);
+
+ if ( myfeof(in) ) {
+ fprintf(stderr,"read_jpegls_scan: EOF while reading frame marker\n");
+ return EOF;
+ }
+ if ( marker_len != 6 + 2*comp ) {
+ fprintf(stderr,"read_jpegls_scan: inconsistent marker length: expected %d, got %d\n",marker_len, 6 + 2*comp);
+ exit(10);
+ }
+ return ct;
+}
+
+
+
+/* reads the JPEG-LS extension marker (not including marker head) */
+/* Supports non-default type (1) and mapping table type (2) */
+int read_jpegls_extmarker(FILE *in, jpeg_ls_header *jp)
+
+{
+ int marker_len, /* marker length */
+ maxval, /* max value */
+ T1, T2, T3, /* thresholds */
+ ct = 0;
+ int IDtype; /* LSE type */
+ int TID; /* table ID */
+ int Wt; /* width of each table entry */
+ int MAXTAB; /* maximum table index */
+ int i;
+
+
+ /* Read marker length */
+ marker_len = read_n_bytes(in, 2); /* marker length */
+ ct += 2;
+
+ /* Read id type */
+ IDtype = read_n_bytes(in, 1);
+ ct += 1;
+
+
+ /* For Type 1 - non default parameters */
+ if (IDtype == LSE_PARAMS)
+ {
+ if ( marker_len != 13 )
+ {
+ fprintf(stderr,"read_jpegls_extmarker: bad marker length %d\n",marker_len);
+ exit(10);
+ }
+
+ /* read maxval */
+ maxval = read_n_bytes(in, 2);
+ ct += 2;
+ jp->alp = maxval +1;
+
+ /* read thresholds and reset */
+ jp->T1 = read_n_bytes(in, 2);
+ ct += 2;
+ jp->T2 = read_n_bytes(in, 2);
+ jp->T3 = read_n_bytes(in, 2);
+ jp->RES = read_n_bytes(in, 2);
+ ct += 6;
+
+ if ( myfeof(in) ) {
+ fprintf(stderr,"read_jpegls_extmarker: EOF while reading frame marker\n");
+ return EOF;
+ }
+
+ return ct;
+ }
+
+ /* For Type 2 - mapping table */
+ if (IDtype == LSE_MAPTABLE)
+ {
+
+ /* Indicate table used */
+ jp->need_table = 1;
+
+ /* Read table ID */
+ jp->TID = TID = read_n_bytes(in, 1);
+ ct += 1;
+
+ /* Read width of table entry */
+ jp->Wt = Wt = read_n_bytes(in, 1);
+ if (Wt<=0 || Wt>3)
+ {
+ fprintf(stderr, "Width of mapping table entries must be either 1,2 or 3 in this implementation. Sorry!\n");
+ exit(0);
+ }
+ ct += 1;
+
+ /* Calculate value of MAXTAB */
+ jp->MAXTAB = MAXTAB = ((marker_len - 5) / Wt) - 1;
+
+ /* Get table entries */
+ jp->TABLE[TID] = (unsigned int *)safecalloc((MAXTAB+1)*sizeof(int), 1);
+ for (i=0; i<=MAXTAB; i++)
+ {
+ jp->TABLE[TID][i] = read_n_bytes(in, Wt);
+ }
+ ct += ((MAXTAB+1) * Wt);
+
+ return ct;
+ }
+
+ /* Non supported types */
+
+ fprintf(stderr, "LSE marker type %i not supported in this implementation.\n", IDtype);
+ exit(0);
+
+}
+
+
+
+
+
+/* Read DRI restart marker */
+int read_jpegls_restartmarker(FILE *in, jpeg_ls_header *jp)
+{
+ int ct = 0;
+ int marker_len; /* the marker length */
+ int Ri; /* the restart interval */
+
+ /* Read marker length */
+ marker_len = read_n_bytes(in, 2);
+ ct += 2;
+
+ /* Read the restart interval */
+ Ri = read_n_bytes(in, marker_len - 2);
+ ct += (marker_len - 2);
+
+ jp->restart_interval = Ri;
+
+ return ct;
+
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* jpegmark.h --- for JPEG markers
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#define BUFINPUT
+#ifndef BIG_ENDIAN
+# define BIG_ENDIAN
+#endif
+
+/* Marker identifiers */
+
+#define SOI 0xFFD8 /* start of image */
+#define EOI 0xFFD9 /* end of image */
+
+#define SOS 0xFFDA /* Start of scan */
+#define DNL 0xFFDC /* Define number of lines */
+#define DRI 0xFFDD /* Define restart interval */
+#define RSTm 0xFFD0 /* Restart marker (FFD0-FFD7) */
+#define COM 0xFFFE /* Comment */
+
+
+/* JPEG-LS specific */
+#define SOF_LS 0xFFF7 /* Start of JPEG-LS regular frame */
+#define LSE 0xFFF8 /* JPEG-LS extension marker */
+#define LSE_PARAMS 1 /* Marker type within LSE - parameters */
+#define LSE_MAPTABLE 2 /* Marker type within LSE - map tables */
+#define LSE_XMAPTABLE 3 /* Marker type within LSE - map table
+ continuation */
+#define LSE_XY 4 /* Marker type within LSE - image dimensions */
+
+
+/* Functions to write markers */
+int write_n_bytes(FILE *out, int value, int n);
+int write_2_bytes(FILE *out, int value);
+int write_marker(FILE *out, int marker);
+int write_jpegls_frame(FILE *out, jpeg_ls_header *jp);
+int write_jpegls_scan(FILE *out, jpeg_ls_header *jp);
+int write_jpegls_extmarker(FILE *out, jpeg_ls_header *jp);
+
+
+/* Functions to read markers */
+unsigned int read_n_bytes(FILE *in, int n);
+int read_marker(FILE *in, int *mkp);
+int seek_marker(FILE *in, int *mkp);
+int read_jpegls_frame(FILE *in, jpeg_ls_header *jp);
+int read_jpegls_scan(FILE *in, jpeg_ls_header *jp);
+int read_jpegls_extmarker(FILE *in, jpeg_ls_header *jp);
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* lossless_d.c --- the main pipeline which processes a scanline by doing
+ * prediction, context computation, context quantization,
+ * and statistics gathering. (for lossless mode)
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include "global.h"
+#include "bitio.h"
+
+#include <stdio.h>
+#include <math.h>
+
+
+static int eor_limit;
+
+/* Do Golomb-Rice statistics and DECODING for LOSSLESS images */
+inline int lossless_regular_mode_d(int Q, int SIGN, int Px)
+{
+ int At, Bt, Nt, Errval, absErrval;
+ int current, k;
+
+ /* This function is called only for regular contexts.
+ End_of_run context is treated separately */
+
+ Nt = N[Q];
+ At = A[Q];
+ {
+ /* Estimate k */
+ register nst = Nt;
+ for(k=0; nst < At; nst *=2, k++);
+ }
+
+ /* Get the number of leading zeros */
+ absErrval = 0;
+ do {
+ int temp;
+
+ temp = zeroLUT[reg >> 24];
+ absErrval += temp;
+ if (temp != 8) {
+ FILLBUFFER(temp + 1);
+ break;
+ }
+ FILLBUFFER(8);
+ } while (1);
+
+ if ( absErrval < limit ) {
+ /* now add the binary part of the Rice code */
+ if (k) {
+ register unsigned long temp;
+ absErrval <<= k;
+ GETBITS(temp,k);
+ absErrval += temp;
+ }
+ }
+ else {
+ /* the original unary would have been too long:
+ (mapped value)-1 was sent verbatim */
+ GETBITS(absErrval, qbpp);
+ absErrval ++;
+ }
+
+ /* Do the Rice mapping */
+ if ( absErrval & 1 ) { /* negative */
+ absErrval = (absErrval + 1) / 2;
+ Errval = -absErrval;
+ } else {
+ absErrval /= 2;
+ Errval = absErrval;
+ }
+
+ Bt = B[Q];
+
+ if ( k==0 && (2*Bt <= -Nt) )
+ {
+ /* special case: see encoder side */
+ Errval = -(Errval+1);
+ absErrval = (Errval<0)? (-Errval):Errval;
+ }
+
+ /* center, clip if necessary, and mask final error */
+ if ( SIGN == -1 ) {
+ Px -= C[Q];
+ clip(Px, alpha);
+
+#if defined(POW2)
+ /* this is valid if alpha is a power of 2 */
+ current = (Px - Errval)&(alpha-1);
+#else
+ current = Px - Errval;
+#endif
+ }
+ else {
+ Px += C[Q];
+ clip(Px,alpha);
+
+#if defined(POW2)
+ /* valid if alpha is a power of 2 */
+ current = (Px + Errval)&(alpha-1);
+#else
+ current = Px + Errval;
+#endif
+ }
+
+
+#if !defined(POW2)
+ /* reduce mod alpha, for arbitrary alpha */
+ if (current < 0)
+ current += alpha;
+ else if (current >= alpha)
+ current -= alpha;
+#endif
+
+
+ /* update bias stats */
+ B[Q] = (Bt += Errval);
+
+ /* update Golomb-Rice stats */
+ A[Q] += absErrval;
+
+
+ /* check reset (joint for Rice-Golomb and bias cancelation) */
+ if(Nt == reset) {
+ N[Q] = (Nt >>= 1);
+ A[Q] >>= 1;
+ B[Q] = (Bt >>= 1);
+ }
+
+
+ /* Do bias estimation for NEXT pixel */
+ N[Q] = (++Nt);
+ if ( Bt <= -Nt ) {
+
+ if (C[Q] > MIN_C)
+ --C[Q];
+
+ Bt = (B[Q] += Nt);
+
+ if ( Bt <= -Nt )
+ B[Q] = -Nt+1;
+
+ } else if ( Bt > 0 ) {
+
+ if (C[Q] < MAX_C)
+ ++C[Q];
+
+ Bt = (B[Q] -= Nt);
+
+ if ( Bt > 0 )
+ B[Q] = 0;
+ }
+
+ return current;
+}
+
+
+
+
+
+
+/* Do end of run DECODING for LOSSLESS images */
+inline pixel lossless_end_of_run_d(pixel Ra, pixel Rb, int RItype)
+{
+
+ int Ix,
+ Errval,
+ absErrval,
+ MErrval,
+ k,
+ Q,
+ oldmap,
+ Nt,
+ At;
+
+ Q = EOR_0 + RItype;
+ Nt = N[Q],
+ At = A[Q];
+
+ if ( RItype )
+ At += Nt/2;
+
+ /* Estimate k */
+ for(k=0; Nt < At; Nt *=2, k++);
+
+ /* read and decode the Golomb code */
+ /* Get the number of leading zeros */
+ MErrval = 0;
+ do {
+ int temp;
+
+ temp = zeroLUT[reg >> 24];
+ MErrval += temp;
+ if (temp != 8) {
+ FILLBUFFER(temp + 1);
+ break;
+ }
+ FILLBUFFER(8);
+ } while (1);
+
+ eor_limit = limit - limit_reduce;
+
+ if ( MErrval < eor_limit ) {
+ /* now add the binary part of the Golomb code */
+ if (k) {
+ register unsigned long temp;
+ MErrval <<= k;
+ GETBITS(temp,k);
+ MErrval += temp;
+ }
+ }
+ else {
+ /* the original unary would have been too long:
+ (mapped value)-1 was sent verbatim */
+ GETBITS(MErrval, qbpp);
+ MErrval ++;
+ }
+
+ oldmap = ( k==0 && (RItype||MErrval) && (2*B[Q]<Nt));
+ /*
+ Note: the Boolean variable 'oldmap' is not
+ identical to the variable 'map' in the
+ JPEG-LS draft. We have
+ oldmap = (qdiff<0) ? (1-map) : map;
+ */
+
+ MErrval += ( RItype + oldmap );
+
+ if ( MErrval & 1 ) { /* negative */
+ Errval = oldmap - (MErrval+1)/2;
+ absErrval = -Errval-RItype;
+ B[Q]++;
+ }
+ else { /* nonnegative */
+ Errval = MErrval/2;
+ absErrval = Errval-RItype;
+ }
+
+
+ if ( Rb < Ra )
+# ifdef POW2
+ Ix = ( Rb - Errval ) & (alpha-1);
+# else
+ Ix = Rb - Errval;
+# endif
+ else /* includes case a==b */
+# ifdef POW2
+ Ix = ( Rb + Errval ) & (alpha-1);
+# else
+ Ix = Rb + Errval;
+# endif
+
+
+#if !defined(POW2)
+ /* reduce mod alpha, for arbitrary alpha */
+ if (Ix < 0)
+ Ix += alpha;
+ else if (Ix >= alpha)
+ Ix -= alpha;
+#endif
+
+ /* update stats */
+ A[Q] += absErrval;
+ if (N[Q] == reset) {
+ N[Q] >>= 1;
+ A[Q] >>= 1;
+ B[Q] >>= 1;
+ }
+
+ N[Q]++; /* for next pixel */
+
+ return Ix;
+}
+
+
+
+
+
+
+/* For line and plane interleaved mode in LOSSLESS mode */
+
+int lossless_undoscanline( pixel *psl, /* previous scanline */
+ pixel *sl, /* current scanline */
+ int no, int color) /* number of values in it */
+/*** watch it! actual pixels in the scan line are numbered 1 to no .
+ pixels with indices < 1 or > no are dummy "border" pixels */
+{
+ int i, psfix;
+ pixel Ra, Rb, Rc, Rd;
+ int SIGN;
+ int cont;
+
+ psfix = 0;
+
+
+ /**********************************************/
+ /* Do for all pixels in the row in 8-bit mode */
+ /**********************************************/
+ if (bpp16==FALSE)
+ {
+
+ Rc = psl[0];
+ Rb = psl[1];
+ Ra = sl[0];
+
+ i = 1;
+ do {
+ pixel Px;
+
+ Rd = psl[i + 1];
+
+ /* Quantize the gradient */
+ cont = vLUT[0][Rd - Rb + LUTMAX8] +
+ vLUT[1][Rb - Rc + LUTMAX8] +
+ vLUT[2][Rc - Ra + LUTMAX8];
+
+ if ( cont == 0 )
+ {
+ /*********** RUN STATE **********/
+
+ register int n, m;
+
+ /* get length of the run */
+ /* arg is # of pixels left */
+ m = n = process_run_dec(no-i+1, color);
+
+ if ( m > 0 ) { /* run of nonzero length, otherwise
+ we go directly to the end-of-run
+ state */
+ do {
+ sl[i++] = Ra;
+ } while(--n > 0);
+
+ if (i > no)
+ /* end of line */
+ return 0;
+
+ /* update context pixels */
+ Rb = psl[i];
+ Rd = psl[i + 1];
+ }
+
+ /* Do end of run encoding for LOSSLESS images */
+ Ra = lossless_end_of_run_d(Ra, Rb, (Ra==Rb));
+
+ } /* Run state block */
+ else
+ {
+ /************ REGULAR CONTEXT **********/
+
+ predict(Rb, Ra, Rc);
+
+ /* map symmetric contexts */
+ cont = classmap[cont];
+
+ if (cont < 0)
+ {
+ SIGN = -1;
+ cont = -cont;
+ }
+ else
+ SIGN = +1;
+
+ /* decode a Rice code of a given context */
+ Ra = lossless_regular_mode_d(cont, SIGN, Px);
+
+ }
+
+ sl[i] = Ra;
+ Rc = Rb;
+ Rb = Rd;
+ ++i;
+
+ } while (i <= no);
+
+ }
+ else
+ /***********************************************/
+ /* Do for all pixels in the row in 16-bit mode */
+ /***********************************************/
+ {
+
+ Rc = ENDIAN16(psl[0]);
+ Rb = ENDIAN16(psl[1]);
+ Ra = ENDIAN16(sl[0]);
+
+ i = 1;
+ do {
+
+ pixel Px;
+
+ Rd = ENDIAN16(psl[i + 1]);
+
+ /* Quantize the gradient */
+ {
+ register int diff;
+
+ /* Following segment assumes that T3 <= LUTMAX16 */
+ /* This condition should have been checked when the
+ lookup tables were built */
+ diff = Rd - Rb;
+ if (diff < 0)
+ cont = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
+ else
+ cont = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
+
+ diff = Rb - Rc;
+ if (diff < 0)
+ cont += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
+ else
+ cont += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
+
+ diff = Rc - Ra;
+ if (diff < 0)
+ cont += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
+ else
+ cont += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
+ }
+
+ if ( cont == 0 ) {
+
+ /********** RUN STATE **********/
+
+ register int n, m;
+
+ /* get length of the run */
+ /* arg is # of pixels left */
+ m = n = process_run_dec(no-i+1, color);
+
+ if ( m > 0 ) { /* run of nonzero length, otherwise
+ we go directly to the end-of-run
+ state */
+ do {
+ sl[i++] = ENDIAN16(Ra);
+ } while(--n > 0);
+
+ if (i > no)
+ /* end of line */
+ return 0;
+
+ /* update context pixels */
+ Rb = ENDIAN16(psl[i]);
+ Rd = ENDIAN16(psl[i + 1]);
+ }
+
+
+ /* Do end of run encoding for LOSSLESS images */
+ Ra = lossless_end_of_run_d(Ra, Rb, (Ra==Rb));
+
+ }
+ else
+ {
+ /********** REGULAR CONTEXT **********/
+
+ predict(Rb, Ra, Rc);
+
+ /* map symmetric contexts */
+ cont = classmap[cont];
+
+ if (cont < 0)
+ {
+ SIGN = -1;
+ cont = -cont;
+ }
+ else
+ SIGN = +1;
+
+ /* decode a Rice code of a given context */
+ Ra = lossless_regular_mode_d(cont, SIGN, Px);
+
+ }
+
+ sl[i] = ENDIAN16(Ra);
+ Rc = Rb;
+ Rb = Rd;
+ ++i;
+
+ } while (i <= no);
+
+ } /* End "if 8/16 bit" */
+
+ return 0;
+}
+
+
+
+
+
+
+
+/* For DEOCODING pixel interleavde mode for LOSSLESS images */
+
+int lossless_undoscanline_pixel(pixel *psl, /* previous scanline */
+ pixel *sl, /* current scanline */
+ int no) /* number of values in it */
+/*** watch it! actual pixels in the scan line are numbered 1 to no .
+ pixels with indices < 1 or > no are dummy "border" pixels */
+{
+ int i, psfix, n_c, color, enter_run=0, break_run, was_in_run = 0,
+ test_run;
+ pixel Ra, Rb, Rc, Rd;
+ pixel c_aa[MAX_COMPONENTS],
+ c_bb[MAX_COMPONENTS],
+ c_cc[MAX_COMPONENTS],
+ c_dd[MAX_COMPONENTS],
+ c_xx[MAX_COMPONENTS];
+
+
+ int SIGN;
+ int cont,c_cont[MAX_COMPONENTS];
+
+ psfix = 0;
+
+ /**********************************************/
+ /* Do for all pixels in the row in 8-bit mode */
+ /**********************************************/
+ if (bpp16==FALSE)
+ {
+
+ for (n_c=0; n_c<components; n_c++) {
+ c_cc[n_c] = psl[n_c];
+ c_bb[n_c] = psl[components+n_c];
+ c_aa[n_c] = sl[n_c];
+ }
+
+ i = components;
+ color = -1;
+
+ do {
+ pixel Px;
+
+ if (!was_in_run) color = (color+1)%components;
+ else color = 0;
+
+ if (color == 0)
+
+ for (n_c=0;n_c<components;n_c++) {
+ c_dd[n_c] = psl[i + components + n_c];
+
+ /* Quantize the gradient */
+ c_cont[n_c] = vLUT[0][c_dd[n_c] - c_bb[n_c] + LUTMAX8] +
+ vLUT[1][c_bb[n_c] - c_cc[n_c] + LUTMAX8] +
+ vLUT[2][c_cc[n_c] - c_aa[n_c] + LUTMAX8];
+ }
+
+ Ra=c_aa[color];
+ Rb=c_bb[color];
+ Rc=c_cc[color];
+ Rd=c_dd[color];
+ cont=c_cont[color];
+
+ enter_run = was_in_run = test_run = 0;
+
+ if (color == 0) {
+ test_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (c_cont[n_c]!=0) {
+ test_run=0;
+ break;
+ }
+ }
+
+ if ( test_run ) {
+
+ /********** RUN STATE *********/
+
+ register int n, m;
+
+ enter_run = was_in_run = 1;
+
+ /* get length of the run */
+ /* arg is # of pixels left */
+ m = n = process_run_dec((no+components-1-i+1)/components, 0);
+
+ if ( m > 0 ) { /* run of nonzero length, otherwise
+ we go directly to the end-of-run
+ state */
+ do {
+ for (n_c=0;n_c<components;n_c++) {
+ sl[i++] = c_aa[n_c];
+ }
+ } while(--n > 0);
+
+ if (i > no+components-1)
+ /* end of line */
+ return 0;
+
+ /* update context pixels */
+ for (n_c=0;n_c<components;n_c++) {
+ c_bb[n_c] = psl[i+n_c];
+ c_dd[n_c] = psl[i+components+n_c];
+ }
+ }
+
+ /* here we handle the "end-of-run" stat */
+
+ for (n_c=0;n_c<components;n_c++) {
+ /* The end of run is processed for each component */
+ Ra = c_aa[n_c];
+ Rb = c_bb[n_c];
+ c_aa[n_c] = c_xx[n_c] = lossless_end_of_run_d(Ra, Rb, 0);
+ } /* Components loop */
+
+ } /* Run state block */
+ else {
+
+ /******* REGULAR CONTEXT *******/
+
+ predict(Rb, Ra, Rc);
+
+ cont = classmap[cont];
+ if (cont < 0)
+ {
+ SIGN = -1;
+ cont = -cont;
+ }
+ else
+ SIGN = +1;
+
+ /* decode a Rice code of a given context */
+ c_aa[color] = Ra = lossless_regular_mode_d(cont, SIGN, Px);
+ }
+
+ if (!was_in_run) {
+ sl[i] = Ra;
+ c_cc[color] = Rb;
+ c_bb[color] = Rd;
+ i++;
+ }
+ else {
+ for (n_c=0;n_c<components;n_c++) {
+ sl[i+n_c] = c_aa[n_c];
+ c_cc[n_c] = c_bb[n_c];
+ c_bb[n_c] = c_dd[n_c];
+ }
+ i+=components;
+ }
+
+ } while (i <= (no+components-1));
+
+ }
+ else
+ /***********************************************/
+ /* Do for all pixels in the row in 16-bit mode */
+ /***********************************************/
+ {
+
+ for (n_c=0; n_c<components; n_c++) {
+ c_cc[n_c] = ENDIAN16(psl[n_c]);
+ c_bb[n_c] = ENDIAN16(psl[components+n_c]);
+ c_aa[n_c] = ENDIAN16(sl[n_c]);
+ }
+
+ i = components;
+ color = -1;
+
+ do {
+ pixel Px;
+
+ if (!was_in_run) color = (color+1)%components;
+ else color = 0;
+
+ if (color == 0)
+ for (n_c=0;n_c<components;n_c++) {
+
+ c_dd[n_c] = ENDIAN16(psl[i + components + n_c]);
+
+ /* Quantize the gradient */
+ {
+ register int diff;
+
+ /* Following segment assumes that T3 <= LUTMAX16 */
+ /* This condition should have been checked when the
+ lookup tables were built */
+ diff = c_dd[n_c] - c_bb[n_c];
+ if (diff < 0)
+ c_cont[n_c] = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
+ else
+ c_cont[n_c] = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
+
+ diff = c_bb[n_c] - c_cc[n_c];
+ if (diff < 0)
+ c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
+ else
+ c_cont[n_c] += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
+
+ diff = c_cc[n_c] - c_aa[n_c];
+ if (diff < 0)
+ c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
+ else
+ c_cont[n_c] += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
+ }
+ }
+
+ Ra=c_aa[color];
+ Rb=c_bb[color];
+ Rc=c_cc[color];
+ Rd=c_dd[color];
+ cont=c_cont[color];
+
+ enter_run = was_in_run = test_run = 0;
+
+ if (color == 0) {
+ test_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (c_cont[n_c]!=0) {
+ test_run=0;
+ break;
+ }
+ }
+
+ if ( test_run ) {
+
+ /********* RUN STATE *********/
+
+ register int n, m;
+
+ enter_run = was_in_run = 1;
+
+ /* get length of the run */
+ /* arg is # of pixels left */
+ m = n = process_run_dec((no+components-1-i+1)/components, 0);
+
+ if ( m > 0 ) { /* run of nonzero length, otherwise
+ we go directly to the end-of-run
+ state */
+ do {
+ for (n_c=0;n_c<components;n_c++) {
+ sl[i++] = ENDIAN16(c_aa[n_c]);
+ }
+ } while(--n > 0);
+
+ if (i > no+components-1)
+ /* end of line */
+ return 0;
+
+ /* update context pixels */
+ for (n_c=0;n_c<components;n_c++) {
+ c_bb[n_c] = ENDIAN16(psl[i+n_c]);
+ c_dd[n_c] = ENDIAN16(psl[i+components+n_c]);
+ }
+ }
+
+ /* here we handle the "end-of-run" state */
+ for (n_c=0;n_c<components;n_c++) {
+ /* The end of run is processed for each component */
+ Ra = c_aa[n_c];
+ Rb = c_bb[n_c];
+
+ c_aa[n_c] = c_xx[n_c] = lossless_end_of_run_d(Ra, Rb, 0);
+ } /* Components loop */
+
+ } /* Run state block */
+ else {
+
+ /******** REGULAR CONTEXT ********/
+
+ predict(Rb, Ra, Rc);
+
+ cont = classmap[cont];
+
+ if (cont < 0)
+ {
+ SIGN = -1;
+ cont = -cont;
+ }
+ else
+ SIGN = +1;
+
+ /* decode a Rice code of a given context */
+ c_aa[color] = Ra = lossless_regular_mode_d(cont, SIGN, Px);
+
+ }
+
+ if (!was_in_run) {
+ sl[i] = ENDIAN16(Ra);
+ c_cc[color] = Rb;
+ c_bb[color] = Rd;
+ i++;
+ }
+ else {
+ for (n_c=0;n_c<components;n_c++) {
+ sl[i+n_c] = ENDIAN16(c_aa[n_c]);
+ c_cc[n_c] = c_bb[n_c];
+ c_bb[n_c] = c_dd[n_c];
+ }
+ i+=components;
+ }
+
+ } while (i <= (no+components-1));
+
+ } /* ends "if 8/16 bit */
+
+ return 0;
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* lossy_d.c --- the main pipeline which processes a scanline by doing
+ * prediction, context computation, context quantization,
+ * and statistics gathering. (for LOSSY images)
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include "global.h"
+#include "bitio.h"
+
+#include <stdio.h>
+#include <math.h>
+
+static int eor_limit;
+
+/* Do Golomb-Rice statistics and DECODING for LOSSY images*/
+inline int lossy_regular_mode_d(int Q, int SIGN, int Px)
+{
+ int At, Bt, Nt, Errval, absErrval;
+ int current, k;
+
+ /* This function is called only for regular contexts.
+ End_of_run context is treated separately */
+
+ Nt = N[Q];
+ At = A[Q];
+ /* Estimate k */
+ {
+ register nst = Nt;
+ for(k=0; nst < At; nst *=2, k++);
+ }
+
+ /* Get the number of leading zeros */
+ absErrval = 0;
+ do {
+ int temp;
+
+ temp = zeroLUT[reg >> 24];
+ absErrval += temp;
+ if (temp != 8) {
+ FILLBUFFER(temp + 1);
+ break;
+ }
+ FILLBUFFER(8);
+ } while (1);
+
+ if ( absErrval < limit ) {
+ /* now add the binary part of the Rice code */
+ if (k) {
+ register unsigned long temp;
+ absErrval <<= k;
+ GETBITS(temp,k);
+ absErrval += temp;
+ }
+ }
+ else {
+ /* the original unary would have been too long:
+ (mapped value)-1 was sent verbatim */
+ GETBITS(absErrval, qbpp);
+ absErrval ++;
+ }
+
+ /* Do the Rice mapping */
+ if ( absErrval & 1 ) { /* negative */
+ absErrval = (absErrval + 1) / 2;
+ Errval = -absErrval;
+ } else {
+ absErrval /= 2;
+ Errval = absErrval;
+ }
+
+ Bt = B[Q];
+
+ /* if ( k==0 && (2*Bt <= -qmul[Nt]) ) */
+ if ( k==0 && NEAR==0 && (2*Bt <= -Nt) )
+ {
+ /* special case: see encoder side */
+ Errval = -(Errval+1);
+ absErrval = (Errval<0)?(-Errval):Errval;
+ }
+
+ Errval = qmul[Errval]; /* dequantize prediction error */
+
+ /* center, clip if necessary, and mask final error */
+ if ( SIGN == -1 ) {
+ Px -= C[Q];
+ clip(Px, alpha);
+ current = Px - Errval;
+ }
+ else {
+ Px += C[Q];
+ clip(Px,alpha);
+ current = Px + Errval;
+ }
+
+ /* first, we reduce mod beta in the range -NEAR <= x <= alpha-1+NEAR,
+ then we clip to [0,alpha] */
+ if (current < negNEAR)
+ current += beta;
+ else if (current > alpha1eps)
+ current -= beta;
+
+ clip(current,alpha);
+
+ /* update bias stats */
+ B[Q] = (Bt += Errval);
+
+ /* update Golomb-Rice stats */
+ A[Q] += absErrval;
+
+ /* check reset (joint for Rice-Golomb and bias cancelation) */
+ if(Nt == reset) {
+ N[Q] = (Nt >>= 1);
+ A[Q] >>= 1;
+ B[Q] = (Bt >>= 1);
+ }
+
+ /* Do bias estimation for NEXT pixel */
+ N[Q] = (++Nt);
+ if ( Bt <= -Nt ) {
+
+ if (C[Q] > MIN_C)
+ --C[Q];
+
+ Bt = (B[Q] += Nt);
+
+ if ( Bt <= -Nt )
+ B[Q] = -Nt+1;
+
+ } else if ( Bt > 0 ) {
+
+ if (C[Q] < MAX_C)
+ ++C[Q];
+
+ Bt = (B[Q] -= Nt);
+
+ if ( Bt > 0 )
+ B[Q] = 0;
+ }
+
+ return current;
+}
+
+
+
+
+
+
+/* Do end of run DECODING for LOSSY images */
+inline pixel lossy_end_of_run_d(pixel Ra, pixel Rb, int RItype)
+{
+ int xpr,
+ Ix,
+ Errval,
+ absErrval,
+ MErrval,
+ k,
+ Q,
+ oldmap,
+ Nt,
+ At;
+
+ Q = EOR_0 + RItype;
+ Nt = N[Q],
+ At = A[Q];
+
+ if ( RItype )
+ At += Nt/2;
+
+ /* Estimate k */
+ for(k=0; Nt < At; Nt *=2, k++);
+
+ /* read and decode the Golomb code */
+ /* Get the number of leading zeros */
+ MErrval = 0;
+ do {
+ int temp;
+
+ temp = zeroLUT[reg >> 24];
+ MErrval += temp;
+ if (temp != 8) {
+ FILLBUFFER(temp + 1);
+ break;
+ }
+ FILLBUFFER(8);
+ } while (1);
+
+ eor_limit = limit - limit_reduce;
+
+ if ( MErrval < eor_limit ) {
+ /* now add the binary part of the Golomb code */
+ if (k) {
+ register unsigned long temp;
+ MErrval <<= k;
+ GETBITS(temp,k);
+ MErrval += temp;
+ }
+ }
+ else {
+ /* the original unary would have been too long:
+ (mapped value)-1 was sent verbatim */
+ GETBITS(MErrval, qbpp);
+ MErrval ++;
+ }
+
+ oldmap = ( k==0 && (RItype||MErrval) && (2*B[Q]<Nt));
+ /*
+ Note: the Boolean variable 'oldmap' is not
+ identical to the variable 'map' in the
+ JPEG-LS draft. We have
+ oldmap = (qdiff<0) ? (1-map) : map;
+ */
+
+ MErrval += ( RItype + oldmap );
+
+ if ( MErrval & 1 ) { /* negative */
+ Errval = oldmap - (MErrval+1)/2;
+ absErrval = -Errval-RItype;
+ B[Q]++;
+ }
+ else { /* nonnegative */
+ Errval = MErrval/2;
+ absErrval = Errval-RItype;
+ }
+
+ Errval = qmul[Errval]; /* de-quantize prediction error */
+ if ( RItype ) {
+ Ix = Ra + Errval;
+ }
+ else {
+ if ( Rb < Ra )
+ Ix = Rb - Errval;
+ else
+ Ix = Rb + Errval;
+ }
+
+ if ( Ix < negNEAR )
+ Ix += beta;
+ else if ( Ix > alpha1eps )
+ Ix -= beta;
+
+ clip(Ix,alpha);
+
+ /* update stats */
+ A[Q] += absErrval;
+ if (N[Q] == reset) {
+ N[Q] >>= 1;
+ A[Q] >>= 1;
+ B[Q] >>= 1;
+ }
+
+ N[Q]++; /* for next pixel */
+
+ return Ix;
+
+}
+
+
+
+
+
+/* For DECODING line and plane interleaved mode for LOSSY images*/
+int lossy_undoscanline( pixel *psl, /* previous scanline */
+ pixel *sl, /* current scanline */
+ int no, int color) /* number of values in it */
+/*** watch it! actual pixels in the scan line are numbered 1 to no .
+ pixels with indices < 1 or > no are dummy "border" pixels */
+{
+ int i, psfix;
+ pixel Ra, Rb, Rc, Rd;
+ int SIGN;
+ int cont;
+ int run_int_type;
+
+ psfix = 0;
+
+ /**********************************************/
+ /* Do for all pixels in the row in 8-bit mode */
+ /**********************************************/
+ if (bpp16==FALSE)
+ {
+ Rc = psl[0];
+ Rb = psl[1];
+ Ra = sl[0];
+
+ i = 1;
+
+ do {
+ pixel Px;
+ Rd = psl[i + 1];
+
+ /* Quantize the gradient */
+ cont = vLUT[0][Rd - Rb + LUTMAX8] +
+ vLUT[1][Rb - Rc + LUTMAX8] +
+ vLUT[2][Rc - Ra + LUTMAX8];
+
+ if ( cont == 0 ) {
+
+ /********** RUN STATE *********/
+
+ register int n, m;
+
+ /* get length of the run */
+ /* arg is # of pixels left */
+ m = n= process_run_dec(no-i+1, color);
+
+ if ( m > 0 ) { /* run of nonzero length, otherwise
+ we go directly to the end-of-run
+ state */
+ do {
+ sl[i++] = Ra;
+ } while(--n > 0);
+
+ if (i > no)
+ /* end of line */
+ return 0;
+
+ /* update context pixels */
+ Rb = psl[i];
+ Rd = psl[i + 1];
+ }
+
+ /* here we handle the "end-of-run" state */
+ run_int_type = ( (Rb-Ra) <= NEAR && (Rb-Ra) >= negNEAR);
+ Ra = lossy_end_of_run_d(Ra, Rb, run_int_type);
+ }
+ else {
+
+ /****** REGULAR CONTEXT ******/
+
+ predict(Rb, Ra, Rc);
+
+ /* map symmetric contexts */
+ cont = classmap[cont];
+
+ if (cont < 0)
+ {
+ SIGN = -1;
+ cont = -cont;
+ }
+ else
+ SIGN = +1;
+
+ /* decode a Rice code of a given context */
+ Ra = lossy_regular_mode_d(cont, SIGN, Px);
+ }
+
+ sl[i] = Ra;
+ Rc = Rb;
+ Rb = Rd;
+ ++i;
+
+ } while (i <= no);
+
+ } else
+ /***********************************************/
+ /* Do for all pixels in the row in 16-bit mode */
+ /***********************************************/
+ {
+
+ Rc = ENDIAN16(psl[0]);
+ Rb = ENDIAN16(psl[1]);
+ Ra = ENDIAN16(sl[0]);
+ i = 1;
+
+ do {
+ pixel Px;
+
+ Rd = ENDIAN16(psl[i + 1]);
+
+ /* Quantize the gradient */
+ {
+ register int diff;
+
+ /* Following segment assumes that T3 <= LUTMAX16 */
+ /* This condition should have been checked when the
+ lookup tables were built */
+ diff = Rd - Rb;
+ if (diff < 0)
+ cont = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
+ else
+ cont = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
+
+ diff = Rb - Rc;
+ if (diff < 0)
+ cont += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
+ else
+ cont += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
+
+ diff = Rc - Ra;
+ if (diff < 0)
+ cont += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
+ else
+ cont += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
+ }
+
+ if ( cont == 0 ) {
+
+ /********* RUN STATE *********/
+
+ register int n, m;
+
+ /* get length of the run */
+ /* arg is # of pixels left */
+ m = n = process_run_dec(no-i+1, color);
+
+ if ( m > 0 ) { /* run of nonzero length, otherwise
+ we go directly to the end-of-run
+ state */
+ do {
+ sl[i++] = ENDIAN16(Ra);
+ } while(--n > 0);
+
+ if (i > no)
+ /* end of line */
+ return 0;
+
+ /* update context pixels */
+ Rb = ENDIAN16(psl[i]);
+ Rd = ENDIAN16(psl[i + 1]);
+ }
+
+ /* here we handle the "end-of-run" state, which is
+ treated separately from regular states */
+ run_int_type = ( (Rb-Ra) <= NEAR && (Rb-Ra) >= negNEAR);
+ Ra = lossy_end_of_run_d(Ra, Rb, run_int_type);
+
+ }
+ else {
+
+ /******REGULAR CONTEXT ******/
+
+ predict(Rb, Ra, Rc);
+
+ /* map symmetric contexts */
+ cont = classmap[cont];
+
+ if (cont < 0)
+ {
+ SIGN = -1;
+ cont = -cont;
+ }
+ else
+ SIGN = +1;
+
+ /* decode a Rice code of a given context */
+ Ra = lossy_regular_mode_d(cont, SIGN, Px);
+ }
+
+ sl[i] = ENDIAN16(Ra);
+ Rc = Rb;
+ Rb = Rd;
+ ++i;
+
+ } while (i <= no);
+
+ } /* ends "if 8/16 bit" */
+
+ return 0;
+}
+
+
+
+
+
+
+
+/* For DECODING pixel interleaved mode in LOSSY mode */
+int lossy_undoscanline_pixel( pixel *psl, /* previous scanline */
+ pixel *sl, /* current scanline */
+ int no) /* number of values in it */
+/*** watch it! actual pixels in the scan line are numbered 1 to no .
+ pixels with indices < 1 or > no are dummy "border" pixels */
+{
+ int i, psfix, n_c, color, enter_run=0, break_run, was_in_run = 0,
+ test_run;
+ pixel Ra, Rb, Rc, Rd;
+ pixel c_aa[MAX_COMPONENTS],
+ c_bb[MAX_COMPONENTS],
+ c_cc[MAX_COMPONENTS],
+ c_dd[MAX_COMPONENTS],
+ c_xx[MAX_COMPONENTS];
+ int SIGN;
+ int cont,c_cont[MAX_COMPONENTS];
+
+ psfix = 0;
+
+
+ /**********************************************/
+ /* Do for all pixels in the row in 8-bit mode */
+ /**********************************************/
+ if (bpp16==FALSE)
+ {
+
+ for (n_c=0; n_c<components; n_c++) {
+ c_cc[n_c] = psl[n_c];
+ c_bb[n_c] = psl[components+n_c];
+ c_aa[n_c] = sl[n_c];
+ }
+
+ i = components;
+ color = -1;
+
+ do {
+ pixel Px;
+
+ if (!was_in_run) color = (color+1)%components;
+ else color = 0;
+
+ if (color == 0)
+ for (n_c=0;n_c<components;n_c++) {
+
+ c_dd[n_c] = psl[i + components + n_c];
+
+ /* Quantize the gradient */
+ c_cont[n_c] = vLUT[0][c_dd[n_c] - c_bb[n_c] + LUTMAX8] +
+ vLUT[1][c_bb[n_c] - c_cc[n_c] + LUTMAX8] +
+ vLUT[2][c_cc[n_c] - c_aa[n_c] + LUTMAX8];
+ }
+
+ Ra=c_aa[color];
+ Rb=c_bb[color];
+ Rc=c_cc[color];
+ Rd=c_dd[color];
+ cont=c_cont[color];
+
+ enter_run = was_in_run = test_run = 0;
+
+ if (color == 0) {
+ test_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (c_cont[n_c]!=0) {
+ test_run=0;
+ break;
+ }
+ }
+
+ if ( test_run ) {
+
+ /********* RUN STATE *********/
+
+ register int n, m;
+
+ enter_run = was_in_run = 1;
+
+ /* get length of the run */
+ /* arg is # of pixels left */
+ m = n = process_run_dec((no+components-1-i+1)/components, 0);
+
+ if ( m > 0 ) { /* run of nonzero length, otherwise
+ we go directly to the end-of-run
+ state */
+ do {
+ for (n_c=0;n_c<components;n_c++) {
+ sl[i++] = c_aa[n_c];
+ }
+ } while(--n > 0);
+
+ if (i > no+components-1)
+ /* end of line */
+ return 0;
+
+ /* update context pixels */
+ for (n_c=0;n_c<components;n_c++) {
+ c_bb[n_c] = psl[i+n_c];
+ c_dd[n_c] = psl[i+components+n_c];
+ }
+ }
+
+ /* here we handle the "end-of-run" state */
+ for (n_c=0;n_c<components;n_c++) {
+ /* The end of run is processed for each component */
+ Ra = c_aa[n_c];
+ Rb = c_bb[n_c];
+
+ c_aa[n_c] = c_xx[n_c] = lossy_end_of_run_d(Ra, Rb, 0);
+
+ } /* Components loop */
+ }
+ else {
+
+ /****** REGULAR CONTEXT *******/
+
+ predict(Rb, Ra, Rc);
+
+ cont = classmap[cont];
+
+ if (cont < 0)
+ {
+ SIGN = -1;
+ cont = -cont;
+ }
+ else
+ SIGN = +1;
+
+ /* decode a Rice code of a given context */
+ c_aa[color] = Ra = lossy_regular_mode_d(cont, SIGN, Px);
+
+ }
+
+ if (!was_in_run) {
+ sl[i] = Ra;
+ c_cc[color] = Rb;
+ c_bb[color] = Rd;
+ i++;
+ }
+ else {
+ for (n_c=0;n_c<components;n_c++) {
+ sl[i+n_c] = c_aa[n_c];
+ c_cc[n_c] = c_bb[n_c];
+ c_bb[n_c] = c_dd[n_c];
+ }
+ i+=components;
+ }
+
+ } while (i <= (no+components-1));
+
+ } else
+
+ /***********************************************/
+ /* Do for all pixels in the row in 16-bit mode */
+ /***********************************************/
+ {
+
+ for (n_c=0; n_c<components; n_c++) {
+ c_cc[n_c] = ENDIAN16(psl[n_c]);
+ c_bb[n_c] = ENDIAN16(psl[components+n_c]);
+ c_aa[n_c] = ENDIAN16(sl[n_c]);
+ }
+
+ i = components;
+ color = -1;
+
+ do {
+ pixel Px;
+
+ if (!was_in_run) color = (color+1)%components;
+ else color = 0;
+
+ if (color == 0)
+ for (n_c=0;n_c<components;n_c++) {
+
+ c_dd[n_c] = ENDIAN16(psl[i + components + n_c]);
+
+ /* Quantize the gradient */
+ {
+ register int diff;
+
+ /* Following segment assumes that T3 <= LUTMAX16 */
+ /* This condition should have been checked when the
+ lookup tables were built */
+ diff = c_dd[n_c] - c_bb[n_c];
+ if (diff < 0)
+ c_cont[n_c] = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
+ else
+ c_cont[n_c] = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
+
+ diff = c_bb[n_c] - c_cc[n_c];
+ if (diff < 0)
+ c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
+ else
+ c_cont[n_c] += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
+
+ diff = c_cc[n_c] - c_aa[n_c];
+ if (diff < 0)
+ c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
+ else
+ c_cont[n_c] += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
+ }
+ }
+
+ Ra=c_aa[color];
+ Rb=c_bb[color];
+ Rc=c_cc[color];
+ Rd=c_dd[color];
+ cont=c_cont[color];
+
+ enter_run = was_in_run = test_run = 0;
+
+ if (color == 0) {
+ test_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (c_cont[n_c]!=0) {
+ test_run=0;
+ break;
+ }
+ }
+
+ if ( test_run ) {
+
+ /********* RUN STATE *********/
+
+ register int n, m;
+
+ enter_run = was_in_run = 1;
+
+ /* get length of the run */
+ /* arg is # of pixels left */
+ m = n = process_run_dec((no+components-1-i+1)/components, 0);
+
+ if ( m > 0 ) { /* run of nonzero length, otherwise
+ we go directly to the end-of-run
+ state */
+ do {
+ for (n_c=0;n_c<components;n_c++) {
+ sl[i++] = ENDIAN16(c_aa[n_c]);
+ }
+ } while(--n > 0);
+
+ if (i > no+components-1)
+ /* end of line */
+ return 0;
+
+ /* update context pixels */
+ for (n_c=0;n_c<components;n_c++) {
+ c_bb[n_c] = ENDIAN16(psl[i+n_c]);
+ c_dd[n_c] = ENDIAN16(psl[i+components+n_c]);
+ }
+ }
+
+ /* here we handle the "end-of-run" state */
+ for (n_c=0;n_c<components;n_c++) {
+ /* The end of run is processed for each component */
+ Ra = c_aa[n_c];
+ Rb = c_bb[n_c];
+ c_aa[n_c] = c_xx[n_c] = lossy_end_of_run_d(Ra, Rb, 0);
+ } /* Components loop */
+
+ }
+ else {
+
+ /******* REGULAR CONTEXT *******/
+
+ predict(Rb, Ra, Rc);
+
+ cont = classmap[cont];
+ if (cont < 0)
+ {
+ SIGN = -1;
+ cont = -cont;
+ }
+ else
+ SIGN = +1;
+
+ /* decode a Rice code of a given context */
+ c_aa[color] = Ra = lossy_regular_mode_d(cont, SIGN, Px);
+ }
+
+ if (!was_in_run) {
+ sl[i] = ENDIAN16(Ra);
+ c_cc[color] = Rb;
+ c_bb[color] = Rd;
+ i++;
+ }
+ else {
+ for (n_c=0;n_c<components;n_c++) {
+ sl[i+n_c] = ENDIAN16(c_aa[n_c]);
+ c_cc[n_c] = c_bb[n_c];
+ c_bb[n_c] = c_dd[n_c];
+ }
+ i+=components;
+ }
+
+ } while (i <= (no+components-1));
+
+ } /* for "if 8/16 bit" mode */
+
+ return 0;
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. They may not be sold for profit or incorporated in
+ commercial programs without the written permission of the copyright holder.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1997.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* melcode.c --- for processing in run mode
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <stdio.h>
+#include "global.h"
+#include "bitio.h"
+
+#define MELCSTATES 32 /* number of melcode states */
+
+static J[MELCSTATES] = {
+ 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,5,5,6,6,7,
+ 7,8,9,10,11,12,13,14,15
+};
+
+
+static int melcstate[MAX_COMPONENTS], /* index to the state array */
+ melclen[MAX_COMPONENTS]; /* contents of the state array location
+ indexed by melcstate: the "expected"
+ run length is 2^melclen, shorter runs are
+ encoded by a 1 followed by the run length
+ in binary representation, wit a fixed length
+ of melclen bits */
+
+static unsigned long melcorder[MAX_COMPONENTS]; /* 2^ melclen */
+
+
+void init_process_run(int maxrun) /* maxrun is ignoreed when using MELCODE,
+ kept here for function compatibility */
+{
+ int n_c;
+
+ for (n_c=0;n_c<components;n_c++)
+ {
+ melcstate[n_c] = 0;
+ melclen[n_c] = J[0];
+ melcorder[n_c] = 1<<melclen[n_c];
+ }
+}
+
+
+
+
+/* decoding routine: reads bits from the input and returns a run length. */
+/* argument is the number of pixels left to end-of-line (bound on run length) */
+int process_run_dec(int lineleft, int color)
+{
+ int runlen = 0;
+
+ do {
+ register temp, hits;
+ temp = zeroLUT[(byte)(~(reg >> 24))]; /* number of leading ones in the
+ input stream, up to 8 */
+ for ( hits = 1; hits<=temp; hits++ )
+ {
+ runlen += melcorder[color];
+ if ( runlen >= lineleft )
+ { /* reached end-of-line */
+ if ( runlen==lineleft && melcstate[color] < MELCSTATES )
+ {
+ melclen[color] = J[++melcstate[color]];
+ melcorder[color] = (1L<<melclen[color]);
+ }
+ FILLBUFFER(hits); /* actual # of 1's consumed */
+ return lineleft;
+ }
+ if ( melcstate[color] < MELCSTATES )
+ {
+ melclen[color] = J[++melcstate[color]];
+ melcorder[color] = (1L<<melclen[color]);
+ }
+ }
+ if (temp != 8)
+ {
+ FILLBUFFER(temp + 1); /* consume the leading
+ 0 of the remainder encoding */
+ break;
+ }
+ FILLBUFFER(8);
+ } while ( 1 );
+
+ /* read the length of the remainder */
+ if ( melclen[color] )
+ {
+ register temp;
+ GETBITS(temp, melclen[color]); /*** GETBITS is a macro, not a function */
+ runlen += temp;
+ }
+ limit_reduce = melclen[color]+1;
+
+ /* adjust melcoder parameters */
+ if ( melcstate[color] )
+ {
+ melclen[color] = J[--melcstate[color]];
+ melcorder[color] = (1L<<melclen[color]);
+ }
+
+ return runlen;
+}
+
+
+
+void
+close_process_run()
+{
+/* retained for compatibility with ranked runs */
+}
--- /dev/null
+#CC=cc
+#PKGNAME=loco
+#OPTFLAGS= -Aa $(CFL) -DBIG_ENDIAN
+#
+#CFLAGS = $(OPTFLAGS) $(VFL) $(DFL) -DPGMPREFIX=\"$(PREFIX)\" -DMELCODE -DEXTERNDISTRIB -Dinline="" -DNDEBUG
+#
+#LNKFLAGS = -lm
+
+SET(SRCS
+ global.c
+ jpegmark.c
+ initialize.c
+ encoder.c
+ lossless_e.c
+ lossy_e.c
+ bitio.c
+ melcode.c
+ )
+
+ADD_LIBRARY(gdcmjpegls2 ${SRCS})
+
+#INCL = global.h jpegmark.h bitio.h
+#
+#EOBJS = global.o jpegmark.o initialize.o encoder.o lossless_e.o lossy_e.o bitio.o melcode.o
+#
+#loco:
+# $(MAKE) -$(MAKEFLAGS) VFL="" PREFIX="loco" codec
+#
+#ENCODER = $(PREFIX)e
+#
+#codec: $(ENCODER)
+#
+#jpegmark.o: jpegmark.c jpegmark.h bitio.h global.h
+#
+#global.o: global.h global.c
+#
+#initialize.o: initialize.c bitio.h global.h
+#
+#lossless_e.o: global.h lossless_e.c bitio.h
+#
+#lossy_e.o: global.h lossy_e.c bitio.h
+#
+#encoder.o: encoder.c jpegmark.c global.h
+#
+#bitio.o: bitio.c bitio.h global.h
+#
+#melcode.o: melcode.c bitio.h global.h
+#
+#
+#$(ENCODER): $(EOBJS)
+# $(CC) $(CFLAGS) -o $@ $(EOBJS) $(LNKFLAGS)
+#
+#lint:
+# lint $(SRCS)
+#clean:
+# -rm -f *.o core loco* *.out
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/*
+ * bitio.c --- for I/O routines
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include "global.h"
+#include "bitio.h"
+
+extern FILE *in, *out;
+
+byte negbuff[BUFSIZE+4]; /* byte I/O buffer, allowing for 4 "negative"
+ locations */
+
+ /*
+ 'buff' is defined as 'rawbuff+4' in bitio.h, so that buff[-4]..buff[-1]
+ are well defined. Those locations are used to "return" data to
+ the byte buffer when flushing the input bit buffer .
+ */
+
+int fp; /* index into byte buffer */
+int truebufsize; /* true size of byte buffer ( <= BUFSIZE) */
+int foundeof;
+
+
+/* BIT I/O variables */
+dword reg; /* BIT buffer for input/output */
+int bits; /* number of bits free in bit buffer (on output) */
+ /* (number of bits free)-8 in bit buffer (on input)*/
+
+
+
+/****************************************************************************
+ * OUTPUT ROUTINES
+ * note: some routines are implemented as preprocessor macros. See bitio.h.
+ ****************************************************************************/
+
+void flushbuff(FILE *fil) {
+ /* fwrite must work correctly, even if fp is equal to 0 */
+ fwrite(buff, 1, fp, fil);
+ fp = 0;
+}
+
+
+
+/* Flushes the bit output buffer and the byte output buffer */
+void bitoflush() {
+ register unsigned int outbyte;
+
+ while (bits < 32) {
+ outbyte = reg >> 24;
+ myputc(outbyte, out);
+ if ( outbyte == 0xff ) {
+ bits += 7;
+ reg <<= 7;
+ reg &= ~(1<<(8*sizeof(reg)-1)); /* stuff a 0 at MSB */
+ } else {
+ bits += 8;
+ reg <<= 8;
+ }
+ }
+ flushbuff(out);
+ bitoinit();
+}
+
+
+
+/* Initializes the bit output routines */
+void bitoinit() {
+ bits = 32;
+ reg = 0;
+ fp = 0;
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ OMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* bitio.h --- for I/O routines
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#ifndef BITIO_H
+#define BITIO_H
+
+#include "global.h"
+
+/* BYTE I/O variables */
+#define BUFSIZE ((16*1024)-4) /* Size of input BYTE buffer */
+extern int fp; /* index into byte buffer */
+extern int truebufsize; /* true size of byte buffer ( <= BUFSIZE) */
+extern byte negbuff[]; /* the buffer */
+#define buff (negbuff+4)
+
+
+/* BIT I/O variables */
+extern dword reg; /* BIT buffer for input/output */
+extern int bits; /* number of bits free in bit buffer (on output) */
+ /* (number of bits free)-8 in bit buffer (on input)*/
+#define BITBUFSIZE (8*sizeof(reg))
+
+extern FILE *in, *out;
+
+#define myputc(c, fil) ((fp >= BUFSIZE) ? (flushbuff(fil), buff[fp++] = c) :\
+ (buff[fp++] = c))
+
+extern void flushbuff(FILE *fil);
+
+
+/* Flushes the bit output buffers and closes the output file */
+extern void bitoflush();
+
+
+#define put_zeros(n) \
+{ \
+ bits -= n; \
+ while (bits <= 24) { \
+ if (fp >= BUFSIZE) { \
+ fwrite(buff, 1, fp, out); \
+ fp = 0; \
+ } \
+ buff[fp++] = reg >> 24; \
+ reg <<= 8; \
+ bits += 8; \
+ } \
+}
+
+#define PUT_ZEROS(n) put_zeros(n)
+
+
+#define put_ones(n) \
+{ \
+ if ( n < 24 ) { \
+ putbits((1<<n)-1,n); \
+ } \
+ else { \
+ register unsigned nn = n; \
+ while ( nn >= 24 ) { \
+ putbits((1<<24)-1,24); \
+ nn -= 24; \
+ } \
+ if ( nn ) putbits((1<<nn)-1,nn); \
+ } \
+}
+
+#define PUT_ONES(n) put_ones(n)
+
+
+/*
+ * Put an n-bit number x in the output stream (inline code).
+ * Check for output bytes of the form 0xff and stuff
+ * a 0 bit following each one.
+ */
+
+#define putbits(x, n) \
+{ \
+ assert(n <= 24 && n >= 0 && ((1<<n)>x)); \
+ bits -= n; \
+ reg |= x << bits; \
+ while (bits <= 24) { \
+ register unsigned int outbyte; \
+ if (fp >= BUFSIZE) { \
+ fwrite(buff, 1, fp, out); \
+ fp = 0; \
+ } \
+ outbyte = (buff[fp++] = (reg >> 24) ); \
+ if ( outbyte == 0xff ) { \
+ bits += 7; \
+ reg <<= 7; \
+ /* stuff a 0 at MSB */ \
+ reg &= ~(1<<(8*sizeof(reg)-1)); \
+ } \
+ else { \
+ bits += 8; \
+ reg <<= 8; \
+ } \
+ } \
+}
+
+
+#define PUTBITS(x,n) putbits(x,n)
+
+
+/* Initializes the bit output routines */
+extern void bitoinit();
+
+
+#endif /* BITIO_H */
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* encoder.c --- the main module, argument parsing, file I/O
+ *
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include "global.h"
+#include "math.h"
+#include "string.h"
+#include "jpegmark.h"
+
+static char *banner="\n\
+=============================================\n\
+SPMG/JPEG-LS COMPRESSOR " JPEGLSVERSION "\n\
+=============================================\n\
+These programs are Copyright (c) University of British Columbia.\n\
+All rights reserved. They may be freely redistributed in their\n\
+entirety provided that this copyright notice is not removed.\n\
+They may not be sold for profit or incorporated in commercial\n\
+programs without the written permission of the copyright holder.\n\
+Each program is provided as is, without any express or implied\n\
+warranty, without even the warranty of fitness for a particular\n\
+purpose.\n\
+\n\
+=========================================================\n\
+THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:\n\
+=========================================================\n\
+(c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.\n";
+
+pixel *pscanline, *cscanline, *scanl0, *scanl1;
+pixel *c_pscanline[MAX_COMPONENTS], *c_cscanline[MAX_COMPONENTS],
+ *c_scanl0[MAX_COMPONENTS], *c_scanl1[MAX_COMPONENTS];
+
+jpeg_ls_header *head_frame,*head_scan[MAX_SCANS];
+
+int columns, rows, components,
+ samplingx[MAX_COMPONENTS], samplingy[MAX_COMPONENTS];
+int c_columns[MAX_COMPONENTS];
+int c_rows[MAX_COMPONENTS];
+int whose_max_size_rows, whose_max_size_columns;
+int color_mode;
+int need_lse; /* if we need an LSE marker (non-default params) */
+int need_table; /* if we need an LSE marker (mapping table) */
+int need_restart; /* if we need to add restart markers */
+int restart_interval; /* indicates the restart interval */
+int multi; /* if the files are separate */
+int application_header; /* application bytes written in the header */
+int all_header; /* all bytes of the header, including application
+ bytes and JPEG-LS bytes */
+int shift=0; /* Shift value for sparse images */
+int palete=0; /* for paletized images */
+int lossy; /* Indicates if in lossy mode or not */
+int lutmax; /* lutmax is either 256 or 4501 */
+int bpp16; /* Indicates if 16 bits per pixel mode or not */
+char *mappingtablefilename=NULL; /* Mapping table filename */
+
+/* reset */
+#ifndef FIXRESET
+int RESET;
+#endif
+
+
+/* alphabet size */
+#ifndef FIXALPHA
+int alpha, /* alphabet size */
+ ceil_half_alpha; /* ceil(alpha/2) */
+#endif
+
+#ifdef POW2
+int highmask;
+#endif
+
+
+
+
+/* Read one row of pixel values */
+
+inline void read_one_line(pixel* line, int cols, FILE* infile)
+{
+ unsigned char* line8;
+ int i;
+
+ if (bpp16==FALSE)
+ {
+ line8 = (unsigned char *)safealloc(cols);
+
+ if (fread(line8, 1, cols, infile) != cols)
+ fprintf(stderr,"Input file is truncated");
+
+ for(i=0; i<cols; i++)
+ line[i] = line8[i];
+ free(line8);
+
+ }
+ else
+ {
+ if (fread(line, 2, cols, infile) != cols)
+ fprintf(stderr,"Input file is truncated");
+
+ }
+}
+
+
+
+
+
+/* Initialize the buffers for each line */
+void initbuffers(int multi, int comp) {
+
+ int i;
+
+ if (multi) /* The files are received independent */
+
+ for (i=0;i<comp;i++) {
+ c_scanl0[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
+ c_scanl1[i] = (pixel *)safecalloc((c_columns[i]+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
+
+ c_pscanline[i] = c_scanl0[i] + (LEFTMARGIN-1);
+ c_cscanline[i] = c_scanl1[i] + (LEFTMARGIN-1);
+ }
+
+ else { /* Only 1 file received */
+
+ scanl0 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
+ scanl1 = (pixel *)safecalloc(components*(columns+LEFTMARGIN+RIGHTMARGIN), sizeof(pixel) );
+
+ /* Adjust scan line pointers taking into account the margins,
+ and also the fact that indexing for scan lines starts from 1
+ */
+ pscanline = scanl0 + components*(LEFTMARGIN-1);
+ cscanline = scanl1 + components*(LEFTMARGIN-1);
+ }
+
+ bitoinit();
+}
+
+
+
+
+/* Swap the pointers to the current and previous scanlines */
+
+void swaplines()
+{
+ pixel *temp;
+ temp = pscanline;
+ pscanline = cscanline;
+ cscanline = temp;
+}
+
+
+
+
+/* Swap the pointers to the current and previous scanlines */
+
+void c_swaplines(int i)
+{
+ pixel *temp;
+ temp = c_pscanline[i];
+ c_pscanline[i] = c_cscanline[i];
+ c_cscanline[i] = temp;
+}
+
+
+
+/* close the line buffers */
+int closebuffers(int multi) {
+ int pos,i;
+
+ bitoflush();
+
+ if (multi==0)
+ fclose(in);
+ else
+ for (i=0;i<components;i++)
+ fclose(c_in[i]);
+
+ pos = ftell(out);
+
+ fclose(out);
+
+ free(scanl0);
+ free(scanl1);
+
+ return pos;
+}
+
+
+
+
+/* Initialization Function - Reads in parameters from image and command line */
+
+void initialize(int argc, char *argv[])
+{
+ char *infilename=NULL,
+ *c_infilename[MAX_COMPONENTS],
+ *outfilename = OUTFILE COMPSUFFIX,
+ *color_mode_string;
+ int i, n_c, common_rows, common_alpha,
+ min_size_rows, min_size_columns,
+ temp_reset,
+ alpha0,
+ gotinf = 0,
+ gotoutf = 0;
+
+
+ n_c=0;
+ multi=0;
+ color_mode=DEFAULT_COLOR_MODE;
+ need_lse=0;
+ need_table=0;
+ need_restart=0;
+ restart_interval=0;
+ components=0;
+ T1=T2=T3=0;
+#ifndef FIXRESET
+ RESET=DEFAULT_RESET;
+#endif
+
+ /* Initialize NEAR to zero and loss-less mode */
+ NEAR = DEF_NEAR;
+ lossy = FALSE;
+
+ /* Go through the arguments in command line */
+ for ( i=1; i<argc; i++ )
+ if ( argv[i][0] == '-' ) {
+ switch ( argv[i][1] ) {
+
+ /* Enable use of Restart Markers */
+ case 't':
+ need_restart = 1;
+ if ( sscanf(argv[i]+2,"%d",&restart_interval) != 1 ) {
+ bad_flag(argv[i]);
+ }
+ break;
+
+ /* Enable use of Mapping Tables */
+ case 'm':
+ need_table = 2;
+ mappingtablefilename = argv[i]+2;
+ break;
+
+ /* Reset value */
+ case 'r':
+ if ( sscanf(argv[i]+2,"%d",&temp_reset) != 1 ) {
+ bad_flag(argv[i]);
+ }
+ if ( temp_reset != DEFAULT_RESET ) {
+ need_lse = 1;
+#ifdef FIXRESET
+ fprintf(stderr,"ERROR: This version compiled with fixed RESET = %d, got %d\n",DEFAULT_RESET,temp_reset);
+ exit(10);
+#else
+ RESET = temp_reset;
+#endif
+ }
+ break;
+
+ /* Colour mode */
+ case 'c':
+ if ( sscanf(argv[i]+2,"%d",&color_mode) != 1 ) {
+ bad_flag(argv[i]);
+ }
+ break;
+
+ /* Sparse(?) mode */
+ case 'p':
+ if ( sscanf(argv[i]+2,"%d",&shift) != 1 ) {
+ bad_flag(argv[i]);
+ }
+ if (shift!=0) {
+ fprintf(stderr,"Sorry, sparse mode not implemented (shift=%d).\n",shift);
+ exit(10);
+ }
+ break;
+
+ /* Infile names */
+ case 'i':
+ infilename = c_infilename[components++] = argv[i]+2;
+ gotinf = 1;
+ break;
+
+ /* Outfile names */
+ case 'o':
+ outfilename = argv[i]+2;
+ gotoutf = 1;
+ break;
+
+ /* Verbose level */
+ case 'v':
+ if ( sscanf(argv[i],"-v%d",&verbose) != 1 ) {
+ verbose=2;
+ }
+ break;
+
+ /* Error level - if 0 then means loss-less mode */
+ case 'e':
+ case 'n':
+ if ( sscanf(argv[i]+2,"%d",&NEAR) != 1 ) {
+ bad_flag(argv[i]);
+ }
+ if ( NEAR == 0 )
+ lossy = FALSE;
+ else
+ lossy = TRUE;
+ break;
+
+ /* Threshold Levels */
+ case 's':
+ case 'S':
+ case 'T':
+ need_lse = 1;
+ switch(argv[i][2]) {
+
+ case 'a':
+ if ( sscanf(argv[i]+3,"%d",&T1) != 1 ) {
+ bad_flag(argv[i]);
+ }
+ break;
+
+ case 'b':
+ if ( sscanf(argv[i]+3,"%d",&T2) != 1 ) {
+ bad_flag(argv[i]);
+ }
+ break;
+
+ case 'c':
+ if ( sscanf(argv[i]+3,"%d",&T3) != 1 ) {
+ bad_flag(argv[i]);
+ }
+ break;
+
+ default:
+ bad_flag(argv[i]);
+ break;
+ }
+ break;
+
+ default:
+ usage();
+ exit(0);
+ }
+ }
+ else {
+ infilename = c_infilename[components++] = argv[i];
+ gotinf = 1;
+ }
+
+
+
+ if ( verbose < 1 )
+ verbose = 1; /* at least the banner will show */
+
+ /* check that color mode is valid and pick color mode string */
+ switch ( color_mode ) {
+ case PLANE_INT:
+ color_mode_string = plane_int_string;
+ multi=1;
+ break;
+ case LINE_INT:
+ color_mode_string = line_int_string;
+ if (components>1) multi=1;
+ break;
+ case PIXEL_INT:
+ color_mode_string = pixel_int_string;
+ if (components>1){
+ fprintf(stderr,"ERROR: specified more than 1 input file in pixel interleaved mode\n");
+ exit(10);
+ }
+ break;
+ default:
+ fprintf(stderr,"ERROR: Invalid color mode %d\n",color_mode);
+ usage();
+ exit(10);
+ }
+
+
+ /* Assign file pointers to in files */
+ if ( (infilename == NULL) && (multi==0 || components<1) ) {
+ usage();
+ exit(0);
+ }
+ else {
+ if ( strcmp(infilename,"-") == 0 )
+ in = stdin;
+ else {
+ if (multi==0) {
+ if ( (in=fopen(infilename,"rb")) == NULL ) {
+ perror(infilename);
+ exit(10);
+ }
+ }
+ else {
+ for (i=0;i<components;i++)
+ if ( (c_in[i]=fopen(c_infilename[i],"rb")) == NULL ) {
+ perror(c_infilename[i]);
+ exit(10);
+ }
+ }
+ }
+ }
+
+
+ /* Assigns pointers to out files */
+ if ( outfilename == NULL ) {
+ usage();
+ exit(0);
+ }
+ else {
+ if ( strcmp(outfilename,"-") == 0 ) {
+ out = stdout;
+ msgfile = stderr;
+ }
+ else if ( (out=fopen(outfilename,"wb")) == NULL ) {
+ perror(outfilename);
+ exit(10);
+ }
+ }
+
+ /* Print messages */
+ if ( verbose )
+ fprintf(msgfile,"%s\n",banner);
+
+
+#define LESS_CONTEXTS 1
+
+ if ( verbose>1 )
+ fprintf(msgfile,"Number of contexts (non-run): %d regular + %d EOR = %d\n",CONTEXTS-LESS_CONTEXTS,EOR_CONTEXTS,TOT_CONTEXTS-LESS_CONTEXTS);
+
+ /* Read image headers*/
+ if (multi==0) {
+ if ( read_header_6(in, &columns, &rows, &alpha0, &components) != 0 )
+ error("Could not read image header. Must be PPM or PGM file.\n");
+ /* Single component => PLANE_INT */
+ if ( (color_mode==LINE_INT || color_mode==PIXEL_INT) && components==1) {
+ /*
+ fprintf(msgfile,"Single component received: Color mode changed to PLANE INTERLEAVED\n");
+ */
+ color_mode=PLANE_INT;
+ color_mode_string = plane_int_string;
+ multi=1;
+ c_columns[0]=columns;
+ c_rows[0] = rows;
+ c_in[0]=in;
+ }
+ }
+ else {
+ for (i=0;i<components;i++) {
+ if (read_header_5(c_in[i], &(c_columns[i]), &(c_rows[i]), &alpha0) != 0 )
+ error("ERROR: Could not read image header. Must be PGM file.\n");
+ if (i==0) {
+ common_rows=c_rows[0];
+ common_alpha=alpha0;
+ }
+ else if ((alpha0!=common_alpha)) {
+ fprintf(stderr,"\nERROR: All components must have same maximal value\n");
+ exit(10);
+ }
+ }
+ }
+
+#ifdef FIXALPHA
+ alpha0++;
+ if ( alpha0 != alpha ) {
+ fprintf(stderr, "Sorry, this version has been optimized for alphabet size = %d, got %d\n",alpha,alpha0);
+ exit(10);
+ }
+#else
+ alpha = alpha0+1; /* number read from file header is alpha-1 */
+ ceil_half_alpha = (alpha+1)/2;
+#endif
+
+#ifdef POW2
+ highmask = -alpha;
+/* check that alpha is a power of 2 */
+ for ( alpha0=alpha, i=-1; alpha0; alpha0>>=1, i++);
+ if ( alpha != (1<<i) ) {
+ fprintf(stderr, "Sorry, this version has been optimized for alphabet size = power of 2, got %d\n",alpha);
+ exit(10);
+ }
+#endif
+
+ /* Check for 16 or 8 bit mode */
+ if (alpha <= MAXA16 && alpha > MAXA8)
+ {
+ bpp16 = TRUE;
+ lutmax = LUTMAX16;
+ }
+ else if (alpha <= MAXA8 && alpha >= 1)
+ {
+ bpp16 = FALSE;
+ lutmax = LUTMAX8;
+ }
+ else {
+ fprintf(stderr,"Got alpha = %d\n",alpha);
+ error("Bad value for alpha. Sorry...\n");
+ }
+
+
+ /* print out parameters */
+ if ( verbose ) {
+ if (!multi)
+ fprintf(msgfile,"Input file: %s\nOutput file: %s\n",infilename,outfilename);
+ else {
+ fprintf(msgfile,"Input files: ");
+ for (i=0;i<components;i++)
+ fprintf(msgfile," %s ",c_infilename[i]);
+ fprintf(msgfile,"\nOutput file: %s\n",outfilename);
+ }
+
+ if (!multi)
+ fprintf(msgfile,"Image: cols=%d rows=%d alpha=%d comp=%d mode=%d (%s)",
+ columns, rows, alpha, components,
+ color_mode, color_mode_string);
+ else {
+ fprintf(msgfile,"Image: cols=");
+ for (i=0;i<components;i++)
+ fprintf(msgfile," %d",c_columns[i]);
+ fprintf(msgfile," rows=");
+ for (i=0;i<components;i++)
+ fprintf(msgfile," %d",c_rows[i]);
+ fprintf(msgfile," alpha=%d comp=%d mode=%d (%s)",
+ alpha, components, color_mode,
+ color_mode_string);
+ }
+
+ fprintf(msgfile,"\n");
+ }
+
+
+ /* compute auxiliary parameters for near-lossless (globals) */
+ if (lossy==TRUE) {
+ quant = 2*NEAR+1;
+ qbeta = (alpha + 2*NEAR + quant-1 )/quant;
+ beta = quant*qbeta;
+ ceil_half_qbeta = (qbeta+1)/2;
+ negNEAR = -NEAR;
+ if ( verbose )
+ fprintf(msgfile,"Near-lossless mode: NEAR = %d beta = %d qbeta = %d\n",NEAR,beta,qbeta);
+ }
+
+
+ /* compute bits per sample for input symbols */
+ for ( bpp=1; (1L<<bpp)<alpha; bpp++ );
+
+ /* check if alpha is a power of 2: */
+ if ( alpha != (1<<bpp) )
+ need_lse = 1; /* if not, MAXVAL will be non-default, and
+ we'll need to specify it in an LSE marker */
+
+
+ /* compute bits per sample for unencoded prediction errors */
+ if (lossy==TRUE)
+ for ( qbpp=1; (1L<<qbpp)<qbeta; qbpp++ );
+ else
+ qbpp = bpp;
+
+
+ if ( bpp < 2 ) bpp = 2;
+
+ /* limit for unary part of Golomb code */
+ if ( bpp < 8 )
+ limit = 2*(bpp + 8) - qbpp -1;
+ else
+ limit = 4*bpp - qbpp - 1;
+
+
+ /* check for smallest subsampled file and compute the sampling */
+ if ((components>1) && (multi)) {
+ min_size_columns=c_columns[components-1];
+ min_size_rows=c_rows[components-1];
+ for (i=0;i<components-1;i++) {
+ if (c_columns[i]<min_size_columns)
+ min_size_columns=c_columns[i];
+ if (c_rows[i]<min_size_rows)
+ min_size_rows=c_rows[i];
+ }
+
+ for (i=0;i<components;i++) {
+ samplingx[i]=c_columns[i]/min_size_columns;
+ samplingy[i]=c_rows[i]/min_size_rows;
+ if ((samplingx[i]>4) || ((c_columns[i]%min_size_columns)!=0)) {
+ fprintf(stderr,"\nImage sizes not compatible\n");
+ exit(10);
+ }
+ if ((samplingy[i]>4) || ((c_rows[i]%min_size_rows)!=0)) {
+ fprintf(stderr,"\nImage sizes not compatible\n");
+ exit(10);
+ }
+ }
+
+ min_size_columns=c_columns[0];
+ whose_max_size_columns=0;
+ min_size_rows=c_rows[0];
+ whose_max_size_rows=0;
+
+ for (i=1;i<components;i++) {
+ if (c_columns[i]>min_size_columns) {
+ whose_max_size_columns=i;
+ min_size_columns=c_columns[i];
+ }
+ if (c_rows[i]>min_size_rows) {
+ whose_max_size_rows=i;
+ min_size_rows=c_rows[i];
+ }
+ }
+ }
+ else {
+ for (i=0;i<components;i++) samplingx[i] = samplingy[i] = 1;
+ }
+
+ /* Allocate memory pools. */
+ initbuffers(multi, components);
+}
+
+
+
+
+
+int main (int argc, char *argv[]) {
+
+ int n,n_c,n_r,my_i, number_of_scans, n_s, i;
+ double t0, t1, get_utime();
+ long tot_in = 0,
+ tot_out = 0,
+ pos0, pos1;
+ int temp_columns;
+ int MCUs_counted;
+
+
+ pixel *local_scanl0,*local_scanl1,*local_pscanline,*local_cscanline;
+
+ application_header = all_header = 0;
+
+ /* Parse the parameters, initialize */
+ initialize(argc, argv);
+
+ /* Start timer (must be AFTER initialize()) */
+ t0 = get_utime();
+
+ /* Compute the number of scans */
+ /* Multiple scans only for PLANE_INT in this implementation */
+
+ if (color_mode==PLANE_INT)
+ number_of_scans=components;
+ else
+ number_of_scans = 1;
+
+
+ /* Write the frame header - allocate memory for jpegls header */
+ head_frame = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
+ for (n_s=0;n_s<number_of_scans;n_s++)
+ head_scan[n_s] = (jpeg_ls_header *) safecalloc(1,sizeof(jpeg_ls_header));
+
+ /* Assigns columns/rows to head_frame */
+ if (!multi) {
+ head_frame->columns=columns;
+ head_frame->rows=rows;
+ }
+ else {
+ head_frame->columns=c_columns[whose_max_size_columns];
+ head_frame->rows=c_rows[whose_max_size_rows];
+ }
+
+ head_frame->alp=alpha;
+ head_frame->comp=components;
+
+ /* Assign component id and samplingx/samplingy */
+ for (i=0;i<components;i++) {
+ head_frame->comp_ids[i]=i+1;
+ head_frame->samplingx[i]=samplingx[i];
+ head_frame->samplingy[i]=samplingy[i];
+ }
+
+ head_frame->NEAR=NEAR; /* Not needed, scan information */
+ head_frame->need_lse=need_lse; /* Not needed, for commpletness */
+ head_frame->color_mode=color_mode; /* Not needed, scan information */
+ head_frame->shift=shift; /* Not needed, scan information */
+
+ for (n_s=0;n_s<number_of_scans;n_s++) {
+ head_scan[n_s]->alp = alpha;
+ head_scan[n_s]->NEAR = NEAR;
+ head_scan[n_s]->T1 = T1;
+ head_scan[n_s]->T2 = T2;
+ head_scan[n_s]->T3 = T3;
+ head_scan[n_s]->RES = RESET;
+ head_scan[n_s]->shift = shift;
+ head_scan[n_s]->color_mode = color_mode;
+ }
+
+
+ if (color_mode==PLANE_INT) { /* One plane per scan */
+ for (n_s=0;n_s<number_of_scans;n_s++) {
+ head_scan[n_s]->comp=1;
+ head_scan[n_s]->comp_ids[0]=n_s+1;
+ }
+ }
+ else {
+ for (n_s=0;n_s<number_of_scans;n_s++) {
+ head_scan[n_s]->comp=head_frame->comp;
+ for (n_c=0;n_c<head_frame->comp;n_c++)
+ head_scan[n_s]->comp_ids[n_c]=n_c+1;
+ }
+ }
+
+ /* Write SOI */
+ all_header = write_marker(out, SOI);
+
+ /* Write the frame */
+ all_header += write_jpegls_frame(out, head_frame);
+
+ /* End of frame header writing */
+
+
+ if ((components>1) && (multi==0)) {
+
+ /* Received PPM file, allocate auxiliary buffers */
+
+ local_scanl0 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof(pixel) );
+ local_scanl1 = (pixel *)safecalloc(columns+LEFTMARGIN+RIGHTMARGIN,sizeof(pixel) );
+
+ local_pscanline = local_scanl0 + LEFTMARGIN-1;
+ local_cscanline = local_scanl1 + LEFTMARGIN-1;
+
+ }
+
+
+ /* Go through each scan and process line by line */
+ for (n_s=0;n_s<number_of_scans;n_s++) {
+
+ /* process scans one by one */
+
+ if (n_s==0) {
+ /* The thresholds for the scan. Must re-do per scan is change. */
+ set_thresholds(alpha, NEAR, &T1, &T2, &T3);
+ for (i=0;i<number_of_scans;i++) {
+ head_scan[n_s]->T1=T1;
+ head_scan[n_s]->T2=T2;
+ head_scan[n_s]->T3=T3;
+ }
+
+ /* After the thresholds are set, write LSE marker if we have */
+ /* non-default parameters or if we need a mapping table */
+ if ( need_lse != 0 )
+ all_header += write_jpegls_extmarker(out, head_scan[n_s], LSE_PARAMS, mappingtablefilename);
+ if ( need_table != 0 )
+ all_header += write_jpegls_extmarker(out, head_scan[n_s], LSE_MAPTABLE, mappingtablefilename);
+
+
+ /* If using restart markers, write the DRI header */
+ if ( need_restart != 0 )
+ {
+ head_scan[n_s]->restart_interval = restart_interval;
+ all_header += write_jpegls_restartmarker(out, head_scan[n_s]);
+ }
+
+
+ /* Print out parameters */
+ if (verbose)
+ fprintf(msgfile,"Parameters: T1=%d T2=%d T3=%d RESET=%d limit=%d\n",T1, T2, T3,RESET,limit);
+
+ /* Prepare LUTs for context quantization */
+ /* Must re-do when Thresholds change */
+ prepareLUTs();
+
+ if (lossy==TRUE)
+ /* prepare div/mul tables for near-lossless quantization */
+ prepare_qtables(alpha, NEAR);
+
+ /* Check for errors */
+ check_compatibility(head_frame, head_scan[0],0);
+
+ }
+
+ /* Restart Marker is reset after every scan */
+ MCUs_counted = 0;
+
+ /* Write the scan header */
+ all_header += write_jpegls_scan(out, head_scan[n_s]);
+ pos0 = ftell(out); /* position in output file, after header */
+
+ /* Initializations for each scan */
+ /* Start from 1st image row */
+ n=0;
+
+ /* initialize stats arrays */
+ if (lossy==TRUE)
+ init_stats(qbeta);
+ else
+ init_stats(alpha);
+
+ /* initialize run processing */
+ init_process_run(MAXRUN);
+
+
+ if (color_mode==LINE_INT) { /* line interleaved */
+ if (!multi) { /* Single file received */
+/***********************************************************************/
+/* Line interleaved mode with single file received */
+/***********************************************************************/
+
+ if (lossy==FALSE)
+
+ /* LOSSLESS mode */
+ while (++n <= rows) {
+
+ read_one_line(cscanline + components, components*columns, in);
+
+ tot_in += components*columns;
+
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[-components+n_c] = cscanline[n_c]=pscanline[components+n_c];
+
+ for (n_c=0;n_c<components;n_c++) {
+ if (components > 1) {
+ for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++){
+ local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
+ local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
+ }
+ }
+ else {
+ local_cscanline=cscanline;
+ local_pscanline=pscanline;
+ }
+
+ /* process the lines */
+ lossless_doscanline(local_pscanline, local_cscanline, columns,n_c);
+ }
+
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[components*(columns+1)+n_c]=cscanline[components*columns+n_c];
+
+ /* make the current scanline the previous one */
+ swaplines();
+
+ /* Insert restart markers if enabled */
+ if (need_restart)
+ {
+ /* Insert restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitoflush();
+ write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));
+ }
+ MCUs_counted++;
+ }
+ }
+
+ else
+
+ /* LOSSY mode */
+ while (++n <= rows) {
+
+ read_one_line(cscanline + components, components*columns, in);
+
+ tot_in += components*columns;
+
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[-components+n_c] = cscanline[n_c]=pscanline[components+n_c];
+
+ for (n_c=0;n_c<components;n_c++) {
+ if (components > 1) {
+ for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++){
+ local_cscanline[-1+my_i]=cscanline[-components+my_i*components+n_c];
+ local_pscanline[-1+my_i]=pscanline[-components+my_i*components+n_c];
+ }
+ }
+ else {
+ local_cscanline=cscanline;
+ local_pscanline=pscanline;
+ }
+
+ /* process the lines */
+ lossy_doscanline(local_pscanline, local_cscanline, columns,n_c);
+
+ if (components>1)
+ for (my_i=0;my_i<columns+LEFTMARGIN+RIGHTMARGIN;my_i++)
+ cscanline[-components+my_i*components+n_c]=local_cscanline[-1+my_i];
+ }
+
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[components*(columns+1)+n_c]=cscanline[components*columns+n_c];
+
+ /* make the current scanline the previous one */
+ swaplines();
+
+ /* Insert restart markers if enabled */
+ if (need_restart)
+ {
+ /* Insert restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitoflush();
+ write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));
+ }
+ MCUs_counted++;
+ }
+ }
+
+ }
+ else { /* Multiple files */
+ /* color_mode==LINE_INT and multi==1 */
+
+/***********************************************************************/
+/* Line interleaved mode with multiple files received */
+/***********************************************************************/
+ n++;
+
+ if (lossy==FALSE)
+
+ /* LOSSLESS mode */
+ while (n <= c_rows[whose_max_size_rows]) {
+
+ for (n_c=0;n_c<components;n_c++) {
+ for (n_r=0;n_r<samplingy[n_c];n_r++) {
+
+ read_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_in[n_c]);
+
+ tot_in += c_columns[n_c];
+
+ /* 'extend' the edges */
+ c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
+
+ /* process the lines */
+ lossless_doscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c],n_c);
+
+ /* 'extend' the edges */
+ c_cscanline[n_c][c_columns[n_c]+1]=c_cscanline[n_c][c_columns[n_c]];
+
+ /* make the current scanline the previous one */
+ c_swaplines(n_c);
+ }
+ } /* End of loop for each file */
+
+ n+=samplingy[whose_max_size_rows];
+
+ /* Insert restart markers if enabled */
+ if (need_restart)
+ {
+ /* Insert restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitoflush();
+ write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));
+ }
+ MCUs_counted++;
+ }
+
+ } /* End while of LINE_INT with multiple input files */
+
+ else
+
+ /* LOSSY mode */
+ while (n <= c_rows[whose_max_size_rows]) {
+
+ for (n_c=0;n_c<components;n_c++) {
+ for (n_r=0;n_r<samplingy[n_c];n_r++) {
+
+ read_one_line(c_cscanline[n_c] + 1, c_columns[n_c], c_in[n_c]);
+
+ tot_in += c_columns[n_c];
+
+ /* 'extend' the edges */
+ c_cscanline[n_c][-1]=c_cscanline[n_c][0]=c_pscanline[n_c][1];
+
+ /* process the lines */
+ lossy_doscanline(c_pscanline[n_c], c_cscanline[n_c], c_columns[n_c],n_c);
+
+ /* 'extend' the edges */
+ c_cscanline[n_c][c_columns[n_c]+1]=c_cscanline[n_c][c_columns[n_c]];
+
+ /* make the current scanline the previous one */
+ c_swaplines(n_c);
+ }
+ } /* End of loop for each file */
+
+ n+=samplingy[whose_max_size_rows];
+
+ /* Insert restart markers if enabled */
+ if (need_restart)
+ {
+ /* Insert restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitoflush();
+ write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));
+ }
+ MCUs_counted++;
+ }
+
+ } /* End while of LINE_INT with multiple input files */
+
+ } /* Closes the else, LINE_INT and multi=1 */
+
+ } /* Closes part for color_mode=LINE_INT */
+ else {
+ if (color_mode==PIXEL_INT) {
+/***********************************************************************/
+/* Pixel interleaved mode with single file received */
+/***********************************************************************/
+
+ if (lossy==FALSE)
+
+ /* LOSSLESS mode */
+ while (++n <= rows) {
+
+ read_one_line(cscanline+components, components*columns, in);
+
+ tot_in += components*columns;
+
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
+
+ /* process the lines */
+ lossless_doscanline_pixel(pscanline, cscanline, components*columns);
+
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
+
+ /* make the current scanline the previous one */
+ swaplines();
+
+ /* Insert restart markers if enabled */
+ if (need_restart)
+ {
+ /* Insert restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitoflush();
+ write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));
+ }
+ MCUs_counted++;
+ }
+ }
+
+ else
+
+ /* LOSSY mode */
+ while (++n <= rows) {
+
+ read_one_line(cscanline+components, components*columns, in);
+
+ tot_in += components*columns;
+
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[-components+n_c]=cscanline[n_c]=pscanline[components+n_c];
+
+ /* process the lines */
+ lossy_doscanline_pixel(pscanline, cscanline, components*columns);
+
+ /* 'extend' the edges */
+ for (n_c=0;n_c<components;n_c++)
+ cscanline[components*(columns+1)+n_c] = cscanline[components*columns+n_c];
+
+ /* make the current scanline the previous one */
+ swaplines();
+
+ /* Insert restart markers if enabled */
+ if (need_restart)
+ {
+ /* Insert restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitoflush();
+ write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));
+ }
+ MCUs_counted++;
+ }
+ }
+
+ } /* Closes if PIXEL_INT */
+ else { /* NON PIXEL_INT */
+/***********************************************************************/
+/* Plane interleaved mode */
+/***********************************************************************/
+
+ if (lossy==FALSE)
+
+ /* LOSSLESS mode */
+ while (++n <= c_rows[n_s]) {
+
+ temp_columns = c_columns[n_s];
+
+ read_one_line(c_cscanline[n_s]+1, temp_columns, c_in[n_s]);
+
+ tot_in += temp_columns;
+
+ /* 'extend' the edges */
+ c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
+
+ /* process the lines */
+ lossless_doscanline(c_pscanline[n_s], c_cscanline[n_s], temp_columns, n_s);
+
+ /* 'extend' the edges */
+ c_cscanline[n_s][temp_columns+1] = c_cscanline[n_s][temp_columns];
+
+ /* make the current scanline the previous one */
+ c_swaplines(n_s);
+
+ /* Insert restart markers if enabled */
+ if (need_restart)
+ {
+ /* Insert restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitoflush();
+ write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));
+ }
+ MCUs_counted++;
+ }
+
+ }
+
+ else
+
+ /* LOSSY mode */
+ while (++n <= c_rows[n_s]) {
+
+ temp_columns = c_columns[n_s];
+
+ read_one_line(c_cscanline[n_s]+1, temp_columns, c_in[n_s]);
+
+ tot_in += temp_columns;
+
+ /* 'extend' the edges */
+ c_cscanline[n_s][-1]=c_cscanline[n_s][0]=c_pscanline[n_s][1];
+
+ /* process the lines */
+ lossy_doscanline(c_pscanline[n_s], c_cscanline[n_s], temp_columns,n_s);
+
+ /* 'extend' the edges */
+ c_cscanline[n_s][temp_columns+1] = c_cscanline[n_s][temp_columns];
+
+ /* make the current scanline the previous one */
+ c_swaplines(n_s);
+
+ /* Insert restart markers if enabled */
+ if (need_restart)
+ {
+ /* Insert restart markers only after a restart interval */
+ if ((MCUs_counted % restart_interval) == 0)
+ {
+ bitoflush();
+ write_marker(out, (RSTm + ((MCUs_counted / restart_interval)%8)));
+ }
+ MCUs_counted++;
+ }
+
+ }
+
+ } /* End for each component in PLANE_INT */
+
+ } /* End for non LINE_INT */
+ bitoflush();
+
+ } /* End of loop on scans */
+
+ all_header += write_marker(out, EOI);
+
+ /* Close down */
+ close_process_run();
+ pos1= closebuffers(multi);
+
+ /* total bytes out, including JPEG-LS header, but not
+ application-specific header bytes */
+ /* tot_out = (pos1-all_header)*8; */
+ tot_out = pos1*8;
+
+ t1 = get_utime();
+
+ if (need_table)
+ fprintf(msgfile, "Used the mapping table from file : %s\n",mappingtablefilename);
+
+ if (need_restart)
+ fprintf(msgfile, "Used restart markers with restart interval : %i\n", restart_interval);
+
+ if ( verbose )
+ fprintf(msgfile,"Marker segment bytes: %ld\n",all_header);
+
+ fprintf(msgfile,"Total bits out: %ld Symbols in: %ld %5.3lf bps (%5.3lf : 1)\n",
+ tot_out,
+ tot_in,tot_out/(double)tot_in,
+ (log((double)alpha)/log(2.0))*tot_in/tot_out);
+ fprintf(msgfile,"Time = %1.3lf secs : %1.0lf KSymbols/sec\n",t1-t0,
+ (tot_in)/(1024*(t1-t0)));
+
+ return 0; /* OK! */
+}
+
+
+
+
+/* Message to show how to use program */
+usage()
+{
+ fprintf(stderr,"%s\n",banner);
+ fprintf(stderr,"Usage: %s [flags] infile1 [infile2,infile3,...] [-ooutfile]\n\
+infile1 : Input file: must be in PGM or PPM format\n\
+infile2,...: Additional input files for \"plane interleaved\"\n\
+ or \"line interleaved\" modes. Must be in PGM (P5) format.\n\
+FLAGS :\n\
+-i<infile> : Alternate input specification, use -i- for stdin.\n\
+-o<outfile>: Output specification, use -o- for stdout (default=%s).\n\
+-Ta<num>, -Tb<num>, -Tc<num>: thresholds for context quantization (a.k.a.\n\
+ T1,T2,T3; must have Ta<=Tb<=Tc<=maxs; defaults depend on alphabet\n\
+ size and lossless/near-lossless mode; see standard specification).\n\
+-r<num> : Reset interval for statistics (standard default=%d).\n\
+", "locoe", OUTFILE COMPSUFFIX,DEFAULT_RESET);
+ fprintf(stderr,"\
+-c<num> : Mode for multi-component images (program default=%d):\n\
+ %d:%s %d:%s %d:%s.\n",
+ DEFAULT_COLOR_MODE,
+ PLANE_INT, "plane-interleaved",
+ LINE_INT, "line-interleaved",
+ PIXEL_INT, "sample-interleaved"
+ );
+fprintf(stderr,"\
+-n<error> or\n\
+-e<error> : Max allowed loss per symbol (default = %d).\n",
+DEF_NEAR);
+
+fprintf(stderr,"\
+-m<table> : Use mapping table where <table> is a file in the format:\n\
+ 1st byte of <table> is the Table ID,\n\
+ 2nd byte of <table> is the Width of each table entry (in bytes),\n\
+ 3rd - 6th byte of <table> is the Max Table Index Value specified\n\
+ as an integer (4 bytes),\n\
+ 7th byte and on are the table entries.\n");
+fprintf(stderr,"\
+-t<num> : Use Restart Markers where <num> is the restart interval \n\
+ (ie. number of MCU's between restart markers).\n");
+
+fprintf(stderr,"\
+-h : Print this help.\n");
+ fprintf(stderr,"\
+*** No spaces allowed between a flag and its argument.\n\
+*** Use -Ta,-Tb,-Tc,-r only if you know what you are doing!\n\
+");
+}
+
+
+
+/* Print out message for a bad flag */
+bad_flag(char *s)
+{
+ fprintf(stderr,"Bad flag %s\n",s);
+ usage();
+ exit(10);
+}
+
+
+
+/* Functions that read the PGM header */
+
+#define HEADER_MAXLINE 256
+
+int read_header_6(FILE *fin, int *widthp, int *heightp, int *maxvalp, int *comp)
+{
+ char line[HEADER_MAXLINE];
+ int cols,rows,maxval;
+
+ if ( nextline(line, fin) != 0 )
+ return -10;
+
+ if (strncmp(line,"P5",2)==0) *comp=1;
+ else if (strncmp(line,"P6",2)==0) *comp=3;
+ else if (strncmp(line,"P7",2)==0) *comp=4;
+ else return -1;
+
+ if ( nextline(line, fin) != 0 )
+ return -10;
+
+ if ( sscanf(line,"%d %d",&cols,&rows) != 2 )
+ return -1;
+
+ if ( nextline(line, fin) != 0 )
+ return -10;
+
+ if ( sscanf(line,"%d",&maxval) != 1 )
+ return -1;
+
+ *widthp = cols;
+ *heightp = rows;
+ *maxvalp = maxval;
+
+ return 0;
+}
+
+
+
+int read_header_5(FILE *fin, int *widthp, int *heightp, int *maxvalp)
+{
+ char line[HEADER_MAXLINE];
+ int cols,rows,maxval;
+
+ if ( nextline(line, fin) != 0 )
+ return -10;
+
+ if (strncmp(line,"P5",2)!=0)
+ return -1;
+
+ if ( nextline(line, fin) != 0 )
+ return -10;
+
+ if ( sscanf(line,"%d %d",&cols,&rows) != 2 )
+ return -1;
+
+ if ( nextline(line, fin) != 0 )
+ return -10;
+
+ if ( sscanf(line,"%d",&maxval) != 1 )
+ return -1;
+
+ *widthp = cols;
+ *heightp = rows;
+ *maxvalp = maxval;
+
+ return 0;
+}
+
+
+
+/* Used to read in header lines of PGM/PPM files */
+int nextline(char *line, FILE *fp)
+{
+ char *p;
+
+ do {
+ p = fgets(line, HEADER_MAXLINE, fp);
+ /*
+ if ( p != NULL )
+ fprintf(stderr,"%s",line);
+ */
+
+ } while ( p != NULL && *p == '#' );
+
+ if ( p==NULL )
+ return -1;
+
+ return 0;
+}
+
--- /dev/null
+/* PMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* global.c --- support and portability routines: error handling, safe memory
+ * management, etc.
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995 - ...
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <time.h>
+#include "global.h"
+
+
+
+char *disclaimer =
+"This program is Copyright (c) University of British Columbia.\n\
+All rights reserved. It may be freely redistributed in its\n\
+entirety provided that this copyright notice is not removed.\n\
+It may not be sold for profit or incorporated in commercial programs\n\
+without the written permission of the copyright holder.\n";
+
+
+
+/* I/O files */
+FILE *in, *out;
+FILE *c_in[MAX_COMPONENTS];
+/*FILE *c_out[MAX_COMPONENTS];*/
+FILE *msgfile = stdout;
+
+/* Context quantization thresholds - initially unset */
+int T3 = -1,
+ T2 = -1,
+ T1 = -1,
+ Ta = -1;
+
+
+int verbose = 1; /* verbosity level */
+int nopause = 0; /* whether to pause the legal notice or not */
+int nolegal = 0; /* whether to print the legal notice or not */
+
+
+/* parameters for LOSSY images */
+int
+ quant, /* quantization = 2*NEAR+1 */
+ beta, /* size of extended alphabet */
+ qbeta, /* size of quantized alphabet */
+ ceil_half_qbeta, /* ceil(qbeta/2) */
+ negNEAR, /* -NEAR */
+ alpha1eps; /* alpha-1+NEAR */
+
+int NEAR = DEF_NEAR; /* loss tolerance per symbol, fixed at 0 for lossless */
+int bpp, /* bits per sample */
+ qbpp, /* bits per sample for quantized prediction errors */
+ limit, /* limit for unary part of Golomb code */
+ limit_reduce; /* reduction on above for EOR states */
+
+
+/* define color mode strings */
+char
+ *plane_int_string = "plane by plane",
+ *line_int_string = "line intlv",
+ *pixel_int_string = "sample intlv";
+
+
+/* function to print out error messages */
+void error(char *msg) {
+ fprintf(stderr, msg);
+ exit(-1);
+}
+
+
+/* function to safely call malloc */
+void *safealloc(size_t size) {
+ void *temp;
+
+ temp = malloc(size);
+ if (temp == NULL)
+ error("\nsafealloc: Out of memory. Aborting...\n");
+ return temp;
+}
+
+
+/* function to safely call calloc **/
+void *safecalloc(size_t numels, size_t size) {
+ void *temp;
+
+ temp = calloc(numels, size);
+ if (temp == NULL)
+ error("\nsafecalloc: Out of memory. Aborting...\n");
+ return temp;
+}
+
+
+
+/*
+ * TIMING ROUTINES
+ */
+
+double get_utime()
+{
+ return (double)clock()/CLOCKS_PER_SEC;
+}
+
+
+/* Set thresholds to default unless specified by header: */
+
+set_thresholds(int alfa, int NEAR, int *T1p, int *T2p, int *T3p)
+{
+ int lambda,
+ ilambda = 256/alfa,
+ quant = 2*NEAR+1,
+ T1 = *T1p,
+ T2 = *T2p,
+ T3 = *T3p;
+
+ if (alfa<4096)
+ lambda = (alfa+127)/256;
+ else
+ lambda = (4096+127)/256;
+
+
+
+ if ( T1 <= 0 ) {
+ /* compute lossless default */
+ if ( lambda )
+ T1 = lambda*(BASIC_T1 - 2) + 2;
+ else { /* alphabet < 8 bits */
+ T1 = BASIC_T1/ilambda;
+ if ( T1 < 2 ) T1 = 2;
+ }
+ /* adjust for lossy */
+ T1 += 3*NEAR;
+
+ /* check that the default threshold is in bounds */
+ if ( T1 < NEAR+1 || T1 > (alfa-1) )
+ T1 = NEAR+1; /* eliminates the threshold */
+ }
+ if ( T2 <= 0 ) {
+ /* compute lossless default */
+ if ( lambda )
+ T2 = lambda*(BASIC_T2 - 3) + 3;
+ else {
+ T2 = BASIC_T2/ilambda;
+ if ( T2 < 3 ) T2 = 3;
+ }
+ /* adjust for lossy */
+ T2 += 5*NEAR;
+
+ /* check that the default threshold is in bounds */
+ if ( T2 < T1 || T2 > (alfa-1) )
+ T2 = T1; /* eliminates the threshold */
+ }
+ if ( T3 <= 0 ) {
+ /* compute lossless default */
+ if ( lambda )
+ T3 = lambda*(BASIC_T3 - 4) + 4;
+ else {
+ T3 = BASIC_T3/ilambda;
+ if ( T3 < 4 ) T3 = 4;
+ }
+ /* adjust for lossy */
+ T3 += 7*NEAR;
+
+ /* check that the default threshold is in bounds */
+ if ( T3 < T2 || T3 > (alfa-1) )
+ T3 = T2; /* eliminates the threshold */
+ }
+
+ *T1p = T1;
+ *T2p = T2;
+ *T3p = T3;
+ return 0;
+}
+
+
+
+
+/* We first check compatibility with JPEG-LS, then with this implementation */
+void check_compatibility(jpeg_ls_header *head_frame, jpeg_ls_header *head_scan, int n_s)
+{
+
+ int number_of_scans,i;
+ int maxreset;
+
+ /* Check implemented color modes */
+ if ((head_scan->color_mode>PIXEL_INT)) {
+ fprintf(stderr,"Color mode %d not supported\n",head_scan->color_mode);
+ exit(10);
+ }
+
+ if (head_scan->color_mode==PLANE_INT)
+ number_of_scans=head_frame->comp;
+ else
+ number_of_scans=1;
+
+ /* Test standard compatibility */
+ if (head_frame->columns<=0 || head_frame->rows <=0) {
+ fprintf(stderr,"Image size must be positive for this implementation.\n");
+ exit(10);
+ }
+
+ if (head_frame->alp<4) {
+ fprintf(stderr,"Alphabet size must be >= 4, got %d\n",head_frame->alp);
+ exit(10);
+ }
+
+
+ if (head_scan->T1>head_scan->T2 || head_scan->T2>head_scan->T3 ||
+ head_scan->T1<head_scan->NEAR+1 || head_scan->T3>=head_scan->alp ) {
+ fprintf(stderr,"Bad thresholds: must be %d <= T1 <= T2 <= T3 <= %d\n",
+ head_scan->NEAR+1,head_scan->alp-1);
+ exit(10);
+ }
+
+ if (head_frame->comp>255) {
+ fprintf(stderr,"Too many components (must be less than 255)\n");
+ exit(10);
+ }
+
+ if (head_scan->NEAR>=head_scan->alp) {
+ fprintf(stderr,"Error for near-lossless must be smaller than alphabet (%d), got %d",head_scan->alp,head_scan->NEAR);
+ exit(10);
+ }
+
+ /*
+ if (head_scan->RES < MINRESET || head_scan->RES >= head_scan->alp ) {
+ fprintf(stderr,"Reset parameter must be between %d and %d\n",
+ MINRESET, head_scan->alp-1);
+ exit(10);
+ }
+ */
+
+ maxreset = (head_scan->alp >= 256)? (head_scan->alp-1):255;
+
+ if (head_scan->RES < MINRESET || head_scan->RES > maxreset ) {
+ fprintf(stderr,"Reset parameter must be between %d and %d\n", MINRESET, head_scan->alp-1);
+ exit(10);
+ }
+
+ for (i=0;i<head_frame->comp;i++)
+ if (head_frame->comp_ids[i] != (i+1)) {
+ fprintf(stderr,"Components id in frame not compatible with this implementation.\n");
+ exit(10);
+ }
+
+ if (number_of_scans == 1) {
+
+ if (head_frame->comp != head_scan->comp) {
+ fprintf(stderr,"In this implementation, when single scan, all components must be in the scan.\n");
+ exit(10);
+ }
+
+ for (i=0;i<head_frame->comp;i++)
+ if (head_scan->comp_ids[i] != (i+1)) {
+ fprintf(stderr,"Components id in single scan not compatible with this implementation.\n");
+ exit(10);
+ }
+
+ } else {
+
+ if (head_scan->comp != 1) {
+ fprintf(stderr,"Only 1 component per scan for plane interleaved mode\n");
+ exit(10);
+ }
+
+ if (head_scan->comp_ids[0] != (n_s+1)) {
+ fprintf(stderr,"Components id in multiple scan not compatible with this implementation.\n");
+ exit(10);
+ }
+
+ }
+}
+
+
+/* for writing disclaimer to command line in DOS */
+
+char *ttyfilename = "CON";
+
+#define PAUSE 20
+
+fprint_disclaimer(FILE *fp, int nopause)
+{
+ char *p0, *p1;
+ FILE *ttyf;
+ int i, c;
+
+ nopause = nopause | !isatty(fileno(fp));
+
+ if ( !nopause && (ttyf=fopen(ttyfilename,"r"))==NULL ) {
+ nopause = 1;
+ }
+
+ for ( i=1, p0=disclaimer; ; i++ ) {
+ if ( !(*p0) ) break;
+ if ( !nopause && i%PAUSE==0 ) {
+ fflush(fp);
+ fprintf(stderr, "--- (press RETURN to continue) ---");
+ fflush(stderr);
+ c = getc(ttyf);
+ }
+ for ( p1=p0; (*p1 != '\n') && (*p1 != 0); p1++ );
+ *p1 = 0;
+ fprintf(fp,"%s\n",p0);
+ p0 = p1+1;
+ }
+ fprintf(fp,"\n"); fflush(fp);
+ if ( !nopause) fclose(ttyf);
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* global.h --- prototypes for functions and global variables
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+
+#ifndef GLOBAL_H
+#define GLOBAL_H
+
+#ifndef CLOCKS_PER_SEC
+#define CLOCKS_PER_SEC 10e6
+#endif
+
+/*#define NDEBUG*/
+#define POW2
+/*#define FIXAPLHA*/
+/*#define FIXRESET*/
+
+
+/* TRUE and FALSE values */
+#define TRUE 1
+#define FALSE 0
+
+
+/* Version number */
+#define JPEGLSVERSION "V.2.1"
+
+
+/* Maximal number of components in the implementation*/
+#define MAX_COMPONENTS 6
+#define MAX_SCANS MAX_COMPONENTS
+
+
+/* For 1st component of plane interl. mode */
+#define FIRST 1
+
+
+/* Different colour modes */
+#define PLANE_INT 0
+#define LINE_INT 1
+#define PIXEL_INT 2
+
+#define DEFAULT_COLOR_MODE LINE_INT
+
+extern char *plane_int_string,
+ *line_int_string,
+ *pixel_int_string;
+
+
+#define BIG_ENDIAN 1
+
+typedef struct jpeg_ls {
+
+ int columns, /* The number of columns */
+ rows, /* Number of rows */
+ alp, /* alphabet size (Max+1) , 2 bytes*/
+ comp, /* number of components, 1 byte */
+ NEAR, /* near-lossless error, 1 byte */
+ color_mode, /* indicates the color mode , 1 byte */
+ need_lse, /* Indicates non-default parameters */
+ need_table, /* Indicates use of mapping table */
+ need_restart, /* Indicates use of restart markers */
+ restart_interval, /* The number of MCU's between restart markers */
+ shift, /* for sparse images, 1 byte */
+ T1,T2,T3, /* Thresholds, 2 bytes each */
+ RES, /* reset value for counters, 2 bytes */
+ samplingx[MAX_COMPONENTS], /* col. sampling rates 1 byte each*/
+ samplingy[MAX_COMPONENTS], /* row sampling rates */
+ comp_ids[MAX_COMPONENTS], /* component id's */
+ acc_size, /* 1 byte */
+ adds[MAX_COMPONENTS]; /* size given by acc_size */
+ unsigned int TID, /* Table ID, 1 byte */
+ Wt, /* Width of each table entry, 1 byte */
+ *TABLE[MAX_COMPONENTS]; /* The table(s) for each component */
+
+} jpeg_ls_header;
+
+extern int components;
+extern int sampling[MAX_COMPONENTS];
+
+#define NAME_LENGTH 40
+
+/* Output file names */
+#define OUTFILE "outfile"
+#define COMPSUFFIX ".jls"
+
+
+/* Define max and min macros */
+#ifndef max
+# define max(a,b) (((a)>=(b))?(a):(b))
+# define min(a,b) (((a)<=(b))?(a):(b))
+#endif
+
+
+/****** Constants */
+
+/* margins for scan lines */
+#define LEFTMARGIN 2
+#define RIGHTMARGIN 1
+
+
+extern char *disclaimer;
+
+
+/* alphabet size */
+#define MAXA8 (256)
+#define MAXA16 (65536)
+#define LUTMAX8 (256)
+#define LUTMAX16 (4501)
+
+
+#ifdef FIXALPHA
+# ifndef alpha
+# define alpha 256
+# endif
+# define highmask (-(alpha))
+# ifndef POW2
+# define POW2
+# endif
+# if (alpha!=2) && (alpha!=4) && (alpha!=8) && (alpha!=16) && (alpha!=32) &&\
+ (alpha!=64) && ( alpha!=128) && (alpha!=256) && (alpha!=512) &&\
+ (alpha!=1024) && ( alpha!=2048) && (alpha!=4096) && (alpha!=8192) &&\
+ (alpha!=16384) && ( alpha!=32768) && (alpha!=65536)\
+# error "Fixed alpha must be a power of 2"
+# endif
+# define ceil_half_alpha (alpha/2)
+#else
+extern int alpha; /* alphabet size */
+extern int ceil_half_alpha; /* ceil(alpha/2) */
+extern int highmask; /* for powers of 2, a mask for high bits */
+#endif
+
+
+
+extern int bpp, /* bits per sample */
+ qbpp, /* bits per sample for quantized prediction errors */
+ limit, /* limit for unary part of Golomb code */
+ limit_reduce; /* reduction on above for EOR states */
+
+
+#define DEF_NEAR 0
+
+/* for LOSSY mode */
+extern int quant,
+ beta,
+ qbeta,
+ ceil_half_qbeta,
+ negNEAR,
+ alpha1eps;
+
+/* loss tolerance */
+extern int NEAR;
+
+
+/* Quantization threshold basic defaults */
+/* These are the defaults for LOSSLESS, 8 bpp. Defaults for other
+ cases are derived from these basic values */
+#define BASIC_T1 3
+#define BASIC_T2 7
+#define BASIC_T3 21
+#define BASIC_Ta 5
+
+#define CREGIONS (9) /* quantization regions for d-b, b-c, c-a */
+
+/* run-length treshold */
+#ifndef MAXRUN
+# define MAXRUN (64)
+#endif
+
+#define EOLINE 1
+#define NOEOLINE 0
+
+/* number of different contexts */
+#define CONTEXTS1 (CREGIONS*CREGIONS*CREGIONS)
+
+#define CONTEXTS ((CONTEXTS1+1)/2) /* all regions, with symmetric merging */
+
+
+/* Mandatory for JPEG-LS: */
+#define CLAMP
+#define CLAMPB
+#define CLAMPC
+
+
+#define MAX_C 127
+#define MIN_C -128
+
+
+#define MAXCODE (N_R_L_ERROR)
+
+
+/* Number of end-of-run contexts */
+#define EOR_CONTEXTS 2
+
+
+/* Total number of contexts */
+#define TOT_CONTEXTS (CONTEXTS + EOR_CONTEXTS)
+
+
+/* index of first end-of-run context */
+#define EOR_0 (CONTEXTS)
+
+
+/* index of run state */
+#define RUNSTATE 0
+
+
+
+/*** offsets */
+
+/* The longest code the bit IO can facilitate */
+#define MAXCODELEN 24
+
+/* The stat initialization values */
+#define INITNSTAT 1 /* init value for N[] */
+#define MIN_INITABSTAT 2 /* min init value for A[] */
+#define INITABSLACK 6 /* init value for A is roughly
+ 2^(bpp-INITABSLACK) but not less than above */
+#define INITBIASTAT 0 /* init value for B[] */
+
+/* Limit for unary code */
+#define LIMIT 23
+
+/* reset values */
+#define DEFAULT_RESET 64
+#define MINRESET 3
+
+#ifdef FIXRESET
+# ifndef RESET
+# define RESET DEFAULT_RESET
+# endif
+#else
+extern int RESET;
+#endif
+
+#define reset RESET /* reset threshold */
+
+#define RESRUN 256
+
+
+/****** Type prototypes */
+
+/* Portability types */
+typedef unsigned char byte;
+typedef unsigned short word;
+typedef unsigned long dword;
+
+typedef unsigned short pixel;
+
+
+/****** Global variables prototypes */
+
+extern FILE *in, *out, *msgfile;
+extern FILE *c_in[MAX_COMPONENTS];
+extern FILE *c_out[MAX_COMPONENTS];
+extern int inhandle;
+extern int T1, T2, T3, Ta;
+extern int verbose,
+ nopause,
+ nolegal;
+
+extern int bpp16; /* Indicates if 16 bits per pixel mode or not */
+extern int lossy;
+
+
+/* for look-up-tables */
+extern int alpha;
+extern int vLUT[3][2 * LUTMAX16];
+extern int lutmax;
+extern int classmap[CONTEXTS1];
+extern int *qdiv0, *qdiv, /* quantization table (division via look-up) */
+ *qmul0, *qmul; /* dequantization table */
+
+/* statistics tables */
+extern int N[TOT_CONTEXTS],
+ A[TOT_CONTEXTS],
+ B[TOT_CONTEXTS],
+ C[TOT_CONTEXTS];
+
+
+/*extern byte getk[65][3000];*/
+/*extern int clipPx[510];*/
+
+
+/****** Function prototypes */
+
+/* global.c */
+void error(char *msg);
+void *safealloc(size_t size);
+void *safecalloc(size_t numels, size_t size);
+
+/* lossless.c */
+void lossless_doscanline_pixel(pixel *psl, pixel *sl, int no);
+void lossless_doscanline(pixel *psl, pixel *sl, int no, int color);
+
+/* lossy.c */
+void lossy_doscanline_pixel(pixel *psl, pixel *sl, int no);
+void lossy_doscanline(pixel *psl, pixel *sl, int no, int color);
+
+/* bitio.c */
+void bitoflush();
+void bitoinit();
+void buffinit(FILE *);
+
+/* melcode.c */
+void init_process_run(int);
+void close_process_run();
+int process_run(int,int,int);
+
+
+/* initialize.c */
+void prepareLUTs();
+void prepare_qtables(int, int);
+void init_stats(int);
+
+
+
+#ifdef BIG_ENDIAN
+# define ENDIAN8(x) (x)
+# define ENDIAN16(x) (x)
+#else
+# define ENDIAN8(x) (x&0x000000ff)
+# define ENDIAN16(x) ( ((x>>8)|(x<<8)) & 0x0000ffff)
+#endif
+
+/* ENDIAN function to fix endian of PCs (for 8 bit pixels)
+#define ENDIAN8(x) (x&0x000000ff)*/
+
+
+/* ENDIAN function to fix endian of PCs (for 16 bit pixels)
+#define ENDIAN16(x) ( ((x>>8)|(x<<8)) & 0x0000ffff )*/
+
+
+
+/* clipping macro */
+#ifdef POW2
+# define clip(x,alpha) \
+ if ( x & highmask ) {\
+ if(x < 0) \
+ x = 0;\
+ else \
+ x = alpha - 1;\
+ }
+#else
+# define clip(x,alpha) \
+ if(x < 0) \
+ x = 0; \
+ else if (x >= alpha) \
+ x = alpha - 1;
+#endif /* POW2 */
+
+
+
+/* macro to predict Px */
+#define predict(Rb, Ra, Rc) \
+{ \
+ register pixel minx; \
+ register pixel maxx; \
+ \
+ if (Rb > Ra) { \
+ minx = Ra; \
+ maxx = Rb; \
+ } else { \
+ maxx = Ra; \
+ minx = Rb; \
+ } \
+ if (Rc >= maxx) \
+ Px = minx; \
+ else if (Rc <= minx) \
+ Px = maxx; \
+ else \
+ Px = Ra + Rb - Rc; \
+}
+
+#endif
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* initialize.c --- functions to initialize look up tables
+ * and statistics tables
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "global.h"
+#include "bitio.h"
+
+
+int vLUT[3][2 * LUTMAX16];
+
+/*byte getk[65][3000];*/
+/*int clipPx[510];*/
+
+int classmap[CONTEXTS1];
+
+int *qdiv0, *qdiv, /* quantization table (division via look-up) */
+ *qmul0, *qmul; /* dequantization table */
+
+int N[TOT_CONTEXTS],
+ A[TOT_CONTEXTS],
+ B[TOT_CONTEXTS],
+ C[TOT_CONTEXTS];
+
+
+
+
+
+
+
+/* Setup Look Up Tables for quantized gradient merging */
+void prepareLUTs()
+{
+ int i, j, idx, lmax;
+ byte k;
+
+ lmax = min(alpha,lutmax);
+
+ /* implementation limitation: */
+ if ( T3 > lmax-1 ) {
+ fprintf(stderr,"Sorry, current implementation does not support threshold T3 > %d, got %d\n",lmax-1,T3);
+ exit(10);
+ }
+
+
+ /* Build classification tables (lossless or lossy) */
+
+ if (lossy==FALSE) {
+
+ for (i = -lmax + 1; i < lmax; i++) {
+
+ if ( i <= -T3 ) /* ...... -T3 */
+ idx = 7;
+ else if ( i <= -T2 ) /* -(T3-1) ... -T2 */
+ idx = 5;
+ else if ( i <= -T1 ) /* -(T2-1) ... -T1 */
+ idx = 3;
+
+ else if ( i <= -1 ) /* -(T1-1) ... -1 */
+ idx = 1;
+ else if ( i == 0 ) /* just 0 */
+ idx = 0;
+
+ else if ( i < T1 ) /* 1 ... T1-1 */
+ idx = 2;
+ else if ( i < T2 ) /* T1 ... T2-1 */
+ idx = 4;
+ else if ( i < T3 ) /* T2 ... T3-1 */
+ idx = 6;
+ else /* T3 ... */
+ idx = 8;
+
+ vLUT[0][i + lutmax] = CREGIONS * CREGIONS * idx;
+ vLUT[1][i + lutmax] = CREGIONS * idx;
+ vLUT[2][i + lutmax] = idx;
+ }
+
+ } else {
+
+ for (i = -lmax + 1; i < lmax; i++) {
+
+ if ( NEAR >= (alpha-1) )
+ idx = 0; /* degenerate case, regardless of thresholds */
+ else
+
+ if ( i <= -T3 ) /* ...... -T3 */
+ idx = 7;
+ else if ( i <= -T2 ) /* -(T3-1) ... -T2 */
+ idx = 5;
+ else if ( i <= -T1 ) /* -(T2-1) ... -T1 */
+ idx = 3;
+
+ else if ( i <= -NEAR-1 ) /* -(T1-1) ... -NEAR-1 */
+ idx = 1;
+ else if ( i <= NEAR ) /* within NEAR of 0 */
+ idx = 0;
+
+ else if ( i < T1 ) /* 1 ... T1-1 */
+ idx = 2;
+ else if ( i < T2 ) /* T1 ... T2-1 */
+ idx = 4;
+ else if ( i < T3 ) /* T2 ... T3-1 */
+ idx = 6;
+ else /* T3 ... */
+ idx = 8;
+
+ vLUT[0][i + lutmax] = CREGIONS * CREGIONS * idx;
+ vLUT[1][i + lutmax] = CREGIONS * idx;
+ vLUT[2][i + lutmax] = idx;
+ }
+
+ }
+
+
+ /* prepare context mapping table (symmetric context merging) */
+ classmap[0] = 0;
+ for ( i=1, j=0; i<CONTEXTS1; i++) {
+ int q1, q2, q3, n1=0, n2=0, n3=0, ineg, sgn;
+
+ if(classmap[i])
+ continue;
+
+ q1 = i/(CREGIONS*CREGIONS); /* first digit */
+ q2 = (i/CREGIONS)%CREGIONS; /* second digit */
+ q3 = i%CREGIONS; /* third digit */
+
+ if((q1%2)||(q1==0 && (q2%2))||(q1==0 && q2==0 && (q3%2)))
+ sgn = -1;
+ else
+ sgn = 1;
+
+ /* compute negative context */
+ if(q1) n1 = q1 + ((q1%2) ? 1 : -1);
+ if(q2) n2 = q2 + ((q2%2) ? 1 : -1);
+ if(q3) n3 = q3 + ((q3%2) ? 1 : -1);
+
+ ineg = (n1*CREGIONS+n2)*CREGIONS+n3;
+ j++ ; /* next class number */
+ classmap[i] = sgn*j;
+ classmap[ineg] = -sgn*j;
+
+ }
+
+ /* prepare table to find k */
+
+
+/* for (i=1; i< 65; i++) /* value of N[] */
+/* for (j=1; j<2500; j++) /* value of A[] */
+/* {
+ register nst = i;
+ for(k=0; nst < j; nst<<=1, k++);
+ getk[i][j]=k;
+ }*/
+
+ /* prepare table to find clip of Px with 8-bit */
+/* for (i=0; i<127; i++)
+ clipPx[i] = 0;
+ for (i=127; i<382; i++)
+ clipPx[i] = i - 127;
+ for (i=382; i<510; i++)
+ clipPx[i] = 255;*/
+
+}
+
+
+
+
+
+/* prepare quantization tables for near-lossless quantization */
+void prepare_qtables(int absize, int NEAR)
+{
+ int dif, qdiff;
+ int beta, quant;
+
+ quant = 2*NEAR+1;
+ beta = absize;
+
+ if ( (qdiv0 = (int *)calloc(2*absize-1,sizeof(int)))==NULL ) {
+ perror("qdiv table");
+ exit(10);
+ }
+ qdiv = qdiv0+absize-1;
+
+ if ( (qmul0 = (int *)calloc(2*beta-1,sizeof(int)))==NULL ) {
+ perror("qmul table");
+ exit(10);
+ }
+ qmul = qmul0+beta-1;
+
+ for ( dif = -(absize-1); dif<absize; dif++ ) {
+ if ( dif<0 )
+ qdiff = - ( (NEAR-dif)/quant );
+ else
+ qdiff = ( NEAR + dif )/quant;
+ qdiv[dif] = qdiff;
+ }
+ for ( qdiff = -(beta-1); qdiff<beta; qdiff++ ) {
+ dif = quant*qdiff;
+ qmul[qdiff] = dif;
+ }
+}
+
+
+
+/* Initialize A[], B[], C[], and N[] arrays */
+void init_stats(int absize)
+{
+ int i, initabstat, slack;
+
+ slack = 1<<INITABSLACK;
+ initabstat = (absize + slack/2)/slack;
+ if ( initabstat < MIN_INITABSTAT ) initabstat = MIN_INITABSTAT;
+
+ /* do the statistics initialization */
+ for (i = 0; i < TOT_CONTEXTS; ++i) {
+ C[i]= B[i] = 0;
+ N[i] = INITNSTAT;
+ A[i] = initabstat;
+ }
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* jpegmark.c --- for JPEG markers
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <stdio.h>
+#include "global.h"
+#include "jpegmark.h"
+
+#ifdef BUFINPUT
+# include "bitio.h"
+#endif
+
+/* Makes sure a parameter falls within its allowed range */
+void check_range(int param, char *name, int low, int high)
+{
+ if ( param < low || param > high )
+ {
+ fprintf(stderr,"Allowed range for %s is [%d..%d]: got %d\n",
+ name, low, high, param);
+ exit(10);
+ }
+}
+
+/* reads n bytes (0 <= n <= 4) from the input stream */
+
+unsigned int read_n_bytes(FILE *in, unsigned int n)
+{
+ unsigned int m = 0;
+ int i;
+
+ for ( i=0; i<n; i++ )
+ m = (m << 8) | ((unsigned char)getc(in));
+ return m;
+}
+
+/*
+ * Marker output functions
+ */
+
+int write_n_bytes(FILE *out, int value, int n)
+{
+
+ int l;
+
+
+ if (n>4) {
+ fprintf(stderr,"write_n_bytes: Only 32 bits variables supported.\n");
+ exit(10);
+ }
+
+
+#ifdef BIG_ENDIAN
+ for (l=n-1;l>=0;l--) {
+ if ( putc((value>>(8*l))&0x000000FF,out) == EOF )
+ return EOF;
+ }
+#else /* little endian */
+ for (l=0;l<n;l++) {
+ if ( putc((value&0x000000FF),out) == EOF )
+ return EOF;
+ value >>= 8;
+ }
+#endif
+ return n;
+
+}
+
+
+
+int write_2_bytes(FILE *out, int value)
+{
+ return write_n_bytes(out,value,2);
+}
+
+
+
+int write_marker(FILE *out, int marker)
+/* Write a two-byte marker (just the marker identifier) */
+{
+ write_n_bytes(out, marker, 2);
+ return 2;
+}
+
+
+/* Write the frame header to the JLS file */
+int write_jpegls_frame(FILE *out, jpeg_ls_header *jp)
+{
+ int i, marker_len,
+ bpp, ct = 0;
+
+ ct += write_marker(out, SOF_LS); /* write JPEG-LS frame marker */
+
+ check_range(jp->comp, "frame components", 1, 255);
+ marker_len = 8 + 3*jp->comp;
+
+ ct += write_n_bytes(out, marker_len, 2); /* write marker length */
+
+ for ( bpp=1; (1L<<bpp)<jp->alp; bpp++ );
+
+ ct += write_n_bytes(out, bpp, 1); /* write bits/sample */
+
+ /* current implementation only supports up to 64K samples in
+ either direction. Also, they must be specified in the frame header */
+ check_range(jp->rows, "rows", 1, 65535);
+ check_range(jp->columns, "columns", 1, 65535);
+
+ ct += write_n_bytes(out, jp->rows, 2); /* write number of rows */
+ ct += write_n_bytes(out, jp->columns, 2); /* write number of cols */
+
+ ct += write_n_bytes(out, jp->comp, 1);
+
+ /* now write a triplet of bytes per component */
+ for ( i=0; i<jp->comp; i++ ) {
+ int sx = jp->samplingx[i],
+ sy = jp->samplingy[i];
+
+ check_range(sx,"sampling(x)",1,4);
+ check_range(sy,"sampling(y)",1,4);
+ ct += write_n_bytes(out, jp->comp_ids[i], 1); /* component identifier */
+ ct += write_n_bytes(out, (sx<<4)|sy, 1); /* sampling rates */
+ ct += write_n_bytes(out, 0, 1); /* Tq unused */
+ }
+ return ct;
+}
+
+
+/* Write the Scan header to JLS file */
+int write_jpegls_scan(FILE *out, jpeg_ls_header *jp)
+{
+ int i, marker_len, ct=0;
+
+ ct += write_marker(out, SOS); /* write JPEG-LS scan marker */
+
+ check_range(jp->comp, "scan components", 1, 4);
+
+ if ( jp->comp == 1 && jp->color_mode != PLANE_INT) {
+ fprintf(stderr,"Interleave for 1 component must be PLANE_INT: got %d\n",
+ jp->color_mode);
+ exit(10);
+ }
+
+ if ( jp->comp >1 && jp->color_mode == 0 ) {
+ fprintf(stderr,"Interleave for multi-component scan must be nonzero: got %d\n",
+ jp->color_mode);
+ exit(10);
+ }
+
+ marker_len = 6 + 2*jp->comp;
+
+ ct += write_n_bytes(out, marker_len, 2); /* write marker length */
+ ct += write_n_bytes(out, jp->comp, 1); /* # of components for the scan */
+
+ /* write 2 bytes per component */
+ for ( i=0; i<jp->comp; i++ ) {
+ ct += write_n_bytes(out, jp->comp_ids[i], 1); /* component identifier */
+ ct += write_n_bytes(out, 0, 1); /* no tables in this implementation */
+ }
+
+ check_range(jp->NEAR, "NEAR", 0, 255);
+ ct += write_n_bytes(out, jp->NEAR, 1);
+
+ check_range(jp->color_mode,"INTERLEAVE", 0, 2);
+ ct += write_n_bytes(out, jp->color_mode, 1);
+
+ check_range(jp->shift, "SHIFT", 0, 15);
+ ct += write_n_bytes(out, jp->shift, 1);
+
+ return ct;
+}
+
+
+
+/* Write out LSE header to JLS file - only supports type 1 and 2 currently */
+int write_jpegls_extmarker(FILE *out, jpeg_ls_header *jp, int IDtype, char *mapfilename)
+{
+ int ct=0;
+
+ /* For Type 1 - non default parameters */
+ if (IDtype == LSE_PARAMS)
+ {
+ ct += write_marker(out, LSE); /* write JPEG-LS extended marker id */
+
+ ct += write_n_bytes(out, 13, 2); /* marker length */
+ ct += write_n_bytes(out, LSE_PARAMS, 1); /* ext marker id */
+ ct += write_n_bytes(out, jp->alp-1, 2); /* MAXVAL */
+ ct += write_n_bytes(out, jp->T1, 2);
+ ct += write_n_bytes(out, jp->T2, 2);
+ ct += write_n_bytes(out, jp->T3, 2);
+ ct += write_n_bytes(out, jp->RES, 2);
+ return ct;
+ }
+
+ /* For Type 2 - Mapping Table */
+ if (IDtype == LSE_MAPTABLE)
+ {
+ unsigned int TID, /* Table ID */
+ Wt, /* Width of table entries */
+ MAXTAB, /* Maximum index of table */
+ length ; /* Marker length */
+ int i;
+ FILE* tablefile;
+
+ /* Is only implemented for 8 bpp images in this implementation */
+ if (bpp16==TRUE)
+ {
+ fprintf(stderr, "Sorry, mapping tables are only supported for 8 bpp images in this implementation.\n");
+ exit(1);
+ }
+
+ /* Open the table file */
+ if ( mapfilename == NULL )
+ {
+ usage();
+ exit(1);
+ }
+ if ( (tablefile=fopen(mapfilename,"rb")) == NULL )
+ {
+ perror(mapfilename);
+ exit(10);
+ }
+
+ /* Assign values to jpeg header */
+ /* Read the table ID */
+ jp->TID = TID = read_n_bytes(tablefile, 1);
+
+ /* Read the width of each entry */
+ jp->Wt = Wt = read_n_bytes(tablefile, 1);
+
+ /* Read the max table index value */
+ MAXTAB = read_n_bytes(tablefile, 4);
+
+ /* Create the table */
+ jp->TABLE[TID] = (unsigned int *) safecalloc ((MAXTAB+1)*sizeof(unsigned int), 1);
+
+ for (i=0; i <= MAXTAB; i++)
+ {
+ if (i==200)
+ i=200;
+
+ jp->TABLE[TID][i] = read_n_bytes(tablefile, Wt);
+ if feof(tablefile)
+ {
+ fprintf(stderr,"Error Reading Table File - Premature EOF found.\n");
+ exit(1);
+ }
+ }
+
+
+ length = 5 + (Wt*(MAXTAB+1));
+
+ /* Write out the header */
+ ct += write_marker(out, LSE);
+ ct += write_n_bytes(out, length, 2); /* marker length */
+ ct += write_n_bytes(out, LSE_MAPTABLE, 1); /* LSE marker id */
+ ct += write_n_bytes(out, TID, 1); /* table id */
+ ct += write_n_bytes(out, Wt, 1); /* width of table entries in bytes */
+
+ for (i=0; i<=MAXTAB; i++)
+ ct += write_n_bytes(out, jp->TABLE[TID][i], Wt);
+
+
+ return ct;
+ }
+ else
+ {
+ fprintf(stderr, "LSE Parameter %i not defined in this implementation.\n",IDtype);
+ exit(1);
+ }
+
+}
+
+
+
+
+
+/* Writes the DRI header to the JLS file */
+int write_jpegls_restartmarker(FILE *out, jpeg_ls_header *jp)
+{
+ int ct=0;
+ int Ri; /* the restart interval (# of MCU's between markers) */
+ int length; /* the length of the DRI header */
+
+ Ri = jp->restart_interval;
+
+ if (Ri <= 65535)
+ length = 4;
+ else
+ length = 6;
+
+ ct += write_marker(out, DRI);
+ ct += write_n_bytes(out, length, 2);
+ ct += write_n_bytes(out, Ri, 2);
+
+ return ct;
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* jpegmark.h --- for JPEG markers
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#define BUFINPUT
+#ifndef BIG_ENDIAN
+# define BIG_ENDIAN
+#endif
+
+/* Marker identifiers */
+
+#define SOI 0xFFD8 /* start of image */
+#define EOI 0xFFD9 /* end of image */
+
+#define SOS 0xFFDA /* Start of scan */
+#define DNL 0xFFDC /* Define number of lines */
+#define DRI 0xFFDD /* Define restart interval */
+#define RSTm 0xFFD0 /* Restart marker (FFD0-FFD7) */
+#define COM 0xFFFE /* Comment */
+
+
+/* JPEG-LS specific */
+#define SOF_LS 0xFFF7 /* Start of JPEG-LS regular frame */
+#define LSE 0xFFF8 /* JPEG-LS extension marker */
+#define LSE_PARAMS 1 /* Marker type within LSE - parameters */
+#define LSE_MAPTABLE 2 /* Marker type within LSE - map tables */
+#define LSE_XMAPTABLE 3 /* Marker type within LSE - map table continuation */
+#define LSE_XY 4 /* Marker type within LSE - image dimensions */
+
+
+/* Functions to write markers */
+int write_n_bytes(FILE *out, int value, int n);
+int write_2_bytes(FILE *out, int value);
+int write_marker(FILE *out, int marker);
+int write_jpegls_frame(FILE *out, jpeg_ls_header *jp);
+int write_jpegls_scan(FILE *out, jpeg_ls_header *jp);
+int write_jpegls_extmarker(FILE *out, jpeg_ls_header *jp, int IDtype, char *mapfilename);
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* lossless_e.c --- the main pipeline which processes a scanline by doing
+ * prediction, context computation, context quantization,
+ * and statistics gathering.
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "global.h"
+#include "bitio.h"
+
+
+/*byte getk[65][3000];*/
+/*byte clipPx[510];*/
+
+static int eor_limit;
+
+
+/* Do Golomb statistics and ENCODING for LOSS-LESS images */
+inline void lossless_regular_mode(int Q, int SIGN, int Px, pixel *xp)
+{
+ int At, Nt, Bt, absErrval, Errval, MErrval,
+ Ix = *xp; /* current pixel */
+ int unary;
+ int temp;
+ byte k;
+
+ Nt = N[Q];
+ At = A[Q];
+
+
+ /* Prediction correction (A.4.2), compute prediction error (A.4.3)
+ , and error quantization (A.4.4) */
+ Px = Px + (SIGN) * C[Q];
+/*Px = clipPx[Px+127];*/
+ clip(Px,alpha);
+ Errval = SIGN * (Ix - Px);
+
+
+ /* Modulo reduction of predication error (A.4.5) */
+ if (Errval < 0)
+ Errval += alpha; /* Errval is now in [0.. alpha-1] */
+
+
+ /* Estimate k - Golomb coding variable computation (A.5.1) */
+ {
+ register nst = Nt;
+ for(k=0; nst < At; nst<<=1, k++);
+ }
+/*k=getk[Nt][At];*/
+
+
+ /* Do Rice mapping and compute magnitude of Errval */
+ Bt = B[Q];
+
+ /* Error Mapping (A.5.2) */
+ temp = ( k==0 && ((Bt<<1) <= -Nt) );
+ if (Errval >= ceil_half_alpha) {
+ Errval -= alpha;
+ absErrval = -Errval;
+ MErrval = (absErrval<<1) - 1 - temp;
+ } else {
+ absErrval = Errval;
+ MErrval = (Errval<<1) + temp;
+ }
+
+
+ /* update bias stats (after correction of the difference) (A.6.1) */
+ B[Q] = (Bt += Errval);
+
+
+ /* update Golomb stats */
+ A[Q] += absErrval;
+
+
+ /* check for reset */
+ if (Nt == reset) {
+ /* reset for Golomb and bias cancelation at the same time */
+ N[Q] = (Nt >>= 1);
+ A[Q] >>= 1;
+ B[Q] = (Bt >>= 1);
+ }
+ N[Q] = (++Nt);
+
+
+ /* Do bias estimation for NEXT pixel */
+ /* Bias cancelation tries to put error in (-1,0] (A.6.2)*/
+ if ( Bt <= -Nt ) {
+
+ if (C[Q] > MIN_C)
+ --C[Q];
+
+ if ( (B[Q] += Nt) <= -Nt )
+ B[Q] = -Nt+1;
+
+ } else if ( Bt > 0 ) {
+
+ if (C[Q] < MAX_C)
+ ++C[Q];
+
+ if ( (B[Q] -= Nt) > 0 )
+ B[Q] = 0;
+ }
+
+
+ /* Actually output the code: Mapped Error Encoding (Appendix G) */
+ unary = MErrval >> k;
+ if ( unary < limit ) {
+ put_zeros(unary);
+ putbits((1 << k) + (MErrval & ((1 << k) - 1)), k + 1);
+ }
+ else {
+ put_zeros(limit);
+ putbits((1<<qbpp) + MErrval - 1, qbpp+1);
+ }
+}
+
+
+
+
+/* Do end of run encoding for LOSSLESS images */
+inline void lossless_end_of_run(pixel Ra, pixel Rb, pixel Ix, int RItype)
+{
+ int Errval,
+ MErrval,
+ Q,
+ absErrval,
+ oldmap,
+ k,
+ At,
+ unary;
+
+ register int Nt;
+
+ Q = EOR_0 + RItype;
+ Nt = N[Q];
+ At = A[Q];
+
+ Errval = Ix - Rb;
+ if (RItype)
+ At += Nt>>1;
+ else {
+ if ( Rb < Ra )
+ Errval = -Errval;
+ }
+
+
+ /* Estimate k */
+ for(k=0; Nt < At; Nt<<=1, k++);
+
+ if (Errval < 0)
+ Errval += alpha;
+ if( Errval >= ceil_half_alpha )
+ Errval -= alpha;
+
+
+ oldmap = ( k==0 && Errval && (B[Q]<<1)<Nt );
+ /* Note: the Boolean variable 'oldmap' is not
+ identical to the variable 'map' in the
+ JPEG-LS draft. We have
+ oldmap = (Errval<0) ? (1-map) : map;
+ */
+
+ /* Error mapping for run-interrupted sample (Figure A.22) */
+ if( Errval < 0) {
+ MErrval = -(Errval<<1)-1-RItype+oldmap;
+ B[Q]++;
+ }else
+ MErrval = (Errval<<1)-RItype-oldmap;
+
+ absErrval = (MErrval+1-RItype)>>1;
+
+ /* Update variables for run-interruped sample (Figure A.23) */
+ A[Q] += absErrval;
+ if (N[Q] == reset) {
+ N[Q] >>= 1;
+ A[Q] >>= 1;
+ B[Q] >>= 1;
+ }
+
+ N[Q]++; /* for next pixel */
+
+ /* Do the actual Golomb encoding: */
+ eor_limit = limit - limit_reduce;
+ unary = MErrval >> k;
+ if ( unary < eor_limit ) {
+ put_zeros(unary);
+ putbits((1 << k) + (MErrval & ((1 << k) - 1)), k + 1);
+ }
+ else {
+ put_zeros(eor_limit);
+ putbits((1<<qbpp) + MErrval-1, qbpp+1);
+ }
+}
+
+
+
+
+
+
+/* For line and plane interleaved mode in LOSS-LESS mode */
+
+void lossless_doscanline( pixel *psl, /* previous scanline */
+ pixel *sl, /* current scanline */
+ int no, int color) /* number of values in it */
+
+/*** watch it! actual pixels in the scan line are numbered 1 to no .
+ pixels with indices < 1 or > no are dummy "border" pixels */
+{
+ int i;
+ pixel Ra, Rb, Rc, Rd, /* context pixels */
+ Ix, /* current pixel */
+ Px; /* predicted current pixel */
+
+ int SIGN; /* sign of current context */
+ int cont; /* context */
+
+ i = 1; /* pixel indices in a scan line go from 1 to no */
+
+ /**********************************************/
+ /* Do for all pixels in the row in 8-bit mode */
+ /**********************************************/
+ if (bpp16==FALSE) {
+
+ Rc = psl[0];
+ Rb = psl[1];
+ Ra = sl[0];
+
+ /* For 8-bit Image */
+
+ do {
+ int RUNcnt;
+
+ Ix = sl[i];
+ Rd = psl[i + 1];
+
+ /* Context determination */
+
+ /* Quantize the gradient */
+ /* partial context number: if (b-e) is used then its
+ contribution is added after determination of the run state.
+ Also, sign flipping, if any, occurs after run
+ state determination */
+
+
+ cont = vLUT[0][Rd - Rb + LUTMAX8] +
+ vLUT[1][Rb - Rc + LUTMAX8] +
+ vLUT[2][Rc - Ra + LUTMAX8];
+
+ if ( cont == 0 )
+ {
+ /*************** RUN STATE ***************************/
+
+ RUNcnt = 0;
+
+ if (Ix == Ra) {
+ while ( 1 ) {
+
+ ++RUNcnt;
+
+ if (++i > no) {
+ /* Run-lenght coding when reach end of line (A.7.1.2) */
+ process_run(RUNcnt, EOLINE, color);
+ return; /* end of line */
+ }
+
+ Ix = sl[i];
+
+ if (Ix != Ra) /* Run is broken */
+ {
+ Rd = psl[i + 1];
+ Rb = psl[i];
+ break; /* out of while loop */
+ }
+ /* Run continues */
+ }
+ }
+
+ /* we only get here if the run is broken by
+ a non-matching symbol */
+
+ /* Run-lenght coding when end of line not reached (A.7.1.2) */
+ process_run(RUNcnt,NOEOLINE, color);
+
+
+ /* This is the END_OF_RUN state */
+ lossless_end_of_run(Ra, Rb, Ix, (Ra==Rb));
+
+ }
+ else {
+
+ /*************** REGULAR CONTEXT *******************/
+
+ predict(Rb, Ra, Rc);
+
+ /* do symmetric context merging */
+ cont = classmap[cont];
+
+ if (cont<0) {
+ SIGN=-1;
+ cont = -cont;
+ }
+ else
+ SIGN=+1;
+
+ /* output a rice code */
+ lossless_regular_mode(cont, SIGN, Px, &Ix);
+ }
+
+ /* context for next pixel: */
+ sl[i] = Ix;
+
+ Ra = Ix;
+ Rc = Rb;
+ Rb = Rd;
+ } while (++i <= no);
+
+ }
+ else
+ {
+ /***********************************************/
+ /* Do for all pixels in the row in 16-bit mode */
+ /***********************************************/
+
+ Rc = ENDIAN16(psl[0]);
+ Rb = ENDIAN16(psl[1]);
+ Ra = ENDIAN16(sl[0]);
+
+ /* For 16-bit Image */
+
+ do {
+ int RUNcnt;
+
+ Ix = ENDIAN16(sl[i]);
+ Rd = ENDIAN16(psl[i + 1]);
+
+ /* Context determination */
+
+ /* Quantize the gradient */
+ /* partial context number: if (b-e) is used then its
+ contribution is added after determination of the run state.
+ Also, sign flipping, if any, occurs after run
+ state determination */
+
+
+ {
+ register int diff;
+
+ /* Following segment assumes that T3 <= LUTMAX16 */
+ /* This condition should have been checked when the
+ lookup tables were built */
+ diff = Rd - Rb;
+ if (diff < 0)
+ cont = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
+ else
+ cont = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
+
+ diff = Rb - Rc;
+ if (diff < 0)
+ cont += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
+ else
+ cont += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
+
+ diff = Rc - Ra;
+ if (diff < 0)
+ cont += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
+ else
+ cont += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
+ }
+
+
+ if ( cont == 0 ) { /* Run state? */
+
+ /*************** RUN STATE ***************************/
+
+ RUNcnt = 0;
+
+ if (Ix == Ra) {
+ while ( 1 ) {
+
+ ++RUNcnt;
+
+ if (++i > no) {
+ /* Run-lenght coding when reach end of line (A.7.1.2) */
+ process_run(RUNcnt, EOLINE, color);
+ return; /* end of line */
+ }
+
+ Ix = ENDIAN16(sl[i]);
+
+ if (Ix != Ra) /* Run is broken */
+ {
+ Rd = ENDIAN16(psl[i + 1]);
+ Rb = ENDIAN16(psl[i]);
+ break; /* out of while loop */
+ }
+ /* Run continues */
+ }
+ }
+
+ /* we only get here if the run is broken by
+ a non-matching symbol */
+
+ /* Run-lenght coding when end of line not reached (A.7.1.2) */
+ process_run(RUNcnt,NOEOLINE, color);
+
+ /* This is the END_OF_RUN state */
+ lossless_end_of_run(Ra, Rb, Ix, (Ra==Rb));
+
+ }
+ else {
+
+ /*************** REGULAR CONTEXT *******************/
+
+ predict(Rb, Ra, Rc);
+
+ /* do symmetric context merging */
+ cont = classmap[cont];
+
+ if (cont<0) {
+ SIGN=-1;
+ cont = -cont;
+ }
+ else
+ SIGN=+1;
+
+ /* output a rice code */
+ lossless_regular_mode(cont, SIGN, Px, &Ix);
+ }
+
+ /* context for next pixel: */
+ sl[i] = ENDIAN16(Ix);
+ Ra = Ix;
+ Rc = Rb;
+ Rb = Rd;
+ } while (++i <= no);
+ }
+}
+
+
+
+
+
+
+/* For pixel interleaved mode for LOSSLESS encoding */
+
+void lossless_doscanline_pixel( pixel *psl, /* previous scanline */
+ pixel *sl, /* current scanline */
+ int no) /* number of values in it */
+
+/*** watch it! actual pixels in the scan line are numbered 1 to no .
+ pixels with indices < 1 or > no are dummy "border" pixels */
+{
+ int i,n_c, enter_run=0, break_run, was_in_run=0, test_run;
+ int color; /* Index to the component, 0..COMPONENTS-1 */
+ pixel c_aa[MAX_COMPONENTS],
+ c_bb[MAX_COMPONENTS],
+ c_cc[MAX_COMPONENTS],
+ c_dd[MAX_COMPONENTS],
+ c_xx[MAX_COMPONENTS],
+ Ra, Rb, Rc, Rd, /* context pixels */
+ Ix, /* current pixel */
+ Px; /* predicted current pixel */
+ int SIGN; /* sign of current context */
+ int cont,c_cont[MAX_COMPONENTS]; /* context */
+
+
+ if (bpp16==FALSE)
+ {
+ /**********************************************/
+ /* Do for all pixels in the row in 8-bit mode */
+ /**********************************************/
+
+ for (n_c=0; n_c<components; n_c++) {
+ c_cc[n_c] = ENDIAN8(psl[n_c]);
+ c_bb[n_c] = ENDIAN8(psl[components+n_c]);
+ c_aa[n_c] = ENDIAN8(sl[n_c]);
+ }
+
+ i = components; /* pixel indices in a scan line go from COMPONENTS to no */
+ color = -1;
+
+ do {
+ int RUNcnt;
+
+ if (!was_in_run) color = (color+1)%components;
+ else color = 0;
+
+ Ix = ENDIAN8(sl[i]);
+
+ for (n_c=0;n_c<components;n_c++)
+ c_xx[n_c]=ENDIAN8(sl[i+n_c]);
+
+ if (color == 0)
+ for (n_c=0;n_c<components;n_c++)
+ {
+ c_dd[n_c] = ENDIAN8(psl[i+components+n_c]);
+
+ /* Context determination */
+
+ /* Quantize the gradient */
+ /* partial context number: if (b-e) is used
+ then its contribution is added after
+ determination of the run state.
+ Also, sign flipping, if any, occurs after run
+ state determination */
+
+ c_cont[n_c] = vLUT[0][c_dd[n_c] - c_bb[n_c] + LUTMAX8] +
+ vLUT[1][c_bb[n_c] - c_cc[n_c] + LUTMAX8] +
+ vLUT[2][c_cc[n_c] - c_aa[n_c] + LUTMAX8];
+ }
+
+ Ra=c_aa[color];
+ Rb=c_bb[color];
+ Rc=c_cc[color];
+ Rd=c_dd[color];
+ cont=c_cont[color];
+
+ enter_run = was_in_run = test_run = 0;
+
+ if (color == 0) {
+ test_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (c_cont[n_c]!=0) {
+ test_run=0;
+ break;
+ }
+ }
+
+ /* Run state? */
+ if ( test_run ) {
+ /*************** RUN STATE ***************************/
+
+ enter_run = was_in_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (ENDIAN8(sl[i+n_c]) != c_bb[n_c]) enter_run=0;
+ RUNcnt = 0;
+ if (enter_run)
+ {
+ while ( 1 ) {
+ ++RUNcnt;
+
+ if((i=i+components)>(no+components-1)){
+ process_run(RUNcnt, EOLINE, 0);
+ return; /* end of line */
+ }
+
+ for (n_c=0;n_c<components;n_c++)
+ c_xx[n_c] = ENDIAN8(sl[i+n_c]);
+
+ break_run=0;
+
+ for (n_c=0;n_c<components;n_c++)
+ if (c_xx[n_c] != c_aa[n_c]) break_run=1;
+
+ if (break_run) /* Run is broken */
+ {
+ for(n_c=0;n_c<components;n_c++){
+ c_dd[n_c] = ENDIAN8(psl[i+components+n_c]);
+ c_bb[n_c] = ENDIAN8(psl[i+n_c]);
+ }
+ break; /* out of while loop */
+ }
+ /* Run continues */
+ }
+ }
+
+ /* we only get here if the run is broken by
+ a non-matching symbol */
+
+ process_run(RUNcnt,NOEOLINE, 0);
+
+ /* This is the END_OF_RUN state */
+ for (n_c=0;n_c<components;n_c++)
+ {
+ /* The end of run is done for each component */
+ Ix = c_xx[n_c];
+ Ra = c_aa[n_c];
+ Rb = c_bb[n_c];
+
+ lossless_end_of_run(Ra, Rb, Ix, 0);
+
+ } /* loop for components */
+
+ } /* Run state block */
+ else {
+
+ /*************** REGULAR CONTEXT *******************/
+
+ predict(Rb, Ra, Rc);
+ cont = classmap[cont];
+
+ if (cont<0) {
+ SIGN=-1;
+ cont=-cont;
+ } else
+ SIGN=1;
+
+ /* output a rice code */
+ lossless_regular_mode(cont, SIGN, Px, &Ix);
+ }
+
+ /* context for next pixel: */
+ if (!was_in_run) {
+ c_aa[color] = Ix;
+ c_cc[color] = Rb;
+ c_bb[color] = Rd;
+ i++;
+ }
+ else {
+ for(n_c=0;n_c<components;n_c++) {
+ c_aa[n_c] = c_xx[n_c];
+ c_cc[n_c] = c_bb[n_c];
+ c_bb[n_c] = c_dd[n_c];
+ }
+ i += components;
+ }
+
+ } while (i <= (no+components-1));
+
+ } else {
+
+ /**********************************************/
+ /* Do for all pixels in the row in 16-bit mode*/
+ /**********************************************/
+
+ for (n_c=0; n_c<components; n_c++) {
+ c_cc[n_c] = ENDIAN16(psl[n_c]);
+ c_bb[n_c] = ENDIAN16(psl[components+n_c]);
+ c_aa[n_c] = ENDIAN16(sl[n_c]);
+ }
+
+ i = components; /* pixel indices in a scan line go from COMPONENTS to no */
+ color = -1;
+
+ do {
+ int RUNcnt;
+
+ if (!was_in_run) color = (color+1)%components;
+ else color = 0;
+
+ Ix = ENDIAN16(sl[i]);
+
+ for (n_c=0;n_c<components;n_c++)
+ c_xx[n_c]=ENDIAN16(sl[i+n_c]);
+
+ if (color == 0)
+ for (n_c=0;n_c<components;n_c++)
+ {
+ c_dd[n_c] = ENDIAN16(psl[i+components+n_c]);
+
+ /* Context determination */
+
+ /* Quantize the gradient */
+ /* partial context number: if (b-e) is used
+ then its contribution is added after
+ determination of the run state.
+ Also, sign flipping, if any, occurs after run
+ state determination */
+
+ {
+ register int diff;
+
+ /* Following segment assumes that Sc <= LUTMAX16 */
+ /* This condition should have been checked when the
+ lookup tables were built */
+ diff = c_dd[n_c] - c_bb[n_c];
+ if (diff < 0)
+ c_cont[n_c] = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
+ else
+ c_cont[n_c] = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
+
+ diff = c_bb[n_c] - c_cc[n_c];
+ if (diff < 0)
+ c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
+ else
+ c_cont[n_c] += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
+
+ diff = c_cc[n_c] - c_aa[n_c];
+ if (diff < 0)
+ c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
+ else
+ c_cont[n_c] += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
+ }
+ }
+
+ Ra=c_aa[color];
+ Rb=c_bb[color];
+ Rc=c_cc[color];
+ Rd=c_dd[color];
+ cont=c_cont[color];
+
+ enter_run = was_in_run = test_run = 0;
+
+ if (color == 0) {
+ test_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (c_cont[n_c]!=0) {
+ test_run=0;
+ break;
+ }
+ }
+
+ /* Run state? */
+ if ( test_run ) {
+ /*************** RUN STATE ***************************/
+
+ enter_run = was_in_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (ENDIAN16(sl[i+n_c]) != c_bb[n_c]) enter_run=0;
+ RUNcnt = 0;
+ if (enter_run)
+ {
+ while ( 1 ) {
+ ++RUNcnt;
+
+ if((i=i+components)>(no+components-1)){
+ process_run(RUNcnt, EOLINE, 0);
+ return; /* end of line */
+ }
+
+ for (n_c=0;n_c<components;n_c++)
+ c_xx[n_c] = ENDIAN16(sl[i+n_c]);
+
+ break_run=0;
+
+ for (n_c=0;n_c<components;n_c++)
+ if (c_xx[n_c] != c_aa[n_c]) break_run=1;
+
+ if (break_run) /* Run is broken */
+ {
+ for(n_c=0;n_c<components;n_c++){
+ c_dd[n_c] = ENDIAN16(psl[i+components+n_c]);
+ c_bb[n_c] = ENDIAN16(psl[i+n_c]);
+ }
+ break; /* out of while loop */
+ }
+ /* Run continues */
+ }
+ }
+
+ /* we only get here if the run is broken by
+ a non-matching symbol */
+
+ process_run(RUNcnt,NOEOLINE, 0);
+
+ /* This is the END_OF_RUN state */
+ for (n_c=0;n_c<components;n_c++)
+ {
+ /* The end of run is done for each component */
+ Ix = c_xx[n_c];
+ Ra = c_aa[n_c];
+ Rb = c_bb[n_c];
+
+ lossless_end_of_run(Ra, Rb, Ix, 0);
+
+ } /* loop for components */
+
+ } /* Run state block */
+ else {
+
+ /*************** REGULAR CONTEXT *******************/
+
+ predict(Rb, Ra, Rc);
+ cont = classmap[cont];
+
+ if (cont<0) {
+ SIGN=-1;
+ cont=-cont;
+ } else
+ SIGN=1;
+
+ /* output a rice code */
+ lossless_regular_mode(cont, SIGN, Px, &Ix);
+ }
+
+ /* context for next pixel: */
+ if (!was_in_run) {
+ c_aa[color] = Ix;
+ c_cc[color] = Rb;
+ c_bb[color] = Rd;
+ i++;
+ }
+ else {
+ for(n_c=0;n_c<components;n_c++) {
+ c_aa[n_c] = c_xx[n_c];
+ c_cc[n_c] = c_bb[n_c];
+ c_bb[n_c] = c_dd[n_c];
+ }
+ i += components;
+ }
+
+ } while (i <= (no+components-1));
+
+ } /* ends "if" for 8 or 16 bit */
+
+}
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* lossy_e.c --- the main pipeline which processes a scanline by doing
+ * prediction, context computation, context quantization,
+ * and statistics gathering. (for LOSSY compression)
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ *
+ */
+
+#include <stdio.h>
+#include <math.h>
+
+#include "global.h"
+#include "bitio.h"
+
+
+/*byte getk[65][3000];
+int clipPx[510];*/
+
+static int eor_limit;
+
+
+/* Do Golomb statistics and ENCODING for LOSSY images */
+inline void lossy_regular_mode(int Q, int SIGN, int Px, pixel *xp)
+{
+ int At, Bt, Nt, absErrval, Errval, MErrval,
+ qErrval, iqErrval, Rx,
+ Ix = *xp; /* current pixel */
+ int unary;
+ int temp;
+ byte k;
+
+
+ Nt = N[Q];
+ At = A[Q];
+ /* Estimate k - Golomb coding variable computation (A.5.1) */
+ {
+ register nst = Nt;
+ for(k=0; nst < At; nst<<=1, k++);
+ }
+
+
+ /* Prediction correction (A.4.2), compute prediction error (A.4.3)
+ , and error quantization (A.4.4) */
+
+ Px = Px + (SIGN) * C[Q];
+ clip(Px,alpha);
+ Errval = SIGN * (Ix - Px);
+ qErrval = qdiv[Errval];
+ iqErrval = qmul[qErrval];
+ Rx = Px + SIGN * iqErrval;
+
+ clip(Rx, alpha);
+ *xp = Rx; /* store reconstructed pixel in scan line */
+
+
+ /* Modulo reduction of predication error (A.4.5) */
+ if ( qErrval < 0 )
+ qErrval += qbeta; /* qErrval is now in [0..qbeta-1] */
+
+
+ /* Do Rice mapping and compute magnitude of diff */
+ Bt = B[Q];
+
+
+ /* Error Mapping (A.5.2) */
+ temp = ( k==0 && NEAR==0 && ((Bt<<1) <= -Nt) );
+ if (qErrval >= ceil_half_qbeta) {
+ qErrval -= qbeta;
+ absErrval = -qErrval;
+ MErrval = 2*absErrval - 1 - temp;
+ } else {
+ absErrval = qErrval;
+ MErrval = 2*qErrval + temp;
+ }
+
+
+ /* update bias stats (after correction of the difference) (A.6.1) */
+
+ Errval = qmul[qErrval]; /* convert back to alphabet space */
+
+ B[Q] = (Bt += Errval);
+
+ /* update Golomb stats */
+ A[Q] += absErrval;
+
+ /* check for reset */
+ if (Nt == reset) {
+ /* reset for Golomb and bias cancelation at the same time */
+ N[Q] = (Nt >>= 1);
+ A[Q] >>= 1;
+ B[Q] = (Bt >>= 1);
+ }
+
+
+ /* Do bias estimation for NEXT pixel */
+ /* Bias cancelation tries to put error in (-1,0] (A.6.2)*/
+ N[Q] = (++Nt);
+ if ( Bt <= -Nt ) {
+
+ if (C[Q] > MIN_C)
+ --C[Q];
+
+ Bt = (B[Q] += Nt);
+
+ if ( Bt <= -Nt )
+ B[Q] = -Nt+1;
+
+ } else if ( Bt > 0 ) {
+
+ if (C[Q] < MAX_C)
+ ++C[Q];
+
+ Bt = (B[Q] -= Nt);
+
+ if ( Bt > 0 )
+ B[Q] = 0;
+
+ }
+
+
+ /* Actually output the code: Mapped Error Encoding (A.5.3) */
+ unary = MErrval >> k;
+ if ( unary < limit ) {
+ put_zeros(unary);
+ putbits((1 << k) + (MErrval & ((1 << k) - 1)), k + 1);
+ }
+ else {
+ put_zeros(limit);
+ putbits((1<<qbpp) + MErrval - 1, qbpp+1);
+ }
+
+}
+
+
+
+
+/* Do end of run encoding for LOSSY images - returns reconstructed value of Ix */
+pixel lossy_end_of_run(pixel Ra, pixel Rb, pixel Ix, int RItype)
+{
+ int qErrval, iqErrval, xpr,
+ MErrval,
+ Q,
+ absErrval,
+ oldmap,
+ k,
+ Nt,
+ At,
+ Errval;
+ int Rx; /* reconstructed pixel */
+ int unary;
+
+ Q = EOR_0 + RItype;
+ Nt = N[Q];
+ At = A[Q];
+
+ if (RItype) {
+ Errval = Ix - (xpr = Ra);
+ At += Nt/2;
+ }
+ else {
+ Errval = Ix - (xpr = Rb);
+ if ( Rb < Ra )
+ Errval = -Errval;
+ }
+
+ qErrval = qdiv[Errval];
+ iqErrval = qmul[qErrval];
+
+ if ( RItype || (Rb >= Ra) )
+ Rx = xpr + iqErrval;
+ else
+ Rx = xpr - iqErrval;
+
+ clip(Rx,alpha); /* reconstructed pixel */
+ Ix = Rx;
+
+ /* Estimate k */
+ for(k=0; Nt < At; Nt *=2, k++);
+
+ if (qErrval < 0)
+ qErrval += qbeta;
+
+ if( qErrval >= ceil_half_qbeta )
+ qErrval -= qbeta;
+
+ oldmap = ( k==0 && qErrval && 2*B[Q]<Nt );
+
+ /*
+ Note: the Boolean variable 'oldmap' is not
+ identical to the variable 'map' in the
+ JPEG-LS draft. We have
+ oldmap = (qErrval<0) ? (1-map) : map;
+ */
+
+ /* Error mapping for run-interrupted sample (Figure A.22) */
+ if( qErrval < 0) {
+ MErrval = -2*qErrval-1-RItype+oldmap;
+ B[Q]++;
+ }
+ else
+ MErrval = 2*qErrval-RItype-oldmap;
+
+ absErrval = (MErrval+1-RItype)/2;
+
+ /* update stats */
+ A[Q] += absErrval;
+ if (N[Q] == reset) {
+ N[Q] >>= 1;
+ A[Q] >>= 1;
+ B[Q] >>= 1;
+ }
+
+ N[Q]++; /* for next pixel */
+
+ /* Do the actual Golomb encoding: */
+ eor_limit = limit - limit_reduce;
+ unary = MErrval >> k;
+ if ( unary < eor_limit ) {
+ put_zeros(unary);
+ putbits((1 << k) + (MErrval & ((1 << k) - 1)), k + 1);
+ }
+ else {
+ put_zeros(eor_limit);
+ putbits((1<<qbpp) + MErrval-1, qbpp+1);
+ }
+
+ return Ix;
+}
+
+
+
+
+
+
+/* For line and plane interleaved mode in LOSSY mode */
+
+void lossy_doscanline(pixel *psl, /* previous scanline */
+ pixel *sl, /* current scanline */
+ int no, int color) /* number of values in it */
+
+/*** watch it! actual pixels in the scan line are numbered 1 to no .
+ pixels with indices < 1 or > no are dummy "border" pixels */
+{
+ int i;
+ pixel Ra, Rb, Rc, Rd, /* context pixels */
+ Ix, /* current pixel */
+ Px; /* predicted current pixel */
+ int Rx; /* reconstructed current pixel */
+
+ int SIGN; /* sign of current context */
+ int cont; /* context */
+ int unary;
+ int RItype;
+
+ i = 1; /* pixel indices in a scan line go from 1 to no */
+
+ /**********************************************/
+ /* Do for all pixels in the row in 8-bit mode */
+ /**********************************************/
+
+ if (bpp16==FALSE) {
+
+ Rc = psl[0];
+ Rb = psl[1];
+ Ra = sl[0];
+
+ /* For 8-bit Image */
+
+ do {
+ int RUNcnt;
+
+ Ix = sl[i];
+ Rd = psl[i + 1];
+
+ /* Context determination */
+
+ /* Quantize the gradient */
+ /* partial context number: if (b-e) is used then its
+ contribution is added after determination of the run state.
+ Also, sign flipping, if any, occurs after run
+ state determination */
+
+ cont = vLUT[0][Rd - Rb + LUTMAX8] +
+ vLUT[1][Rb - Rc + LUTMAX8] +
+ vLUT[2][Rc - Ra + LUTMAX8];
+
+
+ if ( cont == 0 ) { /* Run state? */
+ /*************** RUN STATE ***************************/
+
+ register delta = Ix - Ra;
+ RUNcnt = 0;
+
+ if ( delta <= NEAR && delta >= negNEAR )
+ {
+ while ( 1 )
+ {
+ ++RUNcnt;
+
+ sl[i] = Ra;
+
+ if (++i > no) {
+ /* Run-lenght coding when reach end of line (A.7.1.2) */
+ process_run(RUNcnt, EOLINE, color);
+ return; /* end of line */
+ }
+
+ Ix = sl[i];
+
+ delta = Ix-Ra;
+ if ( delta > NEAR || delta < negNEAR ) /* Run is broken */
+ {
+ Rd = psl[i + 1];
+ Rb = psl[i];
+ break; /* out of while loop */
+ }
+ /* Run continues */
+ }
+ }
+
+ /* we only get here if the run is broken by
+ a non-matching symbol */
+
+ /* Run-lenght coding when end of line not reached (A.7.1.2) */
+ process_run(RUNcnt,NOEOLINE, color);
+
+
+ /* This is the END_OF_RUN state */
+ RItype = ((Rb-Ra)<=NEAR && (Rb-Ra)>=negNEAR);
+ Ix = lossy_end_of_run(Ra, Rb, Ix, RItype);
+
+ }
+ else {
+
+ /*************** REGULAR CONTEXT *******************/
+
+ predict(Rb, Ra, Rc);
+
+ /* do symmetric context merging */
+ cont = classmap[cont];
+
+ if (cont<0) {
+ SIGN=-1;
+ cont = -cont;
+ } else
+ SIGN=+1;
+
+ /* output a rice code */
+ lossy_regular_mode(cont, SIGN, Px, &Ix);
+ }
+
+ /* context for next pixel: */
+ sl[i] = Ix;
+ Ra = Ix;
+ Rc = Rb;
+ Rb = Rd;
+ } while (++i <= no);
+
+ } else { /* 16 bit mode instead of 8 */
+
+ /***********************************************/
+ /* Do for all pixels in the row in 16-bit mode */
+ /***********************************************/
+
+ Rc = ENDIAN16(psl[0]);
+ Rb = ENDIAN16(psl[1]);
+ Ra = ENDIAN16(sl[0]);
+
+ /* For 16-bit Image */
+
+ do {
+ int RUNcnt;
+
+ Ix = ENDIAN16(sl[i]);
+ Rd = ENDIAN16(psl[i + 1]);
+
+ /* Context determination */
+
+ /* Quantize the gradient */
+ /* partial context number: if (b-e) is used then its
+ contribution is added after determination of the run state.
+ Also, sign flipping, if any, occurs after run
+ state determination */
+
+ {
+ register int diff;
+
+ /* Following segment assumes that Sc <= LUTMAX16 */
+ /* This condition should have been checked when the
+ lookup tables were built */
+ diff = Rd - Rb;
+ if (diff < 0)
+ cont = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
+ else
+ cont = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
+
+ diff = Rb - Rc;
+ if (diff < 0)
+ cont += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
+ else
+ cont += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
+
+ diff = Rc - Ra;
+ if (diff < 0)
+ cont += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
+ else
+ cont += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
+ }
+
+ if ( cont == 0 ) { /* Run state? */
+ /*************** RUN STATE ***************************/
+
+ register delta = Ix - Ra;
+ RUNcnt = 0;
+
+ if ( delta <= NEAR && delta >= negNEAR )
+ {
+ while ( 1 )
+ {
+ ++RUNcnt;
+
+ sl[i] = ENDIAN16(Ra);
+
+ if (++i > no) {
+ /* Run-lenght coding when reach end of line (A.7.1.2) */
+ process_run(RUNcnt, EOLINE, color);
+ return; /* end of line */
+ }
+
+ Ix = ENDIAN16(sl[i]);
+
+ delta = Ix-Ra;
+ if ( delta > NEAR || delta < negNEAR ) /* Run is broken */
+ {
+ Rd = ENDIAN16(psl[i + 1]);
+ Rb = ENDIAN16(psl[i]);
+ break; /* out of while loop */
+ }
+ /* Run continues */
+ }
+ }
+
+ /* we only get here if the run is broken by
+ a non-matching symbol */
+
+ /* Run-lenght coding when end of line not reached (A.7.1.2) */
+ process_run(RUNcnt,NOEOLINE, color);
+
+ /* This is the END_OF_RUN state */
+ RItype = ((Rb-Ra)<=NEAR && (Rb-Ra)>=negNEAR);
+ Ix = lossy_end_of_run(Ra, Rb, Ix, RItype);
+
+ }
+ else {
+
+ /*************** REGULAR CONTEXT *******************/
+
+ predict(Rb, Ra, Rc);
+
+ /* do symmetric context merging */
+ cont = classmap[cont];
+
+ if (cont<0) {
+ SIGN=-1;
+ cont = -cont;
+ } else
+ SIGN=+1;
+
+ /* output a rice code */
+ lossy_regular_mode(cont, SIGN, Px, &Ix);
+ }
+
+ /* context for next pixel: */
+ sl[i] = ENDIAN16(Ix);
+ Ra = Ix;
+ Rc = Rb;
+ Rb = Rd;
+ } while (++i <= no);
+
+ } /* for "if" 16 or 8 bit mode */
+
+}
+
+
+
+
+
+
+/* For pixel interleavde mode for LOSSY encoding */
+
+void lossy_doscanline_pixel(pixel *psl, /* previous scanline */
+ pixel *sl, /* current scanline */
+ int no) /* number of values in it */
+/*** watch it! actual pixels in the scan line are numbered 1 to no .
+ pixels with indices < 1 or > no are dummy "border" pixels */
+{
+ int i,n_c, enter_run=0, break_run, was_in_run=0, test_run;
+ int color; /* Index to the component, 0..COMPONENTS-1 */
+ pixel c_aa[MAX_COMPONENTS],
+ c_bb[MAX_COMPONENTS],
+ c_cc[MAX_COMPONENTS],
+ c_dd[MAX_COMPONENTS],
+ c_xx[MAX_COMPONENTS],
+ Ra, Rb, Rc, Rd, /* context pixels */
+ Ix, /* current pixel */
+ Px; /* predicted current pixel */
+ int SIGN; /* sign of current context */
+ int cont,c_cont[MAX_COMPONENTS]; /* context */
+
+
+ if (bpp16==FALSE)
+ {
+ /**********************************************/
+ /* Do for all pixels in the row in 8-bit mode */
+ /**********************************************/
+
+ for (n_c=0; n_c<components; n_c++) {
+ c_cc[n_c] = psl[n_c];
+ c_bb[n_c] = psl[components+n_c];
+ c_aa[n_c] = sl[n_c];
+ }
+
+ i = components; /* pixel indices in a scan line go from COMPONENTS to no */
+ color = -1;
+
+ do {
+ int RUNcnt;
+
+ if (!was_in_run) color = (color+1)%components;
+ else color = 0;
+ Ix = sl[i];
+
+ for (n_c=0;n_c<components;n_c++)
+ c_xx[n_c] = sl[i+n_c];
+
+ if (color == 0)
+ for (n_c=0;n_c<components;n_c++) {
+
+ c_dd[n_c] = psl[i+components+n_c];
+
+ /* Context determination */
+
+ /* Quantize the gradient */
+ /* partial context number: if (b-e) is used
+ then its contribution is added after
+ determination of the run state.
+ Also, sign flipping, if any, occurs after run
+ state determination */
+
+ c_cont[n_c] = vLUT[0][c_dd[n_c] - c_bb[n_c] + LUTMAX8] +
+ vLUT[1][c_bb[n_c] - c_cc[n_c] + LUTMAX8] +
+ vLUT[2][c_cc[n_c] - c_aa[n_c] + LUTMAX8];
+ }
+
+ Ra=c_aa[color];
+ Rb=c_bb[color];
+ Rc=c_cc[color];
+ Rd=c_dd[color];
+ cont=c_cont[color];
+
+ enter_run = was_in_run = test_run = 0;
+
+ if (color == 0) {
+ test_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (c_cont[n_c]!=0) {
+ test_run=0;
+ break;
+ }
+ }
+
+ if ( test_run ) {
+ /*************** RUN STATE ***************************/
+
+ int delta[MAX_COMPONENTS];
+
+ enter_run = was_in_run = 1;
+ for (n_c=0;n_c<components;n_c++) {
+ delta[n_c] = sl[i+n_c] - c_aa[n_c];
+ if (delta[n_c]>NEAR || delta[n_c]<negNEAR) enter_run=0;
+ }
+ RUNcnt = 0;
+
+ if (enter_run)
+ {
+ while ( 1 ) {
+ ++RUNcnt;
+
+ for (n_c=0; n_c<components; n_c++)
+ sl[i+n_c] = c_aa[n_c];
+
+ if((i=i+components)>(no+components-1)){
+ process_run(RUNcnt, EOLINE, 0);
+ return; /* end of line */
+ }
+
+ for (n_c=0;n_c<components;n_c++)
+ c_xx[n_c] = sl[i+n_c];
+
+ break_run=0;
+ for (n_c=0;n_c<components;n_c++) {
+ delta[n_c] = c_xx[n_c] - c_aa[n_c];
+ if(delta[n_c]>NEAR || delta[n_c]<negNEAR) break_run=1;
+ }
+
+ if ( break_run )
+ {
+ for(n_c=0; n_c<components; n_c++){
+ c_dd[n_c] = psl[i+components+n_c];
+ c_bb[n_c] = psl[i+n_c];
+ }
+ break; /* out of while loop */
+ }
+ /* Run continues */
+ }
+ }
+
+ /* we only get here if the run is broken by
+ a non-matching symbol */
+
+ process_run(RUNcnt, NOEOLINE, 0);
+
+ /* This is the END_OF_RUN state */
+
+ for (n_c=0;n_c<components;n_c++) {
+ /* The end of run is done for each component */
+ Ix = c_xx[n_c];
+ Rb = c_bb[n_c];
+ Ra = c_aa[n_c];
+
+ /* Handle two special EOR states */
+ c_xx[n_c] = Ix = lossy_end_of_run(Ra, Rb, Ix, 0);
+
+ } /* loop for components */
+
+ } /* Run state block */
+ else {
+
+ /*************** REGULAR CONTEXT *******************/
+
+ predict(Rb, Ra, Rc);
+ cont = classmap[cont];
+
+ if (cont<0)
+ { SIGN=-1;
+ cont=-cont;
+ }
+ else
+ SIGN=1;
+
+ /* output a rice code */
+ lossy_regular_mode(cont, SIGN, Px, &Ix);
+ }
+
+ /* context for next pixel: */
+ if (!was_in_run) {
+
+ c_aa[color] = Ix;
+ sl[i] = Ix; /* store reconstructed x */
+
+ c_cc[color] = Rb;
+ c_bb[color] = Rd;
+ i++;
+ }
+ else {
+ for(n_c=0;n_c<components;n_c++) {
+ c_aa[n_c] = c_xx[n_c];
+ sl[i+n_c] = c_xx[n_c];
+
+ c_cc[n_c] = c_bb[n_c];
+ c_bb[n_c] = c_dd[n_c];
+ }
+ i += components;
+ }
+
+ } while (i <= (no+components-1));
+
+ } else
+
+ {
+
+ /***********************************************/
+ /* Do for all pixels in the row in 16-bit mode */
+ /***********************************************/
+
+ for (n_c=0; n_c<components; n_c++) {
+ c_cc[n_c] = ENDIAN16(psl[n_c]);
+ c_bb[n_c] = ENDIAN16(psl[components+n_c]);
+ c_aa[n_c] = ENDIAN16(sl[n_c]);
+ }
+
+ i = components; /* pixel indices in a scan line go from COMPONENTS to no */
+ color = -1;
+
+ do {
+ int RUNcnt;
+
+ if (!was_in_run) color = (color+1)%components;
+ else color = 0;
+ Ix = ENDIAN16(sl[i]);
+
+ for (n_c=0;n_c<components;n_c++)
+ c_xx[n_c] = ENDIAN16(sl[i+n_c]);
+
+ if (color == 0)
+ for (n_c=0;n_c<components;n_c++) {
+
+ c_dd[n_c] = ENDIAN16(psl[i+components+n_c]);
+
+ /* Context determination */
+
+ /* Quantize the gradient */
+ /* partial context number: if (b-e) is used
+ then its contribution is added after
+ determination of the run state.
+ Also, sign flipping, if any, occurs after run
+ state determination */
+ {
+ register int diff;
+
+ /* Following segment assumes that Sc <= LUTMAX16 */
+ /* This condition should have been checked when the
+ l ookup tables were built */
+ diff = c_dd[n_c] - c_bb[n_c];
+ if (diff < 0)
+ c_cont[n_c] = (diff > -LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 7*CREGIONS*CREGIONS;
+ else
+ c_cont[n_c] = (diff < LUTMAX16) ? vLUT[0][diff + LUTMAX16] : 8*CREGIONS*CREGIONS;
+ diff = c_bb[n_c] - c_cc[n_c];
+ if (diff < 0)
+ c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 7*CREGIONS;
+ else
+ c_cont[n_c] += (diff < LUTMAX16) ? vLUT[1][diff + LUTMAX16] : 8*CREGIONS;
+ diff = c_cc[n_c] - c_aa[n_c];
+ if (diff < 0)
+ c_cont[n_c] += (diff > -LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 7;
+ else
+ c_cont[n_c] += (diff < LUTMAX16) ? vLUT[2][diff + LUTMAX16] : 8;
+ }
+
+ }
+
+ Ra=c_aa[color];
+ Rb=c_bb[color];
+ Rc=c_cc[color];
+ Rd=c_dd[color];
+ cont=c_cont[color];
+
+ enter_run = was_in_run = test_run = 0;
+
+ if (color == 0) {
+ test_run = 1;
+ for (n_c=0;n_c<components;n_c++)
+ if (c_cont[n_c]!=0) {
+ test_run=0;
+ break;
+ }
+ }
+
+ if ( test_run ) {
+ /*************** RUN STATE ***************************/
+
+ int delta[MAX_COMPONENTS];
+
+ enter_run = was_in_run = 1;
+ for (n_c=0;n_c<components;n_c++) {
+ delta[n_c] = ENDIAN16(sl[i+n_c]) - c_aa[n_c];
+ if (delta[n_c]>NEAR || delta[n_c]<negNEAR) enter_run=0;
+ }
+ RUNcnt = 0;
+
+ if (enter_run)
+ {
+ while ( 1 ) {
+ ++RUNcnt;
+
+ for (n_c=0; n_c<components; n_c++)
+ sl[i+n_c] = ENDIAN16(c_aa[n_c]);
+
+ if((i=i+components)>(no+components-1)){
+ process_run(RUNcnt, EOLINE, 0);
+ return; /* end of line */
+ }
+
+ for (n_c=0;n_c<components;n_c++)
+ c_xx[n_c] = ENDIAN16(sl[i+n_c]);
+
+ break_run=0;
+ for (n_c=0;n_c<components;n_c++) {
+ delta[n_c] = c_xx[n_c] - c_aa[n_c];
+ if(delta[n_c]>NEAR || delta[n_c]<negNEAR) break_run=1;
+ }
+
+ if ( break_run )
+ {
+ for(n_c=0; n_c<components; n_c++){
+ c_dd[n_c] = ENDIAN16(psl[i+components+n_c]);
+ c_bb[n_c] = ENDIAN16(psl[i+n_c]);
+ }
+ break; /* out of while loop */
+ }
+ /* Run continues */
+ }
+ }
+
+ /* we only get here if the run is broken by
+ a non-matching symbol */
+
+ process_run(RUNcnt, NOEOLINE, 0);
+
+ /* This is the END_OF_RUN state */
+
+ for (n_c=0;n_c<components;n_c++) {
+ /* The end of run is done for each component */
+ Ix = c_xx[n_c];
+ Rb = c_bb[n_c];
+ Ra = c_aa[n_c];
+
+ /* Handle two special EOR states */
+ c_xx[n_c] = Ix = lossy_end_of_run(Ra, Rb, Ix, 0);
+
+ } /* loop for components */
+
+ } /* Run state block */
+ else {
+
+ /*************** REGULAR CONTEXT *******************/
+
+ predict(Rb, Ra, Rc);
+ cont = classmap[cont];
+
+ if (cont<0)
+ { SIGN=-1;
+ cont=-cont;
+ }
+ else
+ SIGN=1;
+
+ /* output a rice code */
+ lossy_regular_mode(cont, SIGN, Px, &Ix);
+ }
+
+ /* context for next pixel: */
+ if (!was_in_run) {
+
+ c_aa[color] = Ix;
+ sl[i] = ENDIAN16(Ix); /* store reconstructed x */
+
+ c_cc[color] = Rb;
+ c_bb[color] = Rd;
+ i++;
+ }
+ else {
+ for(n_c=0;n_c<components;n_c++) {
+ c_aa[n_c] = c_xx[n_c];
+ sl[i+n_c] = ENDIAN16(c_xx[n_c]);
+
+ c_cc[n_c] = c_bb[n_c];
+ c_bb[n_c] = c_dd[n_c];
+ }
+ i += components;
+ }
+
+ } while (i <= (no+components-1));
+
+ } /* ends 'if' for 8 or 16 bit */
+}
+
+
--- /dev/null
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+ =====================================
+ These programs are Copyright (c) University of British Columbia. All rights reserved.
+ They may be freely redistributed in their entirety provided that this copyright
+ notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+ COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+ Each program is provided as is, without any express or implied warranty,
+ without even the warranty of fitness for a particular purpose.
+
+ =========================================================
+ THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+ =========================================================
+
+ LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+ -------------------------------------------------------------------------------
+ (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1997.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+ COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+ RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+ ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+ OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+ FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+ INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+ SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+ TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+ OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+ HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+ SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+ THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+ FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+ IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+ MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+ OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+ -------------------------------------------------------------------------------
+*/
+
+/* melcode.c --- for processing in run mode
+ *
+ * Initial code by Alex Jakulin, Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995
+ *
+ * Color Enhancement: Guillermo Sapiro, August 1996
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <stdio.h>
+#include "global.h"
+#include "bitio.h"
+
+
+#define MELCSTATES 32 /* number of melcode states */
+
+static J[MELCSTATES] = {
+ 0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,5,5,6,6,7,
+ 7,8,9,10,11,12,13,14,15
+};
+
+static int melcstate[MAX_COMPONENTS], /* index to the state array */
+ melclen[MAX_COMPONENTS]; /* contents of the state array location
+ indexed by melcstate: the "expected"
+ run length is 2^melclen, shorter runs are
+ encoded by a 1 followed by the run length
+ in binary representation, wit a fixed length
+ of melclen bits */
+
+static unsigned long melcorder[MAX_COMPONENTS]; /* 2^ melclen */
+
+
+void init_process_run(int maxrun) /* maxrun is ignoreed when using MELCODE,
+ kept here for function compatibility */
+{
+ int n_c;
+
+ for (n_c=0;n_c<components;n_c++) {
+ melcstate[n_c] = 0;
+ melclen[n_c] = J[0];
+ melcorder[n_c] = 1<<melclen[n_c];
+ }
+}
+
+
+
+process_run(int runlen, int eoline, int color)
+{
+ int hits = 0;
+
+
+ while ( runlen >= melcorder[color] ) {
+ hits ++;
+ runlen -= melcorder[color];
+ if ( melcstate[color] < MELCSTATES ) {
+ melclen[color] = J[++melcstate[color]];
+ melcorder[color] = (1L<<melclen[color]);
+ }
+ }
+
+ /* send the required number of "hit" bits (one per occurrence
+ of a run of length melcorder). This number is never too big:
+ after 31 such "hit" bits, each "hit" would represent a run of 32K
+ pixels.
+ */
+ PUT_ONES(hits);
+
+ if ( eoline==EOLINE ) {
+ /* when the run is broken by end-of-line, if there is
+ a non-null remainder, send it as if it were
+ a max length run */
+ if ( runlen )
+ PUT_ONES(1);
+ return;
+ }
+
+ /* now send the length of the remainder, encoded as a 0 followed
+ by the length in binary representation, to melclen bits */
+ limit_reduce = melclen[color]+1;
+ PUTBITS(runlen,limit_reduce);
+
+ /* adjust melcoder parameters */
+ if ( melcstate[color] ) {
+ melclen[color] = J[--melcstate[color]];
+ melcorder[color] = (1L<<melclen[color]);
+ }
+ return;
+}
+
+
+
+
+void
+close_process_run()
+{
+/* retained for compatibility with ranked runs */
+}
--- /dev/null
+COMPILATION INSTRUCTIONS:
+1. Unpack archive.
+2. Run
+
+ make clean "name",
+ where "name" is
+ loco -- for encoder/decoder
+
+This program supports:
+"8 bit" images with 8 bits per color component or less.
+"16 bit" images with between 9 and 16 bits per color component.
+ component.
+
+3. Executable for compressor is "locoe," decompressor is "locod".
+
+USAGE:
+ General remarks for multiple-component images:
+
+ a) Encoder input (uncompressed) or decoder output (decompressed)
+ images are in either PGM (grayscale) or PPM (3-color) format.
+ This is of course NOT part of the JPEG-LS standard, and these
+ input/output formats were selected for this implementation only.
+
+ These formats have an ASCII header consisting of 3 lines of the
+ following form
+
+ * PGM (single component):
+
+ P5
+ cols rows
+ maxval
+
+ * PPM (3 components)
+
+ P6
+ cols rows
+ maxval
+
+
+ For PGM, the header is followed by cols*rows samples in binary
+ format, where cols and rows are the number of columns and rows,
+ respectively. A test image "cmpnd2g.pgm" is included in the
+ archive. Samples have 8 bits if maxval < 256, or 16 bits if
+ 256 <= maxval < 65536.
+
+ For PPM, the header is followed by cols*rows TRIPLETS of symbols in
+ binary format. Each symbol in a triplet represents a color plane
+ value (viewers usually interpret PPM triplets as RGB).
+
+ For more than 3 components, the PPM output file
+ format is extended to arbitrary m-tuples,
+ where m is the number of components.
+ The first row of the header is Px, where x = 10+m
+ (e.g. P15 for a 5-component image). P5 (m=1), P6 (m=3),
+ and P7 (m=4) are used, in addition to P11, P13, and P14,
+ respectively.
+
+ A multi-component image can be specified to the encoder either
+ as a list of PGM files (each representing a color plane), or
+ a single PPM-type file.
+
+ b) Three modes of operation are supported for multi-component
+ images (images of the type RGB, CMYK, YUV, etc).
+ We briefly describe them now, for details see the
+ JPEG-LS Working Draft document.
+
+ * Plane-interleaved. The image components are
+ compressed one after the other, in a completely
+ independent form. Only multiple input
+ (one PGM file per plane) in the encoder, and multiple
+ output (one PGM file per plane) in the decoder are supported
+ in this mode. This mode also works when m=1.
+
+ * Line-interleaved. One row per image component is processed
+ at a time, in an interleaved form.
+ Common context statistics for all the components
+ are used in this mode, and is plane independent otherwise.
+ Both multiple PGM and single PPM input
+ (output) are supported in the encoder (decoder).
+ Line-interleaved mode is the default mode of the encoder.
+ This mode also works when m=1.
+
+ * Sample-interleaved mode. One sample per image component is
+ processed at a time, using common statistics. Only single PPM
+ input and single PPM output are supported in this mode.
+
+ c) Which of the three multi-components modes runs faster depends
+ on the specific system (UNIX or PC).
+ For the line interleaved mode, the processing time relation
+ between the single and the multiple files input/output depends
+ on the system as well.
+
+ d) Sub-sampled components can be specified to the encoder (e.g.,
+ a YUV representation with the U and V components having a fraction
+ of the number of columns of the Y component).
+ For sub-sampled files, the input to the encoder must be
+ given as a series of PGM files in non-increasing order of size.
+ Sample-interleaved mode is not supported for images with
+ sub-sampled components.
+
+ e) The output of the encoder, and input to the decoder, is
+ always a unique JPEG-LS compressed file, independently of the
+ number of image components. All the image components share the
+ same header in JPEG-LS.
+
+
+ COMMAND LINES:
+
+ encoder:
+
+ locoe [flags] infile1 [infile2,infile3,...] [-ooutfile]
+
+ DEFAULTS:
+ infile1 : must be in PGM or PPM format
+ infile2,... : additional input files for Plane Interleaved
+ or Line Interleaved modes. Must be in PGM (P5) format
+ outfile : default is locoe.out
+
+ FLAGS, PARAMETERS:
+ -i<infile> : alternate input-specification, use -i- for stdin
+ -o<outfile> : output specification, use -o- for stdout
+ -c : mode for multi-component images:
+ 0: plane interleaved
+ 1: line interleaved (Default)
+ 2: sample interleaved
+ -n<error> or
+ -e<error> : Max allowed loss per symbol (default = 0, lossless).
+ -h : print help
+
+ Remarks:
+ The following optional flags allow specification of
+ parameters in the algorithm. These parameters,
+ if not default, are included in the JPEG-LS
+ header, and are part of the standard. Please
+ refer to Working Document for details.
+
+ -r : RESET (if not compiled with FIXRESET, see below)
+ -S<a,b,c> : Context modeling thresholds
+ -m<table> : Use mapping table where <table> is a file in the
+ format:
+ 1st byte of <table> is the Table ID, 2nd byte
+ of <table> is the Width of each table entry (in bytes),
+ 3rd - 6th byte of <table> is the Max Table Index Value
+ specified as an integer (4 bytes), 7th byte and on
+ are the table entries.
+ -t<num> : Use Restart Markers where <num> is the restart interval
+ (ie. number of MCU's between restart markers).\n");
+
+ *** Use only if you know what you are doing!
+
+ decoder:
+
+ locod [flags] [infile] [outfile1 [outfile2, ...]]
+
+ DEFAULTS:
+ infile = locoe.out
+ outfile1 = locod.out for single output file
+ outfile[1,2,...] = locod[1,2,...].out for multiple output files in
+ Plane or Line Interleaved mode
+ FLAGS, PARAMETERS:
+ outfile2, ... : multiple output specification for plane- or
+ line-interleaved mode
+ -i<infile> : alternate input specification, use -i- for stdin
+ -o<outfile> : alternate output specification, use -o- for stdout
+ -P : generate single (.ppm) output file for
+ sample/line-int. mode. Mandatory for sample-int. mode.
+
+EXAMPLES:
+
+ For the examples, assume:
+ * red.pgm, green.pgm, and blue.pgm are 3 color components of
+ a color image, of the same size.
+ * color.ppm is the color image corresponding to red.pgm, green.pgm, blue.pgm
+ * hotely.pgm, hotelu.pgm, hotelv.pgm are 3 components of a color image
+ sub-sampled in the horizontal direction 2:1:1
+
+
+ a) locoe red.pgm green.pgm blue.pgm
+
+ Compresses the three files using the default color mode (line int., c=1)
+ Compressed file is in locoe.out
+
+ locod
+
+ Decompresses locoe.out into 3 pgm files:
+ locod1.out, locod2.out, locod3.out
+
+ locod locoe.out a.pgm b.pgm c.pgm
+
+ Decompresses locoe.out into 3 pgm files: a.pgm, b.pgm, c.pgm
+
+ locod -P
+
+ Decompresses locoe.out into one ppm file: locod.out
+
+
+
+ b) locoe color.ppm
+
+ Same as (a), using single input
+
+ c) locoe -c0 red.pgm green.pgm blue.pgm
+
+ Compresses the three files using the plane interleaved color mode
+
+ locod
+
+ Decompresses locoe.out into 3 pgm files: locod1.out, locod2.out,
+ locod3.out In this case, since c=0, the command locod -P will give
+ an error.
+
+ d) locoe -c2 color.ppm
+
+ Compresses color.ppm with sample int. mode. Note that only one (ppm) input
+ file must be given in this mode.
+ Output is in locoe.out
+
+ locod -P
+
+ Decompresses locoe.out into locod.out. Note that -P must be given, since
+ for sample int. mode, only single output file is supported.
+
+ g) locoe -Sa5 -Sb9 red.pgm
+
+ Compress red.pgm with Sa=5, Sb=9, and Sc=DEFAULT
+
+ h) locoe -r128 green.pgm
+
+ Compresses green.pgm with RESET=128.
+
+
+OTHER CAVEATS, LIMITATIONS, ANNOYANCES, BUGS (?)
+=================================================
+* The makefiles included in this version are very simple and could lead to
+ a slower executable files than HP executables.
+* Annoyance: no spaces are allowed between flags and their arguments. This
+ will be fixed in a future version.
+* Other bugs, annoyances: you tell us.
+
+------------------------------------------------------------------------------
+
+Feedback to
+-----------
+The SPMG lab at the University of British Columbia:
+ismaeil R. Ismaeil ismail@ee.ubc.ca
+Dr. Faouzi Kossentini faouzi@ece.ubc.ca, or
--- /dev/null
+SPMG/JPEG-LS IMPLEMENTATION V.2.1
+=====================================
+These programs are Copyright (c) University of British Columbia. All rights reserved.
+They may be freely redistributed in their entirety provided that this copyright
+notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+Each program is provided as is, without any express or implied warranty,
+without even the warranty of fitness for a particular purpose.
+
+=========================================================
+THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+=========================================================
+
+LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+-------------------------------------------------------------------------------
+(c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1997.
+ HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+COMPLETENESS OF THE INFORMATION GIVEN HERE. ANY USE MADE OF, OR
+RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+ BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+OF THIS LICENSING AGREEMENT.
+ YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+FREE OF CHARGE OR FURTHER OBLIGATION. YOU MAY NOT, DIRECTLY OR
+INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+ YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+ THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+FINAL OR FULL IMPLEMENTATION OF THE STANDARD. HP GIVES NO EXPRESS OR
+IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+ HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+-------------------------------------------------------------------------------
+
+
+This software package contains an implementation of JPEG-LS, the
+emerging lossless/near-lossless compression standard for continuous-tone
+images being developed by ISO/IEC JTC1/SC29/WG1 (draft document FCD14495
+as of November 1997). The names of the executables in the software package
+derive from the acronym LOCO, as the core of the new standard is
+based on the LOCO-I algorithm (LOw COmplexity LOssless
+COmpression for Images) developed at Hewlett-Packard Laboratories
+(reference: M. Weinberger, G. Seroussi, G. Sapiro, "LOCO-I: A Low
+Complexity, Context-Based, Lossless Image Compression Algorithm,"
+Proc. IEEE Data Compression Conference, Snowbird, Utah, March-April 1996).
+
+The term "near-lossless compression" refers to a lossy algorithm
+for which each decompressed image sample differs from the corresponding
+original image sample by not more than a pre-specified value, the (usually
+small) "loss." Lossless compression corresponds to loss=0.
+Even though the term "continuous-tone image" refers in principle to any
+image whose components have more than one bit per sample, palletized images
+may require a reordering of the color palette for best compression results
+using LOCO-I on the array of color indices. This functionality is not
+implemented in the present software, although it is supported by the new
+standard, and is easy enough to implement with the tools given. Notice,
+however, that LOCO-I and JPEG-LS were not designed, and might not give
+optimal performance, for images that have been palletized through dithering.
+
+At various points in the README file, we refer to the FCD14495 draft
+standard. An electronic version of the draft is available from the official
+JPEG Web site at <http://www.disc.org.uk/public/jpegnew.htm> (a very nice
+site worth browsing in any case).
+
+
+THIS PACKAGE CONTAINS:
+----------------------
+
+ README.DIST - this file
+ Encoder - contains the encoder's source code.
+ Decoder - contains the dncoder's source code.
+ JLSEncoder.exe - the executable of a Win95/NT based
+ GUI implementation of the jpeg-ls codec
+ (The images lena8b.jls and lena24b.jls are provided so that
+ you can immediately "play" with the executable.)
+
+ Two table files which they can be used to test the mapping
+ tables:
+ "table_r" is for 8bpp PGM's which will reverse the colour.
+ "table24_no_red" is also for 8bpp PGM's and converts it to
+ a RGB PPM file but has all its red values 0.
+
+
+IMAGE FORMATS:
+--------------
+
+ Encoder input (uncompressed) or decoder output (decompressed)
+ images are in either PGM (grayscale) or PPM (3-color) format.
+ These input/output formats are NOT part of the JPEG-LS standard,
+ and they were selected for the sake of simplicity in this
+ implementation.
+
+ The PGM and PPM formats have an ASCII header consisting of 3 lines
+ of the following form:
+
+ * PGM (single component):
+
+ P5
+ cols rows
+ maxval
+
+ * PPM (3 components)
+
+ P6
+ cols rows
+ maxval
+
+ P5 and P6 appear verbatim in the header. The parameters "cols,"
+ "rows," and "maxval" are decimal numbers in ASCII representation.
+ For PGM, the header is followed by cols*rows samples in binary format,
+ where cols and rows are the number of columns and rows, respectively.
+ For this implementation, each sample occupies one 8-bit byte if
+ maxval < 256, or two bytes if 256 <= maxval < 65536. In the case of
+ 16-bit samples, BIG ENDIAN convention is used (most significant byte
+ first).
+
+ For PPM, the header is followed by cols*rows TRIPLETS of symbols in
+ binary format. Each symbol in a triplet represents a color plane
+ value (viewers usually interpret PPM triplets as RGB).
+
+ A multi-component image can be specified to the encoder either as
+ a list of PGM files (each representing a color plane), or as a single
+ PPM-type file.
+
+MULTIPLE-COMPONENT IMAGES:
+--------------------------
+
+ Three modes of operation are supported for multi-component images
+ (images of the type RGB, CMYK, YUV, etc). This is a subset of the
+ more general scan-based structure supported by JPEG-LS, and is
+ briefly described next:
+
+ * Plane-by-plane (PbP) compression. The image components are
+ compressed one after the other, in a completely independent
+ manner (in JPEG terminology, there is one component per scan).
+ In this mode, the input to the encoder is one PGM file per
+ component (i.e., no PPM input is allowed). The same applies to
+ the output of the decoder.
+
+ * Line-interleaved (LI) compression. One row per image component
+ is processed at a time, in an interleaved manner (in JPEG
+ terminology, all the components are encoded in the same
+ scan). Both multiple PGM file and single file PPM input
+ (output) are supported by the encoder (decoder). LI mode is
+ the default mode of this implementation.
+
+ * Sample-interleaved (SI) compression. One sample per image
+ component is processed at a time, in an interleaved manner
+ (again, all the components are encoded in the same scan).
+ In this mode, the input to the encoder (output from the
+ decoder) is always a single PPM file.
+
+ Remarks:
+
+ a) Sub-sampled components can be specified to the encoder in
+ PbP and LI modes (e.g., a YUV representation with the U and
+ V components having a fraction of the number of columns of
+ the Y component). For sub-sampled images, the input to the
+ encoder must be given as a sequence of PGM files. JPEG-LS
+ does not support sub-sampling in SI mode.
+
+ b) Regardless of the input format, the output of the encoder (input
+ to the decoder), is always a single JPEG-LS compressed bit-stream,
+ consisting of marker segments and compressed image data segments.
+
+ c) The SI mode is recommended only for computer generated compound
+ documents. On other image types, this mode is likely to be slower,
+ and compress worse, than the other modes.
+
+ d) For single-component images, the three modes are equivalent.
+ By default, the JPEG-LS header will indicate LI mode in this case.
+
+
+COMMAND LINES:
+--------------
+
+ encoder:
+ --------------------------
+
+ locoe [flags] infile1 [infile2,infile3,...] [-ooutfile]
+
+ FILES:
+ infile1 : Input file -- must be in PGM or PPM format. If there
+ are additional input files, then infile1 must be in
+ PGM format.
+ infile2,...: Additional input files for PbP or LI modes. Must be
+ in PGM format.
+ outfile : Output file in JPEG-LS format. Default = locoe.jls.
+
+ FLAGS, PARAMETERS:
+ (*** NOTE: no spaces allowed between a flag and its argument ***)
+
+ -i<infile> : Alternate input specification, use -i- for stdin.
+ -o<outfile>: Output specification, use -o- for stdout
+ (default=locoe.jls).
+ -c<num> : Mode for multi-component images (program default=1):
+ 0:plane-by-plane
+ 1:line-interleaved
+ 2:sample-interleaved.
+ -n<error> or
+ -e<error> : Max allowed loss per symbol (default = 0, lossless).
+
+ -h : Print help.
+
+ OTHER FLAGS AND PARAMETERS:
+ The following optional flags allow for overriding of JPEG-LS
+ default parameters. Please refer to JPEG-LS specification (FCD14495)
+ for details. *** Use only if you know what you are doing! ***
+
+ -r<num> : reset frequency
+ -Ta<num>,
+ -Tb<num>,
+ -Tc<num> : context modeling thresholds
+ -m<table> : Use mapping table where <table> is a file in the
+ format:
+ 1st byte of <table> is the Table ID, 2nd byte
+ of <table> is the Width of each table entry (in bytes),
+ 3rd - 6th byte of <table> is the Max Table Index Value
+ specified as an integer (4 bytes), 7th byte and on
+ are the table entries.
+ -t<num> : Use Restart Markers where <num> is the restart interval
+ (ie. number of MCU's between restart markers).
+
+
+ decoder:
+ --------------------------
+
+ locod [flags] [infile] [outfile1 [outfile2,outfile3,...]]
+
+ FILES:
+ infile : Input file in JPEG-LS format. Default = locoe.jls.
+ outfile[1,2,...] : Output files. If a single PPM file is generated
+ for a multi-component image (in LI or SI modes), the
+ default name is locod.out. In all other cases, the
+ default names for the of PGM output files are
+ locod1.out, locod2.out, locod3.out, ...
+
+ FLAGS, PARAMETERS:
+ -i<infile> : Alternate input specification, use -i- for stdin.
+ -o<outfile>: Alternate output specification, use -o- for stdout.
+ -P : Generate single PPM output file for SI or LI modes. This
+ is the default for SI mode. The default for LI mode (and
+ only option for PbP mode) is a sequence of PGM files.
+
+
+EXAMPLES:
+---------
+
+ For the examples, assume:
+ * red.pgm, green.pgm, and blue.pgm are 3 PGM components of a color
+ image, of the same size.
+ * color.ppm is the color PPM image corresponding to red.pgm,
+ green.pgm, blue.pgm
+ * hotely.pgm, hotelu.pgm, hotelv.pgm are 3 components of a color
+ image sub-sampled in the horizontal direction 2:1:1
+
+
+ a) locoe red.pgm green.pgm blue.pgm
+
+ Compresses the three components using the program default color
+ mode (LI, c=1). Compressed bit-stream is locoe.jls
+
+ locod
+
+ Decompresses locoe.jls into 3 PGM files:
+ locod1.out, locod2.out, locod3.out
+
+ locod locoe.jls a.pgm b.pgm c.pgm
+
+ Decompresses locoe.jls into 3 PGM files: a.pgm, b.pgm, c.pgm
+
+ locod -P
+
+ Decompresses locoe.jls into one PPM file: locod.out
+
+
+ b) locoe color.ppm
+
+ Same as (a), using single input
+
+
+ c) locoe -c0 red.pgm green.pgm blue.pgm
+
+ Compresses the three components in PbP mode. Compressed
+ bit-stream is locoe.jls
+
+ locod
+
+ Decompresses locoe.jls into 3 PGM files: locod1.out, locod2.out,
+ locod3.out.
+
+ locod -P
+
+ Since c=0, this command will produce an error.
+
+ d) locoe -c2 color.ppm
+
+ Compresses color.ppm in SI mode. Only one (PPM) input file
+ can be specified in this mode. Compressed bit stream is locoe.jls.
+
+ locod
+
+ Decompresses locoe.jls into locod.out, a PPM file.
+ Note that -P needs not be specified in this case.
+
+ g) locoe -Ta5 -Tb9 red.pgm
+
+ Compresses red.pgm with context thresholds Ta=5, Tb=9,
+ and Tc=DEFAULT
+
+ h) locoe -r128 green.pgm
+
+ Compresses green.pgm with RESET=128.
+
+
+OTHER CAVEATS, LIMITATIONS, ANNOYANCES, BUGS (?)
+=================================================
+
+ * Annoyance: no spaces are allowed between flags and their arguments.
+ This will be fixed in a future version.
+ * Other bugs, annoyances: guaranteed to exist. Please tell us
+ if you find significant ones. We will be thankful. However, we
+ cannot guarantee that we will maintain the code or that we will
+ satisfy requests for added functionality, recompilation,
+ executables for other operating systems, etc.
+
+Feedback to the SPMG/JPEGLS at UBC:
+www.spmg.ece.ubc.ca, or
+
+LOCO-I/JPEG-LS team at HP Labs:
+http://www.hpl.hp.com/loco
--- /dev/null
+This directory contains a subset of the JPEG-LS Public Domain Code.
+ISO/IEC JPEG-LS "The emerging lossless/near-lossless compression standard for
+continuous-tone still images"
+
+UBC's JPEG-LS Codec Implementation
+
+The software is available via anonymous ftp at
+ftp://dspftp.ece.ubc.ca/pub/jpeg-ls. Version 1.1 supports only the lossless part
+of the standard, while version 2 supports the lossless and near lossless mode of
+JPEG-LS. Version 2 also supports color and gray level images. Please note that
+version 2 is based on HP's LOCO-I/JPEG-LS implementation V.0.90.
+
+We only include enough of distribution to build libjpegls. We do not include
+either the standard executables that come with JPEG-LS (JLSEncoder.exe), or the
+sample dataset. Furthermore, the standard libjpegls build process is replaced
+with a CMake build process.
+
+We'd like to thank the UBC for releasing an open source JPEG-LS implementation
+
+Modifications
+-------------
+
+- modification were made so that compilation with gcc -Wall flags passes without warnings
+- remove all explicit tabs and replace by proper amount of spaces
+- remove all hardcoded makefile (hpux, vc)