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"
34 ==========================================================
36 ==========================================================
39 static bool pi_next_lrcp(opj_pi_iterator_t * pi) {
40 opj_pi_comp_t *comp = NULL;
41 opj_pi_resolution_t *res = NULL;
45 comp = &pi->comps[pi->compno];
46 res = &comp->resolutions[pi->resno];
52 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
53 for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1;
55 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
56 comp = &pi->comps[pi->compno];
57 if (pi->resno >= comp->numresolutions) {
60 res = &comp->resolutions[pi->resno];
61 for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) {
62 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
63 if (!pi->include[index]) {
64 pi->include[index] = 1;
76 static bool pi_next_rlcp(opj_pi_iterator_t * pi) {
77 opj_pi_comp_t *comp = NULL;
78 opj_pi_resolution_t *res = NULL;
82 comp = &pi->comps[pi->compno];
83 res = &comp->resolutions[pi->resno];
89 for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
90 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
91 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
92 comp = &pi->comps[pi->compno];
93 if (pi->resno >= comp->numresolutions) {
96 res = &comp->resolutions[pi->resno];
97 for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) {
98 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
99 if (!pi->include[index]) {
100 pi->include[index] = 1;
112 static bool pi_next_rpcl(opj_pi_iterator_t * pi) {
113 opj_pi_comp_t *comp = NULL;
114 opj_pi_resolution_t *res = NULL;
124 for (compno = 0; compno < pi->numcomps; compno++) {
125 comp = &pi->comps[compno];
126 for (resno = 0; resno < comp->numresolutions; resno++) {
128 res = &comp->resolutions[resno];
129 dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
130 dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
131 pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
132 pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
137 for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) {
138 for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
139 for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
140 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
146 comp = &pi->comps[pi->compno];
147 if (pi->resno >= comp->numresolutions) {
150 res = &comp->resolutions[pi->resno];
151 levelno = comp->numresolutions - 1 - pi->resno;
152 trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
153 try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
154 trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
155 try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
156 rpx = res->pdx + levelno;
157 rpy = res->pdy + levelno;
158 if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
161 if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
165 if ((res->pw==0)||(res->pw==0)) continue;
167 if ((trx0==trx1)||(try0==try1)) continue;
169 prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx)
170 - int_floordivpow2(trx0, res->pdx);
171 prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy)
172 - int_floordivpow2(try0, res->pdy);
173 pi->precno = prci + prcj * res->pw;
174 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
175 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
176 if (!pi->include[index]) {
177 pi->include[index] = 1;
190 static bool pi_next_pcrl(opj_pi_iterator_t * pi) {
191 opj_pi_comp_t *comp = NULL;
192 opj_pi_resolution_t *res = NULL;
196 comp = &pi->comps[pi->compno];
203 for (compno = 0; compno < pi->numcomps; compno++) {
204 comp = &pi->comps[compno];
205 for (resno = 0; resno < comp->numresolutions; resno++) {
207 res = &comp->resolutions[resno];
208 dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
209 dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
210 pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
211 pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
216 for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
217 for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
218 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
219 comp = &pi->comps[pi->compno];
220 for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
226 res = &comp->resolutions[pi->resno];
227 levelno = comp->numresolutions - 1 - pi->resno;
228 trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
229 try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
230 trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
231 try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
232 rpx = res->pdx + levelno;
233 rpy = res->pdy + levelno;
234 if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
237 if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
241 if ((res->pw==0)||(res->pw==0)) continue;
243 if ((trx0==trx1)||(try0==try1)) continue;
245 prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx)
246 - int_floordivpow2(trx0, res->pdx);
247 prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy)
248 - int_floordivpow2(try0, res->pdy);
249 pi->precno = prci + prcj * res->pw;
250 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
251 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
252 if (!pi->include[index]) {
253 pi->include[index] = 1;
266 static bool pi_next_cprl(opj_pi_iterator_t * pi) {
267 opj_pi_comp_t *comp = NULL;
268 opj_pi_resolution_t *res = NULL;
272 comp = &pi->comps[pi->compno];
278 for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
280 comp = &pi->comps[pi->compno];
283 for (resno = 0; resno < comp->numresolutions; resno++) {
285 res = &comp->resolutions[resno];
286 dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno));
287 dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno));
288 pi->dx = !pi->dx ? dx : int_min(pi->dx, dx);
289 pi->dy = !pi->dy ? dy : int_min(pi->dy, dy);
291 for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) {
292 for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) {
293 for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
299 res = &comp->resolutions[pi->resno];
300 levelno = comp->numresolutions - 1 - pi->resno;
301 trx0 = int_ceildiv(pi->tx0, comp->dx << levelno);
302 try0 = int_ceildiv(pi->ty0, comp->dy << levelno);
303 trx1 = int_ceildiv(pi->tx1, comp->dx << levelno);
304 try1 = int_ceildiv(pi->ty1, comp->dy << levelno);
305 rpx = res->pdx + levelno;
306 rpy = res->pdy + levelno;
307 if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) {
310 if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
314 if ((res->pw==0)||(res->pw==0)) continue;
316 if ((trx0==trx1)||(try0==try1)) continue;
318 prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), res->pdx)
319 - int_floordivpow2(trx0, res->pdx);
320 prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), res->pdy)
321 - int_floordivpow2(try0, res->pdy);
322 pi->precno = prci + prcj * res->pw;
323 for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
324 index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p;
325 if (!pi->include[index]) {
326 pi->include[index] = 1;
340 ==========================================================
341 Packet iterator interface
342 ==========================================================
345 opj_pi_iterator_t *pi_create(opj_image_t *image, opj_cp_t *cp, int tileno) {
347 int compno, resno, pino;
349 opj_pi_iterator_t *pi = NULL;
350 opj_tcp_t *tcp = NULL;
351 opj_tccp_t *tccp = NULL;
354 tcp = &cp->tcps[tileno];
356 array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t);
357 pi = (opj_pi_iterator_t *) opj_malloc(array_size);
359 /* TODO: throw an error */
363 for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */
367 pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, image->x0);
368 pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, image->y0);
369 pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, image->x1);
370 pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, image->y1);
371 pi[pino].numcomps = image->numcomps;
373 array_size = image->numcomps * sizeof(opj_pi_comp_t);
374 pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size);
375 if(!pi[pino].comps) {
376 /* TODO: throw an error */
377 pi_destroy(pi, cp, tileno);
380 memset(pi[pino].comps, 0, array_size);
382 for (compno = 0; compno < pi->numcomps; compno++) {
383 int tcx0, tcy0, tcx1, tcy1;
384 opj_pi_comp_t *comp = &pi[pino].comps[compno];
385 tccp = &tcp->tccps[compno];
386 comp->dx = image->comps[compno].dx;
387 comp->dy = image->comps[compno].dy;
388 comp->numresolutions = tccp->numresolutions;
390 array_size = comp->numresolutions * sizeof(opj_pi_resolution_t);
391 comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size);
392 if(!comp->resolutions) {
393 /* TODO: throw an error */
394 pi_destroy(pi, cp, tileno);
398 tcx0 = int_ceildiv(pi->tx0, comp->dx);
399 tcy0 = int_ceildiv(pi->ty0, comp->dy);
400 tcx1 = int_ceildiv(pi->tx1, comp->dx);
401 tcy1 = int_ceildiv(pi->ty1, comp->dy);
402 if (comp->numresolutions > maxres) {
403 maxres = comp->numresolutions;
406 for (resno = 0; resno < comp->numresolutions; resno++) {
408 int rx0, ry0, rx1, ry1;
409 int px0, py0, px1, py1;
410 opj_pi_resolution_t *res = &comp->resolutions[resno];
411 if (tccp->csty & J2K_CCP_CSTY_PRT) {
412 res->pdx = tccp->prcw[resno];
413 res->pdy = tccp->prch[resno];
418 levelno = comp->numresolutions - 1 - resno;
419 rx0 = int_ceildivpow2(tcx0, levelno);
420 ry0 = int_ceildivpow2(tcy0, levelno);
421 rx1 = int_ceildivpow2(tcx1, levelno);
422 ry1 = int_ceildivpow2(tcy1, levelno);
423 px0 = int_floordivpow2(rx0, res->pdx) << res->pdx;
424 py0 = int_floordivpow2(ry0, res->pdy) << res->pdy;
425 px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx;
426 py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy;
427 res->pw = (rx0==rx1)?0:((px1 - px0) >> res->pdx);
428 res->ph = (ry0==ry1)?0:((py1 - py0) >> res->pdy);
432 tccp = &tcp->tccps[0];
434 pi[pino].step_c = 100 * pi[pino].step_p;
435 pi[pino].step_r = image->numcomps * pi[pino].step_c;
436 pi[pino].step_l = maxres * pi[pino].step_r;
439 array_size = image->numcomps * maxres * tcp->numlayers * 100 * sizeof(short int);
440 pi[pino].include = (short int *) opj_malloc(array_size);
441 if(!pi[pino].include) {
442 /* TODO: throw an error */
443 pi_destroy(pi, cp, tileno);
448 pi[pino].include = pi[pino - 1].include;
453 pi[pino].poc.resno0 = 0;
454 pi[pino].poc.compno0 = 0;
455 pi[pino].poc.layno1 = tcp->numlayers;
456 pi[pino].poc.resno1 = maxres;
457 pi[pino].poc.compno1 = image->numcomps;
458 pi[pino].poc.prg = tcp->prg;
461 pi[pino].poc.resno0 = tcp->pocs[pino].resno0;
462 pi[pino].poc.compno0 = tcp->pocs[pino].compno0;
463 pi[pino].poc.layno1 = tcp->pocs[pino].layno1;
464 pi[pino].poc.resno1 = tcp->pocs[pino].resno1;
465 pi[pino].poc.compno1 = tcp->pocs[pino].compno1;
466 pi[pino].poc.prg = tcp->pocs[pino].prg;
473 void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {
475 opj_tcp_t *tcp = &cp->tcps[tileno];
477 for (pino = 0; pino < tcp->numpocs + 1; pino++) {
479 for (compno = 0; compno < pi->numcomps; compno++) {
480 opj_pi_comp_t *comp = &pi[pino].comps[compno];
481 if(comp->resolutions) {
482 opj_free(comp->resolutions);
485 opj_free(pi[pino].comps);
489 opj_free(pi->include);
495 bool pi_next(opj_pi_iterator_t * pi) {
496 switch (pi->poc.prg) {
498 return pi_next_lrcp(pi);
500 return pi_next_rlcp(pi);
502 return pi_next_rpcl(pi);
504 return pi_next_pcrl(pi);
506 return pi_next_cprl(pi);