Update to 2.0.0 tree from current Fremantle build
[opencv] / 3rdparty / libjasper / jpc_t2enc.c
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 Encoder
66  *
67  * $Id: jpc_t2enc.c,v 1.2 2008-05-26 09:40:52 vp153 Exp $
68  */
69
70 /******************************************************************************\
71 * Includes.
72 \******************************************************************************/
73
74 #include <stdio.h>
75 #include <stdlib.h>
76 #include <assert.h>
77
78 #include "jasper/jas_fix.h"
79 #include "jasper/jas_malloc.h"
80 #include "jasper/jas_math.h"
81 #include "jasper/jas_debug.h"
82
83 #include "jpc_flt.h"
84 #include "jpc_t2enc.h"
85 #include "jpc_t2cod.h"
86 #include "jpc_tagtree.h"
87 #include "jpc_enc.h"
88 #include "jpc_math.h"
89
90 /******************************************************************************\
91 * Code.
92 \******************************************************************************/
93
94 static int jpc_putcommacode(jpc_bitstream_t *out, int n)
95 {
96         assert(n >= 0);
97
98         while (--n >= 0) {
99                 if (jpc_bitstream_putbit(out, 1) == EOF) {
100                         return -1;
101                 }
102         }
103         if (jpc_bitstream_putbit(out, 0) == EOF) {
104                 return -1;
105         }
106         return 0;
107 }
108
109 static int jpc_putnumnewpasses(jpc_bitstream_t *out, int n)
110 {
111         int ret;
112
113         if (n <= 0) {
114                 return -1;
115         } else if (n == 1) {
116                 ret = jpc_bitstream_putbit(out, 0);
117         } else if (n == 2) {
118                 ret = jpc_bitstream_putbits(out, 2, 2);
119         } else if (n <= 5) {
120                 ret = jpc_bitstream_putbits(out, 4, 0xc | (n - 3));
121         } else if (n <= 36) {
122                 ret = jpc_bitstream_putbits(out, 9, 0x1e0 | (n - 6));
123         } else if (n <= 164) {
124                 ret = jpc_bitstream_putbits(out, 16, 0xff80 | (n - 37));
125         } else {
126                 /* The standard has no provision for encoding a larger value.
127                 In practice, however, it is highly unlikely that this
128                 limitation will ever be encountered. */
129                 return -1;
130         }
131
132         return (ret != EOF) ? 0 : (-1);
133 }
134
135 int jpc_enc_encpkts(jpc_enc_t *enc, jas_stream_t *out)
136 {
137         jpc_enc_tile_t *tile;
138         jpc_pi_t *pi;
139
140         tile = enc->curtile;
141
142         jpc_init_t2state(enc, 0);
143         pi = tile->pi;
144         jpc_pi_init(pi);
145
146         if (!jpc_pi_next(pi)) {
147                 for (;;) {
148                         if (jpc_enc_encpkt(enc, out, jpc_pi_cmptno(pi), jpc_pi_rlvlno(pi),
149                           jpc_pi_prcno(pi), jpc_pi_lyrno(pi))) {
150                                 return -1;
151                         }
152                         if (jpc_pi_next(pi)) {
153                                 break;
154                         }
155                 }
156         }
157         
158         return 0;
159 }
160
161 int jpc_enc_encpkt(jpc_enc_t *enc, jas_stream_t *out, int compno, int lvlno, int prcno, int lyrno)
162 {
163         jpc_enc_tcmpt_t *comp;
164         jpc_enc_rlvl_t *lvl;
165         jpc_enc_band_t *band;
166         jpc_enc_band_t *endbands;
167         jpc_enc_cblk_t *cblk;
168         jpc_enc_cblk_t *endcblks;
169         jpc_bitstream_t *outb;
170         jpc_enc_pass_t *pass;
171         jpc_enc_pass_t *startpass;
172         jpc_enc_pass_t *lastpass;
173         jpc_enc_pass_t *endpass;
174         jpc_enc_pass_t *endpasses;
175         int i;
176         int included;
177         int ret;
178         jpc_tagtreenode_t *leaf;
179         int n;
180         int t1;
181         int t2;
182         int adjust;
183         int maxadjust;
184         int datalen;
185         int numnewpasses;
186         int passcount;
187         jpc_enc_tile_t *tile;
188         jpc_enc_prc_t *prc;
189         jpc_enc_cp_t *cp;
190         jpc_ms_t *ms;
191
192         tile = enc->curtile;
193         cp = enc->cp;
194
195         if (cp->tcp.csty & JPC_COD_SOP) {
196                 if (!(ms = jpc_ms_create(JPC_MS_SOP))) {
197                         return -1;
198                 }
199                 ms->parms.sop.seqno = jpc_pi_getind(tile->pi);
200                 if (jpc_putms(out, enc->cstate, ms)) {
201                         return -1;
202                 }
203                 jpc_ms_destroy(ms);
204         }
205
206         outb = jpc_bitstream_sopen(out, "w+");
207         assert(outb);
208
209         if (jpc_bitstream_putbit(outb, 1) == EOF) {
210                 return -1;
211         }
212         JAS_DBGLOG(10, ("\n"));
213         JAS_DBGLOG(10, ("present. "));
214
215         comp = &tile->tcmpts[compno];
216         lvl = &comp->rlvls[lvlno];
217         endbands = &lvl->bands[lvl->numbands];
218         for (band = lvl->bands; band != endbands; ++band) {
219                 if (!band->data) {
220                         continue;
221                 }
222                 prc = &band->prcs[prcno];
223                 if (!prc->cblks) {
224                         continue;
225                 }
226
227                 endcblks = &prc->cblks[prc->numcblks];
228                 for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
229                         if (!lyrno) {
230                                 leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks);
231                                 jpc_tagtree_setvalue(prc->nlibtree, leaf, cblk->numimsbs);
232                         }
233                         pass = cblk->curpass;
234                         included = (pass && pass->lyrno == lyrno);
235                         if (included && (!cblk->numencpasses)) {
236                                 assert(pass->lyrno == lyrno);
237                                 leaf = jpc_tagtree_getleaf(prc->incltree,
238                                   cblk - prc->cblks);
239                                 jpc_tagtree_setvalue(prc->incltree, leaf, pass->lyrno);
240                         }
241                 }
242
243                 endcblks = &prc->cblks[prc->numcblks];
244                 for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
245                         pass = cblk->curpass;
246                         included = (pass && pass->lyrno == lyrno);
247                         if (!cblk->numencpasses) {
248                                 leaf = jpc_tagtree_getleaf(prc->incltree,
249                                   cblk - prc->cblks);
250                                 if (jpc_tagtree_encode(prc->incltree, leaf, lyrno
251                                   + 1, outb) < 0) {
252                                         return -1;
253                                 }
254                         } else {
255                                 if (jpc_bitstream_putbit(outb, included) == EOF) {
256                                         return -1;
257                                 }
258                         }
259                         JAS_DBGLOG(10, ("included=%d ", included));
260                         if (!included) {
261                                 continue;
262                         }
263                         if (!cblk->numencpasses) {
264                                 i = 1;
265                                 leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks);
266                                 for (;;) {
267                                         if ((ret = jpc_tagtree_encode(prc->nlibtree, leaf, i, outb)) < 0) {
268                                                 return -1;
269                                         }
270                                         if (ret) {
271                                                 break;
272                                         }
273                                         ++i;
274                                 }
275                                 assert(leaf->known_ && i == leaf->value_ + 1);
276                         }
277
278                         endpasses = &cblk->passes[cblk->numpasses];
279                         startpass = pass;
280                         endpass = startpass;
281                         while (endpass != endpasses && endpass->lyrno == lyrno){
282                                 ++endpass;
283                         }
284                         numnewpasses = endpass - startpass;
285                         if (jpc_putnumnewpasses(outb, numnewpasses)) {
286                                 return -1;
287                         }
288                         JAS_DBGLOG(10, ("numnewpasses=%d ", numnewpasses));
289
290                         lastpass = endpass - 1;
291                         n = startpass->start;
292                         passcount = 1;
293                         maxadjust = 0;
294                         for (pass = startpass; pass != endpass; ++pass) {
295                                 if (pass->term || pass == lastpass) {
296                                         datalen = pass->end - n;
297                                         t1 = jpc_firstone(datalen) + 1;
298                                         t2 = cblk->numlenbits + jpc_floorlog2(passcount);
299                                         adjust = JAS_MAX(t1 - t2, 0);
300                                         maxadjust = JAS_MAX(adjust, maxadjust);
301                                         n += datalen;
302                                         passcount = 1;
303                                 } else {
304                                         ++passcount;
305                                 }
306                         }
307                         if (jpc_putcommacode(outb, maxadjust)) {
308                                 return -1;
309                         }
310                         cblk->numlenbits += maxadjust;
311
312                         lastpass = endpass - 1;
313                         n = startpass->start;
314                         passcount = 1;
315                         for (pass = startpass; pass != endpass; ++pass) {
316                                 if (pass->term || pass == lastpass) {
317                                         datalen = pass->end - n;
318 assert(jpc_firstone(datalen) < cblk->numlenbits + jpc_floorlog2(passcount));
319                                         if (jpc_bitstream_putbits(outb, cblk->numlenbits + jpc_floorlog2(passcount), datalen) == EOF) {
320                                                 return -1;
321                                         }
322                                         n += datalen;
323                                         passcount = 1;
324                                 } else {
325                                         ++passcount;
326                                 }
327                         }
328                 }
329         }
330
331         jpc_bitstream_outalign(outb, 0);
332         jpc_bitstream_close(outb);
333
334         if (cp->tcp.csty & JPC_COD_EPH) {
335                 if (!(ms = jpc_ms_create(JPC_MS_EPH))) {
336                         return -1;
337                 }
338                 jpc_putms(out, enc->cstate, ms);
339                 jpc_ms_destroy(ms);
340         }
341
342         comp = &tile->tcmpts[compno];
343         lvl = &comp->rlvls[lvlno];
344         endbands = &lvl->bands[lvl->numbands];
345         for (band = lvl->bands; band != endbands; ++band) {
346                 if (!band->data) {
347                         continue;
348                 }
349                 prc = &band->prcs[prcno];
350                 if (!prc->cblks) {
351                         continue;
352                 }
353                 endcblks = &prc->cblks[prc->numcblks];
354                 for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
355                         pass = cblk->curpass;
356
357                         if (!pass) {
358                                 continue;
359                         }
360                         if (pass->lyrno != lyrno) {
361                                 assert(pass->lyrno < 0 || pass->lyrno > lyrno);
362                                 continue;
363                         }
364
365                         endpasses = &cblk->passes[cblk->numpasses];
366                         startpass = pass;
367                         endpass = startpass;
368                         while (endpass != endpasses && endpass->lyrno == lyrno){
369                                 ++endpass;
370                         }
371                         lastpass = endpass - 1;
372                         numnewpasses = endpass - startpass;
373
374                         jas_stream_seek(cblk->stream, startpass->start, SEEK_SET);
375                         assert(jas_stream_tell(cblk->stream) == startpass->start);
376                         if (jas_stream_copy(out, cblk->stream, lastpass->end - startpass->start)) {
377                                 return -1;
378                         }
379                         cblk->curpass = (endpass != endpasses) ? endpass : 0;
380                         cblk->numencpasses += numnewpasses;
381
382                 }
383         }
384
385         return 0;
386 }
387
388 void jpc_save_t2state(jpc_enc_t *enc)
389 {
390 /* stream pos in embedded T1 stream may be wrong since not saved/restored! */
391
392         jpc_enc_tcmpt_t *comp;
393         jpc_enc_tcmpt_t *endcomps;
394         jpc_enc_rlvl_t *lvl;
395         jpc_enc_rlvl_t *endlvls;
396         jpc_enc_band_t *band;
397         jpc_enc_band_t *endbands;
398         jpc_enc_cblk_t *cblk;
399         jpc_enc_cblk_t *endcblks;
400         jpc_enc_tile_t *tile;
401         int prcno;
402         jpc_enc_prc_t *prc;
403
404         tile = enc->curtile;
405
406         endcomps = &tile->tcmpts[tile->numtcmpts];
407         for (comp = tile->tcmpts; comp != endcomps; ++comp) {
408                 endlvls = &comp->rlvls[comp->numrlvls];
409                 for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
410                         if (!lvl->bands) {
411                                 continue;
412                         }
413                         endbands = &lvl->bands[lvl->numbands];
414                         for (band = lvl->bands; band != endbands; ++band) {
415                                 if (!band->data) {
416                                         continue;
417                                 }
418                                 for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) {
419                                         if (!prc->cblks) {
420                                                 continue;
421                                         }
422                                         jpc_tagtree_copy(prc->savincltree, prc->incltree);
423                                         jpc_tagtree_copy(prc->savnlibtree, prc->nlibtree);
424                                         endcblks = &prc->cblks[prc->numcblks];
425                                         for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
426                                                 cblk->savedcurpass = cblk->curpass;
427                                                 cblk->savednumencpasses = cblk->numencpasses;
428                                                 cblk->savednumlenbits = cblk->numlenbits;
429                                         }
430                                 }
431                         }
432                 }
433         }
434
435 }
436
437 void jpc_restore_t2state(jpc_enc_t *enc)
438 {
439
440         jpc_enc_tcmpt_t *comp;
441         jpc_enc_tcmpt_t *endcomps;
442         jpc_enc_rlvl_t *lvl;
443         jpc_enc_rlvl_t *endlvls;
444         jpc_enc_band_t *band;
445         jpc_enc_band_t *endbands;
446         jpc_enc_cblk_t *cblk;
447         jpc_enc_cblk_t *endcblks;
448         jpc_enc_tile_t *tile;
449         int prcno;
450         jpc_enc_prc_t *prc;
451
452         tile = enc->curtile;
453
454         endcomps = &tile->tcmpts[tile->numtcmpts];
455         for (comp = tile->tcmpts; comp != endcomps; ++comp) {
456                 endlvls = &comp->rlvls[comp->numrlvls];
457                 for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
458                         if (!lvl->bands) {
459                                 continue;
460                         }
461                         endbands = &lvl->bands[lvl->numbands];
462                         for (band = lvl->bands; band != endbands; ++band) {
463                                 if (!band->data) {
464                                         continue;
465                                 }
466                                 for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) {
467                                         if (!prc->cblks) {
468                                                 continue;
469                                         }
470                                         jpc_tagtree_copy(prc->incltree, prc->savincltree);
471                                         jpc_tagtree_copy(prc->nlibtree, prc->savnlibtree);
472                                         endcblks = &prc->cblks[prc->numcblks];
473                                         for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
474                                                 cblk->curpass = cblk->savedcurpass;
475                                                 cblk->numencpasses = cblk->savednumencpasses;
476                                                 cblk->numlenbits = cblk->savednumlenbits;
477                                         }
478                                 }
479                         }
480                 }
481         }
482 }
483
484 void jpc_init_t2state(jpc_enc_t *enc, int raflag)
485 {
486 /* It is assumed that band->numbps and cblk->numbps precomputed */
487
488         jpc_enc_tcmpt_t *comp;
489         jpc_enc_tcmpt_t *endcomps;
490         jpc_enc_rlvl_t *lvl;
491         jpc_enc_rlvl_t *endlvls;
492         jpc_enc_band_t *band;
493         jpc_enc_band_t *endbands;
494         jpc_enc_cblk_t *cblk;
495         jpc_enc_cblk_t *endcblks;
496         jpc_enc_pass_t *pass;
497         jpc_enc_pass_t *endpasses;
498         jpc_tagtreenode_t *leaf;
499         jpc_enc_tile_t *tile;
500         int prcno;
501         jpc_enc_prc_t *prc;
502
503         tile = enc->curtile;
504
505         endcomps = &tile->tcmpts[tile->numtcmpts];
506         for (comp = tile->tcmpts; comp != endcomps; ++comp) {
507                 endlvls = &comp->rlvls[comp->numrlvls];
508                 for (lvl = comp->rlvls; lvl != endlvls; ++lvl) {
509                         if (!lvl->bands) {
510                                 continue;
511                         }
512                         endbands = &lvl->bands[lvl->numbands];
513                         for (band = lvl->bands; band != endbands; ++band) {
514                                 if (!band->data) {
515                                         continue;
516                                 }
517                                 for (prcno = 0, prc = band->prcs; prcno < lvl->numprcs; ++prcno, ++prc) {
518                                         if (!prc->cblks) {
519                                                 continue;
520                                         }
521                                         jpc_tagtree_reset(prc->incltree);
522                                         jpc_tagtree_reset(prc->nlibtree);
523                                         endcblks = &prc->cblks[prc->numcblks];
524                                         for (cblk = prc->cblks; cblk != endcblks; ++cblk) {
525                                                 if (jas_stream_rewind(cblk->stream)) {
526                                                         assert(0);
527                                                 }
528                                                 cblk->curpass = (cblk->numpasses > 0) ? cblk->passes : 0;
529                                                 cblk->numencpasses = 0;
530                                                 cblk->numlenbits = 3;
531                                                 cblk->numimsbs = band->numbps - cblk->numbps;
532                                                 assert(cblk->numimsbs >= 0);
533                                                 leaf = jpc_tagtree_getleaf(prc->nlibtree, cblk - prc->cblks);
534                                                 jpc_tagtree_setvalue(prc->nlibtree, leaf, cblk->numimsbs);
535
536                                                 if (raflag) {
537                                                         endpasses = &cblk->passes[cblk->numpasses];
538                                                         for (pass = cblk->passes; pass != endpasses; ++pass) {
539                                                                 pass->lyrno = -1;
540                                                                 pass->lyrno = 0;
541                                                         }
542                                                 }
543                                         }
544                                 }
545                         }
546                 }
547         }
548
549 }
550
551 jpc_pi_t *jpc_enc_pi_create(jpc_enc_cp_t *cp, jpc_enc_tile_t *tile)
552 {
553         jpc_pi_t *pi;
554         int compno;
555         jpc_picomp_t *picomp;
556         jpc_pirlvl_t *pirlvl;
557         jpc_enc_tcmpt_t *tcomp;
558         int rlvlno;
559         jpc_enc_rlvl_t *rlvl;
560         int prcno;
561         int *prclyrno;
562
563         if (!(pi = jpc_pi_create0())) {
564                 return 0;
565         }
566         pi->pktno = -1;
567         pi->numcomps = cp->numcmpts;
568         if (!(pi->picomps = jas_malloc(pi->numcomps * sizeof(jpc_picomp_t)))) {
569                 jpc_pi_destroy(pi);
570                 return 0;
571         }
572         for (compno = 0, picomp = pi->picomps; compno < pi->numcomps; ++compno,
573           ++picomp) {
574                 picomp->pirlvls = 0;
575         }
576
577         for (compno = 0, tcomp = tile->tcmpts, picomp = pi->picomps;
578           compno < pi->numcomps; ++compno, ++tcomp, ++picomp) {
579                 picomp->numrlvls = tcomp->numrlvls;
580                 if (!(picomp->pirlvls = jas_malloc(picomp->numrlvls *
581                   sizeof(jpc_pirlvl_t)))) {
582                         jpc_pi_destroy(pi);
583                         return 0;
584                 }
585                 for (rlvlno = 0, pirlvl = picomp->pirlvls; rlvlno <
586                   picomp->numrlvls; ++rlvlno, ++pirlvl) {
587                         pirlvl->prclyrnos = 0;
588                 }
589                 for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls;
590                   rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) {
591 /* XXX sizeof(long) should be sizeof different type */
592                         pirlvl->numprcs = rlvl->numprcs;
593                         if (rlvl->numprcs) {
594                                 if (!(pirlvl->prclyrnos = jas_malloc(pirlvl->numprcs *
595                                   sizeof(long)))) {
596                                         jpc_pi_destroy(pi);
597                                         return 0;
598                                 }
599                         } else {
600                                 pirlvl->prclyrnos = 0;
601                         }
602                 }
603         }
604
605         pi->maxrlvls = 0;
606         for (compno = 0, tcomp = tile->tcmpts, picomp = pi->picomps;
607           compno < pi->numcomps; ++compno, ++tcomp, ++picomp) {
608                 picomp->hsamp = cp->ccps[compno].sampgrdstepx;
609                 picomp->vsamp = cp->ccps[compno].sampgrdstepy;
610                 for (rlvlno = 0, pirlvl = picomp->pirlvls, rlvl = tcomp->rlvls;
611                   rlvlno < picomp->numrlvls; ++rlvlno, ++pirlvl, ++rlvl) {
612                         pirlvl->prcwidthexpn = rlvl->prcwidthexpn;
613                         pirlvl->prcheightexpn = rlvl->prcheightexpn;
614                         for (prcno = 0, prclyrno = pirlvl->prclyrnos;
615                           prcno < pirlvl->numprcs; ++prcno, ++prclyrno) {
616                                 *prclyrno = 0;
617                         }
618                         pirlvl->numhprcs = rlvl->numhprcs;
619                 }
620                 if (pi->maxrlvls < tcomp->numrlvls) {
621                         pi->maxrlvls = tcomp->numrlvls;
622                 }
623         }
624
625         pi->numlyrs = tile->numlyrs;
626         pi->xstart = tile->tlx;
627         pi->ystart = tile->tly;
628         pi->xend = tile->brx;
629         pi->yend = tile->bry;
630
631         pi->picomp = 0;
632         pi->pirlvl = 0;
633         pi->x = 0;
634         pi->y = 0;
635         pi->compno = 0;
636         pi->rlvlno = 0;
637         pi->prcno = 0;
638         pi->lyrno = 0;
639         pi->xstep = 0;
640         pi->ystep = 0;
641
642         pi->pchgno = -1;
643
644         pi->defaultpchg.prgord = tile->prg;
645         pi->defaultpchg.compnostart = 0;
646         pi->defaultpchg.compnoend = pi->numcomps;
647         pi->defaultpchg.rlvlnostart = 0;
648         pi->defaultpchg.rlvlnoend = pi->maxrlvls;
649         pi->defaultpchg.lyrnoend = pi->numlyrs;
650         pi->pchg = 0;
651
652         pi->valid = 0;
653
654         return pi;
655 }