/src/freeimage-svn/FreeImage/trunk/Source/LibOpenJPEG/mqc.c
Line | Count | Source (jump to first uncovered line) |
1 | | /* |
2 | | * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium |
3 | | * Copyright (c) 2002-2007, Professor Benoit Macq |
4 | | * Copyright (c) 2001-2003, David Janssens |
5 | | * Copyright (c) 2002-2003, Yannick Verschueren |
6 | | * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe |
7 | | * Copyright (c) 2005, Herve Drolon, FreeImage Team |
8 | | * Copyright (c) 2008, Jerome Fimes, Communications & Systemes <jerome.fimes@c-s.fr> |
9 | | * All rights reserved. |
10 | | * |
11 | | * Redistribution and use in source and binary forms, with or without |
12 | | * modification, are permitted provided that the following conditions |
13 | | * are met: |
14 | | * 1. Redistributions of source code must retain the above copyright |
15 | | * notice, this list of conditions and the following disclaimer. |
16 | | * 2. Redistributions in binary form must reproduce the above copyright |
17 | | * notice, this list of conditions and the following disclaimer in the |
18 | | * documentation and/or other materials provided with the distribution. |
19 | | * |
20 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' |
21 | | * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
22 | | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
23 | | * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE |
24 | | * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
25 | | * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
26 | | * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS |
27 | | * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
28 | | * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) |
29 | | * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
30 | | * POSSIBILITY OF SUCH DAMAGE. |
31 | | */ |
32 | | |
33 | | #include "opj_includes.h" |
34 | | |
35 | | /** @defgroup MQC MQC - Implementation of an MQ-Coder */ |
36 | | /*@{*/ |
37 | | |
38 | | /** @name Local static functions */ |
39 | | /*@{*/ |
40 | | |
41 | | /** |
42 | | Output a byte, doing bit-stuffing if necessary. |
43 | | After a 0xff byte, the next byte must be smaller than 0x90. |
44 | | @param mqc MQC handle |
45 | | */ |
46 | | static void opj_mqc_byteout(opj_mqc_t *mqc); |
47 | | /** |
48 | | Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000 |
49 | | @param mqc MQC handle |
50 | | */ |
51 | | static void opj_mqc_renorme(opj_mqc_t *mqc); |
52 | | /** |
53 | | Encode the most probable symbol |
54 | | @param mqc MQC handle |
55 | | */ |
56 | | static void opj_mqc_codemps(opj_mqc_t *mqc); |
57 | | /** |
58 | | Encode the most least symbol |
59 | | @param mqc MQC handle |
60 | | */ |
61 | | static void opj_mqc_codelps(opj_mqc_t *mqc); |
62 | | /** |
63 | | Fill mqc->c with 1's for flushing |
64 | | @param mqc MQC handle |
65 | | */ |
66 | | static void opj_mqc_setbits(opj_mqc_t *mqc); |
67 | | /** |
68 | | FIXME DOC |
69 | | @param mqc MQC handle |
70 | | @return |
71 | | */ |
72 | | static INLINE OPJ_INT32 opj_mqc_mpsexchange(opj_mqc_t *const mqc); |
73 | | /** |
74 | | FIXME DOC |
75 | | @param mqc MQC handle |
76 | | @return |
77 | | */ |
78 | | static INLINE OPJ_INT32 opj_mqc_lpsexchange(opj_mqc_t *const mqc); |
79 | | /** |
80 | | Input a byte |
81 | | @param mqc MQC handle |
82 | | */ |
83 | | static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc); |
84 | | /** |
85 | | Renormalize mqc->a and mqc->c while decoding |
86 | | @param mqc MQC handle |
87 | | */ |
88 | | static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc); |
89 | | /*@}*/ |
90 | | |
91 | | /*@}*/ |
92 | | |
93 | | /* <summary> */ |
94 | | /* This array defines all the possible states for a context. */ |
95 | | /* </summary> */ |
96 | | static opj_mqc_state_t mqc_states[47 * 2] = { |
97 | | {0x5601, 0, &mqc_states[2], &mqc_states[3]}, |
98 | | {0x5601, 1, &mqc_states[3], &mqc_states[2]}, |
99 | | {0x3401, 0, &mqc_states[4], &mqc_states[12]}, |
100 | | {0x3401, 1, &mqc_states[5], &mqc_states[13]}, |
101 | | {0x1801, 0, &mqc_states[6], &mqc_states[18]}, |
102 | | {0x1801, 1, &mqc_states[7], &mqc_states[19]}, |
103 | | {0x0ac1, 0, &mqc_states[8], &mqc_states[24]}, |
104 | | {0x0ac1, 1, &mqc_states[9], &mqc_states[25]}, |
105 | | {0x0521, 0, &mqc_states[10], &mqc_states[58]}, |
106 | | {0x0521, 1, &mqc_states[11], &mqc_states[59]}, |
107 | | {0x0221, 0, &mqc_states[76], &mqc_states[66]}, |
108 | | {0x0221, 1, &mqc_states[77], &mqc_states[67]}, |
109 | | {0x5601, 0, &mqc_states[14], &mqc_states[13]}, |
110 | | {0x5601, 1, &mqc_states[15], &mqc_states[12]}, |
111 | | {0x5401, 0, &mqc_states[16], &mqc_states[28]}, |
112 | | {0x5401, 1, &mqc_states[17], &mqc_states[29]}, |
113 | | {0x4801, 0, &mqc_states[18], &mqc_states[28]}, |
114 | | {0x4801, 1, &mqc_states[19], &mqc_states[29]}, |
115 | | {0x3801, 0, &mqc_states[20], &mqc_states[28]}, |
116 | | {0x3801, 1, &mqc_states[21], &mqc_states[29]}, |
117 | | {0x3001, 0, &mqc_states[22], &mqc_states[34]}, |
118 | | {0x3001, 1, &mqc_states[23], &mqc_states[35]}, |
119 | | {0x2401, 0, &mqc_states[24], &mqc_states[36]}, |
120 | | {0x2401, 1, &mqc_states[25], &mqc_states[37]}, |
121 | | {0x1c01, 0, &mqc_states[26], &mqc_states[40]}, |
122 | | {0x1c01, 1, &mqc_states[27], &mqc_states[41]}, |
123 | | {0x1601, 0, &mqc_states[58], &mqc_states[42]}, |
124 | | {0x1601, 1, &mqc_states[59], &mqc_states[43]}, |
125 | | {0x5601, 0, &mqc_states[30], &mqc_states[29]}, |
126 | | {0x5601, 1, &mqc_states[31], &mqc_states[28]}, |
127 | | {0x5401, 0, &mqc_states[32], &mqc_states[28]}, |
128 | | {0x5401, 1, &mqc_states[33], &mqc_states[29]}, |
129 | | {0x5101, 0, &mqc_states[34], &mqc_states[30]}, |
130 | | {0x5101, 1, &mqc_states[35], &mqc_states[31]}, |
131 | | {0x4801, 0, &mqc_states[36], &mqc_states[32]}, |
132 | | {0x4801, 1, &mqc_states[37], &mqc_states[33]}, |
133 | | {0x3801, 0, &mqc_states[38], &mqc_states[34]}, |
134 | | {0x3801, 1, &mqc_states[39], &mqc_states[35]}, |
135 | | {0x3401, 0, &mqc_states[40], &mqc_states[36]}, |
136 | | {0x3401, 1, &mqc_states[41], &mqc_states[37]}, |
137 | | {0x3001, 0, &mqc_states[42], &mqc_states[38]}, |
138 | | {0x3001, 1, &mqc_states[43], &mqc_states[39]}, |
139 | | {0x2801, 0, &mqc_states[44], &mqc_states[38]}, |
140 | | {0x2801, 1, &mqc_states[45], &mqc_states[39]}, |
141 | | {0x2401, 0, &mqc_states[46], &mqc_states[40]}, |
142 | | {0x2401, 1, &mqc_states[47], &mqc_states[41]}, |
143 | | {0x2201, 0, &mqc_states[48], &mqc_states[42]}, |
144 | | {0x2201, 1, &mqc_states[49], &mqc_states[43]}, |
145 | | {0x1c01, 0, &mqc_states[50], &mqc_states[44]}, |
146 | | {0x1c01, 1, &mqc_states[51], &mqc_states[45]}, |
147 | | {0x1801, 0, &mqc_states[52], &mqc_states[46]}, |
148 | | {0x1801, 1, &mqc_states[53], &mqc_states[47]}, |
149 | | {0x1601, 0, &mqc_states[54], &mqc_states[48]}, |
150 | | {0x1601, 1, &mqc_states[55], &mqc_states[49]}, |
151 | | {0x1401, 0, &mqc_states[56], &mqc_states[50]}, |
152 | | {0x1401, 1, &mqc_states[57], &mqc_states[51]}, |
153 | | {0x1201, 0, &mqc_states[58], &mqc_states[52]}, |
154 | | {0x1201, 1, &mqc_states[59], &mqc_states[53]}, |
155 | | {0x1101, 0, &mqc_states[60], &mqc_states[54]}, |
156 | | {0x1101, 1, &mqc_states[61], &mqc_states[55]}, |
157 | | {0x0ac1, 0, &mqc_states[62], &mqc_states[56]}, |
158 | | {0x0ac1, 1, &mqc_states[63], &mqc_states[57]}, |
159 | | {0x09c1, 0, &mqc_states[64], &mqc_states[58]}, |
160 | | {0x09c1, 1, &mqc_states[65], &mqc_states[59]}, |
161 | | {0x08a1, 0, &mqc_states[66], &mqc_states[60]}, |
162 | | {0x08a1, 1, &mqc_states[67], &mqc_states[61]}, |
163 | | {0x0521, 0, &mqc_states[68], &mqc_states[62]}, |
164 | | {0x0521, 1, &mqc_states[69], &mqc_states[63]}, |
165 | | {0x0441, 0, &mqc_states[70], &mqc_states[64]}, |
166 | | {0x0441, 1, &mqc_states[71], &mqc_states[65]}, |
167 | | {0x02a1, 0, &mqc_states[72], &mqc_states[66]}, |
168 | | {0x02a1, 1, &mqc_states[73], &mqc_states[67]}, |
169 | | {0x0221, 0, &mqc_states[74], &mqc_states[68]}, |
170 | | {0x0221, 1, &mqc_states[75], &mqc_states[69]}, |
171 | | {0x0141, 0, &mqc_states[76], &mqc_states[70]}, |
172 | | {0x0141, 1, &mqc_states[77], &mqc_states[71]}, |
173 | | {0x0111, 0, &mqc_states[78], &mqc_states[72]}, |
174 | | {0x0111, 1, &mqc_states[79], &mqc_states[73]}, |
175 | | {0x0085, 0, &mqc_states[80], &mqc_states[74]}, |
176 | | {0x0085, 1, &mqc_states[81], &mqc_states[75]}, |
177 | | {0x0049, 0, &mqc_states[82], &mqc_states[76]}, |
178 | | {0x0049, 1, &mqc_states[83], &mqc_states[77]}, |
179 | | {0x0025, 0, &mqc_states[84], &mqc_states[78]}, |
180 | | {0x0025, 1, &mqc_states[85], &mqc_states[79]}, |
181 | | {0x0015, 0, &mqc_states[86], &mqc_states[80]}, |
182 | | {0x0015, 1, &mqc_states[87], &mqc_states[81]}, |
183 | | {0x0009, 0, &mqc_states[88], &mqc_states[82]}, |
184 | | {0x0009, 1, &mqc_states[89], &mqc_states[83]}, |
185 | | {0x0005, 0, &mqc_states[90], &mqc_states[84]}, |
186 | | {0x0005, 1, &mqc_states[91], &mqc_states[85]}, |
187 | | {0x0001, 0, &mqc_states[90], &mqc_states[86]}, |
188 | | {0x0001, 1, &mqc_states[91], &mqc_states[87]}, |
189 | | {0x5601, 0, &mqc_states[92], &mqc_states[92]}, |
190 | | {0x5601, 1, &mqc_states[93], &mqc_states[93]}, |
191 | | }; |
192 | | |
193 | | /* |
194 | | ========================================================== |
195 | | local functions |
196 | | ========================================================== |
197 | | */ |
198 | | |
199 | 0 | void opj_mqc_byteout(opj_mqc_t *mqc) { |
200 | 0 | if (*mqc->bp == 0xff) { |
201 | 0 | mqc->bp++; |
202 | 0 | *mqc->bp = (OPJ_BYTE)(mqc->c >> 20); |
203 | 0 | mqc->c &= 0xfffff; |
204 | 0 | mqc->ct = 7; |
205 | 0 | } else { |
206 | 0 | if ((mqc->c & 0x8000000) == 0) { /* ((mqc->c&0x8000000)==0) CHANGE */ |
207 | 0 | mqc->bp++; |
208 | 0 | *mqc->bp = (OPJ_BYTE)(mqc->c >> 19); |
209 | 0 | mqc->c &= 0x7ffff; |
210 | 0 | mqc->ct = 8; |
211 | 0 | } else { |
212 | 0 | (*mqc->bp)++; |
213 | 0 | if (*mqc->bp == 0xff) { |
214 | 0 | mqc->c &= 0x7ffffff; |
215 | 0 | mqc->bp++; |
216 | 0 | *mqc->bp = (OPJ_BYTE)(mqc->c >> 20); |
217 | 0 | mqc->c &= 0xfffff; |
218 | 0 | mqc->ct = 7; |
219 | 0 | } else { |
220 | 0 | mqc->bp++; |
221 | 0 | *mqc->bp = (OPJ_BYTE)(mqc->c >> 19); |
222 | 0 | mqc->c &= 0x7ffff; |
223 | 0 | mqc->ct = 8; |
224 | 0 | } |
225 | 0 | } |
226 | 0 | } |
227 | 0 | } |
228 | | |
229 | 0 | void opj_mqc_renorme(opj_mqc_t *mqc) { |
230 | 0 | do { |
231 | 0 | mqc->a <<= 1; |
232 | 0 | mqc->c <<= 1; |
233 | 0 | mqc->ct--; |
234 | 0 | if (mqc->ct == 0) { |
235 | 0 | opj_mqc_byteout(mqc); |
236 | 0 | } |
237 | 0 | } while ((mqc->a & 0x8000) == 0); |
238 | 0 | } |
239 | | |
240 | 0 | void opj_mqc_codemps(opj_mqc_t *mqc) { |
241 | 0 | mqc->a -= (*mqc->curctx)->qeval; |
242 | 0 | if ((mqc->a & 0x8000) == 0) { |
243 | 0 | if (mqc->a < (*mqc->curctx)->qeval) { |
244 | 0 | mqc->a = (*mqc->curctx)->qeval; |
245 | 0 | } else { |
246 | 0 | mqc->c += (*mqc->curctx)->qeval; |
247 | 0 | } |
248 | 0 | *mqc->curctx = (*mqc->curctx)->nmps; |
249 | 0 | opj_mqc_renorme(mqc); |
250 | 0 | } else { |
251 | 0 | mqc->c += (*mqc->curctx)->qeval; |
252 | 0 | } |
253 | 0 | } |
254 | | |
255 | 0 | void opj_mqc_codelps(opj_mqc_t *mqc) { |
256 | 0 | mqc->a -= (*mqc->curctx)->qeval; |
257 | 0 | if (mqc->a < (*mqc->curctx)->qeval) { |
258 | 0 | mqc->c += (*mqc->curctx)->qeval; |
259 | 0 | } else { |
260 | 0 | mqc->a = (*mqc->curctx)->qeval; |
261 | 0 | } |
262 | 0 | *mqc->curctx = (*mqc->curctx)->nlps; |
263 | 0 | opj_mqc_renorme(mqc); |
264 | 0 | } |
265 | | |
266 | 0 | void opj_mqc_setbits(opj_mqc_t *mqc) { |
267 | 0 | OPJ_UINT32 tempc = mqc->c + mqc->a; |
268 | 0 | mqc->c |= 0xffff; |
269 | 0 | if (mqc->c >= tempc) { |
270 | 0 | mqc->c -= 0x8000; |
271 | 0 | } |
272 | 0 | } |
273 | | |
274 | 0 | static INLINE OPJ_INT32 opj_mqc_mpsexchange(opj_mqc_t *const mqc) { |
275 | 0 | OPJ_INT32 d; |
276 | 0 | if (mqc->a < (*mqc->curctx)->qeval) { |
277 | 0 | d = (OPJ_INT32)(1 - (*mqc->curctx)->mps); |
278 | 0 | *mqc->curctx = (*mqc->curctx)->nlps; |
279 | 0 | } else { |
280 | 0 | d = (OPJ_INT32)(*mqc->curctx)->mps; |
281 | 0 | *mqc->curctx = (*mqc->curctx)->nmps; |
282 | 0 | } |
283 | | |
284 | 0 | return d; |
285 | 0 | } |
286 | | |
287 | 0 | static INLINE OPJ_INT32 opj_mqc_lpsexchange(opj_mqc_t *const mqc) { |
288 | 0 | OPJ_INT32 d; |
289 | 0 | if (mqc->a < (*mqc->curctx)->qeval) { |
290 | 0 | mqc->a = (*mqc->curctx)->qeval; |
291 | 0 | d = (OPJ_INT32)(*mqc->curctx)->mps; |
292 | 0 | *mqc->curctx = (*mqc->curctx)->nmps; |
293 | 0 | } else { |
294 | 0 | mqc->a = (*mqc->curctx)->qeval; |
295 | 0 | d = (OPJ_INT32)(1 - (*mqc->curctx)->mps); |
296 | 0 | *mqc->curctx = (*mqc->curctx)->nlps; |
297 | 0 | } |
298 | | |
299 | 0 | return d; |
300 | 0 | } |
301 | | |
302 | | #ifdef MQC_PERF_OPT |
303 | | static INLINE void opj_mqc_bytein(opj_mqc_t *const mqc) { |
304 | | unsigned int i = *((unsigned int *) mqc->bp); |
305 | | mqc->c += i & 0xffff00; |
306 | | mqc->ct = i & 0x0f; |
307 | | mqc->bp += (i >> 2) & 0x04; |
308 | | } |
309 | | #else |
310 | 0 | static void opj_mqc_bytein(opj_mqc_t *const mqc) { |
311 | 0 | if (mqc->bp != mqc->end) { |
312 | 0 | OPJ_UINT32 c; |
313 | 0 | if (mqc->bp + 1 != mqc->end) { |
314 | 0 | c = *(mqc->bp + 1); |
315 | 0 | } else { |
316 | 0 | c = 0xff; |
317 | 0 | } |
318 | 0 | if (*mqc->bp == 0xff) { |
319 | 0 | if (c > 0x8f) { |
320 | 0 | mqc->c += 0xff00; |
321 | 0 | mqc->ct = 8; |
322 | 0 | } else { |
323 | 0 | mqc->bp++; |
324 | 0 | mqc->c += c << 9; |
325 | 0 | mqc->ct = 7; |
326 | 0 | } |
327 | 0 | } else { |
328 | 0 | mqc->bp++; |
329 | 0 | mqc->c += c << 8; |
330 | 0 | mqc->ct = 8; |
331 | 0 | } |
332 | 0 | } else { |
333 | 0 | mqc->c += 0xff00; |
334 | 0 | mqc->ct = 8; |
335 | 0 | } |
336 | 0 | } |
337 | | #endif |
338 | | |
339 | 0 | static INLINE void opj_mqc_renormd(opj_mqc_t *const mqc) { |
340 | 0 | do { |
341 | 0 | if (mqc->ct == 0) { |
342 | 0 | opj_mqc_bytein(mqc); |
343 | 0 | } |
344 | 0 | mqc->a <<= 1; |
345 | 0 | mqc->c <<= 1; |
346 | 0 | mqc->ct--; |
347 | 0 | } while (mqc->a < 0x8000); |
348 | 0 | } |
349 | | |
350 | | /* |
351 | | ========================================================== |
352 | | MQ-Coder interface |
353 | | ========================================================== |
354 | | */ |
355 | | |
356 | 0 | opj_mqc_t* opj_mqc_create(void) { |
357 | 0 | opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t)); |
358 | | #ifdef MQC_PERF_OPT |
359 | | mqc->buffer = NULL; |
360 | | #endif |
361 | 0 | return mqc; |
362 | 0 | } |
363 | | |
364 | 0 | void opj_mqc_destroy(opj_mqc_t *mqc) { |
365 | 0 | if(mqc) { |
366 | | #ifdef MQC_PERF_OPT |
367 | | opj_free(mqc->buffer); |
368 | | #endif |
369 | 0 | opj_free(mqc); |
370 | 0 | } |
371 | 0 | } |
372 | | |
373 | 0 | OPJ_UINT32 opj_mqc_numbytes(opj_mqc_t *mqc) { |
374 | 0 | const ptrdiff_t diff = mqc->bp - mqc->start; |
375 | | #if 0 |
376 | | assert( diff <= 0xffffffff && diff >= 0 ); /* UINT32_MAX */ |
377 | | #endif |
378 | 0 | return (OPJ_UINT32)diff; |
379 | 0 | } |
380 | | |
381 | 0 | void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp) { |
382 | | /* TODO MSD: need to take a look to the v2 version */ |
383 | 0 | opj_mqc_setcurctx(mqc, 0); |
384 | 0 | mqc->a = 0x8000; |
385 | 0 | mqc->c = 0; |
386 | 0 | mqc->bp = bp - 1; |
387 | 0 | mqc->ct = 12; |
388 | 0 | if (*mqc->bp == 0xff) { |
389 | 0 | mqc->ct = 13; |
390 | 0 | } |
391 | 0 | mqc->start = bp; |
392 | 0 | } |
393 | | |
394 | 0 | void opj_mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d) { |
395 | 0 | if ((*mqc->curctx)->mps == d) { |
396 | 0 | opj_mqc_codemps(mqc); |
397 | 0 | } else { |
398 | 0 | opj_mqc_codelps(mqc); |
399 | 0 | } |
400 | 0 | } |
401 | | |
402 | 0 | void opj_mqc_flush(opj_mqc_t *mqc) { |
403 | 0 | opj_mqc_setbits(mqc); |
404 | 0 | mqc->c <<= mqc->ct; |
405 | 0 | opj_mqc_byteout(mqc); |
406 | 0 | mqc->c <<= mqc->ct; |
407 | 0 | opj_mqc_byteout(mqc); |
408 | | |
409 | 0 | if (*mqc->bp != 0xff) { |
410 | 0 | mqc->bp++; |
411 | 0 | } |
412 | 0 | } |
413 | | |
414 | 0 | void opj_mqc_bypass_init_enc(opj_mqc_t *mqc) { |
415 | 0 | mqc->c = 0; |
416 | 0 | mqc->ct = 8; |
417 | | /*if (*mqc->bp == 0xff) { |
418 | | mqc->ct = 7; |
419 | | } */ |
420 | 0 | } |
421 | | |
422 | 0 | void opj_mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 d) { |
423 | 0 | mqc->ct--; |
424 | 0 | mqc->c = mqc->c + (d << mqc->ct); |
425 | 0 | if (mqc->ct == 0) { |
426 | 0 | mqc->bp++; |
427 | 0 | *mqc->bp = (OPJ_BYTE)mqc->c; |
428 | 0 | mqc->ct = 8; |
429 | 0 | if (*mqc->bp == 0xff) { |
430 | 0 | mqc->ct = 7; |
431 | 0 | } |
432 | 0 | mqc->c = 0; |
433 | 0 | } |
434 | 0 | } |
435 | | |
436 | 0 | OPJ_UINT32 opj_mqc_bypass_flush_enc(opj_mqc_t *mqc) { |
437 | 0 | OPJ_BYTE bit_padding; |
438 | | |
439 | 0 | bit_padding = 0; |
440 | | |
441 | 0 | if (mqc->ct != 0) { |
442 | 0 | while (mqc->ct > 0) { |
443 | 0 | mqc->ct--; |
444 | 0 | mqc->c += (OPJ_UINT32)(bit_padding << mqc->ct); |
445 | 0 | bit_padding = (bit_padding + 1) & 0x01; |
446 | 0 | } |
447 | 0 | mqc->bp++; |
448 | 0 | *mqc->bp = (OPJ_BYTE)mqc->c; |
449 | 0 | mqc->ct = 8; |
450 | 0 | mqc->c = 0; |
451 | 0 | } |
452 | | |
453 | 0 | return 1; |
454 | 0 | } |
455 | | |
456 | 0 | void opj_mqc_reset_enc(opj_mqc_t *mqc) { |
457 | 0 | opj_mqc_resetstates(mqc); |
458 | 0 | opj_mqc_setstate(mqc, T1_CTXNO_UNI, 0, 46); |
459 | 0 | opj_mqc_setstate(mqc, T1_CTXNO_AGG, 0, 3); |
460 | 0 | opj_mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); |
461 | 0 | } |
462 | | |
463 | 0 | OPJ_UINT32 opj_mqc_restart_enc(opj_mqc_t *mqc) { |
464 | 0 | OPJ_UINT32 correction = 1; |
465 | | |
466 | | /* <flush part> */ |
467 | 0 | OPJ_INT32 n = (OPJ_INT32)(27 - 15 - mqc->ct); |
468 | 0 | mqc->c <<= mqc->ct; |
469 | 0 | while (n > 0) { |
470 | 0 | opj_mqc_byteout(mqc); |
471 | 0 | n -= (OPJ_INT32)mqc->ct; |
472 | 0 | mqc->c <<= mqc->ct; |
473 | 0 | } |
474 | 0 | opj_mqc_byteout(mqc); |
475 | | |
476 | 0 | return correction; |
477 | 0 | } |
478 | | |
479 | 0 | void opj_mqc_restart_init_enc(opj_mqc_t *mqc) { |
480 | | /* <Re-init part> */ |
481 | 0 | opj_mqc_setcurctx(mqc, 0); |
482 | 0 | mqc->a = 0x8000; |
483 | 0 | mqc->c = 0; |
484 | 0 | mqc->ct = 12; |
485 | 0 | mqc->bp--; |
486 | 0 | if (*mqc->bp == 0xff) { |
487 | 0 | mqc->ct = 13; |
488 | 0 | } |
489 | 0 | } |
490 | | |
491 | 0 | void opj_mqc_erterm_enc(opj_mqc_t *mqc) { |
492 | 0 | OPJ_INT32 k = (OPJ_INT32)(11 - mqc->ct + 1); |
493 | | |
494 | 0 | while (k > 0) { |
495 | 0 | mqc->c <<= mqc->ct; |
496 | 0 | mqc->ct = 0; |
497 | 0 | opj_mqc_byteout(mqc); |
498 | 0 | k -= (OPJ_INT32)mqc->ct; |
499 | 0 | } |
500 | | |
501 | 0 | if (*mqc->bp != 0xff) { |
502 | 0 | opj_mqc_byteout(mqc); |
503 | 0 | } |
504 | 0 | } |
505 | | |
506 | 0 | void opj_mqc_segmark_enc(opj_mqc_t *mqc) { |
507 | 0 | OPJ_UINT32 i; |
508 | 0 | opj_mqc_setcurctx(mqc, 18); |
509 | | |
510 | 0 | for (i = 1; i < 5; i++) { |
511 | 0 | opj_mqc_encode(mqc, i % 2); |
512 | 0 | } |
513 | 0 | } |
514 | | |
515 | 0 | OPJ_BOOL opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len) { |
516 | 0 | opj_mqc_setcurctx(mqc, 0); |
517 | 0 | mqc->start = bp; |
518 | 0 | mqc->end = bp + len; |
519 | 0 | mqc->bp = bp; |
520 | 0 | if (len==0) mqc->c = 0xff << 16; |
521 | 0 | else mqc->c = (OPJ_UINT32)(*mqc->bp << 16); |
522 | |
|
523 | | #ifdef MQC_PERF_OPT /* TODO_MSD: check this option and put in experimental */ |
524 | | { |
525 | | OPJ_UINT32 c; |
526 | | OPJ_UINT32 *ip; |
527 | | OPJ_BYTE *end = mqc->end - 1; |
528 | | void* new_buffer = opj_realloc(mqc->buffer, (len + 1) * sizeof(OPJ_UINT32)); |
529 | | if (! new_buffer) { |
530 | | opj_free(mqc->buffer); |
531 | | mqc->buffer = NULL; |
532 | | return OPJ_FALSE; |
533 | | } |
534 | | mqc->buffer = new_buffer; |
535 | | |
536 | | ip = (OPJ_UINT32 *) mqc->buffer; |
537 | | |
538 | | while (bp < end) { |
539 | | c = *(bp + 1); |
540 | | if (*bp == 0xff) { |
541 | | if (c > 0x8f) { |
542 | | break; |
543 | | } else { |
544 | | *ip = 0x00000017 | (c << 9); |
545 | | } |
546 | | } else { |
547 | | *ip = 0x00000018 | (c << 8); |
548 | | } |
549 | | bp++; |
550 | | ip++; |
551 | | } |
552 | | |
553 | | /* Handle last byte of data */ |
554 | | c = 0xff; |
555 | | if (*bp == 0xff) { |
556 | | *ip = 0x0000ff18; |
557 | | } else { |
558 | | bp++; |
559 | | *ip = 0x00000018 | (c << 8); |
560 | | } |
561 | | ip++; |
562 | | |
563 | | *ip = 0x0000ff08; |
564 | | mqc->bp = mqc->buffer; |
565 | | } |
566 | | #endif |
567 | 0 | opj_mqc_bytein(mqc); |
568 | 0 | mqc->c <<= 7; |
569 | 0 | mqc->ct -= 7; |
570 | 0 | mqc->a = 0x8000; |
571 | 0 | return OPJ_TRUE; |
572 | 0 | } |
573 | | |
574 | 0 | OPJ_INT32 opj_mqc_decode(opj_mqc_t *const mqc) { |
575 | 0 | OPJ_INT32 d; |
576 | 0 | mqc->a -= (*mqc->curctx)->qeval; |
577 | 0 | if ((mqc->c >> 16) < (*mqc->curctx)->qeval) { |
578 | 0 | d = opj_mqc_lpsexchange(mqc); |
579 | 0 | opj_mqc_renormd(mqc); |
580 | 0 | } else { |
581 | 0 | mqc->c -= (*mqc->curctx)->qeval << 16; |
582 | 0 | if ((mqc->a & 0x8000) == 0) { |
583 | 0 | d = opj_mqc_mpsexchange(mqc); |
584 | 0 | opj_mqc_renormd(mqc); |
585 | 0 | } else { |
586 | 0 | d = (OPJ_INT32)(*mqc->curctx)->mps; |
587 | 0 | } |
588 | 0 | } |
589 | |
|
590 | 0 | return d; |
591 | 0 | } |
592 | | |
593 | 0 | void opj_mqc_resetstates(opj_mqc_t *mqc) { |
594 | 0 | OPJ_UINT32 i; |
595 | 0 | for (i = 0; i < MQC_NUMCTXS; i++) { |
596 | 0 | mqc->ctxs[i] = mqc_states; |
597 | 0 | } |
598 | 0 | } |
599 | | |
600 | 0 | void opj_mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb, OPJ_INT32 prob) { |
601 | 0 | mqc->ctxs[ctxno] = &mqc_states[msb + (OPJ_UINT32)(prob << 1)]; |
602 | 0 | } |
603 | | |
604 | | |