]> Creatis software - gdcm.git/blobdiff - src/gdcmjpegls/Decoder/global.c
ENH: Adding an open source, BSD compatible jpeg-ls library. Thanks to UBC for releasi...
[gdcm.git] / src / gdcmjpegls / Decoder / global.c
diff --git a/src/gdcmjpegls/Decoder/global.c b/src/gdcmjpegls/Decoder/global.c
new file mode 100644 (file)
index 0000000..62922b4
--- /dev/null
@@ -0,0 +1,352 @@
+/* SPMG/JPEG-LS IMPLEMENTATION V.2.1
+   =====================================
+   These programs are Copyright (c) University of British Columbia. All rights reserved.
+   They may be freely redistributed in their entirety provided that this copyright
+   notice is not removed.  THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
+   COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
+   Each program is provided as is, without any express or implied warranty,
+   without even the warranty of fitness for a particular purpose.
+
+   =========================================================
+   THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
+   =========================================================
+
+   LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
+   -------------------------------------------------------------------------------
+   (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
+        HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
+   COMPLETENESS OF THE INFORMATION GIVEN HERE.  ANY USE MADE OF, OR
+   RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
+        BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
+   ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
+   OF THIS LICENSING AGREEMENT.
+        YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
+   FREE OF CHARGE OR FURTHER OBLIGATION.  YOU MAY NOT, DIRECTLY OR
+   INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
+   SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
+   TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
+        YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
+   OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
+   HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
+   SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
+        THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
+   THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
+   FINAL OR FULL IMPLEMENTATION OF THE STANDARD.  HP GIVES NO EXPRESS OR
+   IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
+   MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
+        HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
+   OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
+   -------------------------------------------------------------------------------
+*/
+
+/* global.c --- support and portability routines: error handling, safe memory
+ *                              management, etc.
+ *
+ * Initial code by Alex Jakulin,  Aug. 1995
+ *
+ * Modified and optimized: Gadiel Seroussi, October 1995 - ...
+ *
+ * Modified and added Restart marker and input tables by:
+ * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
+ */
+
+#include <time.h>
+#include "global.h"
+
+
+
+char *disclaimer = "\
+This program is Copyright (c) University of British Columbia.\n\
+All rights reserved. It may be freely redistributed in its\n\
+entirety provided that this copyright notice is not removed.\n\
+It may not be sold for profit or incorporated in commercial programs\n\
+without the written permission of the copyright holder.\n\
+";
+
+
+
+/* I/O files */
+FILE *in, *out;
+FILE *c_in[MAX_COMPONENTS];
+FILE *c_out[MAX_COMPONENTS];
+FILE *msgfile = stdout;
+
+/* Context quantization thresholds  - initially unset */
+int     T3 = -1,
+        T2 = -1,
+        T1 = -1,
+    Ta = -1;
+
+
+int verbose = 1;   /* verbosity level */
+int nopause = 0;   /* whether to pause the legal notice or not */
+int nolegal = 0;   /* whether to print the legal notice or not */
+
+
+/* parameters for LOSSY images */
+int  quant,          /* quantization = 2*NEAR+1 */
+  beta,    /* size of extended alphabet */
+  qbeta,          /* size of quantized alphabet */
+  ceil_half_qbeta, /* ceil(qbeta/2) */
+  negNEAR,            /* -NEAR */
+  alpha1eps;       /* alpha-1+NEAR */
+
+int  NEAR = DEF_NEAR;   /* loss tolerance per symbol, fixed at 0 for lossless */
+int bpp,    /* bits per sample */
+  qbpp,   /* bits per sample for quantized prediction errors */
+    limit,  /* limit for unary part of Golomb code */
+    limit_reduce;  /* reduction on above for EOR states */
+
+
+/* define color mode strings */
+char *plane_int_string = "plane by plane",
+   *line_int_string = "line intlv",
+   *pixel_int_string = "sample intlv";
+
+
+/* function to print out error messages */
+void error(char *msg) {
+  fprintf(stderr, msg);
+  exit(-1);
+}
+
+
+/* function to safely call malloc */
+void *safealloc(size_t size) {
+  void *temp;
+
+  temp = malloc(size);
+    if (temp == NULL)
+    error("\nsafealloc: Out of memory. Aborting...\n");
+  return temp;
+}
+
+
+/* function to safely call calloc **/
+void *safecalloc(size_t numels, size_t size) {
+  void *temp;
+
+  temp = calloc(numels, size);
+    if (temp == NULL)
+    error("\nsafecalloc: Out of memory. Aborting...\n");
+  return temp;
+}
+
+
+/*
+ * TIMING ROUTINES
+ */
+
+
+double get_utime()
+{
+  clock_t c;
+
+  return (double)clock()/CLOCKS_PER_SEC;
+}
+
+
+/* Set thresholds to default unless specified by header: */
+set_thresholds(int alfa, int NEAR, int *T1p, int *T2p, int *T3p)
+{
+  int lambda,
+      ilambda = 256/alfa,
+      quant = 2*NEAR+1,
+      T1 = *T1p, 
+      T2 = *T2p, 
+      T3 = *T3p;
+  
+  if (alfa<4096)
+     lambda = (alfa+127)/256;
+        else
+     lambda = (4096+127)/256;
+
+
+
+  if ( T1 <= 0 )  {
+    /* compute lossless default */
+    if ( lambda ) 
+      T1 = lambda*(BASIC_T1 - 2) + 2;
+    else {  /* alphabet < 8 bits */
+      T1 = BASIC_T1/ilambda;
+      if ( T1 < 2 ) T1 = 2;
+    }
+    /* adjust for lossy */
+    T1 += 3*NEAR;
+
+    /* check that the default threshold is in bounds */
+    if ( T1 < NEAR+1 || T1 > (alfa-1) ) 
+         T1 = NEAR+1;         /* eliminates the threshold */
+  }
+  if ( T2 <= 0 )  {
+    /* compute lossless default */
+    if ( lambda ) 
+      T2 = lambda*(BASIC_T2 - 3) + 3;
+    else {
+      T2 = BASIC_T2/ilambda;
+      if ( T2 < 3 ) T2 = 3;
+    }
+    /* adjust for lossy */
+    T2 += 5*NEAR;
+
+    /* check that the default threshold is in bounds */
+    if ( T2 < T1 || T2 > (alfa-1) ) 
+         T2 = T1;         /* eliminates the threshold */
+  }
+  if ( T3 <= 0 )  {
+    /* compute lossless default */
+    if ( lambda ) 
+      T3 = lambda*(BASIC_T3 - 4) + 4;
+    else {
+      T3 = BASIC_T3/ilambda;
+      if ( T3 < 4 ) T3 = 4;
+    }
+    /* adjust for lossy */
+    T3 += 7*NEAR;
+
+    /* check that the default threshold is in bounds */
+    if ( T3 < T2 || T3 > (alfa-1) ) 
+         T3 = T2;         /* eliminates the threshold */
+  }
+
+  *T1p = T1;
+  *T2p = T2;
+  *T3p = T3;
+  return 0;
+}
+
+
+
+
+/* We first check compatibility with JPEG-LS, then with this implementation */
+
+void check_compatibility(jpeg_ls_header *head_frame, jpeg_ls_header *head_scan, int n_s) 
+{
+
+    int  number_of_scans,i;  
+    int maxreset;
+
+/* Check implemented color modes */
+    if ((head_scan->color_mode>PIXEL_INT)) {
+  fprintf(stderr,"Color mode %d not supported\n",head_scan->color_mode);
+  exit(10);
+    }
+
+    if (head_scan->color_mode==PLANE_INT) 
+  number_of_scans=head_frame->comp;
+    else 
+  number_of_scans=1;
+    
+
+/* Test standard compatibility */
+
+    if (head_frame->columns<=0 || head_frame->rows <=0) {
+  fprintf(stderr,"Image size must be positive for this implementation.\n");
+  exit(10);
+    }
+
+    if (head_frame->alp<4) {
+  fprintf(stderr,"Alphabet size must be >= 4, got %d\n",head_frame->alp);
+  exit(10);
+    }
+
+
+    if (head_scan->T1>head_scan->T2 || head_scan->T2>head_scan->T3 ||
+  head_scan->T1<head_scan->NEAR+1 || head_scan->T3>=head_scan->alp ) {
+  fprintf(stderr,"Bad thresholds: must be %d <= Ta <= Tb <= Tc <= %d\n",
+      head_scan->NEAR+1,head_scan->alp-1);
+  exit(10);
+    }
+
+    if (head_frame->comp>255) {
+  fprintf(stderr,"Too many components (must be less than 255)\n");
+  exit(10);
+    }
+
+    if (head_scan->NEAR>=head_scan->alp) {
+  fprintf(stderr,"Error for near-lossless must be smaller than alphabet (%d), got %d",head_scan->alp,head_scan->NEAR);
+  exit(10);
+    }
+
+    /*
+    if (head_scan->RES < MINRESET || head_scan->RES >= head_scan->alp ) {
+  fprintf(stderr,"Reset parameter must be between %d and %d\n",
+          MINRESET, head_scan->alp-1);
+  exit(10);
+    }
+    */
+
+    maxreset = (head_scan->alp >= 256)? (head_scan->alp-1):255;
+
+    if (head_scan->RES < MINRESET || head_scan->RES > maxreset ) {
+  fprintf(stderr,"Reset parameter must be between %d and %d\n",
+          MINRESET, head_scan->alp-1);
+  exit(10);
+    }
+
+    for (i=0;i<head_frame->comp;i++)
+  if (head_frame->comp_ids[i] != (i+1)) {
+     fprintf(stderr,"Components id in frame not compatible with this implementation.\n");
+     exit(10);
+        }
+
+    if (number_of_scans == 1) {
+  if (head_frame->comp != head_scan->comp) {
+     fprintf(stderr,"In this implementation, when single scan, all components must be in the scan.\n");
+     exit(10);
+        }
+        for (i=0;i<head_frame->comp;i++)
+    if (head_scan->comp_ids[i] != (i+1)) {
+       fprintf(stderr,"Components id in single scan not compatible with this implementation.\n");
+       exit(10);
+          }
+
+    }
+    else {
+  if (head_scan->comp != 1) {
+     fprintf(stderr,"Only 1 component per scan for plane interleaved mode\n");
+     exit(10);
+        }
+        if (head_scan->comp_ids[0] != (n_s+1)) {
+     fprintf(stderr,"Components id in multiple scan not compatible with this implementation.\n");
+     exit(10);
+        }
+
+    }
+}
+
+
+/* for writing disclaimer to command line in DOS */
+
+char *ttyfilename = "CON";
+
+#define PAUSE  20
+
+fprint_disclaimer(FILE *fp, int nopause)
+{
+    char *p0, *p1;
+    FILE *ttyf;
+    int  i, c;
+
+    nopause = nopause | !isatty(fileno(fp));
+
+    if ( !nopause && (ttyf=fopen(ttyfilename,"r"))==NULL ) {
+  nopause = 1;
+    }
+
+    for ( i=1, p0=disclaimer; ; i++ ) {
+  if ( !(*p0)  ) break;
+  if ( !nopause && i%PAUSE==0 ) {
+      fflush(fp);
+      fprintf(stderr, "--- (press RETURN to continue) ---"); 
+      fflush(stderr);
+      c = getc(ttyf);
+  }
+  for ( p1=p0; (*p1 != '\n') && (*p1 != 0); p1++ );
+  *p1 = 0;
+  fprintf(fp,"%s\n",p0);
+  p0 = p1+1;
+    }
+    fprintf(fp,"\n"); fflush(fp);
+    if ( !nopause) fclose(ttyf);
+}