]> Creatis software - gdcm.git/blob - src/gdcmopenjpeg/libopenjpeg/pi.c
521e966ed2ff8ff51fb60c642b1e8c5e12b3d3ac
[gdcm.git] / src / gdcmopenjpeg / libopenjpeg / pi.c
1 /*\r
2  * Copyright (c) 2001-2003, David Janssens\r
3  * Copyright (c) 2002-2003, Yannick Verschueren\r
4  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe\r
5  * Copyright (c) 2005, HervĂ© Drolon, FreeImage Team\r
6  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium\r
7  * All rights reserved.\r
8  *\r
9  * Redistribution and use in source and binary forms, with or without\r
10  * modification, are permitted provided that the following conditions\r
11  * are met:\r
12  * 1. Redistributions of source code must retain the above copyright\r
13  *    notice, this list of conditions and the following disclaimer.\r
14  * 2. Redistributions in binary form must reproduce the above copyright\r
15  *    notice, this list of conditions and the following disclaimer in the\r
16  *    documentation and/or other materials provided with the distribution.\r
17  *\r
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'\r
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\r
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\r
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE\r
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\r
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\r
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\r
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\r
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\r
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\r
28  * POSSIBILITY OF SUCH DAMAGE.\r
29  */\r
30 \r
31 #include "opj_includes.h"\r
32 \r
33 /** @defgroup PI PI - Implementation of a packet iterator */\r
34 /*@{*/\r
35 \r
36 /** @name Local static functions */\r
37 /*@{*/\r
38 \r
39 /**\r
40 Get next packet in layer-resolution-component-precinct order.\r
41 @param pi packet iterator to modify\r
42 @return returns false if pi pointed to the last packet or else returns true \r
43 */\r
44 static bool pi_next_lrcp(opj_pi_iterator_t * pi);\r
45 /**\r
46 Get next packet in resolution-layer-component-precinct order.\r
47 @param pi packet iterator to modify\r
48 @return returns false if pi pointed to the last packet or else returns true \r
49 */\r
50 static bool pi_next_rlcp(opj_pi_iterator_t * pi);\r
51 /**\r
52 Get next packet in resolution-precinct-component-layer order.\r
53 @param pi packet iterator to modify\r
54 @return returns false if pi pointed to the last packet or else returns true \r
55 */\r
56 static bool pi_next_rpcl(opj_pi_iterator_t * pi);\r
57 /**\r
58 Get next packet in precinct-component-resolution-layer order.\r
59 @param pi packet iterator to modify\r
60 @return returns false if pi pointed to the last packet or else returns true \r
61 */\r
62 static bool pi_next_pcrl(opj_pi_iterator_t * pi);\r
63 /**\r
64 Get next packet in component-precinct-resolution-layer order.\r
65 @param pi packet iterator to modify\r
66 @return returns false if pi pointed to the last packet or else returns true \r
67 */\r
68 static bool pi_next_cprl(opj_pi_iterator_t * pi);\r
69 \r
70 /*@}*/\r
71 \r
72 /*@}*/\r
73 \r
74 /* \r
75 ==========================================================\r
76    local functions\r
77 ==========================================================\r
78 */\r
79 \r
80 static bool pi_next_lrcp(opj_pi_iterator_t * pi) {\r
81   opj_pi_comp_t *comp = NULL;\r
82   opj_pi_resolution_t *res = NULL;\r
83   long index = 0;\r
84   \r
85   if (!pi->first) {\r
86     comp = &pi->comps[pi->compno];\r
87     res = &comp->resolutions[pi->resno];\r
88     goto LABEL_SKIP;\r
89   } else {\r
90     pi->first = 0;\r
91   }\r
92 \r
93   for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {\r
94     for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1;\r
95     pi->resno++) {\r
96       for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {\r
97         comp = &pi->comps[pi->compno];\r
98         if (pi->resno >= comp->numresolutions) {\r
99           continue;\r
100         }\r
101         res = &comp->resolutions[pi->resno];\r
102         for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) {\r
103           index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;\r
104           if (!pi->include[index]) {\r
105             pi->include[index] = 1;\r
106             return true;\r
107           }\r
108 LABEL_SKIP:;\r
109         }\r
110       }\r
111     }\r
112   }\r
113   \r
114   return false;\r
115 }\r
116 \r
117 static bool pi_next_rlcp(opj_pi_iterator_t * pi) {\r
118   opj_pi_comp_t *comp = NULL;\r
119   opj_pi_resolution_t *res = NULL;\r
120   long index = 0;\r
121 \r
122   if (!pi->first) {\r
123     comp = &pi->comps[pi->compno];\r
124     res = &comp->resolutions[pi->resno];\r
125     goto LABEL_SKIP;\r
126   } else {\r
127     pi->first = 0;\r
128   }\r
129 \r
130   for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {\r
131     for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {\r
132       for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {\r
133         comp = &pi->comps[pi->compno];\r
134         if (pi->resno >= comp->numresolutions) {\r
135           continue;\r
136         }\r
137         res = &comp->resolutions[pi->resno];\r
138         for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) {\r
139           index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;\r
140           if (!pi->include[index]) {\r
141             pi->include[index] = 1;\r
142             return true;\r
143           }\r
144 LABEL_SKIP:;\r
145         }\r
146       }\r
147     }\r
148   }\r
149   \r
150   return false;\r
151 }\r
152 \r
153 static bool pi_next_rpcl(opj_pi_iterator_t * pi) {\r
154   opj_pi_comp_t *comp = NULL;\r
155   opj_pi_resolution_t *res = NULL;\r
156   long index = 0;\r
157 \r
158   if (!pi->first) {\r
159     goto LABEL_SKIP;\r
160   } else {\r
161     int compno, resno;\r
162     pi->first = 0;\r
163     pi->dx = 0;\r
164     pi->dy = 0;\r
165     for (compno = 0; compno < pi->numcomps; compno++) {\r
166       comp = &pi->comps[compno];\r
167       for (resno = 0; resno < comp->numresolutions; resno++) {\r
168         int dx, dy;\r
169         res = &comp->resolutions[resno];\r
170         dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));\r
171         dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));\r
172         pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);\r
173         pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);\r
174       }\r
175     }\r
176   }\r
177 \r
178   for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {\r
179     for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {\r
180       for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {\r
181         for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {\r
182           int levelno;\r
183           int trx0, try0;\r
184           int trx1, try1;\r
185           int rpx, rpy;\r
186           int prci, prcj;\r
187           comp = &pi->comps[pi->compno];\r
188           if (pi->resno >= comp->numresolutions) {\r
189             continue;\r
190           }\r
191           res = &comp->resolutions[pi->resno];\r
192           levelno = comp->numresolutions - 1 - pi->resno;\r
193           trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);\r
194           try0 = int_ceildiv(pi->ty0, comp->dy << levelno);\r
195           trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);\r
196           try1 = int_ceildiv(pi->ty1, comp->dy << levelno);\r
197           rpx = res->pdx + levelno;\r
198           rpy = res->pdy + levelno;\r
199           if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {\r
200             continue;\r
201           }\r
202           if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {\r
203             continue;\r
204           }\r
205           \r
206           if ((res->pw==0)||(res->pw==0)) continue;\r
207           \r
208           if ((trx0==trx1)||(try0==try1)) continue;\r
209           \r
210           prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) \r
211              - int_floordivpow2(trx0, res->pdx);\r
212           prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) \r
213              - int_floordivpow2(try0, res->pdy);\r
214           pi->precno = prci + prcj * res->pw;\r
215           for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {\r
216             index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;\r
217             if (!pi->include[index]) {\r
218               pi->include[index] = 1;\r
219               return true;\r
220             }\r
221 LABEL_SKIP:;\r
222           }\r
223         }\r
224       }\r
225     }\r
226   }\r
227   \r
228   return false;\r
229 }\r
230 \r
231 static bool pi_next_pcrl(opj_pi_iterator_t * pi) {\r
232   opj_pi_comp_t *comp = NULL;\r
233   opj_pi_resolution_t *res = NULL;\r
234   long index = 0;\r
235 \r
236   if (!pi->first) {\r
237     comp = &pi->comps[pi->compno];\r
238     goto LABEL_SKIP;\r
239   } else {\r
240     int compno, resno;\r
241     pi->first = 0;\r
242     pi->dx = 0;\r
243     pi->dy = 0;\r
244     for (compno = 0; compno < pi->numcomps; compno++) {\r
245       comp = &pi->comps[compno];\r
246       for (resno = 0; resno < comp->numresolutions; resno++) {\r
247         int dx, dy;\r
248         res = &comp->resolutions[resno];\r
249         dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));\r
250         dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));\r
251         pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);\r
252         pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);\r
253       }\r
254     }\r
255   }\r
256 \r
257   for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {\r
258     for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {\r
259       for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {\r
260         comp = &pi->comps[pi->compno];\r
261         for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {\r
262           int levelno;\r
263           int trx0, try0;\r
264           int trx1, try1;\r
265           int rpx, rpy;\r
266           int prci, prcj;\r
267           res = &comp->resolutions[pi->resno];\r
268           levelno = comp->numresolutions - 1 - pi->resno;\r
269           trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);\r
270           try0 = int_ceildiv(pi->ty0, comp->dy << levelno);\r
271           trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);\r
272           try1 = int_ceildiv(pi->ty1, comp->dy << levelno);\r
273           rpx = res->pdx + levelno;\r
274           rpy = res->pdy + levelno;\r
275           if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {\r
276             continue;\r
277           }\r
278           if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {\r
279             continue;\r
280           }\r
281           \r
282           if ((res->pw==0)||(res->pw==0)) continue;\r
283           \r
284           if ((trx0==trx1)||(try0==try1)) continue;\r
285           \r
286           prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) \r
287              - int_floordivpow2(trx0, res->pdx);\r
288           prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) \r
289              - int_floordivpow2(try0, res->pdy);\r
290           pi->precno = prci + prcj * res->pw;\r
291           for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {\r
292             index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;\r
293             if (!pi->include[index]) {\r
294               pi->include[index] = 1;\r
295               return true;\r
296             }  \r
297 LABEL_SKIP:;\r
298           }\r
299         }\r
300       }\r
301     }\r
302   }\r
303   \r
304   return false;\r
305 }\r
306 \r
307 static bool pi_next_cprl(opj_pi_iterator_t * pi) {\r
308   opj_pi_comp_t *comp = NULL;\r
309   opj_pi_resolution_t *res = NULL;\r
310   long index = 0;\r
311 \r
312   if (!pi->first) {\r
313     comp = &pi->comps[pi->compno];\r
314     goto LABEL_SKIP;\r
315   } else {\r
316     pi->first = 0;\r
317   }\r
318 \r
319   for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {\r
320     int resno;\r
321     comp = &pi->comps[pi->compno];\r
322     pi->dx = 0;\r
323     pi->dy = 0;\r
324     for (resno = 0; resno < comp->numresolutions; resno++) {\r
325       int dx, dy;\r
326       res = &comp->resolutions[resno];\r
327       dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));\r
328       dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));\r
329       pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);\r
330       pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);\r
331     }\r
332     for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {\r
333       for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {\r
334         for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {\r
335           int levelno;\r
336           int trx0, try0;\r
337           int trx1, try1;\r
338           int rpx, rpy;\r
339           int prci, prcj;\r
340           res = &comp->resolutions[pi->resno];\r
341           levelno = comp->numresolutions - 1 - pi->resno;\r
342           trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);\r
343           try0 = int_ceildiv(pi->ty0, comp->dy << levelno);\r
344           trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);\r
345           try1 = int_ceildiv(pi->ty1, comp->dy << levelno);\r
346           rpx = res->pdx + levelno;\r
347           rpy = res->pdy + levelno;\r
348           if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {\r
349             continue;\r
350           }\r
351           if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {\r
352             continue;\r
353           }\r
354           \r
355           if ((res->pw==0)||(res->pw==0)) continue;\r
356           \r
357           if ((trx0==trx1)||(try0==try1)) continue;\r
358           \r
359           prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx) \r
360              - int_floordivpow2(trx0, res->pdx);\r
361           prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy) \r
362              - int_floordivpow2(try0, res->pdy);\r
363           pi->precno = prci + prcj * res->pw;\r
364           for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {\r
365             index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;\r
366             if (!pi->include[index]) {\r
367               pi->include[index] = 1;\r
368               return true;\r
369             }\r
370 LABEL_SKIP:;\r
371           }\r
372         }\r
373       }\r
374     }\r
375   }\r
376   \r
377   return false;\r
378 }\r
379 \r
380 /* \r
381 ==========================================================\r
382    Packet iterator interface\r
383 ==========================================================\r
384 */\r
385 \r
386 opj_pi_iterator_t *pi_create(opj_image_t *image, opj_cp_t *cp, int tileno) {\r
387   int p, q;\r
388   int compno, resno, pino;\r
389   int maxres = 0;\r
390   opj_pi_iterator_t *pi = NULL;\r
391   opj_tcp_t *tcp = NULL;\r
392   opj_tccp_t *tccp = NULL;\r
393   size_t array_size;\r
394   \r
395   tcp = &cp->tcps[tileno];\r
396 \r
397   array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t);\r
398   pi = (opj_pi_iterator_t *) opj_malloc(array_size);\r
399   if(!pi) {\r
400     /* TODO: throw an error */\r
401     return NULL;\r
402   }\r
403   \r
404   for (pino = 0; pino < tcp->numpocs + 1; pino++) {  /* change */\r
405     p = tileno % cp->tw;\r
406     q = tileno / cp->tw;\r
407 \r
408     pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0);\r
409     pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0);\r
410     pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1);\r
411     pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1);\r
412     pi[pino].numcomps = image->numcomps;\r
413 \r
414     array_size = image->numcomps * sizeof(opj_pi_comp_t);\r
415     pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size);\r
416     if(!pi[pino].comps) {\r
417       /* TODO: throw an error */\r
418       pi_destroy(pi, cp, tileno);\r
419       return NULL;\r
420     }\r
421     memset(pi[pino].comps, 0, array_size);\r
422     \r
423     for (compno = 0; compno < pi->numcomps; compno++) {\r
424       int tcx0, tcy0, tcx1, tcy1;\r
425       opj_pi_comp_t *comp = &pi[pino].comps[compno];\r
426       tccp = &tcp->tccps[compno];\r
427       comp->dx = image->comps[compno].dx;\r
428       comp->dy = image->comps[compno].dy;\r
429       comp->numresolutions = tccp->numresolutions;\r
430 \r
431       array_size = comp->numresolutions * sizeof(opj_pi_resolution_t);\r
432       comp->resolutions =  (opj_pi_resolution_t *) opj_malloc(array_size);\r
433       if(!comp->resolutions) {\r
434         /* TODO: throw an error */\r
435         pi_destroy(pi, cp, tileno);\r
436         return NULL;\r
437       }\r
438 \r
439       tcx0 = int_ceildiv(pi->tx0, comp->dx);\r
440       tcy0 = int_ceildiv(pi->ty0, comp->dy);\r
441       tcx1 = int_ceildiv(pi->tx1, comp->dx);\r
442       tcy1 = int_ceildiv(pi->ty1, comp->dy);\r
443       if (comp->numresolutions > maxres) {\r
444         maxres = comp->numresolutions;\r
445       }\r
446 \r
447       for (resno = 0; resno < comp->numresolutions; resno++) {\r
448         int levelno;\r
449         int rx0, ry0, rx1, ry1;\r
450         int px0, py0, px1, py1;\r
451         opj_pi_resolution_t *res = &comp->resolutions[resno];\r
452         if (tccp->csty & J2K_CCP_CSTY_PRT) {\r
453           res->pdx = tccp->prcw[resno];\r
454           res->pdy = tccp->prch[resno];\r
455         } else {\r
456           res->pdx = 15;\r
457           res->pdy = 15;\r
458         }\r
459         levelno = comp->numresolutions - 1 - resno;\r
460         rx0 = int_ceildivpow2(tcx0, levelno);\r
461         ry0 = int_ceildivpow2(tcy0, levelno);\r
462         rx1 = int_ceildivpow2(tcx1, levelno);\r
463         ry1 = int_ceildivpow2(tcy1, levelno);\r
464         px0 = int_floordivpow2(rx0, res->pdx) << res->pdx;\r
465         py0 = int_floordivpow2(ry0, res->pdy) << res->pdy;\r
466         px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx;\r
467         py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy;\r
468         res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx);\r
469         res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy);\r
470       }\r
471     }\r
472     \r
473     tccp = &tcp->tccps[0];\r
474     pi[pino].step_p = 1;\r
475     pi[pino].step_c = 100 * pi[pino].step_p;\r
476     pi[pino].step_r = image->numcomps * pi[pino].step_c;\r
477     pi[pino].step_l = maxres * pi[pino].step_r;\r
478     \r
479     if (pino == 0) {\r
480       array_size = image->numcomps * maxres * tcp->numlayers * 100 * sizeof(short int);\r
481       pi[pino].include = (short int *) opj_malloc(array_size);\r
482       if(!pi[pino].include) {\r
483         /* TODO: throw an error */\r
484         pi_destroy(pi, cp, tileno);\r
485         return NULL;\r
486       }\r
487     }\r
488     else {\r
489       pi[pino].include = pi[pino - 1].include;\r
490     }\r
491     \r
492     if (tcp->POC == 0) {\r
493       pi[pino].first = 1;\r
494       pi[pino].poc.resno0 = 0;\r
495       pi[pino].poc.compno0 = 0;\r
496       pi[pino].poc.layno1 = tcp->numlayers;\r
497       pi[pino].poc.resno1 = maxres;\r
498       pi[pino].poc.compno1 = image->numcomps;\r
499       pi[pino].poc.prg = tcp->prg;\r
500     } else {\r
501       pi[pino].first = 1;\r
502       pi[pino].poc.resno0 = tcp->pocs[pino].resno0;\r
503       pi[pino].poc.compno0 = tcp->pocs[pino].compno0;\r
504       pi[pino].poc.layno1 = tcp->pocs[pino].layno1;\r
505       pi[pino].poc.resno1 = tcp->pocs[pino].resno1;\r
506       pi[pino].poc.compno1 = tcp->pocs[pino].compno1;\r
507       pi[pino].poc.prg = tcp->pocs[pino].prg;\r
508     }\r
509   }\r
510   \r
511   return pi;\r
512 }\r
513 \r
514 void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {\r
515   int compno, pino;\r
516   opj_tcp_t *tcp = &cp->tcps[tileno];\r
517   if(pi) {\r
518     for (pino = 0; pino < tcp->numpocs + 1; pino++) {  \r
519       if(pi[pino].comps) {\r
520         for (compno = 0; compno < pi->numcomps; compno++) {\r
521           opj_pi_comp_t *comp = &pi[pino].comps[compno];\r
522           if(comp->resolutions) {\r
523             opj_free(comp->resolutions);\r
524           }\r
525         }\r
526         opj_free(pi[pino].comps);\r
527       }\r
528     }\r
529     if(pi->include) {\r
530       opj_free(pi->include);\r
531     }\r
532     opj_free(pi);\r
533   }\r
534 }\r
535 \r
536 bool pi_next(opj_pi_iterator_t * pi) {\r
537   switch (pi->poc.prg) {\r
538     case LRCP:\r
539       return pi_next_lrcp(pi);\r
540     case RLCP:\r
541       return pi_next_rlcp(pi);\r
542     case RPCL:\r
543       return pi_next_rpcl(pi);\r
544     case PCRL:\r
545       return pi_next_pcrl(pi);\r
546     case CPRL:\r
547       return pi_next_cprl(pi);\r
548   }\r
549   \r
550   return false;\r
551 }\r
552 \r