1 /*
2  * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3  *   British Columbia.
4  * Copyright (c) 2001-2003 Michael David Adams.
5  * All rights reserved.
6  */
7 
8 /* __START_OF_JASPER_LICENSE__
9  *
10  * JasPer License Version 2.0
11  *
12  * Copyright (c) 2001-2006 Michael David Adams
13  * Copyright (c) 1999-2000 Image Power, Inc.
14  * Copyright (c) 1999-2000 The University of British Columbia
15  *
16  * All rights reserved.
17  *
18  * Permission is hereby granted, free of charge, to any person (the
19  * "User") obtaining a copy of this software and associated documentation
20  * files (the "Software"), to deal in the Software without restriction,
21  * including without limitation the rights to use, copy, modify, merge,
22  * publish, distribute, and/or sell copies of the Software, and to permit
23  * persons to whom the Software is furnished to do so, subject to the
24  * following conditions:
25  *
26  * 1.  The above copyright notices and this permission notice (which
27  * includes the disclaimer below) shall be included in all copies or
28  * substantial portions of the Software.
29  *
30  * 2.  The name of a copyright holder shall not be used to endorse or
31  * promote products derived from the Software without specific prior
32  * written permission.
33  *
34  * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS
35  * LICENSE.  NO USE OF THE SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
36  * THIS DISCLAIMER.  THE SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS
37  * "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
38  * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
39  * PARTICULAR PURPOSE AND NONINFRINGEMENT OF THIRD PARTY RIGHTS.  IN NO
40  * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, OR ANY SPECIAL
41  * INDIRECT OR CONSEQUENTIAL DAMAGES, OR ANY DAMAGES WHATSOEVER RESULTING
42  * FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
43  * NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
44  * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.  NO ASSURANCES ARE
45  * PROVIDED BY THE COPYRIGHT HOLDERS THAT THE SOFTWARE DOES NOT INFRINGE
46  * THE PATENT OR OTHER INTELLECTUAL PROPERTY RIGHTS OF ANY OTHER ENTITY.
47  * EACH COPYRIGHT HOLDER DISCLAIMS ANY LIABILITY TO THE USER FOR CLAIMS
48  * BROUGHT BY ANY OTHER ENTITY BASED ON INFRINGEMENT OF INTELLECTUAL
49  * PROPERTY RIGHTS OR OTHERWISE.  AS A CONDITION TO EXERCISING THE RIGHTS
50  * GRANTED HEREUNDER, EACH USER HEREBY ASSUMES SOLE RESPONSIBILITY TO SECURE
51  * ANY OTHER INTELLECTUAL PROPERTY RIGHTS NEEDED, IF ANY.  THE SOFTWARE
52  * IS NOT FAULT-TOLERANT AND IS NOT INTENDED FOR USE IN MISSION-CRITICAL
53  * SYSTEMS, SUCH AS THOSE USED IN THE OPERATION OF NUCLEAR FACILITIES,
54  * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL
55  * SYSTEMS, DIRECT LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH
56  * THE FAILURE OF THE SOFTWARE OR SYSTEM COULD LEAD DIRECTLY TO DEATH,
57  * PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH
58  * RISK ACTIVITIES").  THE COPYRIGHT HOLDERS SPECIFICALLY DISCLAIM ANY
59  * EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.
60  *
61  * __END_OF_JASPER_LICENSE__
62  */
63 
64 /*
65  * $Id: jpc_t1cod.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $
66  */
67 
68 /******************************************************************************\
69 * Includes.
70 \******************************************************************************/
71 
72 #include <stdio.h>
73 #include <stdlib.h>
74 #include <assert.h>
75 #include <math.h>
76 
77 #include "jasper/jas_types.h"
78 #include "jasper/jas_math.h"
79 
80 #include "jpc_bs.h"
81 #include "jpc_dec.h"
82 #include "jpc_cs.h"
83 #include "jpc_mqcod.h"
84 #include "jpc_t1cod.h"
85 #include "jpc_tsfb.h"
86 
87 double jpc_pow2i(int n);
88 
89 /******************************************************************************\
90 * Global data.
91 \******************************************************************************/
92 
93 int jpc_zcctxnolut[4 * 256];
94 int jpc_spblut[256];
95 int jpc_scctxnolut[256];
96 int jpc_magctxnolut[4096];
97 
98 jpc_fix_t jpc_signmsedec[1 << JPC_NMSEDEC_BITS];
99 jpc_fix_t jpc_refnmsedec[1 << JPC_NMSEDEC_BITS];
100 jpc_fix_t jpc_signmsedec0[1 << JPC_NMSEDEC_BITS];
101 jpc_fix_t jpc_refnmsedec0[1 << JPC_NMSEDEC_BITS];
102 
103 jpc_mqctx_t jpc_mqctxs[JPC_NUMCTXS];
104 
105 /******************************************************************************\
106 *
107 \******************************************************************************/
108 
109 void jpc_initmqctxs(void);
110 
111 /******************************************************************************\
112 * Code.
113 \******************************************************************************/
114 
JPC_PASSTYPE(int passno)115 int JPC_PASSTYPE(int passno)
116 {
117     int passtype;
118     switch (passno % 3) {
119     case 0:
120         passtype = JPC_CLNPASS;
121         break;
122     case 1:
123         passtype = JPC_SIGPASS;
124         break;
125     case 2:
126         passtype = JPC_REFPASS;
127         break;
128     default:
129         passtype = -1;
130         assert(0);
131         break;
132     }
133     return passtype;
134 }
135 
JPC_NOMINALGAIN(int qmfbid,int numlvls,int lvlno,int orient)136 int JPC_NOMINALGAIN(int qmfbid, int numlvls, int lvlno, int orient)
137 {
138     /* Avoid compiler warnings about unused parameters. */
139     numlvls = 0;
140 
141 if (qmfbid == JPC_COX_INS) {
142     return 0;
143 }
144     assert(qmfbid == JPC_COX_RFT);
145     if (lvlno == 0) {
146         assert(orient == JPC_TSFB_LL);
147         return 0;
148     } else {
149         switch (orient) {
150         case JPC_TSFB_LH:
151         case JPC_TSFB_HL:
152             return 1;
153             break;
154         case JPC_TSFB_HH:
155             return 2;
156             break;
157         }
158     }
159     abort();
160 }
161 
162 /******************************************************************************\
163 * Coding pass related functions.
164 \******************************************************************************/
165 
JPC_SEGTYPE(int passno,int firstpassno,int bypass)166 int JPC_SEGTYPE(int passno, int firstpassno, int bypass)
167 {
168     int passtype;
169     if (bypass) {
170         passtype = JPC_PASSTYPE(passno);
171         if (passtype == JPC_CLNPASS) {
172             return JPC_SEG_MQ;
173         }
174         return ((passno < firstpassno + 10) ? JPC_SEG_MQ : JPC_SEG_RAW);
175     } else {
176         return JPC_SEG_MQ;
177     }
178 }
179 
JPC_SEGPASSCNT(int passno,int firstpassno,int numpasses,int bypass,int termall)180 int JPC_SEGPASSCNT(int passno, int firstpassno, int numpasses, int bypass, int termall)
181 {
182     int ret;
183     int passtype;
184 
185     if (termall) {
186         ret = 1;
187     } else if (bypass) {
188         if (passno < firstpassno + 10) {
189             ret = 10 - (passno - firstpassno);
190         } else {
191             passtype = JPC_PASSTYPE(passno);
192             switch (passtype) {
193             case JPC_SIGPASS:
194                 ret = 2;
195                 break;
196             case JPC_REFPASS:
197                 ret = 1;
198                 break;
199             case JPC_CLNPASS:
200                 ret = 1;
201                 break;
202             default:
203                 ret = -1;
204                 assert(0);
205                 break;
206             }
207         }
208     } else {
209         ret = JPC_PREC * 3 - 2;
210     }
211     ret = JAS_MIN(ret, numpasses - passno);
212     return ret;
213 }
214 
JPC_ISTERMINATED(int passno,int firstpassno,int numpasses,int termall,int lazy)215 int JPC_ISTERMINATED(int passno, int firstpassno, int numpasses, int termall,
216   int lazy)
217 {
218     int ret;
219     int n;
220     if (passno - firstpassno == numpasses - 1) {
221         ret = 1;
222     } else {
223         n = JPC_SEGPASSCNT(passno, firstpassno, numpasses, lazy, termall);
224         ret = (n <= 1) ? 1 : 0;
225     }
226 
227     return ret;
228 }
229 
230 /******************************************************************************\
231 * Lookup table code.
232 \******************************************************************************/
233 
jpc_initluts()234 void jpc_initluts()
235 {
236     int i;
237     int orient;
238     int refine;
239     float u;
240     float v;
241     float t;
242 
243 /* XXX - hack */
244 jpc_initmqctxs();
245 
246     for (orient = 0; orient < 4; ++orient) {
247         for (i = 0; i < 256; ++i) {
248             jpc_zcctxnolut[(orient << 8) | i] = jpc_getzcctxno(i, orient);
249         }
250     }
251 
252     for (i = 0; i < 256; ++i) {
253         jpc_spblut[i] = jpc_getspb(i << 4);
254     }
255 
256     for (i = 0; i < 256; ++i) {
257         jpc_scctxnolut[i] = jpc_getscctxno(i << 4);
258     }
259 
260     for (refine = 0; refine < 2; ++refine) {
261         for (i = 0; i < 2048; ++i) {
262             jpc_magctxnolut[(refine << 11) + i] = jpc_getmagctxno((refine ? JPC_REFINE : 0) | i);
263         }
264     }
265 
266     for (i = 0; i < (1 << JPC_NMSEDEC_BITS); ++i) {
267         t = i * jpc_pow2i(-JPC_NMSEDEC_FRACBITS);
268         u = t;
269         v = t - 1.5;
270         jpc_signmsedec[i] = jpc_dbltofix(floor((u * u - v * v) * jpc_pow2i(JPC_NMSEDEC_FRACBITS) + 0.5) / jpc_pow2i(JPC_NMSEDEC_FRACBITS));
271 /* XXX - this calc is not correct */
272         jpc_signmsedec0[i] = jpc_dbltofix(floor((u * u) * jpc_pow2i(JPC_NMSEDEC_FRACBITS) + 0.5) / jpc_pow2i(JPC_NMSEDEC_FRACBITS));
273         u = t - 1.0;
274         if (i & (1 << (JPC_NMSEDEC_BITS - 1))) {
275             v = t - 1.5;
276         } else {
277             v = t - 0.5;
278         }
279         jpc_refnmsedec[i] = jpc_dbltofix(floor((u * u - v * v) * jpc_pow2i(JPC_NMSEDEC_FRACBITS) + 0.5) / jpc_pow2i(JPC_NMSEDEC_FRACBITS));
280 /* XXX - this calc is not correct */
281         jpc_refnmsedec0[i] = jpc_dbltofix(floor((u * u) * jpc_pow2i(JPC_NMSEDEC_FRACBITS) + 0.5) / jpc_pow2i(JPC_NMSEDEC_FRACBITS));
282     }
283 }
284 
jpc_getsignmsedec_func(jpc_fix_t x,int bitpos)285 jpc_fix_t jpc_getsignmsedec_func(jpc_fix_t x, int bitpos)
286 {
287     jpc_fix_t y;
288     assert(!(x & (~JAS_ONES(bitpos + 1))));
289     y = jpc_getsignmsedec_macro(x, bitpos);
290     return y;
291 }
292 
jpc_getzcctxno(int f,int orient)293 int jpc_getzcctxno(int f, int orient)
294 {
295     int h;
296     int v;
297     int d;
298     int n;
299     int t;
300     int hv;
301 
302     /* Avoid compiler warning. */
303     n = 0;
304 
305     h = ((f & JPC_WSIG) != 0) + ((f & JPC_ESIG) != 0);
306     v = ((f & JPC_NSIG) != 0) + ((f & JPC_SSIG) != 0);
307     d = ((f & JPC_NWSIG) != 0) + ((f & JPC_NESIG) != 0) + ((f & JPC_SESIG) != 0) + ((f & JPC_SWSIG) != 0);
308     switch (orient) {
309     case JPC_TSFB_HL:
310         t = h;
311         h = v;
312         v = t;
313     case JPC_TSFB_LL:
314     case JPC_TSFB_LH:
315         if (!h) {
316             if (!v) {
317                 if (!d) {
318                     n = 0;
319                 } else if (d == 1) {
320                     n = 1;
321                 } else {
322                     n = 2;
323                 }
324             } else if (v == 1) {
325                 n = 3;
326             } else {
327                 n = 4;
328             }
329         } else if (h == 1) {
330             if (!v) {
331                 if (!d) {
332                     n = 5;
333                 } else {
334                     n = 6;
335                 }
336             } else {
337                 n = 7;
338             }
339         } else {
340             n = 8;
341         }
342         break;
343     case JPC_TSFB_HH:
344         hv = h + v;
345         if (!d) {
346             if (!hv) {
347                 n = 0;
348             } else if (hv == 1) {
349                 n = 1;
350             } else {
351                 n = 2;
352             }
353         } else if (d == 1) {
354             if (!hv) {
355                 n = 3;
356             } else if (hv == 1) {
357                 n = 4;
358             } else {
359                 n = 5;
360             }
361         } else if (d == 2) {
362             if (!hv) {
363                 n = 6;
364             } else {
365                 n = 7;
366             }
367         } else {
368             n = 8;
369         }
370         break;
371     }
372     assert(n < JPC_NUMZCCTXS);
373     return JPC_ZCCTXNO + n;
374 }
375 
jpc_getspb(int f)376 int jpc_getspb(int f)
377 {
378     int hc;
379     int vc;
380     int n;
381 
382     hc = JAS_MIN(((f & (JPC_ESIG | JPC_ESGN)) == JPC_ESIG) + ((f & (JPC_WSIG | JPC_WSGN)) == JPC_WSIG), 1) -
383       JAS_MIN(((f & (JPC_ESIG | JPC_ESGN)) == (JPC_ESIG | JPC_ESGN)) + ((f & (JPC_WSIG | JPC_WSGN)) == (JPC_WSIG | JPC_WSGN)), 1);
384     vc = JAS_MIN(((f & (JPC_NSIG | JPC_NSGN)) == JPC_NSIG) + ((f & (JPC_SSIG | JPC_SSGN)) == JPC_SSIG), 1) -
385       JAS_MIN(((f & (JPC_NSIG | JPC_NSGN)) == (JPC_NSIG | JPC_NSGN)) + ((f & (JPC_SSIG | JPC_SSGN)) == (JPC_SSIG | JPC_SSGN)), 1);
386     if (!hc && !vc) {
387         n = 0;
388     } else {
389         n = (!(hc > 0 || (!hc && vc > 0)));
390     }
391     return n;
392 }
393 
jpc_getscctxno(int f)394 int jpc_getscctxno(int f)
395 {
396     int hc;
397     int vc;
398     int n;
399 
400     /* Avoid compiler warning. */
401     n = 0;
402 
403     hc = JAS_MIN(((f & (JPC_ESIG | JPC_ESGN)) == JPC_ESIG) + ((f & (JPC_WSIG | JPC_WSGN)) == JPC_WSIG),
404       1) - JAS_MIN(((f & (JPC_ESIG | JPC_ESGN)) == (JPC_ESIG | JPC_ESGN)) +
405       ((f & (JPC_WSIG | JPC_WSGN)) == (JPC_WSIG | JPC_WSGN)), 1);
406     vc = JAS_MIN(((f & (JPC_NSIG | JPC_NSGN)) == JPC_NSIG) + ((f & (JPC_SSIG | JPC_SSGN)) == JPC_SSIG),
407       1) - JAS_MIN(((f & (JPC_NSIG | JPC_NSGN)) == (JPC_NSIG | JPC_NSGN)) +
408       ((f & (JPC_SSIG | JPC_SSGN)) == (JPC_SSIG | JPC_SSGN)), 1);
409     assert(hc >= -1 && hc <= 1 && vc >= -1 && vc <= 1);
410     if (hc < 0) {
411         hc = -hc;
412         vc = -vc;
413     }
414     if (!hc) {
415         if (vc == -1) {
416             n = 1;
417         } else if (!vc) {
418             n = 0;
419         } else {
420             n = 1;
421         }
422     } else if (hc == 1) {
423         if (vc == -1) {
424             n = 2;
425         } else if (!vc) {
426             n = 3;
427         } else {
428             n = 4;
429         }
430     }
431     assert(n < JPC_NUMSCCTXS);
432     return JPC_SCCTXNO + n;
433 }
434 
jpc_getmagctxno(int f)435 int jpc_getmagctxno(int f)
436 {
437     int n;
438 
439     if (!(f & JPC_REFINE)) {
440         n = (f & (JPC_OTHSIGMSK)) ? 1 : 0;
441     } else {
442         n = 2;
443     }
444 
445     assert(n < JPC_NUMMAGCTXS);
446     return JPC_MAGCTXNO + n;
447 }
448 
jpc_initctxs(jpc_mqctx_t * ctxs)449 void jpc_initctxs(jpc_mqctx_t *ctxs)
450 {
451     jpc_mqctx_t *ctx;
452     int i;
453 
454     ctx = ctxs;
455     for (i = 0; i < JPC_NUMCTXS; ++i) {
456         ctx->mps = 0;
457         switch (i) {
458         case JPC_UCTXNO:
459             ctx->ind = 46;
460             break;
461         case JPC_ZCCTXNO:
462             ctx->ind = 4;
463             break;
464         case JPC_AGGCTXNO:
465             ctx->ind = 3;
466             break;
467         default:
468             ctx->ind = 0;
469             break;
470         }
471         ++ctx;
472     }
473 }
474 
jpc_initmqctxs()475 void jpc_initmqctxs()
476 {
477     jpc_initctxs(jpc_mqctxs);
478 }
479 
480 /* Calculate the real quantity exp2(n), where x is an integer. */
jpc_pow2i(int n)481 double jpc_pow2i(int n)
482 {
483     double x;
484     double a;
485 
486     x = 1.0;
487     if (n < 0) {
488         a = 0.5;
489         n = -n;
490     } else {
491         a = 2.0;
492     }
493     while (--n >= 0) {
494         x *= a;
495     }
496     return x;
497 }
498