From 8a8b4ae83ad19690f0cc51ebc9091d75ffc1cd8d Mon Sep 17 00:00:00 2001 From: malaterre Date: Sat, 4 Jun 2005 18:02:55 +0000 Subject: [PATCH] ENH: Adding an open source, BSD compatible jpeg-ls library. Thanks to UBC for releasing the sources --- src/gdcmjpegls/CMakeLists.txt | 5 + src/gdcmjpegls/Decoder/CMakeLists.txt | 55 + src/gdcmjpegls/Decoder/bitio.c | 256 +++++ src/gdcmjpegls/Decoder/bitio.h | 146 +++ src/gdcmjpegls/Decoder/decoder.c | 1509 +++++++++++++++++++++++++ src/gdcmjpegls/Decoder/global.c | 352 ++++++ src/gdcmjpegls/Decoder/global.h | 421 +++++++ src/gdcmjpegls/Decoder/initialize.c | 252 +++++ src/gdcmjpegls/Decoder/jpegmark.c | 549 +++++++++ src/gdcmjpegls/Decoder/jpegmark.h | 96 ++ src/gdcmjpegls/Decoder/lossless_d.c | 841 ++++++++++++++ src/gdcmjpegls/Decoder/lossy_d.c | 815 +++++++++++++ src/gdcmjpegls/Decoder/melcode.c | 156 +++ src/gdcmjpegls/Encoder/CMakeLists.txt | 56 + src/gdcmjpegls/Encoder/bitio.c | 119 ++ src/gdcmjpegls/Encoder/bitio.h | 159 +++ src/gdcmjpegls/Encoder/encoder.c | 1396 +++++++++++++++++++++++ src/gdcmjpegls/Encoder/global.c | 351 ++++++ src/gdcmjpegls/Encoder/global.h | 425 +++++++ src/gdcmjpegls/Encoder/initialize.c | 270 +++++ src/gdcmjpegls/Encoder/jpegmark.c | 344 ++++++ src/gdcmjpegls/Encoder/jpegmark.h | 86 ++ src/gdcmjpegls/Encoder/lossless_e.c | 845 ++++++++++++++ src/gdcmjpegls/Encoder/lossy_e.c | 915 +++++++++++++++ src/gdcmjpegls/Encoder/melcode.c | 141 +++ src/gdcmjpegls/README | 246 ++++ src/gdcmjpegls/README.DIST | 337 ++++++ src/gdcmjpegls/README.gdcm.txt | 25 + 28 files changed, 11168 insertions(+) create mode 100644 src/gdcmjpegls/CMakeLists.txt create mode 100644 src/gdcmjpegls/Decoder/CMakeLists.txt create mode 100644 src/gdcmjpegls/Decoder/bitio.c create mode 100644 src/gdcmjpegls/Decoder/bitio.h create mode 100644 src/gdcmjpegls/Decoder/decoder.c create mode 100644 src/gdcmjpegls/Decoder/global.c create mode 100644 src/gdcmjpegls/Decoder/global.h create mode 100644 src/gdcmjpegls/Decoder/initialize.c create mode 100644 src/gdcmjpegls/Decoder/jpegmark.c create mode 100644 src/gdcmjpegls/Decoder/jpegmark.h create mode 100644 src/gdcmjpegls/Decoder/lossless_d.c create mode 100644 src/gdcmjpegls/Decoder/lossy_d.c create mode 100644 src/gdcmjpegls/Decoder/melcode.c create mode 100644 src/gdcmjpegls/Encoder/CMakeLists.txt create mode 100644 src/gdcmjpegls/Encoder/bitio.c create mode 100644 src/gdcmjpegls/Encoder/bitio.h create mode 100644 src/gdcmjpegls/Encoder/encoder.c create mode 100644 src/gdcmjpegls/Encoder/global.c create mode 100644 src/gdcmjpegls/Encoder/global.h create mode 100644 src/gdcmjpegls/Encoder/initialize.c create mode 100644 src/gdcmjpegls/Encoder/jpegmark.c create mode 100644 src/gdcmjpegls/Encoder/jpegmark.h create mode 100644 src/gdcmjpegls/Encoder/lossless_e.c create mode 100644 src/gdcmjpegls/Encoder/lossy_e.c create mode 100644 src/gdcmjpegls/Encoder/melcode.c create mode 100644 src/gdcmjpegls/README create mode 100644 src/gdcmjpegls/README.DIST create mode 100644 src/gdcmjpegls/README.gdcm.txt diff --git a/src/gdcmjpegls/CMakeLists.txt b/src/gdcmjpegls/CMakeLists.txt new file mode 100644 index 00000000..b1aa20e0 --- /dev/null +++ b/src/gdcmjpegls/CMakeLists.txt @@ -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 index 00000000..8de55c3d --- /dev/null +++ b/src/gdcmjpegls/Decoder/CMakeLists.txt @@ -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 index 00000000..8353b108 --- /dev/null +++ b/src/gdcmjpegls/Decoder/bitio.c @@ -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 7 ) { + fprintf(stderr,"bitiflush: inconsistent bits=%d filled=%d k=%d\n",bits,filled,k); + exit(10); + } + discard = filled-k; + if ( treg != (reg< 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 index 00000000..c9258eab --- /dev/null +++ b/src/gdcmjpegls/Decoder/bitio.h @@ -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 index 00000000..99745ff8 --- /dev/null +++ b/src/gdcmjpegls/Decoder/decoder.c @@ -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 +#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; iWt == 2) + { + unsigned short* line16; + line16 = (unsigned short*)safealloc(cols*2); + + maptable = head_scan[0]->TABLE[head_scan[0]->TID]; + + for (i=0; iWt == 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> 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;i1)) { + 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_sT1=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;isamplingx[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;imax_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>=1, i++); + if ( alpha != (1<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;iWt==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;iWt==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;i1) && (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 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_c1) + for (my_i=0;my_i1) + for (my_i=0;my_i1) + for (my_i=0;my_i1) + for (my_i=0;my_i 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 : Alternate input specification, use -i- for stdin.\n\ +-o : 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 index 00000000..62922b4f --- /dev/null +++ b/src/gdcmjpegls/Decoder/global.c @@ -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 +#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->T1NEAR+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;icomp;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;icomp;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 index 00000000..8f80731f --- /dev/null +++ b/src/gdcmjpegls/Decoder/global.h @@ -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 +#include +#include + +#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 index 00000000..6fe30cce --- /dev/null +++ b/src/gdcmjpegls/Decoder/initialize.c @@ -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 +#include + +#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 +#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>= 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<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; icomp; 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; icomp; 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; ialp = 1<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>= 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; icomp_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 index 00000000..2b1a02be --- /dev/null +++ b/src/gdcmjpegls/Decoder/jpegmark.h @@ -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 index 00000000..a99a73e9 --- /dev/null +++ b/src/gdcmjpegls/Decoder/lossless_d.c @@ -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 +#include + + +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]= 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 0 ) { /* run of nonzero length, otherwise + we go directly to the end-of-run + state */ + do { + for (n_c=0;n_c 0); + + if (i > no+components-1) + /* end of line */ + return 0; + + /* update context pixels */ + for (n_c=0;n_c -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 0 ) { /* run of nonzero length, otherwise + we go directly to the end-of-run + state */ + do { + for (n_c=0;n_c 0); + + if (i > no+components-1) + /* end of line */ + return 0; + + /* update context pixels */ + for (n_c=0;n_c +#include + +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] 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 0 ) { /* run of nonzero length, otherwise + we go directly to the end-of-run + state */ + do { + for (n_c=0;n_c 0); + + if (i > no+components-1) + /* end of line */ + return 0; + + /* update context pixels */ + for (n_c=0;n_c -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 0 ) { /* run of nonzero length, otherwise + we go directly to the end-of-run + state */ + do { + for (n_c=0;n_c 0); + + if (i > no+components-1) + /* end of line */ + return 0; + + /* update context pixels */ + for (n_c=0;n_c +#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> 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<> 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 index 00000000..6e00199a --- /dev/null +++ b/src/gdcmjpegls/Encoder/bitio.h @@ -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<= 24 ) { \ + putbits((1<<24)-1,24); \ + nn -= 24; \ + } \ + if ( nn ) putbits((1<= 0 && ((1<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 index 00000000..81c34dae --- /dev/null +++ b/src/gdcmjpegls/Encoder/encoder.c @@ -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; i1) 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;i1 ) + 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>=1, i++); + if ( alpha != (1< 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;i1) && (multi)) { + min_size_columns=c_columns[components-1]; + min_size_rows=c_rows[components-1]; + for (i=0;i4) || ((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;imin_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;icolumns=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;icomp_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_salp = 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_scomp=1; + head_scan[n_s]->comp_ids[0]=n_s+1; + } + } + else { + for (n_s=0;n_scomp=head_frame->comp; + for (n_c=0;n_ccomp;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_sT1=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 1) { + for (my_i=0;my_i 1) { + for (my_i=0;my_i1) + for (my_i=0;my_i : Alternate input specification, use -i- for stdin.\n\ +-o: Output specification, use -o- for stdout (default=%s).\n\ +-Ta, -Tb, -Tc: 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 : Reset interval for statistics (standard default=%d).\n\ +", "locoe", OUTFILE COMPSUFFIX,DEFAULT_RESET); + fprintf(stderr,"\ +-c : 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 or\n\ +-e : Max allowed loss per symbol (default = %d).\n", +DEF_NEAR); + +fprintf(stderr,"\ +-m : Use mapping table where
is a file in the format:\n\ + 1st byte of
is the Table ID,\n\ + 2nd byte of
is the Width of each table entry (in bytes),\n\ + 3rd - 6th byte of
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 : Use Restart Markers where 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 index 00000000..01eebf5d --- /dev/null +++ b/src/gdcmjpegls/Encoder/global.c @@ -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 +#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->T1NEAR+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;icomp;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;icomp;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 index 00000000..47c37702 --- /dev/null +++ b/src/gdcmjpegls/Encoder/global.h @@ -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 +#include +#include + +#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 index 00000000..2d4b6f2e --- /dev/null +++ b/src/gdcmjpegls/Encoder/initialize.c @@ -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 +#include + +#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 +#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; i4) { + 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>= 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<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; icomp; 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; icomp; 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 index 00000000..452949e0 --- /dev/null +++ b/src/gdcmjpegls/Encoder/jpegmark.h @@ -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 index 00000000..b39aee10 --- /dev/null +++ b/src/gdcmjpegls/Encoder/lossless_e.c @@ -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 +#include + +#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<>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)>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< 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(no+components-1)){ + process_run(RUNcnt, EOLINE, 0); + return; /* end of line */ + } + + for (n_c=0;n_c -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(no+components-1)){ + process_run(RUNcnt, EOLINE, 0); + return; /* end of line */ + } + + for (n_c=0;n_c +#include + +#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<= 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]>= 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< 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_cNEAR || delta[n_c](no+components-1)){ + process_run(RUNcnt, EOLINE, 0); + return; /* end of line */ + } + + for (n_c=0;n_cNEAR || delta[n_c] -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_cNEAR || delta[n_c](no+components-1)){ + process_run(RUNcnt, EOLINE, 0); + return; /* end of line */ + } + + for (n_c=0;n_cNEAR || delta[n_c] +#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= melcorder[color] ) { + hits ++; + runlen -= melcorder[color]; + if ( melcstate[color] < MELCSTATES ) { + melclen[color] = J[++melcstate[color]]; + melcorder[color] = (1L< : alternate input-specification, use -i- for stdin + -o : output specification, use -o- for stdout + -c : mode for multi-component images: + 0: plane interleaved + 1: line interleaved (Default) + 2: sample interleaved + -n or + -e : 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 : Context modeling thresholds + -m
: Use mapping table where
is a file in the + format: + 1st byte of
is the Table ID, 2nd byte + of
is the Width of each table entry (in bytes), + 3rd - 6th byte of
is the Max Table Index Value + specified as an integer (4 bytes), 7th byte and on + are the table entries. + -t : Use Restart Markers where 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 : alternate input specification, use -i- for stdin + -o : 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 index 00000000..bad44e39 --- /dev/null +++ b/src/gdcmjpegls/README.DIST @@ -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 (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 : Alternate input specification, use -i- for stdin. + -o: Output specification, use -o- for stdout + (default=locoe.jls). + -c : Mode for multi-component images (program default=1): + 0:plane-by-plane + 1:line-interleaved + 2:sample-interleaved. + -n or + -e : 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 : reset frequency + -Ta, + -Tb, + -Tc : context modeling thresholds + -m
: Use mapping table where
is a file in the + format: + 1st byte of
is the Table ID, 2nd byte + of
is the Width of each table entry (in bytes), + 3rd - 6th byte of
is the Max Table Index Value + specified as an integer (4 bytes), 7th byte and on + are the table entries. + -t : Use Restart Markers where 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 : Alternate input specification, use -i- for stdin. + -o: 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 index 00000000..9de1e1ff --- /dev/null +++ b/src/gdcmjpegls/README.gdcm.txt @@ -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) -- 2.46.0