1/*
2 * Copyright (c) 1999-2000 Image Power, Inc. and the University of
3 *   British Columbia.
4 * Copyright (c) 2001-2002 Michael David Adams.
5 * All rights reserved.
6 */
7
8/* __START_OF_JASPER_LICENSE__
9 *
10 * JasPer Software License
11 *
12 * IMAGE POWER JPEG-2000 PUBLIC LICENSE
13 * ************************************
14 *
15 * GRANT:
16 *
17 * Permission is hereby granted, free of charge, to any person (the "User")
18 * obtaining a copy of this software and associated documentation, to deal
19 * in the JasPer Software without restriction, including without limitation
20 * the right to use, copy, modify, merge, publish, distribute, sublicense,
21 * and/or sell copies of the JasPer Software (in source and binary forms),
22 * and to permit persons to whom the JasPer Software is furnished to do so,
23 * provided further that the License Conditions below are met.
24 *
25 * License Conditions
26 * ******************
27 *
28 * A.  Redistributions of source code must retain the above copyright notice,
29 * and this list of conditions, and the following disclaimer.
30 *
31 * B.  Redistributions in binary form must reproduce the above copyright
32 * notice, and this list of conditions, and the following disclaimer in
33 * the documentation and/or other materials provided with the distribution.
34 *
35 * C.  Neither the name of Image Power, Inc. nor any other contributor
36 * (including, but not limited to, the University of British Columbia and
37 * Michael David Adams) may be used to endorse or promote products derived
38 * from this software without specific prior written permission.
39 *
40 * D.  User agrees that it shall not commence any action against Image Power,
41 * Inc., the University of British Columbia, Michael David Adams, or any
42 * other contributors (collectively "Licensors") for infringement of any
43 * intellectual property rights ("IPR") held by the User in respect of any
44 * technology that User owns or has a right to license or sublicense and
45 * which is an element required in order to claim compliance with ISO/IEC
46 * 15444-1 (i.e., JPEG-2000 Part 1).  "IPR" means all intellectual property
47 * rights worldwide arising under statutory or common law, and whether
48 * or not perfected, including, without limitation, all (i) patents and
49 * patent applications owned or licensable by User; (ii) rights associated
50 * with works of authorship including copyrights, copyright applications,
51 * copyright registrations, mask work rights, mask work applications,
52 * mask work registrations; (iii) rights relating to the protection of
53 * trade secrets and confidential information; (iv) any right analogous
54 * to those set forth in subsections (i), (ii), or (iii) and any other
55 * proprietary rights relating to intangible property (other than trademark,
56 * trade dress, or service mark rights); and (v) divisions, continuations,
57 * renewals, reissues and extensions of the foregoing (as and to the extent
58 * applicable) now existing, hereafter filed, issued or acquired.
59 *
60 * E.  If User commences an infringement action against any Licensor(s) then
61 * such Licensor(s) shall have the right to terminate User's license and
62 * all sublicenses that have been granted hereunder by User to other parties.
63 *
64 * F.  This software is for use only in hardware or software products that
65 * are compliant with ISO/IEC 15444-1 (i.e., JPEG-2000 Part 1).  No license
66 * or right to this Software is granted for products that do not comply
67 * with ISO/IEC 15444-1.  The JPEG-2000 Part 1 standard can be purchased
68 * from the ISO.
69 *
70 * THIS DISCLAIMER OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE.
71 * NO USE OF THE JASPER SOFTWARE IS AUTHORIZED HEREUNDER EXCEPT UNDER
72 * THIS DISCLAIMER.  THE JASPER SOFTWARE IS PROVIDED BY THE LICENSORS AND
73 * CONTRIBUTORS UNDER THIS LICENSE ON AN ``AS-IS'' BASIS, WITHOUT WARRANTY
74 * OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION,
75 * WARRANTIES THAT THE JASPER SOFTWARE IS FREE OF DEFECTS, IS MERCHANTABLE,
76 * IS FIT FOR A PARTICULAR PURPOSE OR IS NON-INFRINGING.  THOSE INTENDING
77 * TO USE THE JASPER SOFTWARE OR MODIFICATIONS THEREOF FOR USE IN HARDWARE
78 * OR SOFTWARE PRODUCTS ARE ADVISED THAT THEIR USE MAY INFRINGE EXISTING
79 * PATENTS, COPYRIGHTS, TRADEMARKS, OR OTHER INTELLECTUAL PROPERTY RIGHTS.
80 * THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE JASPER SOFTWARE
81 * IS WITH THE USER.  SHOULD ANY PART OF THE JASPER SOFTWARE PROVE DEFECTIVE
82 * IN ANY RESPECT, THE USER (AND NOT THE INITIAL DEVELOPERS, THE UNIVERSITY
83 * OF BRITISH COLUMBIA, IMAGE POWER, INC., MICHAEL DAVID ADAMS, OR ANY
84 * OTHER CONTRIBUTOR) SHALL ASSUME THE COST OF ANY NECESSARY SERVICING,
85 * REPAIR OR CORRECTION.  UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY,
86 * WHETHER TORT (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL THE
87 * INITIAL DEVELOPER, THE UNIVERSITY OF BRITISH COLUMBIA, IMAGE POWER, INC.,
88 * MICHAEL DAVID ADAMS, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF THE
89 * JASPER SOFTWARE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO
90 * THE USER OR ANY OTHER PERSON FOR ANY INDIRECT, SPECIAL, INCIDENTAL, OR
91 * CONSEQUENTIAL DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT LIMITATION,
92 * DAMAGES FOR LOSS OF GOODWILL, WORK STOPPAGE, COMPUTER FAILURE OR
93 * MALFUNCTION, OR ANY AND ALL OTHER COMMERCIAL DAMAGES OR LOSSES, EVEN IF
94 * SUCH PARTY HAD BEEN INFORMED, OR OUGHT TO HAVE KNOWN, OF THE POSSIBILITY
95 * OF SUCH DAMAGES.  THE JASPER SOFTWARE AND UNDERLYING TECHNOLOGY ARE NOT
96 * FAULT-TOLERANT AND ARE NOT DESIGNED, MANUFACTURED OR INTENDED FOR USE OR
97 * RESALE AS ON-LINE CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING
98 * FAIL-SAFE PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES,
99 * AIRCRAFT NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT
100 * LIFE SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
101 * JASPER SOFTWARE OR UNDERLYING TECHNOLOGY OR PRODUCT COULD LEAD DIRECTLY
102 * TO DEATH, PERSONAL INJURY, OR SEVERE PHYSICAL OR ENVIRONMENTAL DAMAGE
103 * ("HIGH RISK ACTIVITIES").  LICENSOR SPECIFICALLY DISCLAIMS ANY EXPRESS
104 * OR IMPLIED WARRANTY OF FITNESS FOR HIGH RISK ACTIVITIES.  USER WILL NOT
105 * KNOWINGLY USE, DISTRIBUTE OR RESELL THE JASPER SOFTWARE OR UNDERLYING
106 * TECHNOLOGY OR PRODUCTS FOR HIGH RISK ACTIVITIES AND WILL ENSURE THAT ITS
107 * CUSTOMERS AND END-USERS OF ITS PRODUCTS ARE PROVIDED WITH A COPY OF THE
108 * NOTICE SPECIFIED IN THIS SECTION.
109 *
110 * __END_OF_JASPER_LICENSE__
111 */
112
113/*
114 * MQ Arithmetic Encoder
115 *
116 * $Id: jpc_mqenc.c 14449 2005-10-20 12:15:56Z stippi $
117 */
118
119/******************************************************************************\
120* Includes.
121\******************************************************************************/
122
123#include <assert.h>
124#include <stdlib.h>
125
126#include "jasper/jas_stream.h"
127#include "jasper/jas_malloc.h"
128#include "jasper/jas_math.h"
129#include "jasper/jas_debug.h"
130
131#include "jpc_mqenc.h"
132
133/******************************************************************************\
134* Macros
135\******************************************************************************/
136
137#if defined(DEBUG)
138#define	JPC_MQENC_CALL(n, x) \
139	((jas_getdbglevel() >= (n)) ? ((void)(x)) : ((void)0))
140#else
141#define	JPC_MQENC_CALL(n, x)
142#endif
143
144#define	jpc_mqenc_codemps9(areg, creg, ctreg, curctx, enc) \
145{ \
146	jpc_mqstate_t *state = *(curctx); \
147	(areg) -= state->qeval; \
148	if (!((areg) & 0x8000)) { \
149		if ((areg) < state->qeval) { \
150			(areg) = state->qeval; \
151		} else { \
152			(creg) += state->qeval; \
153		} \
154		*(curctx) = state->nmps; \
155		jpc_mqenc_renorme((areg), (creg), (ctreg), (enc)); \
156	} else { \
157		(creg) += state->qeval; \
158	} \
159}
160
161#define	jpc_mqenc_codelps2(areg, creg, ctreg, curctx, enc) \
162{ \
163	jpc_mqstate_t *state = *(curctx); \
164	(areg) -= state->qeval; \
165	if ((areg) < state->qeval) { \
166		(creg) += state->qeval; \
167	} else { \
168		(areg) = state->qeval; \
169	} \
170	*(curctx) = state->nlps; \
171	jpc_mqenc_renorme((areg), (creg), (ctreg), (enc)); \
172}
173
174#define	jpc_mqenc_renorme(areg, creg, ctreg, enc) \
175{ \
176	do { \
177		(areg) <<= 1; \
178		(creg) <<= 1; \
179		if (!--(ctreg)) { \
180			jpc_mqenc_byteout((areg), (creg), (ctreg), (enc)); \
181		} \
182	} while (!((areg) & 0x8000)); \
183}
184
185#define	jpc_mqenc_byteout(areg, creg, ctreg, enc) \
186{ \
187	if ((enc)->outbuf != 0xff) { \
188		if ((creg) & 0x8000000) { \
189			if (++((enc)->outbuf) == 0xff) { \
190				(creg) &= 0x7ffffff; \
191				jpc_mqenc_byteout2(enc); \
192				enc->outbuf = ((creg) >> 20) & 0xff; \
193				(creg) &= 0xfffff; \
194				(ctreg) = 7; \
195			} else { \
196				jpc_mqenc_byteout2(enc); \
197				enc->outbuf = ((creg) >> 19) & 0xff; \
198				(creg) &= 0x7ffff; \
199				(ctreg) = 8; \
200			} \
201		} else { \
202			jpc_mqenc_byteout2(enc); \
203			(enc)->outbuf = ((creg) >> 19) & 0xff; \
204			(creg) &= 0x7ffff; \
205			(ctreg) = 8; \
206		} \
207	} else { \
208		jpc_mqenc_byteout2(enc); \
209		(enc)->outbuf = ((creg) >> 20) & 0xff; \
210		(creg) &= 0xfffff; \
211		(ctreg) = 7; \
212	} \
213}
214
215#define	jpc_mqenc_byteout2(enc) \
216{ \
217	if (enc->outbuf >= 0) { \
218		if (jas_stream_putc(enc->out, (unsigned char)enc->outbuf) == EOF) { \
219			enc->err |= 1; \
220		} \
221	} \
222	enc->lastbyte = enc->outbuf; \
223}
224
225/******************************************************************************\
226* Local function protoypes.
227\******************************************************************************/
228
229static void jpc_mqenc_setbits(jpc_mqenc_t *mqenc);
230
231/******************************************************************************\
232* Code for creation and destruction of encoder.
233\******************************************************************************/
234
235/* Create a MQ encoder. */
236
237jpc_mqenc_t *jpc_mqenc_create(int maxctxs, jas_stream_t *out)
238{
239	jpc_mqenc_t *mqenc;
240
241	/* Allocate memory for the MQ encoder. */
242	if (!(mqenc = jas_malloc(sizeof(jpc_mqenc_t)))) {
243		goto error;
244	}
245	mqenc->out = out;
246	mqenc->maxctxs = maxctxs;
247
248	/* Allocate memory for the per-context state information. */
249	if (!(mqenc->ctxs = jas_malloc(mqenc->maxctxs * sizeof(jpc_mqstate_t *)))) {
250		goto error;
251	}
252
253	/* Set the current context to the first one. */
254	mqenc->curctx = mqenc->ctxs;
255
256	jpc_mqenc_init(mqenc);
257
258	/* Initialize the per-context state information to something sane. */
259	jpc_mqenc_setctxs(mqenc, 0, 0);
260
261	return mqenc;
262
263error:
264	if (mqenc) {
265		jpc_mqenc_destroy(mqenc);
266	}
267	return 0;
268}
269
270/* Destroy a MQ encoder. */
271
272void jpc_mqenc_destroy(jpc_mqenc_t *mqenc)
273{
274	if (mqenc->ctxs) {
275		jas_free(mqenc->ctxs);
276	}
277	jas_free(mqenc);
278}
279
280/******************************************************************************\
281* State initialization code.
282\******************************************************************************/
283
284/* Initialize the coding state of a MQ encoder. */
285
286void jpc_mqenc_init(jpc_mqenc_t *mqenc)
287{
288	mqenc->areg = 0x8000;
289	mqenc->outbuf = -1;
290	mqenc->creg = 0;
291	mqenc->ctreg = 12;
292	mqenc->lastbyte = -1;
293	mqenc->err = 0;
294}
295
296/* Initialize one or more contexts. */
297
298void jpc_mqenc_setctxs(jpc_mqenc_t *mqenc, int numctxs, jpc_mqctx_t *ctxs)
299{
300	jpc_mqstate_t **ctx;
301	int n;
302
303	ctx = mqenc->ctxs;
304	n = JAS_MIN(mqenc->maxctxs, numctxs);
305	while (--n >= 0) {
306		*ctx = &jpc_mqstates[2 * ctxs->ind + ctxs->mps];
307		++ctx;
308		++ctxs;
309	}
310	n = mqenc->maxctxs - numctxs;
311	while (--n >= 0) {
312		*ctx = &jpc_mqstates[0];
313		++ctx;
314	}
315
316}
317
318/* Get the coding state for a MQ encoder. */
319
320void jpc_mqenc_getstate(jpc_mqenc_t *mqenc, jpc_mqencstate_t *state)
321{
322	state->areg = mqenc->areg;
323	state->creg = mqenc->creg;
324	state->ctreg = mqenc->ctreg;
325	state->lastbyte = mqenc->lastbyte;
326}
327
328/******************************************************************************\
329* Code for coding symbols.
330\******************************************************************************/
331
332/* Encode a bit. */
333
334int jpc_mqenc_putbit_func(jpc_mqenc_t *mqenc, int bit)
335{
336	const jpc_mqstate_t *state;
337	JAS_DBGLOG(100, ("jpc_mqenc_putbit(%p, %d)\n", mqenc, bit));
338	JPC_MQENC_CALL(100, jpc_mqenc_dump(mqenc, stderr));
339
340	state = *(mqenc->curctx);
341
342	if (state->mps == bit) {
343		/* Apply the CODEMPS algorithm as defined in the standard. */
344		mqenc->areg -= state->qeval;
345		if (!(mqenc->areg & 0x8000)) {
346			jpc_mqenc_codemps2(mqenc);
347		} else {
348			mqenc->creg += state->qeval;
349		}
350	} else {
351		/* Apply the CODELPS algorithm as defined in the standard. */
352		jpc_mqenc_codelps2(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc->curctx, mqenc);
353	}
354
355	return jpc_mqenc_error(mqenc) ? (-1) : 0;
356}
357
358int jpc_mqenc_codemps2(jpc_mqenc_t *mqenc)
359{
360	/* Note: This function only performs part of the work associated with
361	the CODEMPS algorithm from the standard.  Some of the work is also
362	performed by the caller. */
363
364	jpc_mqstate_t *state = *(mqenc->curctx);
365	if (mqenc->areg < state->qeval) {
366		mqenc->areg = state->qeval;
367	} else {
368		mqenc->creg += state->qeval;
369	}
370	*mqenc->curctx = state->nmps;
371	jpc_mqenc_renorme(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc);
372	return jpc_mqenc_error(mqenc) ? (-1) : 0;
373}
374
375int jpc_mqenc_codelps(jpc_mqenc_t *mqenc)
376{
377	jpc_mqenc_codelps2(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc->curctx, mqenc);
378	return jpc_mqenc_error(mqenc) ? (-1) : 0;
379}
380
381/******************************************************************************\
382* Miscellaneous code.
383\******************************************************************************/
384
385/* Terminate the code word. */
386
387int jpc_mqenc_flush(jpc_mqenc_t *mqenc, int termmode)
388{
389	int_fast16_t k;
390
391	switch (termmode) {
392	case JPC_MQENC_PTERM:
393		k = 11 - mqenc->ctreg + 1;
394		while (k > 0) {
395			mqenc->creg <<= mqenc->ctreg;
396			mqenc->ctreg = 0;
397			jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg,
398			  mqenc);
399			k -= mqenc->ctreg;
400		}
401		if (mqenc->outbuf != 0xff) {
402			jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc);
403		}
404		break;
405	case JPC_MQENC_DEFTERM:
406		jpc_mqenc_setbits(mqenc);
407		mqenc->creg <<= mqenc->ctreg;
408		jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc);
409		mqenc->creg <<= mqenc->ctreg;
410		jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc);
411		if (mqenc->outbuf != 0xff) {
412			jpc_mqenc_byteout(mqenc->areg, mqenc->creg, mqenc->ctreg, mqenc);
413		}
414		break;
415	default:
416		abort();
417		break;
418	}
419	return 0;
420}
421
422static void jpc_mqenc_setbits(jpc_mqenc_t *mqenc)
423{
424	uint_fast32_t tmp = mqenc->creg + mqenc->areg;
425	mqenc->creg |= 0xffff;
426	if (mqenc->creg >= tmp) {
427		mqenc->creg -= 0x8000;
428	}
429}
430
431/* Dump a MQ encoder to a stream for debugging. */
432
433int jpc_mqenc_dump(jpc_mqenc_t *mqenc, FILE *out)
434{
435	fprintf(out, "AREG = %08x, CREG = %08x, CTREG = %d\n",
436	  mqenc->areg, mqenc->creg, mqenc->ctreg);
437	fprintf(out, "IND = %02d, MPS = %d, QEVAL = %04x\n",
438	  *mqenc->curctx - jpc_mqstates, (*mqenc->curctx)->mps,
439	  (*mqenc->curctx)->qeval);
440	return 0;
441}
442