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 Coding Library
66  *
67  * $Id: jpc_t2cod.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $
68  */
69 
70 #include "jasper/jas_math.h"
71 #include "jasper/jas_malloc.h"
72 #include "jasper/jas_math.h"
73 
74 #include "jpc_cs.h"
75 #include "jpc_t2cod.h"
76 #include "jpc_math.h"
77 
78 static int jpc_pi_nextlrcp(jpc_pi_t *pi);
79 static int jpc_pi_nextrlcp(jpc_pi_t *pi);
80 static int jpc_pi_nextrpcl(jpc_pi_t *pi);
81 static int jpc_pi_nextpcrl(jpc_pi_t *pi);
82 static int jpc_pi_nextcprl(jpc_pi_t *pi);
83 
jpc_pi_next(jpc_pi_t * pi)84 int jpc_pi_next(jpc_pi_t *pi)
85 {
86     jpc_pchg_t *pchg;
87     int ret;
88 
89 
90     for (;;) {
91 
92         pi->valid = false;
93 
94         if (!pi->pchg) {
95             ++pi->pchgno;
96             pi->compno = 0;
97             pi->rlvlno = 0;
98             pi->prcno = 0;
99             pi->lyrno = 0;
100             pi->prgvolfirst = true;
101             if (pi->pchgno < jpc_pchglist_numpchgs(pi->pchglist)) {
102                 pi->pchg = jpc_pchglist_get(pi->pchglist, pi->pchgno);
103             } else if (pi->pchgno == jpc_pchglist_numpchgs(pi->pchglist)) {
104                 pi->pchg = &pi->defaultpchg;
105             } else {
106                 return 1;
107             }
108         }
109 
110         pchg = pi->pchg;
111         switch (pchg->prgord) {
112         case JPC_COD_LRCPPRG:
113             ret = jpc_pi_nextlrcp(pi);
114             break;
115         case JPC_COD_RLCPPRG:
116             ret = jpc_pi_nextrlcp(pi);
117             break;
118         case JPC_COD_RPCLPRG:
119             ret = jpc_pi_nextrpcl(pi);
120             break;
121         case JPC_COD_PCRLPRG:
122             ret = jpc_pi_nextpcrl(pi);
123             break;
124         case JPC_COD_CPRLPRG:
125             ret = jpc_pi_nextcprl(pi);
126             break;
127         default:
128             ret = -1;
129             break;
130         }
131         if (!ret) {
132             pi->valid = true;
133             ++pi->pktno;
134             return 0;
135         }
136         pi->pchg = 0;
137     }
138 }
139 
jpc_pi_nextlrcp(register jpc_pi_t * pi)140 static int jpc_pi_nextlrcp(register jpc_pi_t *pi)
141 {
142     jpc_pchg_t *pchg;
143     int *prclyrno;
144 
145     pchg = pi->pchg;
146     if (!pi->prgvolfirst) {
147         prclyrno = &pi->pirlvl->prclyrnos[pi->prcno];
148         goto skip;
149     } else {
150         pi->prgvolfirst = false;
151     }
152 
153     for (pi->lyrno = 0; pi->lyrno < pi->numlyrs && pi->lyrno <
154       JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) {
155         for (pi->rlvlno = pchg->rlvlnostart; pi->rlvlno < pi->maxrlvls &&
156           pi->rlvlno < pchg->rlvlnoend; ++pi->rlvlno) {
157             for (pi->compno = pchg->compnostart, pi->picomp =
158               &pi->picomps[pi->compno]; pi->compno < pi->numcomps
159               && pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno,
160               ++pi->picomp) {
161                 if (pi->rlvlno >= pi->picomp->numrlvls) {
162                     continue;
163                 }
164                 pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno];
165                 for (pi->prcno = 0, prclyrno =
166                   pi->pirlvl->prclyrnos; pi->prcno <
167                   pi->pirlvl->numprcs; ++pi->prcno,
168                   ++prclyrno) {
169                     if (pi->lyrno >= *prclyrno) {
170                         *prclyrno = pi->lyrno;
171                         ++(*prclyrno);
172                         return 0;
173                     }
174 skip:
175                     ;
176                 }
177             }
178         }
179     }
180     return 1;
181 }
182 
jpc_pi_nextrlcp(register jpc_pi_t * pi)183 static int jpc_pi_nextrlcp(register jpc_pi_t *pi)
184 {
185     jpc_pchg_t *pchg;
186     int *prclyrno;
187 
188     pchg = pi->pchg;
189     if (!pi->prgvolfirst) {
190         assert(pi->prcno < pi->pirlvl->numprcs);
191         prclyrno = &pi->pirlvl->prclyrnos[pi->prcno];
192         goto skip;
193     } else {
194         pi->prgvolfirst = 0;
195     }
196 
197     for (pi->rlvlno = pchg->rlvlnostart; pi->rlvlno < pi->maxrlvls &&
198       pi->rlvlno < pchg->rlvlnoend; ++pi->rlvlno) {
199         for (pi->lyrno = 0; pi->lyrno < pi->numlyrs && pi->lyrno <
200           JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) {
201             for (pi->compno = pchg->compnostart, pi->picomp =
202               &pi->picomps[pi->compno]; pi->compno < pi->numcomps &&
203               pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno, ++pi->picomp) {
204                 if (pi->rlvlno >= pi->picomp->numrlvls) {
205                     continue;
206                 }
207                 pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno];
208                 for (pi->prcno = 0, prclyrno = pi->pirlvl->prclyrnos;
209                   pi->prcno < pi->pirlvl->numprcs; ++pi->prcno, ++prclyrno) {
210                     if (pi->lyrno >= *prclyrno) {
211                         *prclyrno = pi->lyrno;
212                         ++(*prclyrno);
213                         return 0;
214                     }
215 skip:
216                     ;
217                 }
218             }
219         }
220     }
221     return 1;
222 }
223 
jpc_pi_nextrpcl(register jpc_pi_t * pi)224 static int jpc_pi_nextrpcl(register jpc_pi_t *pi)
225 {
226     int rlvlno;
227     jpc_pirlvl_t *pirlvl;
228     jpc_pchg_t *pchg;
229     int prchind;
230     int prcvind;
231     int *prclyrno;
232     int compno;
233     jpc_picomp_t *picomp;
234     int xstep;
235     int ystep;
236     uint_fast32_t r;
237     uint_fast32_t rpx;
238     uint_fast32_t rpy;
239     uint_fast32_t trx0;
240     uint_fast32_t try0;
241 
242     pchg = pi->pchg;
243     if (!pi->prgvolfirst) {
244         goto skip;
245     } else {
246         pi->xstep = 0;
247         pi->ystep = 0;
248         for (compno = 0, picomp = pi->picomps; compno < pi->numcomps;
249           ++compno, ++picomp) {
250             for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno <
251               picomp->numrlvls; ++rlvlno, ++pirlvl) {
252                 xstep = picomp->hsamp * (1 << (pirlvl->prcwidthexpn +
253                   picomp->numrlvls - rlvlno - 1));
254                 ystep = picomp->vsamp * (1 << (pirlvl->prcheightexpn +
255                   picomp->numrlvls - rlvlno - 1));
256                 pi->xstep = (!pi->xstep) ? xstep : JAS_MIN(pi->xstep, xstep);
257                 pi->ystep = (!pi->ystep) ? ystep : JAS_MIN(pi->ystep, ystep);
258             }
259         }
260         pi->prgvolfirst = 0;
261     }
262 
263     for (pi->rlvlno = pchg->rlvlnostart; pi->rlvlno < pchg->rlvlnoend &&
264       pi->rlvlno < pi->maxrlvls; ++pi->rlvlno) {
265         for (pi->y = pi->ystart; pi->y < pi->yend; pi->y +=
266           pi->ystep - (pi->y % pi->ystep)) {
267             for (pi->x = pi->xstart; pi->x < pi->xend; pi->x +=
268               pi->xstep - (pi->x % pi->xstep)) {
269                 for (pi->compno = pchg->compnostart,
270                   pi->picomp = &pi->picomps[pi->compno];
271                   pi->compno < JAS_CAST(int, pchg->compnoend) && pi->compno <
272                   pi->numcomps; ++pi->compno, ++pi->picomp) {
273                     if (pi->rlvlno >= pi->picomp->numrlvls) {
274                         continue;
275                     }
276                     pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno];
277                     if (pi->pirlvl->numprcs == 0) {
278                         continue;
279                     }
280                     r = pi->picomp->numrlvls - 1 - pi->rlvlno;
281                     rpx = r + pi->pirlvl->prcwidthexpn;
282                     rpy = r + pi->pirlvl->prcheightexpn;
283                     trx0 = JPC_CEILDIV(pi->xstart, pi->picomp->hsamp << r);
284                     try0 = JPC_CEILDIV(pi->ystart, pi->picomp->vsamp << r);
285                     if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx)))
286                       || !(pi->x % (1 << rpx))) &&
287                       ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy)))
288                       || !(pi->y % (1 << rpy)))) {
289                         prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp
290                           << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0,
291                           pi->pirlvl->prcwidthexpn);
292                         prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp
293                           << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0,
294                           pi->pirlvl->prcheightexpn);
295                         pi->prcno = prcvind * pi->pirlvl->numhprcs + prchind;
296 
297                         assert(pi->prcno < pi->pirlvl->numprcs);
298                         for (pi->lyrno = 0; pi->lyrno <
299                           pi->numlyrs && pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) {
300                             prclyrno = &pi->pirlvl->prclyrnos[pi->prcno];
301                             if (pi->lyrno >= *prclyrno) {
302                                 ++(*prclyrno);
303                                 return 0;
304                             }
305 skip:
306                             ;
307                         }
308                     }
309                 }
310             }
311         }
312     }
313     return 1;
314 }
315 
jpc_pi_nextpcrl(register jpc_pi_t * pi)316 static int jpc_pi_nextpcrl(register jpc_pi_t *pi)
317 {
318     int rlvlno;
319     jpc_pirlvl_t *pirlvl;
320     jpc_pchg_t *pchg;
321     int prchind;
322     int prcvind;
323     int *prclyrno;
324     int compno;
325     jpc_picomp_t *picomp;
326     int xstep;
327     int ystep;
328     uint_fast32_t trx0;
329     uint_fast32_t try0;
330     uint_fast32_t r;
331     uint_fast32_t rpx;
332     uint_fast32_t rpy;
333 
334     pchg = pi->pchg;
335     if (!pi->prgvolfirst) {
336         goto skip;
337     } else {
338         pi->xstep = 0;
339         pi->ystep = 0;
340         for (compno = 0, picomp = pi->picomps; compno < pi->numcomps;
341           ++compno, ++picomp) {
342             for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno <
343               picomp->numrlvls; ++rlvlno, ++pirlvl) {
344                 xstep = picomp->hsamp * (1 <<
345                   (pirlvl->prcwidthexpn + picomp->numrlvls -
346                   rlvlno - 1));
347                 ystep = picomp->vsamp * (1 <<
348                   (pirlvl->prcheightexpn + picomp->numrlvls -
349                   rlvlno - 1));
350                 pi->xstep = (!pi->xstep) ? xstep :
351                   JAS_MIN(pi->xstep, xstep);
352                 pi->ystep = (!pi->ystep) ? ystep :
353                   JAS_MIN(pi->ystep, ystep);
354             }
355         }
356         pi->prgvolfirst = 0;
357     }
358 
359     for (pi->y = pi->ystart; pi->y < pi->yend; pi->y += pi->ystep -
360       (pi->y % pi->ystep)) {
361         for (pi->x = pi->xstart; pi->x < pi->xend; pi->x += pi->xstep -
362           (pi->x % pi->xstep)) {
363             for (pi->compno = pchg->compnostart, pi->picomp =
364               &pi->picomps[pi->compno]; pi->compno < pi->numcomps
365               && pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno,
366               ++pi->picomp) {
367                 for (pi->rlvlno = pchg->rlvlnostart,
368                   pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno];
369                   pi->rlvlno < pi->picomp->numrlvls &&
370                   pi->rlvlno < pchg->rlvlnoend; ++pi->rlvlno,
371                   ++pi->pirlvl) {
372                     if (pi->pirlvl->numprcs == 0) {
373                         continue;
374                     }
375                     r = pi->picomp->numrlvls - 1 - pi->rlvlno;
376                     trx0 = JPC_CEILDIV(pi->xstart, pi->picomp->hsamp << r);
377                     try0 = JPC_CEILDIV(pi->ystart, pi->picomp->vsamp << r);
378                     rpx = r + pi->pirlvl->prcwidthexpn;
379                     rpy = r + pi->pirlvl->prcheightexpn;
380                     if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx))) ||
381                       !(pi->x % (pi->picomp->hsamp << rpx))) &&
382                       ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy))) ||
383                       !(pi->y % (pi->picomp->vsamp << rpy)))) {
384                         prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp
385                           << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0,
386                           pi->pirlvl->prcwidthexpn);
387                         prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp
388                           << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0,
389                           pi->pirlvl->prcheightexpn);
390                         pi->prcno = prcvind * pi->pirlvl->numhprcs + prchind;
391                         assert(pi->prcno < pi->pirlvl->numprcs);
392                         for (pi->lyrno = 0; pi->lyrno < pi->numlyrs &&
393                           pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) {
394                             prclyrno = &pi->pirlvl->prclyrnos[pi->prcno];
395                             if (pi->lyrno >= *prclyrno) {
396                                 ++(*prclyrno);
397                                 return 0;
398                             }
399 skip:
400                             ;
401                         }
402                     }
403                 }
404             }
405         }
406     }
407     return 1;
408 }
409 
jpc_pi_nextcprl(register jpc_pi_t * pi)410 static int jpc_pi_nextcprl(register jpc_pi_t *pi)
411 {
412     int rlvlno;
413     jpc_pirlvl_t *pirlvl;
414     jpc_pchg_t *pchg;
415     int prchind;
416     int prcvind;
417     int *prclyrno;
418     uint_fast32_t trx0;
419     uint_fast32_t try0;
420     uint_fast32_t r;
421     uint_fast32_t rpx;
422     uint_fast32_t rpy;
423 
424     pchg = pi->pchg;
425     if (!pi->prgvolfirst) {
426         goto skip;
427     } else {
428         pi->prgvolfirst = 0;
429     }
430 
431     for (pi->compno = pchg->compnostart, pi->picomp =
432       &pi->picomps[pi->compno]; pi->compno < JAS_CAST(int, pchg->compnoend); ++pi->compno,
433       ++pi->picomp) {
434         pirlvl = pi->picomp->pirlvls;
435         pi->xstep = pi->picomp->hsamp * (1 << (pirlvl->prcwidthexpn +
436           pi->picomp->numrlvls - 1));
437         pi->ystep = pi->picomp->vsamp * (1 << (pirlvl->prcheightexpn +
438           pi->picomp->numrlvls - 1));
439         for (rlvlno = 1, pirlvl = &pi->picomp->pirlvls[1];
440           rlvlno < pi->picomp->numrlvls; ++rlvlno, ++pirlvl) {
441             pi->xstep = JAS_MIN(pi->xstep, pi->picomp->hsamp * (1 <<
442               (pirlvl->prcwidthexpn + pi->picomp->numrlvls -
443               rlvlno - 1)));
444             pi->ystep = JAS_MIN(pi->ystep, pi->picomp->vsamp * (1 <<
445               (pirlvl->prcheightexpn + pi->picomp->numrlvls -
446               rlvlno - 1)));
447         }
448         for (pi->y = pi->ystart; pi->y < pi->yend;
449           pi->y += pi->ystep - (pi->y % pi->ystep)) {
450             for (pi->x = pi->xstart; pi->x < pi->xend;
451               pi->x += pi->xstep - (pi->x % pi->xstep)) {
452                 for (pi->rlvlno = pchg->rlvlnostart,
453                   pi->pirlvl = &pi->picomp->pirlvls[pi->rlvlno];
454                   pi->rlvlno < pi->picomp->numrlvls && pi->rlvlno <
455                   pchg->rlvlnoend; ++pi->rlvlno, ++pi->pirlvl) {
456                     if (pi->pirlvl->numprcs == 0) {
457                         continue;
458                     }
459                     r = pi->picomp->numrlvls - 1 - pi->rlvlno;
460                     trx0 = JPC_CEILDIV(pi->xstart, pi->picomp->hsamp << r);
461                     try0 = JPC_CEILDIV(pi->ystart, pi->picomp->vsamp << r);
462                     rpx = r + pi->pirlvl->prcwidthexpn;
463                     rpy = r + pi->pirlvl->prcheightexpn;
464                     if (((pi->x == pi->xstart && ((trx0 << r) % (1 << rpx))) ||
465                       !(pi->x % (pi->picomp->hsamp << rpx))) &&
466                       ((pi->y == pi->ystart && ((try0 << r) % (1 << rpy))) ||
467                       !(pi->y % (pi->picomp->vsamp << rpy)))) {
468                         prchind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->x, pi->picomp->hsamp
469                           << r), pi->pirlvl->prcwidthexpn) - JPC_FLOORDIVPOW2(trx0,
470                           pi->pirlvl->prcwidthexpn);
471                         prcvind = JPC_FLOORDIVPOW2(JPC_CEILDIV(pi->y, pi->picomp->vsamp
472                           << r), pi->pirlvl->prcheightexpn) - JPC_FLOORDIVPOW2(try0,
473                           pi->pirlvl->prcheightexpn);
474                         pi->prcno = prcvind *
475                           pi->pirlvl->numhprcs +
476                           prchind;
477                         assert(pi->prcno <
478                           pi->pirlvl->numprcs);
479                         for (pi->lyrno = 0; pi->lyrno <
480                           pi->numlyrs && pi->lyrno < JAS_CAST(int, pchg->lyrnoend); ++pi->lyrno) {
481                             prclyrno = &pi->pirlvl->prclyrnos[pi->prcno];
482                             if (pi->lyrno >= *prclyrno) {
483                                 ++(*prclyrno);
484                                 return 0;
485                             }
486 skip:
487                             ;
488                         }
489                     }
490                 }
491             }
492         }
493     }
494     return 1;
495 }
496 
pirlvl_destroy(jpc_pirlvl_t * rlvl)497 static void pirlvl_destroy(jpc_pirlvl_t *rlvl)
498 {
499     if (rlvl->prclyrnos) {
500         jas_free(rlvl->prclyrnos);
501     }
502 }
503 
jpc_picomp_destroy(jpc_picomp_t * picomp)504 static void jpc_picomp_destroy(jpc_picomp_t *picomp)
505 {
506     int rlvlno;
507     jpc_pirlvl_t *pirlvl;
508     if (picomp->pirlvls) {
509         for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno <
510           picomp->numrlvls; ++rlvlno, ++pirlvl) {
511             pirlvl_destroy(pirlvl);
512         }
513         jas_free(picomp->pirlvls);
514     }
515 }
516 
jpc_pi_destroy(jpc_pi_t * pi)517 void jpc_pi_destroy(jpc_pi_t *pi)
518 {
519     jpc_picomp_t *picomp;
520     int compno;
521     if (pi->picomps) {
522         for (compno = 0, picomp = pi->picomps; compno < pi->numcomps;
523           ++compno, ++picomp) {
524             jpc_picomp_destroy(picomp);
525         }
526         jas_free(pi->picomps);
527     }
528     if (pi->pchglist) {
529         jpc_pchglist_destroy(pi->pchglist);
530     }
531     jas_free(pi);
532 }
533 
jpc_pi_create0()534 jpc_pi_t *jpc_pi_create0()
535 {
536     jpc_pi_t *pi;
537     if (!(pi = jas_malloc(sizeof(jpc_pi_t)))) {
538         return 0;
539     }
540     pi->picomps = 0;
541     pi->pchgno = 0;
542     if (!(pi->pchglist = jpc_pchglist_create())) {
543         jas_free(pi);
544         return 0;
545     }
546     return pi;
547 }
548 
jpc_pi_addpchg(jpc_pi_t * pi,jpc_pocpchg_t * pchg)549 int jpc_pi_addpchg(jpc_pi_t *pi, jpc_pocpchg_t *pchg)
550 {
551     return jpc_pchglist_insert(pi->pchglist, -1, pchg);
552 }
553 
jpc_pchglist_create()554 jpc_pchglist_t *jpc_pchglist_create()
555 {
556     jpc_pchglist_t *pchglist;
557     if (!(pchglist = jas_malloc(sizeof(jpc_pchglist_t)))) {
558         return 0;
559     }
560     pchglist->numpchgs = 0;
561     pchglist->maxpchgs = 0;
562     pchglist->pchgs = 0;
563     return pchglist;
564 }
565 
jpc_pchglist_insert(jpc_pchglist_t * pchglist,int pchgno,jpc_pchg_t * pchg)566 int jpc_pchglist_insert(jpc_pchglist_t *pchglist, int pchgno, jpc_pchg_t *pchg)
567 {
568     int i;
569     int newmaxpchgs;
570     jpc_pchg_t **newpchgs;
571     if (pchgno < 0) {
572         pchgno = pchglist->numpchgs;
573     }
574     if (pchglist->numpchgs >= pchglist->maxpchgs) {
575         newmaxpchgs = pchglist->maxpchgs + 128;
576         if (!(newpchgs = jas_realloc2(pchglist->pchgs, newmaxpchgs, sizeof(jpc_pchg_t *)))) {
577             return -1;
578         }
579         pchglist->maxpchgs = newmaxpchgs;
580         pchglist->pchgs = newpchgs;
581     }
582     for (i = pchglist->numpchgs; i > pchgno; --i) {
583         pchglist->pchgs[i] = pchglist->pchgs[i - 1];
584     }
585     pchglist->pchgs[pchgno] = pchg;
586     ++pchglist->numpchgs;
587     return 0;
588 }
589 
jpc_pchglist_remove(jpc_pchglist_t * pchglist,int pchgno)590 jpc_pchg_t *jpc_pchglist_remove(jpc_pchglist_t *pchglist, int pchgno)
591 {
592     int i;
593     jpc_pchg_t *pchg;
594     assert(pchgno < pchglist->numpchgs);
595     pchg = pchglist->pchgs[pchgno];
596     for (i = pchgno + 1; i < pchglist->numpchgs; ++i) {
597         pchglist->pchgs[i - 1] = pchglist->pchgs[i];
598     }
599     --pchglist->numpchgs;
600     return pchg;
601 }
602 
jpc_pchg_copy(jpc_pchg_t * pchg)603 jpc_pchg_t *jpc_pchg_copy(jpc_pchg_t *pchg)
604 {
605     jpc_pchg_t *newpchg;
606     if (!(newpchg = jas_malloc(sizeof(jpc_pchg_t)))) {
607         return 0;
608     }
609     *newpchg = *pchg;
610     return newpchg;
611 }
612 
jpc_pchglist_copy(jpc_pchglist_t * pchglist)613 jpc_pchglist_t *jpc_pchglist_copy(jpc_pchglist_t *pchglist)
614 {
615     jpc_pchglist_t *newpchglist;
616     jpc_pchg_t *newpchg;
617     int pchgno;
618     if (!(newpchglist = jpc_pchglist_create())) {
619         return 0;
620     }
621     for (pchgno = 0; pchgno < pchglist->numpchgs; ++pchgno) {
622         if (!(newpchg = jpc_pchg_copy(pchglist->pchgs[pchgno])) ||
623           jpc_pchglist_insert(newpchglist, -1, newpchg)) {
624             jpc_pchglist_destroy(newpchglist);
625             return 0;
626         }
627     }
628     return newpchglist;
629 }
630 
jpc_pchglist_destroy(jpc_pchglist_t * pchglist)631 void jpc_pchglist_destroy(jpc_pchglist_t *pchglist)
632 {
633     int pchgno;
634     if (pchglist->pchgs) {
635         for (pchgno = 0; pchgno < pchglist->numpchgs; ++pchgno) {
636             jpc_pchg_destroy(pchglist->pchgs[pchgno]);
637         }
638         jas_free(pchglist->pchgs);
639     }
640     jas_free(pchglist);
641 }
642 
jpc_pchg_destroy(jpc_pchg_t * pchg)643 void jpc_pchg_destroy(jpc_pchg_t *pchg)
644 {
645     jas_free(pchg);
646 }
647 
jpc_pchglist_get(jpc_pchglist_t * pchglist,int pchgno)648 jpc_pchg_t *jpc_pchglist_get(jpc_pchglist_t *pchglist, int pchgno)
649 {
650     return pchglist->pchgs[pchgno];
651 }
652 
jpc_pchglist_numpchgs(jpc_pchglist_t * pchglist)653 int jpc_pchglist_numpchgs(jpc_pchglist_t *pchglist)
654 {
655     return pchglist->numpchgs;
656 }
657 
jpc_pi_init(jpc_pi_t * pi)658 int jpc_pi_init(jpc_pi_t *pi)
659 {
660     int compno;
661     int rlvlno;
662     int prcno;
663     jpc_picomp_t *picomp;
664     jpc_pirlvl_t *pirlvl;
665     int *prclyrno;
666 
667     pi->prgvolfirst = 0;
668     pi->valid = 0;
669     pi->pktno = -1;
670     pi->pchgno = -1;
671     pi->pchg = 0;
672 
673     for (compno = 0, picomp = pi->picomps; compno < pi->numcomps;
674       ++compno, ++picomp) {
675         for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno <
676           picomp->numrlvls; ++rlvlno, ++pirlvl) {
677             for (prcno = 0, prclyrno = pirlvl->prclyrnos;
678               prcno < pirlvl->numprcs; ++prcno, ++prclyrno) {
679                 *prclyrno = 0;
680             }
681         }
682     }
683     return 0;
684 }
685