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