2 * Copyright (c) 2001-2003, David Janssens
3 * Copyright (c) 2002-2003, Yannick Verschueren
4 * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
5 * Copyright (c) 2005, Hervé Drolon, FreeImage Team
6 * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
31 #include "opj_includes.h"
33 /** @defgroup PI PI - Implementation of a packet iterator */
36 /** @name Local static functions */
40 Get next packet in layer-resolution-component-precinct order.
41 @param pi packet iterator to modify
42 @return returns false if pi pointed to the last packet or else returns true
44 static bool pi_next_lrcp(opj_pi_iterator_t * pi);
46 Get next packet in resolution-layer-component-precinct order.
47 @param pi packet iterator to modify
48 @return returns false if pi pointed to the last packet or else returns true
50 static bool pi_next_rlcp(opj_pi_iterator_t * pi);
52 Get next packet in resolution-precinct-component-layer order.
53 @param pi packet iterator to modify
54 @return returns false if pi pointed to the last packet or else returns true
56 static bool pi_next_rpcl(opj_pi_iterator_t * pi);
58 Get next packet in precinct-component-resolution-layer order.
59 @param pi packet iterator to modify
60 @return returns false if pi pointed to the last packet or else returns true
62 static bool pi_next_pcrl(opj_pi_iterator_t * pi);
64 Get next packet in component-precinct-resolution-layer order.
65 @param pi packet iterator to modify
66 @return returns false if pi pointed to the last packet or else returns true
68 static bool pi_next_cprl(opj_pi_iterator_t * pi);
75 ==========================================================
77 ==========================================================
80 static bool pi_next_lrcp(opj_pi_iterator_t * pi) {
81 opj_pi_comp_t *comp = NULL;
82 opj_pi_resolution_t *res = NULL;
86 comp = &pi->comps[pi->compno];
87 res = &comp->resolutions[pi->resno];
93 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
94 for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1;
96 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
97 comp = &pi->comps[pi->compno];
98 if (pi->resno >= comp->numresolutions) {
101 res = &comp->resolutions[pi->resno];
102 for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) {
103 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
104 if (!pi->include[index]) {
105 pi->include[index] = 1;
117 static bool pi_next_rlcp(opj_pi_iterator_t * pi) {
118 opj_pi_comp_t *comp = NULL;
119 opj_pi_resolution_t *res = NULL;
123 comp = &pi->comps[pi->compno];
124 res = &comp->resolutions[pi->resno];
130 for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
131 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
132 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
133 comp = &pi->comps[pi->compno];
134 if (pi->resno >= comp->numresolutions) {
137 res = &comp->resolutions[pi->resno];
138 for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) {
139 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
140 if (!pi->include[index]) {
141 pi->include[index] = 1;
153 static bool pi_next_rpcl(opj_pi_iterator_t * pi) {
154 opj_pi_comp_t *comp = NULL;
155 opj_pi_resolution_t *res = NULL;
165 for (compno = 0; compno < pi->numcomps; compno++) {
166 comp = &pi->comps[compno];
167 for (resno = 0; resno < comp->numresolutions; resno++) {
169 res = &comp->resolutions[resno];
170 dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
171 dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
172 pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
173 pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
178 for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
179 for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
180 for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
181 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
187 comp = &pi->comps[pi->compno];
188 if (pi->resno >= comp->numresolutions) {
191 res = &comp->resolutions[pi->resno];
192 levelno = comp->numresolutions - 1 - pi->resno;
193 trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
194 try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
195 trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
196 try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
197 rpx = res->pdx + levelno;
198 rpy = res->pdy + levelno;
199 if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
202 if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
206 if ((res->pw==0)||(res->pw==0)) continue;
208 if ((trx0==trx1)||(try0==try1)) continue;
210 prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx)
211 - int_floordivpow2(trx0, res->pdx);
212 prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy)
213 - int_floordivpow2(try0, res->pdy);
214 pi->precno = prci + prcj * res->pw;
215 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
216 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
217 if (!pi->include[index]) {
218 pi->include[index] = 1;
231 static bool pi_next_pcrl(opj_pi_iterator_t * pi) {
232 opj_pi_comp_t *comp = NULL;
233 opj_pi_resolution_t *res = NULL;
237 comp = &pi->comps[pi->compno];
244 for (compno = 0; compno < pi->numcomps; compno++) {
245 comp = &pi->comps[compno];
246 for (resno = 0; resno < comp->numresolutions; resno++) {
248 res = &comp->resolutions[resno];
249 dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
250 dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
251 pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
252 pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
257 for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
258 for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
259 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
260 comp = &pi->comps[pi->compno];
261 for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
267 res = &comp->resolutions[pi->resno];
268 levelno = comp->numresolutions - 1 - pi->resno;
269 trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
270 try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
271 trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
272 try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
273 rpx = res->pdx + levelno;
274 rpy = res->pdy + levelno;
275 if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
278 if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
282 if ((res->pw==0)||(res->pw==0)) continue;
284 if ((trx0==trx1)||(try0==try1)) continue;
286 prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx)
287 - int_floordivpow2(trx0, res->pdx);
288 prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy)
289 - int_floordivpow2(try0, res->pdy);
290 pi->precno = prci + prcj * res->pw;
291 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
292 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
293 if (!pi->include[index]) {
294 pi->include[index] = 1;
307 static bool pi_next_cprl(opj_pi_iterator_t * pi) {
308 opj_pi_comp_t *comp = NULL;
309 opj_pi_resolution_t *res = NULL;
313 comp = &pi->comps[pi->compno];
319 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
321 comp = &pi->comps[pi->compno];
324 for (resno = 0; resno < comp->numresolutions; resno++) {
326 res = &comp->resolutions[resno];
327 dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
328 dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
329 pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
330 pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
332 for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
333 for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
334 for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
340 res = &comp->resolutions[pi->resno];
341 levelno = comp->numresolutions - 1 - pi->resno;
342 trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
343 try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
344 trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
345 try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
346 rpx = res->pdx + levelno;
347 rpy = res->pdy + levelno;
348 if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
351 if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
355 if ((res->pw==0)||(res->pw==0)) continue;
357 if ((trx0==trx1)||(try0==try1)) continue;
359 prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx)
360 - int_floordivpow2(trx0, res->pdx);
361 prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy)
362 - int_floordivpow2(try0, res->pdy);
363 pi->precno = prci + prcj * res->pw;
364 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
365 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
366 if (!pi->include[index]) {
367 pi->include[index] = 1;
381 ==========================================================
382 Packet iterator interface
383 ==========================================================
386 opj_pi_iterator_t *pi_create(opj_image_t *image, opj_cp_t *cp, int tileno) {
388 int compno, resno, pino;
390 opj_pi_iterator_t *pi = NULL;
391 opj_tcp_t *tcp = NULL;
392 opj_tccp_t *tccp = NULL;
395 tcp = &cp->tcps[tileno];
397 array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t);
398 pi = (opj_pi_iterator_t *) opj_malloc(array_size);
400 /* TODO: throw an error */
404 for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */
408 pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
409 pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0);
410 pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1);
411 pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1);
412 pi[pino].numcomps = image->numcomps;
414 array_size = image->numcomps * sizeof(opj_pi_comp_t);
415 pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size);
416 if(!pi[pino].comps) {
417 /* TODO: throw an error */
418 pi_destroy(pi, cp, tileno);
421 memset(pi[pino].comps, 0, array_size);
423 for (compno = 0; compno < pi->numcomps; compno++) {
424 int tcx0, tcy0, tcx1, tcy1;
425 opj_pi_comp_t *comp = &pi[pino].comps[compno];
426 tccp = &tcp->tccps[compno];
427 comp->dx = image->comps[compno].dx;
428 comp->dy = image->comps[compno].dy;
429 comp->numresolutions = tccp->numresolutions;
431 array_size = comp->numresolutions * sizeof(opj_pi_resolution_t);
432 comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size);
433 if(!comp->resolutions) {
434 /* TODO: throw an error */
435 pi_destroy(pi, cp, tileno);
439 tcx0 = int_ceildiv(pi->tx0, comp->dx);
440 tcy0 = int_ceildiv(pi->ty0, comp->dy);
441 tcx1 = int_ceildiv(pi->tx1, comp->dx);
442 tcy1 = int_ceildiv(pi->ty1, comp->dy);
443 if (comp->numresolutions > maxres) {
444 maxres = comp->numresolutions;
447 for (resno = 0; resno < comp->numresolutions; resno++) {
449 int rx0, ry0, rx1, ry1;
450 int px0, py0, px1, py1;
451 opj_pi_resolution_t *res = &comp->resolutions[resno];
452 if (tccp->csty & J2K_CCP_CSTY_PRT) {
453 res->pdx = tccp->prcw[resno];
454 res->pdy = tccp->prch[resno];
459 levelno = comp->numresolutions - 1 - resno;
460 rx0 = int_ceildivpow2(tcx0, levelno);
461 ry0 = int_ceildivpow2(tcy0, levelno);
462 rx1 = int_ceildivpow2(tcx1, levelno);
463 ry1 = int_ceildivpow2(tcy1, levelno);
464 px0 = int_floordivpow2(rx0, res->pdx) << res->pdx;
465 py0 = int_floordivpow2(ry0, res->pdy) << res->pdy;
466 px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx;
467 py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy;
468 res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx);
469 res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy);
473 tccp = &tcp->tccps[0];
475 pi[pino].step_c = 100 * pi[pino].step_p;
476 pi[pino].step_r = image->numcomps * pi[pino].step_c;
477 pi[pino].step_l = maxres * pi[pino].step_r;
480 array_size = image->numcomps * maxres * tcp->numlayers * 100 * sizeof(short int);
481 pi[pino].include = (short int *) opj_malloc(array_size);
482 if(!pi[pino].include) {
483 /* TODO: throw an error */
484 pi_destroy(pi, cp, tileno);
489 pi[pino].include = pi[pino - 1].include;
494 pi[pino].poc.resno0 = 0;
495 pi[pino].poc.compno0 = 0;
496 pi[pino].poc.layno1 = tcp->numlayers;
497 pi[pino].poc.resno1 = maxres;
498 pi[pino].poc.compno1 = image->numcomps;
499 pi[pino].poc.prg = tcp->prg;
502 pi[pino].poc.resno0 = tcp->pocs[pino].resno0;
503 pi[pino].poc.compno0 = tcp->pocs[pino].compno0;
504 pi[pino].poc.layno1 = tcp->pocs[pino].layno1;
505 pi[pino].poc.resno1 = tcp->pocs[pino].resno1;
506 pi[pino].poc.compno1 = tcp->pocs[pino].compno1;
507 pi[pino].poc.prg = tcp->pocs[pino].prg;
514 void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {
516 opj_tcp_t *tcp = &cp->tcps[tileno];
518 for (pino = 0; pino < tcp->numpocs + 1; pino++) {
520 for (compno = 0; compno < pi->numcomps; compno++) {
521 opj_pi_comp_t *comp = &pi[pino].comps[compno];
522 if(comp->resolutions) {
523 opj_free(comp->resolutions);
526 opj_free(pi[pino].comps);
530 opj_free(pi->include);
536 bool pi_next(opj_pi_iterator_t * pi) {
537 switch (pi->poc.prg) {
539 return pi_next_lrcp(pi);
541 return pi_next_rlcp(pi);
543 return pi_next_rpcl(pi);
545 return pi_next_pcrl(pi);
547 return pi_next_cprl(pi);