/src/jasper/src/libjasper/jpc/jpc_t2dec.c
Line | Count | Source |
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 | | * Tier 2 Decoder |
66 | | * |
67 | | * $Id$ |
68 | | */ |
69 | | |
70 | | /******************************************************************************\ |
71 | | * Includes. |
72 | | \******************************************************************************/ |
73 | | |
74 | | #include "jpc_t2dec.h" |
75 | | #include "jpc_bs.h" |
76 | | #include "jpc_dec.h" |
77 | | #include "jpc_cs.h" |
78 | | #include "jpc_t1cod.h" |
79 | | #include "jpc_math.h" |
80 | | |
81 | | #include "jasper/jas_types.h" |
82 | | #include "jasper/jas_malloc.h" |
83 | | #include "jasper/jas_math.h" |
84 | | #include "jasper/jas_stream.h" |
85 | | #include "jasper/jas_debug.h" |
86 | | |
87 | | #include <stdio.h> |
88 | | |
89 | | /******************************************************************************\ |
90 | | * |
91 | | \******************************************************************************/ |
92 | | |
93 | | static long jpc_dec_lookahead(jas_stream_t *in); |
94 | | static int jpc_getcommacode(jpc_bitstream_t *in); |
95 | | static int jpc_getnumnewpasses(jpc_bitstream_t *in); |
96 | | static int jpc_dec_decodepkt(jpc_dec_t *dec, jas_stream_t *pkthdrstream, jas_stream_t *in, int compno, int lvlno, |
97 | | int prcno, unsigned lyrno); |
98 | | |
99 | | /******************************************************************************\ |
100 | | * Code. |
101 | | \******************************************************************************/ |
102 | | |
103 | | static int jpc_getcommacode(jpc_bitstream_t *in) |
104 | 361k | { |
105 | 361k | int n; |
106 | 361k | int v; |
107 | | |
108 | 361k | n = 0; |
109 | 414k | for (;;) { |
110 | 414k | if ((v = jpc_bitstream_getbit(in)) < 0) { |
111 | 0 | return -1; |
112 | 0 | } |
113 | 414k | if (jpc_bitstream_eof(in)) { |
114 | 285 | return -1; |
115 | 285 | } |
116 | 414k | if (!v) { |
117 | 361k | break; |
118 | 361k | } |
119 | 53.5k | ++n; |
120 | 53.5k | } |
121 | | |
122 | 361k | return n; |
123 | 361k | } |
124 | | |
125 | | static int jpc_getnumnewpasses(jpc_bitstream_t *in) |
126 | 361k | { |
127 | 361k | int n; |
128 | | |
129 | 361k | if ((n = jpc_bitstream_getbit(in)) > 0) { |
130 | 197k | if ((n = jpc_bitstream_getbit(in)) > 0) { |
131 | 166k | if ((n = jpc_bitstream_getbits(in, 2)) == 3) { |
132 | 62.0k | if ((n = jpc_bitstream_getbits(in, 5)) == 31) { |
133 | 1.11k | if ((n = jpc_bitstream_getbits(in, 7)) >= 0) { |
134 | 1.11k | n += 36 + 1; |
135 | 1.11k | } |
136 | 60.9k | } else if (n >= 0) { |
137 | 60.9k | n += 5 + 1; |
138 | 60.9k | } |
139 | 104k | } else if (n >= 0) { |
140 | 104k | n += 2 + 1; |
141 | 104k | } |
142 | 166k | } else if (!n) { |
143 | 30.7k | n += 2; |
144 | 30.7k | } |
145 | 197k | } else if (!n) { |
146 | 163k | ++n; |
147 | 163k | } |
148 | | |
149 | 361k | return n; |
150 | 361k | } |
151 | | |
152 | | static int jpc_dec_decodepkt(jpc_dec_t *dec, jas_stream_t *pkthdrstream, jas_stream_t *in, int compno, int rlvlno, |
153 | | int prcno, unsigned lyrno) |
154 | 16.1M | { |
155 | 16.1M | jpc_bitstream_t *inb; |
156 | 16.1M | jpc_dec_tcomp_t *tcomp; |
157 | 16.1M | jpc_dec_rlvl_t *rlvl; |
158 | 16.1M | jpc_dec_band_t *band; |
159 | 16.1M | jpc_dec_cblk_t *cblk; |
160 | 16.1M | int m; |
161 | 16.1M | jpc_tagtreenode_t *leaf; |
162 | 16.1M | int included; |
163 | 16.1M | int ret; |
164 | 16.1M | int numnewpasses; |
165 | 16.1M | jpc_dec_seg_t *seg; |
166 | 16.1M | int len; |
167 | 16.1M | int present; |
168 | 16.1M | jpc_ms_t *ms; |
169 | 16.1M | jpc_dec_tile_t *tile; |
170 | 16.1M | jpc_dec_ccp_t *ccp; |
171 | 16.1M | jpc_dec_cp_t *cp; |
172 | 16.1M | jpc_dec_prc_t *prc; |
173 | 16.1M | uint_fast32_t bodylen; |
174 | 16.1M | bool discard; |
175 | | |
176 | | /* Avoid compiler warning about possible use of uninitialized |
177 | | variable. */ |
178 | 16.1M | bodylen = 0; |
179 | | |
180 | 16.1M | discard = (lyrno >= dec->maxlyrs); |
181 | | |
182 | 16.1M | tile = dec->curtile; |
183 | 16.1M | cp = tile->cp; |
184 | 16.1M | ccp = &cp->ccps[compno]; |
185 | | |
186 | | /* |
187 | | * Decode the packet header. |
188 | | */ |
189 | | |
190 | | /* Decode the SOP marker segment if present. */ |
191 | 16.1M | if (cp->csty & JPC_COD_SOP) { |
192 | 1.85M | if (jpc_dec_lookahead(in) == JPC_MS_SOP) { |
193 | 328k | if (!(ms = jpc_getms(in, dec->cstate))) { |
194 | 17 | jas_logerrorf("cannot get marker segment\n"); |
195 | 17 | return -1; |
196 | 17 | } |
197 | 328k | if (jpc_ms_gettype(ms) != JPC_MS_SOP) { |
198 | 0 | jpc_ms_destroy(ms); |
199 | 0 | jas_logerrorf("cannot get (SOP) marker segment\n"); |
200 | 0 | return -1; |
201 | 0 | } |
202 | 328k | unsigned int maxNsop = 65536; |
203 | | /* checking the packet sequence number */ |
204 | 328k | if (tile->pi->pktno % maxNsop != ms->parms.sop.seqno) { |
205 | 84 | jas_logerrorf("incorrect packet sequence number %d was found, but expected %d\n", |
206 | 84 | ms->parms.sop.seqno, tile->pi->pktno % maxNsop); |
207 | 84 | jpc_ms_destroy(ms); |
208 | 84 | return -1; |
209 | 84 | } |
210 | 328k | jpc_ms_destroy(ms); |
211 | 328k | } |
212 | 1.85M | } |
213 | | |
214 | 16.1M | const uint_least64_t hdroffstart = jas_stream_getrwcount(pkthdrstream); |
215 | | |
216 | 16.1M | if (!(inb = jpc_bitstream_sopen(pkthdrstream, "r"))) { |
217 | 0 | jas_logerrorf("cannot open bitstream\n"); |
218 | 0 | return -1; |
219 | 0 | } |
220 | | |
221 | 16.1M | if ((present = jpc_bitstream_getbit(inb)) < 0) { |
222 | 0 | jas_logerrorf("cannot get bit\n"); |
223 | 0 | jpc_bitstream_close(inb); |
224 | 0 | return 1; |
225 | 0 | } |
226 | 16.1M | JAS_LOGDEBUGF(10, "\n", present); |
227 | 16.1M | JAS_LOGDEBUGF(10, "present=%d ", present); |
228 | | |
229 | | /* Is the packet non-empty? */ |
230 | 16.1M | if (present) { |
231 | | /* The packet is non-empty. */ |
232 | 12.7M | tcomp = &tile->tcomps[compno]; |
233 | 12.7M | rlvl = &tcomp->rlvls[rlvlno]; |
234 | 12.7M | bodylen = 0; |
235 | 12.7M | unsigned bandno; |
236 | 47.4M | for (bandno = 0, band = rlvl->bands; bandno < (unsigned)rlvl->numbands; |
237 | 34.6M | ++bandno, ++band) { |
238 | 34.6M | if (!band->data) { |
239 | 28.8M | continue; |
240 | 28.8M | } |
241 | 5.82M | prc = &band->prcs[prcno]; |
242 | 5.82M | if (!prc->cblks) { |
243 | 52.5k | continue; |
244 | 52.5k | } |
245 | 5.77M | unsigned cblkno; |
246 | 5.77M | unsigned usedcblkcnt = 0; |
247 | 13.6M | for (cblkno = 0, cblk = prc->cblks; cblkno < (unsigned)prc->numcblks; |
248 | 7.89M | ++cblkno, ++cblk) { |
249 | 7.89M | ++usedcblkcnt; |
250 | 7.89M | if (!cblk->numpasses) { |
251 | 3.23M | leaf = jpc_tagtree_getleaf(prc->incltagtree, usedcblkcnt - 1); |
252 | 3.23M | if ((included = jpc_tagtree_decode(prc->incltagtree, leaf, lyrno + 1, inb)) < 0) { |
253 | 0 | jas_logerrorf("cannot decode tagtree\n"); |
254 | 0 | jpc_bitstream_close(inb); |
255 | 0 | return -1; |
256 | 0 | } |
257 | 4.66M | } else { |
258 | 4.66M | if ((included = jpc_bitstream_getbit(inb)) < 0) { |
259 | 0 | jas_logerrorf("cannot get bit\n"); |
260 | 0 | jpc_bitstream_close(inb); |
261 | 0 | return -1; |
262 | 0 | } |
263 | 4.66M | } |
264 | 7.89M | JAS_LOGDEBUGF(10, "\n"); |
265 | 7.89M | JAS_LOGDEBUGF(10, "included=%d ", included); |
266 | 7.89M | if (!included) { |
267 | 7.53M | continue; |
268 | 7.53M | } |
269 | 361k | if (!cblk->numpasses) { |
270 | 139k | unsigned i = 1; |
271 | 139k | leaf = jpc_tagtree_getleaf(prc->numimsbstagtree, usedcblkcnt - 1); |
272 | 44.0M | for (;;) { |
273 | 44.0M | if ((ret = jpc_tagtree_decode(prc->numimsbstagtree, leaf, i, inb)) < 0) { |
274 | 0 | jas_logerrorf("cannot decode tagtree\n"); |
275 | 0 | jpc_bitstream_close(inb); |
276 | 0 | return -1; |
277 | 0 | } |
278 | 44.0M | if (ret) { |
279 | 139k | break; |
280 | 139k | } |
281 | 43.9M | ++i; |
282 | 43.9M | } |
283 | 139k | cblk->numimsbs = i - 1; |
284 | 139k | cblk->firstpassno = cblk->numimsbs * 3; |
285 | 139k | } |
286 | 361k | if ((numnewpasses = jpc_getnumnewpasses(inb)) < 0) { |
287 | 0 | jas_logerrorf("cannot get number of new passes\n"); |
288 | 0 | jpc_bitstream_close(inb); |
289 | 0 | return -1; |
290 | 0 | } |
291 | 361k | JAS_LOGDEBUGF(10, "numnewpasses=%d ", numnewpasses); |
292 | 361k | seg = cblk->curseg; |
293 | 361k | const unsigned savenumnewpasses = numnewpasses; |
294 | 361k | unsigned mycounter = 0; |
295 | 361k | if (numnewpasses > 0) { |
296 | 361k | if (cblk->firstpassno > 10000) { |
297 | | /* workaround for |
298 | | CVE-2016-9398: this |
299 | | large value would |
300 | | make |
301 | | JPC_SEGPASSCNT() |
302 | | return a negative |
303 | | value, causing an |
304 | | assertion failure |
305 | | in |
306 | | jpc_floorlog2() */ |
307 | 59 | jas_logerrorf("first pass number unreasonably large\n"); |
308 | 59 | jpc_bitstream_close(inb); |
309 | 59 | return -1; |
310 | 59 | } |
311 | 361k | if ((m = jpc_getcommacode(inb)) < 0) { |
312 | 285 | jas_logerrorf("cannot get comma code\n"); |
313 | 285 | jpc_bitstream_close(inb); |
314 | 285 | return -1; |
315 | 285 | } |
316 | 361k | cblk->numlenbits += m; |
317 | 361k | JAS_LOGDEBUGF(10, "increment=%d ", m); |
318 | 969k | while (numnewpasses > 0) { |
319 | 608k | const unsigned passno = cblk->firstpassno + cblk->numpasses + mycounter; |
320 | 608k | if (passno >= 10000) { |
321 | | /* with this value, |
322 | | JPC_SEGPASSCNT() |
323 | | would return 0, |
324 | | which is an illegal |
325 | | value and would |
326 | | later crash in |
327 | | jpc_floorlog2() */ |
328 | 9 | jas_logerrorf("pass number unreasonably large\n"); |
329 | 9 | jpc_bitstream_close(inb); |
330 | 9 | return -1; |
331 | 9 | } |
332 | | /* XXX - the maxpasses is not set precisely but this doesn't matter... */ |
333 | 608k | const unsigned maxpasses = JPC_SEGPASSCNT(passno, cblk->firstpassno, 10000, (ccp->cblkctx & JPC_COX_LAZY) != 0, (ccp->cblkctx & JPC_COX_TERMALL) != 0); |
334 | 608k | if (!discard && !seg) { |
335 | 465k | if (!(seg = jpc_seg_alloc())) { |
336 | 0 | jas_logerrorf("cannot allocate segment\n"); |
337 | 0 | jpc_bitstream_close(inb); |
338 | 0 | return -1; |
339 | 0 | } |
340 | 465k | jpc_seglist_insert(&cblk->segs, cblk->segs.tail, seg); |
341 | 465k | if (!cblk->curseg) { |
342 | 235k | cblk->curseg = seg; |
343 | 235k | } |
344 | 465k | seg->passno = passno; |
345 | 465k | seg->type = JPC_SEGTYPE(seg->passno, cblk->firstpassno, (ccp->cblkctx & JPC_COX_LAZY) != 0); |
346 | 465k | seg->maxpasses = maxpasses; |
347 | 465k | } |
348 | 608k | const unsigned n = JAS_MIN((unsigned)numnewpasses, maxpasses); |
349 | 608k | mycounter += n; |
350 | 608k | numnewpasses -= n; |
351 | 608k | if ((len = jpc_bitstream_getbits(inb, |
352 | 608k | cblk->numlenbits + jpc_floorlog2(n))) < 0) { |
353 | 29 | jpc_bitstream_close(inb); |
354 | 29 | jas_logerrorf("cannot get bits\n"); |
355 | 29 | return -1; |
356 | 29 | } |
357 | 608k | JAS_LOGDEBUGF(10, "len=%d ", len); |
358 | 608k | if (!discard) { |
359 | 578k | seg->lyrno = lyrno; |
360 | 578k | seg->numpasses += n; |
361 | 578k | seg->cnt = len; |
362 | 578k | seg = seg->next; |
363 | 578k | } |
364 | 608k | bodylen += len; |
365 | 608k | } |
366 | 361k | } |
367 | 361k | cblk->numpasses += savenumnewpasses; |
368 | 361k | } |
369 | 5.77M | } |
370 | | |
371 | 12.7M | jpc_bitstream_inalign(inb, 0, 0); |
372 | | |
373 | 12.7M | } else { |
374 | 3.39M | if (jpc_bitstream_inalign(inb, 0x7f, 0)) { |
375 | 462 | jas_logerrorf("alignment failed\n"); |
376 | 462 | jpc_bitstream_close(inb); |
377 | 462 | return -1; |
378 | 462 | } |
379 | 3.39M | } |
380 | 16.1M | jpc_bitstream_close(inb); |
381 | | |
382 | 16.1M | if (jas_get_debug_level() >= 5) { |
383 | 0 | const uint_least64_t hdroffend = jas_stream_getrwcount(pkthdrstream); |
384 | 0 | const unsigned long hdrlen = hdroffend - hdroffstart; |
385 | 0 | jas_logdebugf(5, "hdrlen=%lu bodylen=%lu \n", (unsigned long) hdrlen, |
386 | 0 | (unsigned long) bodylen); |
387 | 0 | } |
388 | | |
389 | 16.1M | if (cp->csty & JPC_COD_EPH) { |
390 | 330k | if (!(ms = jpc_getms(pkthdrstream, dec->cstate))) { |
391 | 70 | jas_logerrorf("cannot get (EPH) marker segment\n"); |
392 | 70 | return -1; |
393 | 70 | } |
394 | 330k | if (jpc_ms_gettype(ms) != JPC_MS_EPH) { |
395 | 5 | jpc_ms_destroy(ms); |
396 | 5 | jas_logerrorf("missing EPH marker segment\n"); |
397 | 5 | return -1; |
398 | 5 | } |
399 | 330k | jpc_ms_destroy(ms); |
400 | 330k | } |
401 | | |
402 | | /* decode the packet body. */ |
403 | | |
404 | 16.1M | if (jas_get_debug_level() >= 1) { |
405 | 0 | jas_logdebugf(1, "packet body offset=%06ld\n", (long) jas_stream_getrwcount(in)); |
406 | 0 | } |
407 | | |
408 | 16.1M | if (!discard) { |
409 | 11.4M | tcomp = &tile->tcomps[compno]; |
410 | 11.4M | rlvl = &tcomp->rlvls[rlvlno]; |
411 | 11.4M | unsigned bandno; |
412 | 36.5M | for (bandno = 0, band = rlvl->bands; bandno < (unsigned)rlvl->numbands; |
413 | 25.1M | ++bandno, ++band) { |
414 | 25.1M | if (!band->data) { |
415 | 16.9M | continue; |
416 | 16.9M | } |
417 | 8.23M | prc = &band->prcs[prcno]; |
418 | 8.23M | if (!prc->cblks) { |
419 | 54.1k | continue; |
420 | 54.1k | } |
421 | 8.18M | unsigned cblkno; |
422 | 397M | for (cblkno = 0, cblk = prc->cblks; cblkno < (unsigned)prc->numcblks; |
423 | 389M | ++cblkno, ++cblk) { |
424 | 389M | seg = cblk->curseg; |
425 | 391M | while (seg) { |
426 | 2.25M | if (!seg->stream) { |
427 | 426k | if (!(seg->stream = jas_stream_memopen(0, 0))) { |
428 | 0 | jas_logerrorf("cannot open memory stream\n"); |
429 | 0 | return -1; |
430 | 0 | } |
431 | 426k | } |
432 | | #if 0 |
433 | | jas_eprintf("lyrno=%02d, compno=%02d, lvlno=%02d, prcno=%02d, bandno=%02d, cblkno=%02d, passno=%02d numpasses=%02d cnt=%d numbps=%d, numimsbs=%d\n", |
434 | | lyrno, compno, rlvlno, prcno, band - rlvl->bands, |
435 | | cblk - prc->cblks, seg->passno, seg->numpasses, seg->cnt, |
436 | | band->numbps, cblk->numimsbs); |
437 | | #endif |
438 | 2.25M | if (seg->cnt > 0) { |
439 | 366k | if (jpc_getdata(in, seg->stream, seg->cnt) < 0) { |
440 | 443 | jas_logerrorf("jas_getdata failed\n"); |
441 | 443 | return -1; |
442 | 443 | } |
443 | 365k | seg->cnt = 0; |
444 | 365k | } |
445 | 2.25M | if (seg->numpasses >= seg->maxpasses) { |
446 | 308k | cblk->curseg = seg->next; |
447 | 308k | } |
448 | 2.25M | seg = seg->next; |
449 | 2.25M | } |
450 | 389M | } |
451 | 8.18M | } |
452 | 11.4M | } else { |
453 | 4.74M | if (jas_stream_gobble(in, bodylen) != JAS_CAST(int, bodylen)) { |
454 | 158 | jas_logerrorf("jas_stream_gobble failed\n"); |
455 | 158 | return -1; |
456 | 158 | } |
457 | 4.74M | } |
458 | 16.1M | return 0; |
459 | 16.1M | } |
460 | | |
461 | | /********************************************************************************************/ |
462 | | /********************************************************************************************/ |
463 | | |
464 | | int jpc_dec_decodepkts(jpc_dec_t *dec, jas_stream_t *pkthdrstream, jas_stream_t *in) |
465 | 13.4k | { |
466 | 13.4k | jpc_dec_tile_t *tile; |
467 | 13.4k | jpc_pi_t *pi; |
468 | 13.4k | int ret; |
469 | | |
470 | 13.4k | tile = dec->curtile; |
471 | 13.4k | pi = tile->pi; |
472 | 16.1M | for (;;) { |
473 | 16.1M | if (!tile->pkthdrstream || |
474 | 15.8M | jas_stream_peekc(tile->pkthdrstream) == EOF) { |
475 | 15.8M | switch (jpc_dec_lookahead(in)) { |
476 | 3.72k | case JPC_MS_EOC: |
477 | 10.7k | case JPC_MS_SOT: |
478 | 10.7k | return 0; |
479 | 9.95k | case JPC_MS_SOP: |
480 | 12.9k | case JPC_MS_EPH: |
481 | 15.8M | case 0: |
482 | 15.8M | break; |
483 | 508 | default: |
484 | 508 | jas_logerrorf("jpc_dec_lookahead failed\n"); |
485 | 508 | return -1; |
486 | 15.8M | } |
487 | 15.8M | } |
488 | | // jpc_pi_dump(pi); |
489 | 16.1M | if ((ret = jpc_pi_next(pi))) { |
490 | 522 | if (ret < 0) { |
491 | 0 | jas_logerrorf("jpc_pi_next failed\n"); |
492 | 0 | } |
493 | | //jas_logerrorf("jpc_pi_next failed (%d)\n", ret); |
494 | 522 | return ret; |
495 | 522 | } |
496 | 16.1M | if (dec->maxpkts >= 0 && dec->numpkts >= (unsigned)dec->maxpkts) { |
497 | 0 | jas_logwarnf("warning: stopping decode prematurely as requested\n"); |
498 | 0 | return 0; |
499 | 0 | } |
500 | 16.1M | if (jas_get_debug_level() >= 1) { |
501 | 0 | jas_logdebugf(1, "packet offset=%08ld prg=%d cmptno=%02d " |
502 | 0 | "rlvlno=%02d prcno=%03d lyrno=%02d\n", (long) |
503 | 0 | jas_stream_getrwcount(in), jpc_pi_prg(pi), jpc_pi_cmptno(pi), |
504 | 0 | jpc_pi_rlvlno(pi), jpc_pi_prcno(pi), jpc_pi_lyrno(pi)); |
505 | 0 | } |
506 | 16.1M | if (jpc_dec_decodepkt(dec, pkthdrstream, in, jpc_pi_cmptno(pi), |
507 | 16.1M | jpc_pi_rlvlno(pi), jpc_pi_prcno(pi), jpc_pi_lyrno(pi))) { |
508 | 1.62k | jas_logerrorf("jpc_dec_decodepkt failed\n"); |
509 | 1.62k | return -1; |
510 | 1.62k | } |
511 | 16.1M | ++dec->numpkts; |
512 | 16.1M | } |
513 | | |
514 | 0 | return 0; |
515 | 13.4k | } |
516 | | |
517 | | jpc_pi_t *jpc_dec_pi_create(jpc_dec_t *dec, jpc_dec_tile_t *tile) |
518 | 12.6k | { |
519 | 12.6k | jpc_pi_t *pi; |
520 | 12.6k | unsigned compno; |
521 | 12.6k | jpc_picomp_t *picomp; |
522 | 12.6k | jpc_pirlvl_t *pirlvl; |
523 | 12.6k | jpc_dec_tcomp_t *tcomp; |
524 | 12.6k | unsigned rlvlno; |
525 | 12.6k | jpc_dec_rlvl_t *rlvl; |
526 | 12.6k | unsigned prcno; |
527 | 12.6k | unsigned *prclyrno; |
528 | 12.6k | jpc_dec_cmpt_t *cmpt; |
529 | | |
530 | 12.6k | if (!(pi = jpc_pi_create0())) { |
531 | 0 | return 0; |
532 | 0 | } |
533 | 12.6k | pi->numcomps = dec->numcomps; |
534 | 12.6k | if (!(pi->picomps = jas_alloc2(pi->numcomps, sizeof(jpc_picomp_t)))) { |
535 | 0 | jpc_pi_destroy(pi); |
536 | 0 | return 0; |
537 | 0 | } |
538 | 43.3k | for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; ++compno, |
539 | 30.7k | ++picomp) { |
540 | 30.7k | picomp->pirlvls = 0; |
541 | 30.7k | } |
542 | | |
543 | 12.6k | for (compno = 0, tcomp = tile->tcomps, picomp = pi->picomps; |
544 | 43.3k | compno < pi->numcomps; ++compno, ++tcomp, ++picomp) { |
545 | 30.7k | picomp->numrlvls = tcomp->numrlvls; |
546 | 30.7k | if (!(picomp->pirlvls = jas_alloc2(picomp->numrlvls, |
547 | 30.7k | sizeof(jpc_pirlvl_t)))) { |
548 | 0 | jpc_pi_destroy(pi); |
549 | 0 | return 0; |
550 | 0 | } |
551 | 179k | for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno < |
552 | 179k | picomp->numrlvls; ++rlvlno, ++pirlvl) { |
553 | 148k | pirlvl->prclyrnos = 0; |
554 | 148k | } |
555 | 30.7k | for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls; |
556 | 179k | rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) { |
557 | | /* XXX sizeof(long) should be sizeof different type */ |
558 | 148k | pirlvl->numprcs = rlvl->numprcs; |
559 | 148k | if (!(pirlvl->prclyrnos = jas_alloc2(pirlvl->numprcs, |
560 | 148k | sizeof(long)))) { |
561 | 0 | jpc_pi_destroy(pi); |
562 | 0 | return 0; |
563 | 0 | } |
564 | 148k | } |
565 | 30.7k | } |
566 | | |
567 | 12.6k | pi->maxrlvls = 0; |
568 | 12.6k | for (compno = 0, tcomp = tile->tcomps, picomp = pi->picomps, cmpt = |
569 | 43.3k | dec->cmpts; compno < pi->numcomps; ++compno, ++tcomp, ++picomp, |
570 | 30.7k | ++cmpt) { |
571 | 30.7k | picomp->hsamp = cmpt->hstep; |
572 | 30.7k | picomp->vsamp = cmpt->vstep; |
573 | 30.7k | for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls; |
574 | 179k | rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) { |
575 | 148k | pirlvl->prcwidthexpn = rlvl->prcwidthexpn; |
576 | 148k | pirlvl->prcheightexpn = rlvl->prcheightexpn; |
577 | 148k | for (prcno = 0, prclyrno = pirlvl->prclyrnos; |
578 | 5.38M | prcno < pirlvl->numprcs; ++prcno, ++prclyrno) { |
579 | 5.23M | *prclyrno = 0; |
580 | 5.23M | } |
581 | 148k | pirlvl->numhprcs = rlvl->numhprcs; |
582 | 148k | } |
583 | 30.7k | if (pi->maxrlvls < tcomp->numrlvls) { |
584 | 12.7k | pi->maxrlvls = tcomp->numrlvls; |
585 | 12.7k | } |
586 | 30.7k | } |
587 | | |
588 | 12.6k | pi->numlyrs = tile->cp->numlyrs; |
589 | 12.6k | pi->xstart = tile->xstart; |
590 | 12.6k | pi->ystart = tile->ystart; |
591 | 12.6k | pi->xend = tile->xend; |
592 | 12.6k | pi->yend = tile->yend; |
593 | | |
594 | 12.6k | pi->picomp = 0; |
595 | 12.6k | pi->pirlvl = 0; |
596 | 12.6k | pi->x = 0; |
597 | 12.6k | pi->y = 0; |
598 | 12.6k | pi->compno = 0; |
599 | 12.6k | pi->rlvlno = 0; |
600 | 12.6k | pi->prcno = 0; |
601 | 12.6k | pi->lyrno = 0; |
602 | 12.6k | pi->xstep = 0; |
603 | 12.6k | pi->ystep = 0; |
604 | | |
605 | 12.6k | pi->pchgno = -1; |
606 | | |
607 | 12.6k | pi->defaultpchg.prgord = tile->cp->prgord; |
608 | 12.6k | pi->defaultpchg.compnostart = 0; |
609 | 12.6k | pi->defaultpchg.compnoend = pi->numcomps; |
610 | 12.6k | pi->defaultpchg.rlvlnostart = 0; |
611 | 12.6k | pi->defaultpchg.rlvlnoend = pi->maxrlvls; |
612 | 12.6k | pi->defaultpchg.lyrnoend = pi->numlyrs; |
613 | 12.6k | pi->pchg = 0; |
614 | | |
615 | 12.6k | pi->valid = 0; |
616 | | |
617 | 12.6k | return pi; |
618 | 12.6k | } |
619 | | |
620 | | static long jpc_dec_lookahead(jas_stream_t *in) |
621 | 17.7M | { |
622 | 17.7M | uint_fast16_t x; |
623 | 17.7M | if (jpc_getuint16(in, &x)) { |
624 | 950 | return -1; |
625 | 950 | } |
626 | 17.7M | if (jas_stream_ungetc(in, x & 0xff) == EOF || |
627 | 17.7M | jas_stream_ungetc(in, x >> 8) == EOF) { |
628 | 0 | return -1; |
629 | 0 | } |
630 | 17.7M | if (x >= JPC_MS_INMIN && x <= JPC_MS_INMAX) { |
631 | 353k | return x; |
632 | 353k | } |
633 | 17.3M | return 0; |
634 | 17.7M | } |