]> Creatis software - gdcm.git/blob - src/gdcmjpegls/Encoder/global.c
Fix trouble with BCC
[gdcm.git] / src / gdcmjpegls / Encoder / global.c
1 /* PMG/JPEG-LS IMPLEMENTATION V.2.1
2    =====================================
3    These programs are Copyright (c) University of British Columbia. All rights reserved.
4    They may be freely redistributed in their entirety provided that this copyright
5    notice is not removed. THEY MAY NOT BE SOLD FOR PROFIT OR INCORPORATED IN
6    COMMERCIAL PROGRAMS WITHOUT THE WRITTEN PERMISSION OF THE COPYRIGHT HOLDER.
7    Each program is provided as is, without any express or implied warranty,
8    without even the warranty of fitness for a particular purpose.
9
10    =========================================================
11    THIS SOFTWARE IS BASED ON HP's implementation of jpeg-ls:
12    =========================================================
13
14    LOCO-I/JPEG-LS IMPLEMENTATION V.0.90
15    -------------------------------------------------------------------------------
16    (c) COPYRIGHT HEWLETT-PACKARD COMPANY, 1995-1999.
17         HEWLETT-PACKARD COMPANY ("HP") DOES NOT WARRANT THE ACCURACY OR
18    COMPLETENESS OF THE INFORMATION GIVEN HERE.  ANY USE MADE OF, OR
19    RELIANCE ON, SUCH INFORMATION IS ENTIRELY AT USER'S OWN RISK.
20         BY DOWNLOADING THE LOCO-I/JPEG-LS COMPRESSORS/DECOMPRESSORS
21    ("THE SOFTWARE") YOU AGREE TO BE BOUND BY THE TERMS AND CONDITIONS
22    OF THIS LICENSING AGREEMENT.
23         YOU MAY DOWNLOAD AND USE THE SOFTWARE FOR NON-COMMERCIAL PURPOSES
24    FREE OF CHARGE OR FURTHER OBLIGATION.  YOU MAY NOT, DIRECTLY OR
25    INDIRECTLY, DISTRIBUTE THE SOFTWARE FOR A FEE, INCORPORATE THIS
26    SOFTWARE INTO ANY PRODUCT OFFERED FOR SALE, OR USE THE SOFTWARE
27    TO PROVIDE A SERVICE FOR WHICH A FEE IS CHARGED.
28         YOU MAY MAKE COPIES OF THE SOFTWARE AND DISTRIBUTE SUCH COPIES TO
29    OTHER PERSONS PROVIDED THAT SUCH COPIES ARE ACCOMPANIED BY
30    HEWLETT-PACKARD'S COPYRIGHT NOTICE AND THIS AGREEMENT AND THAT
31    SUCH OTHER PERSONS AGREE TO BE BOUND BY THE TERMS OF THIS AGREEMENT.
32         THE SOFTWARE IS NOT OF PRODUCT QUALITY AND MAY HAVE ERRORS OR DEFECTS.
33    THE JPEG-LS STANDARD IS STILL UNDER DEVELOPMENT. THE SOFTWARE IS NOT A
34    FINAL OR FULL IMPLEMENTATION OF THE STANDARD.  HP GIVES NO EXPRESS OR
35    IMPLIED WARRANTY OF ANY KIND AND ANY IMPLIED WARRANTIES OF
36    MERCHANTABILITY AND FITNESS FOR PURPOSE ARE DISCLAIMED.
37         HP SHALL NOT BE LIABLE FOR ANY DIRECT, INDIRECT, SPECIAL, INCIDENTAL,
38    OR CONSEQUENTIAL DAMAGES ARISING OUT OF ANY USE OF THE SOFTWARE.
39    -------------------------------------------------------------------------------
40 */
41
42 /* global.c --- support and portability routines: error handling, safe memory
43  *                              management, etc.
44  *
45  * Initial code by Alex Jakulin,  Aug. 1995
46  *
47  * Modified and optimized: Gadiel Seroussi, October 1995 - ...
48  *
49  * Modified and added Restart marker and input tables by:
50  * David Cheng-Hsiu Chu, and Ismail R. Ismail march 1999
51  */
52
53 #include <time.h>
54 #include "global.h"
55
56
57
58 char *disclaimer = 
59 "This program is Copyright (c) University of British Columbia.\n\
60 All rights reserved. It may be freely redistributed in its\n\
61 entirety provided that this copyright notice is not removed.\n\
62 It may not be sold for profit or incorporated in commercial programs\n\
63 without the written permission of the copyright holder.\n";
64
65
66
67 /* I/O files */
68 FILE *in, *out;
69 FILE *c_in[MAX_COMPONENTS];
70 /*FILE *c_out[MAX_COMPONENTS];*/
71 FILE *msgfile = stdout;
72
73 /* Context quantization thresholds  - initially unset */
74 int  T3 = -1,
75   T2 = -1,
76   T1 = -1,
77   Ta = -1;
78
79
80 int verbose = 1;   /* verbosity level */
81 int nopause = 0;   /* whether to pause the legal notice or not */
82 int nolegal = 0;   /* whether to print the legal notice or not */
83
84
85 /* parameters for LOSSY images */
86 int  
87   quant,           /* quantization = 2*NEAR+1 */
88   beta,       /* size of extended alphabet */
89   qbeta,           /* size of quantized alphabet */
90   ceil_half_qbeta, /* ceil(qbeta/2) */
91   negNEAR,            /* -NEAR */
92   alpha1eps;       /* alpha-1+NEAR */
93
94 int  NEAR = DEF_NEAR;   /* loss tolerance per symbol, fixed at 0 for lossless */
95 int bpp,        /* bits per sample */
96   qbpp,      /* bits per sample for quantized prediction errors */
97     limit,      /* limit for unary part of Golomb code */
98     limit_reduce;  /* reduction on above for EOR states */
99
100
101 /* define color mode strings */
102 char
103   *plane_int_string = "plane by plane",
104   *line_int_string = "line intlv",
105     *pixel_int_string = "sample intlv";
106
107
108 /* function to print out error messages */
109 void error(char *msg) {
110         fprintf(stderr, msg);
111         exit(-1);
112 }
113
114
115 /* function to safely call malloc */
116 void *safealloc(size_t size) {
117         void *temp;
118
119         temp = malloc(size);
120         if (temp == NULL)
121                 error("\nsafealloc: Out of memory. Aborting...\n");
122         return temp;
123 }
124
125
126 /* function to safely call calloc **/
127 void *safecalloc(size_t numels, size_t size) {
128         void *temp;
129
130         temp = calloc(numels, size);
131         if (temp == NULL)
132                 error("\nsafecalloc: Out of memory. Aborting...\n");
133         return temp;
134 }
135
136
137
138 /*
139  * TIMING ROUTINES
140  */
141
142 double get_utime()
143 {
144   return (double)clock()/CLOCKS_PER_SEC;
145 }
146
147
148 /* Set thresholds to default unless specified by header: */
149
150 set_thresholds(int alfa, int NEAR, int *T1p, int *T2p, int *T3p)
151 {
152   int lambda,
153       ilambda = 256/alfa,
154       quant = 2*NEAR+1,
155       T1 = *T1p, 
156       T2 = *T2p, 
157       T3 = *T3p;
158   
159   if (alfa<4096)
160     lambda = (alfa+127)/256;
161   else
162     lambda = (4096+127)/256;
163
164
165
166   if ( T1 <= 0 )  {
167     /* compute lossless default */
168     if ( lambda ) 
169       T1 = lambda*(BASIC_T1 - 2) + 2;
170     else {  /* alphabet < 8 bits */
171       T1 = BASIC_T1/ilambda;
172       if ( T1 < 2 ) T1 = 2;
173     }
174     /* adjust for lossy */
175     T1 += 3*NEAR;
176
177     /* check that the default threshold is in bounds */
178     if ( T1 < NEAR+1 || T1 > (alfa-1) ) 
179          T1 = NEAR+1;         /* eliminates the threshold */
180   }
181   if ( T2 <= 0 )  {
182     /* compute lossless default */
183     if ( lambda ) 
184       T2 = lambda*(BASIC_T2 - 3) + 3;
185     else {
186       T2 = BASIC_T2/ilambda;
187       if ( T2 < 3 ) T2 = 3;
188     }
189     /* adjust for lossy */
190     T2 += 5*NEAR;
191
192     /* check that the default threshold is in bounds */
193     if ( T2 < T1 || T2 > (alfa-1) ) 
194          T2 = T1;         /* eliminates the threshold */
195   }
196   if ( T3 <= 0 )  {
197     /* compute lossless default */
198     if ( lambda ) 
199       T3 = lambda*(BASIC_T3 - 4) + 4;
200     else {
201       T3 = BASIC_T3/ilambda;
202       if ( T3 < 4 ) T3 = 4;
203     }
204     /* adjust for lossy */
205     T3 += 7*NEAR;
206
207     /* check that the default threshold is in bounds */
208     if ( T3 < T2 || T3 > (alfa-1) ) 
209          T3 = T2;         /* eliminates the threshold */
210   }
211
212   *T1p = T1;
213   *T2p = T2;
214   *T3p = T3;
215   return 0;
216 }
217
218
219
220
221 /* We first check compatibility with JPEG-LS, then with this implementation */
222 void check_compatibility(jpeg_ls_header *head_frame, jpeg_ls_header *head_scan, int n_s) 
223 {
224
225     int  number_of_scans,i;  
226     int maxreset;
227
228   /* Check implemented color modes */
229     if ((head_scan->color_mode>PIXEL_INT)) {
230     fprintf(stderr,"Color mode %d not supported\n",head_scan->color_mode);
231     exit(10);
232     }
233
234     if (head_scan->color_mode==PLANE_INT) 
235     number_of_scans=head_frame->comp;
236     else 
237     number_of_scans=1;
238     
239   /* Test standard compatibility */
240     if (head_frame->columns<=0 || head_frame->rows <=0) {
241     fprintf(stderr,"Image size must be positive for this implementation.\n");
242     exit(10);
243     }
244
245     if (head_frame->alp<4) {
246     fprintf(stderr,"Alphabet size must be >= 4, got %d\n",head_frame->alp);
247     exit(10);
248     }
249
250
251     if (head_scan->T1>head_scan->T2 || head_scan->T2>head_scan->T3 ||
252   head_scan->T1<head_scan->NEAR+1 || head_scan->T3>=head_scan->alp ) {
253     fprintf(stderr,"Bad thresholds: must be %d <= T1 <= T2 <= T3 <= %d\n",
254     head_scan->NEAR+1,head_scan->alp-1);
255   exit(10);
256     }
257
258     if (head_frame->comp>255) {
259     fprintf(stderr,"Too many components (must be less than 255)\n");
260     exit(10);
261     }
262
263     if (head_scan->NEAR>=head_scan->alp) {
264     fprintf(stderr,"Error for near-lossless must be smaller than alphabet (%d), got %d",head_scan->alp,head_scan->NEAR);
265     exit(10);
266     }
267
268     /*
269     if (head_scan->RES < MINRESET || head_scan->RES >= head_scan->alp ) {
270   fprintf(stderr,"Reset parameter must be between %d and %d\n",
271           MINRESET, head_scan->alp-1);
272   exit(10);
273     }
274     */
275
276     maxreset = (head_scan->alp >= 256)? (head_scan->alp-1):255;
277
278     if (head_scan->RES < MINRESET || head_scan->RES > maxreset ) {
279     fprintf(stderr,"Reset parameter must be between %d and %d\n", MINRESET, head_scan->alp-1);
280     exit(10);
281     }
282
283     for (i=0;i<head_frame->comp;i++)
284   if (head_frame->comp_ids[i] != (i+1)) {
285      fprintf(stderr,"Components id in frame not compatible with this implementation.\n");
286      exit(10);
287   }
288
289     if (number_of_scans == 1) {
290
291     if (head_frame->comp != head_scan->comp) {
292       fprintf(stderr,"In this implementation, when single scan, all components must be in the scan.\n");
293       exit(10);
294     }
295     
296     for (i=0;i<head_frame->comp;i++)
297     if (head_scan->comp_ids[i] != (i+1)) {
298       fprintf(stderr,"Components id in single scan not compatible with this implementation.\n");
299       exit(10);
300     }
301
302   } else {
303   
304     if (head_scan->comp != 1) {
305       fprintf(stderr,"Only 1 component per scan for plane interleaved mode\n");
306       exit(10);
307         }
308
309         if (head_scan->comp_ids[0] != (n_s+1)) {
310       fprintf(stderr,"Components id in multiple scan not compatible with this implementation.\n");
311       exit(10);
312         }
313
314     }
315 }
316
317
318 /* for writing disclaimer to command line in DOS */
319
320 char *ttyfilename = "CON";
321
322 #define PAUSE  20
323
324 fprint_disclaimer(FILE *fp, int nopause)
325 {
326     char *p0, *p1;
327     FILE *ttyf;
328     int  i, c;
329
330     nopause = nopause | !isatty(fileno(fp));
331
332     if ( !nopause && (ttyf=fopen(ttyfilename,"r"))==NULL ) {
333   nopause = 1;
334     }
335
336     for ( i=1, p0=disclaimer; ; i++ ) {
337   if ( !(*p0)  ) break;
338   if ( !nopause && i%PAUSE==0 ) {
339       fflush(fp);
340       fprintf(stderr, "--- (press RETURN to continue) ---"); 
341       fflush(stderr);
342       c = getc(ttyf);
343   }
344   for ( p1=p0; (*p1 != '\n') && (*p1 != 0); p1++ );
345   *p1 = 0;
346   fprintf(fp,"%s\n",p0);
347   p0 = p1+1;
348     }
349     fprintf(fp,"\n"); fflush(fp);
350     if ( !nopause) fclose(ttyf);
351 }