]> Creatis software - gdcm.git/commitdiff
ENH: Adding an open source, BSD compatible jpeg-ls library. Thanks to UBC for releasi...
authormalaterre <malaterre>
Sat, 4 Jun 2005 18:02:55 +0000 (18:02 +0000)
committermalaterre <malaterre>
Sat, 4 Jun 2005 18:02:55 +0000 (18:02 +0000)
28 files changed:
src/gdcmjpegls/CMakeLists.txt [new file with mode: 0644]
src/gdcmjpegls/Decoder/CMakeLists.txt [new file with mode: 0644]
src/gdcmjpegls/Decoder/bitio.c [new file with mode: 0644]
src/gdcmjpegls/Decoder/bitio.h [new file with mode: 0644]
src/gdcmjpegls/Decoder/decoder.c [new file with mode: 0644]
src/gdcmjpegls/Decoder/global.c [new file with mode: 0644]
src/gdcmjpegls/Decoder/global.h [new file with mode: 0644]
src/gdcmjpegls/Decoder/initialize.c [new file with mode: 0644]
src/gdcmjpegls/Decoder/jpegmark.c [new file with mode: 0644]
src/gdcmjpegls/Decoder/jpegmark.h [new file with mode: 0644]
src/gdcmjpegls/Decoder/lossless_d.c [new file with mode: 0644]
src/gdcmjpegls/Decoder/lossy_d.c [new file with mode: 0644]
src/gdcmjpegls/Decoder/melcode.c [new file with mode: 0644]
src/gdcmjpegls/Encoder/CMakeLists.txt [new file with mode: 0644]
src/gdcmjpegls/Encoder/bitio.c [new file with mode: 0644]
src/gdcmjpegls/Encoder/bitio.h [new file with mode: 0644]
src/gdcmjpegls/Encoder/encoder.c [new file with mode: 0644]
src/gdcmjpegls/Encoder/global.c [new file with mode: 0644]
src/gdcmjpegls/Encoder/global.h [new file with mode: 0644]
src/gdcmjpegls/Encoder/initialize.c [new file with mode: 0644]
src/gdcmjpegls/Encoder/jpegmark.c [new file with mode: 0644]
src/gdcmjpegls/Encoder/jpegmark.h [new file with mode: 0644]
src/gdcmjpegls/Encoder/lossless_e.c [new file with mode: 0644]
src/gdcmjpegls/Encoder/lossy_e.c [new file with mode: 0644]
src/gdcmjpegls/Encoder/melcode.c [new file with mode: 0644]
src/gdcmjpegls/README [new file with mode: 0644]
src/gdcmjpegls/README.DIST [new file with mode: 0644]
src/gdcmjpegls/README.gdcm.txt [new file with mode: 0644]

diff --git a/src/gdcmjpegls/CMakeLists.txt b/src/gdcmjpegls/CMakeLists.txt
new file mode 100644 (file)
index 0000000..b1aa20e
--- /dev/null
@@ -0,0 +1,5 @@
+PROJECT(GDCMJPEGLS)
+
+SUBDIRS(Decoder
+  # Encoder
+  )
diff --git a/src/gdcmjpegls/Decoder/CMakeLists.txt b/src/gdcmjpegls/Decoder/CMakeLists.txt
new file mode 100644 (file)
index 0000000..8de55c3
--- /dev/null
@@ -0,0 +1,55 @@
+#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
diff --git a/src/gdcmjpegls/Decoder/bitio.c b/src/gdcmjpegls/Decoder/bitio.c
new file mode 100644 (file)
index 0000000..8353b10
--- /dev/null
@@ -0,0 +1,256 @@
+/* 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
diff --git a/src/gdcmjpegls/Decoder/bitio.h b/src/gdcmjpegls/Decoder/bitio.h
new file mode 100644 (file)
index 0000000..c9258ea
--- /dev/null
@@ -0,0 +1,146 @@
+/* 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 */
diff --git a/src/gdcmjpegls/Decoder/decoder.c b/src/gdcmjpegls/Decoder/decoder.c
new file mode 100644 (file)
index 0000000..99745ff
--- /dev/null
@@ -0,0 +1,1509 @@
+/* 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);
+}
+
diff --git a/src/gdcmjpegls/Decoder/global.c b/src/gdcmjpegls/Decoder/global.c
new file mode 100644 (file)
index 0000000..62922b4
--- /dev/null
@@ -0,0 +1,352 @@
+/* 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);
+}
diff --git a/src/gdcmjpegls/Decoder/global.h b/src/gdcmjpegls/Decoder/global.h
new file mode 100644 (file)
index 0000000..8f80731
--- /dev/null
@@ -0,0 +1,421 @@
+/* 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
diff --git a/src/gdcmjpegls/Decoder/initialize.c b/src/gdcmjpegls/Decoder/initialize.c
new file mode 100644 (file)
index 0000000..6fe30cc
--- /dev/null
@@ -0,0 +1,252 @@
+/* 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;
+  }
+}
+
+
+
diff --git a/src/gdcmjpegls/Decoder/jpegmark.c b/src/gdcmjpegls/Decoder/jpegmark.c
new file mode 100644 (file)
index 0000000..64dcc88
--- /dev/null
@@ -0,0 +1,549 @@
+/* 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;
+  
+}
diff --git a/src/gdcmjpegls/Decoder/jpegmark.h b/src/gdcmjpegls/Decoder/jpegmark.h
new file mode 100644 (file)
index 0000000..2b1a02b
--- /dev/null
@@ -0,0 +1,96 @@
+/* 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);
diff --git a/src/gdcmjpegls/Decoder/lossless_d.c b/src/gdcmjpegls/Decoder/lossless_d.c
new file mode 100644 (file)
index 0000000..a99a73e
--- /dev/null
@@ -0,0 +1,841 @@
+/* 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;
+}
diff --git a/src/gdcmjpegls/Decoder/lossy_d.c b/src/gdcmjpegls/Decoder/lossy_d.c
new file mode 100644 (file)
index 0000000..7046e3e
--- /dev/null
@@ -0,0 +1,815 @@
+/* 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;
+}
diff --git a/src/gdcmjpegls/Decoder/melcode.c b/src/gdcmjpegls/Decoder/melcode.c
new file mode 100644 (file)
index 0000000..82e5cbc
--- /dev/null
@@ -0,0 +1,156 @@
+/* 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 */
+}
diff --git a/src/gdcmjpegls/Encoder/CMakeLists.txt b/src/gdcmjpegls/Encoder/CMakeLists.txt
new file mode 100644 (file)
index 0000000..4ae9e9d
--- /dev/null
@@ -0,0 +1,56 @@
+#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
diff --git a/src/gdcmjpegls/Encoder/bitio.c b/src/gdcmjpegls/Encoder/bitio.c
new file mode 100644 (file)
index 0000000..40e0ae8
--- /dev/null
@@ -0,0 +1,119 @@
+/* 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;
+}
diff --git a/src/gdcmjpegls/Encoder/bitio.h b/src/gdcmjpegls/Encoder/bitio.h
new file mode 100644 (file)
index 0000000..6e00199
--- /dev/null
@@ -0,0 +1,159 @@
+/* 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 */
diff --git a/src/gdcmjpegls/Encoder/encoder.c b/src/gdcmjpegls/Encoder/encoder.c
new file mode 100644 (file)
index 0000000..81c34da
--- /dev/null
@@ -0,0 +1,1396 @@
+/* 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;
+}
+
diff --git a/src/gdcmjpegls/Encoder/global.c b/src/gdcmjpegls/Encoder/global.c
new file mode 100644 (file)
index 0000000..01eebf5
--- /dev/null
@@ -0,0 +1,351 @@
+/* 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);
+}
diff --git a/src/gdcmjpegls/Encoder/global.h b/src/gdcmjpegls/Encoder/global.h
new file mode 100644 (file)
index 0000000..47c3770
--- /dev/null
@@ -0,0 +1,425 @@
+/* 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
diff --git a/src/gdcmjpegls/Encoder/initialize.c b/src/gdcmjpegls/Encoder/initialize.c
new file mode 100644 (file)
index 0000000..2d4b6f2
--- /dev/null
@@ -0,0 +1,270 @@
+/* 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;
+  }
+}
diff --git a/src/gdcmjpegls/Encoder/jpegmark.c b/src/gdcmjpegls/Encoder/jpegmark.c
new file mode 100644 (file)
index 0000000..1274576
--- /dev/null
@@ -0,0 +1,344 @@
+/* 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;
+}
diff --git a/src/gdcmjpegls/Encoder/jpegmark.h b/src/gdcmjpegls/Encoder/jpegmark.h
new file mode 100644 (file)
index 0000000..452949e
--- /dev/null
@@ -0,0 +1,86 @@
+/* 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);
diff --git a/src/gdcmjpegls/Encoder/lossless_e.c b/src/gdcmjpegls/Encoder/lossless_e.c
new file mode 100644 (file)
index 0000000..b39aee1
--- /dev/null
@@ -0,0 +1,845 @@
+/* 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 */
+
+}
diff --git a/src/gdcmjpegls/Encoder/lossy_e.c b/src/gdcmjpegls/Encoder/lossy_e.c
new file mode 100644 (file)
index 0000000..d128588
--- /dev/null
@@ -0,0 +1,915 @@
+/* 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 */
+}
+
+
diff --git a/src/gdcmjpegls/Encoder/melcode.c b/src/gdcmjpegls/Encoder/melcode.c
new file mode 100644 (file)
index 0000000..da4412b
--- /dev/null
@@ -0,0 +1,141 @@
+/* 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 */
+}
diff --git a/src/gdcmjpegls/README b/src/gdcmjpegls/README
new file mode 100644 (file)
index 0000000..d660e11
--- /dev/null
@@ -0,0 +1,246 @@
+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 
diff --git a/src/gdcmjpegls/README.DIST b/src/gdcmjpegls/README.DIST
new file mode 100644 (file)
index 0000000..bad44e3
--- /dev/null
@@ -0,0 +1,337 @@
+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
diff --git a/src/gdcmjpegls/README.gdcm.txt b/src/gdcmjpegls/README.gdcm.txt
new file mode 100644 (file)
index 0000000..9de1e1f
--- /dev/null
@@ -0,0 +1,25 @@
+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)