87bd26353481867fc9675158711089754052a41b
[openjpeg.git] / libopenjpeg / pi.c
1 /*
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
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
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.
17  *
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.
29  */
30
31 #include "opj_includes.h"
32
33 /* 
34 ==========================================================
35    local functions
36 ==========================================================
37 */
38
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;
42   long index = 0;
43   
44   if (!pi->first) {
45     comp = &pi->comps[pi->compno];
46     res = &comp->resolutions[pi->resno];
47     goto LABEL_SKIP;
48   } else {
49     pi->first = 0;
50   }
51
52   for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) {
53     for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1;
54     pi->resno++) {
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) {
58           continue;
59         }
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;
65             return true;
66           }
67 LABEL_SKIP:;
68         }
69       }
70     }
71   }
72   
73   return false;
74 }
75
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;
79   long index = 0;
80
81   if (!pi->first) {
82     comp = &pi->comps[pi->compno];
83     res = &comp->resolutions[pi->resno];
84     goto LABEL_SKIP;
85   } else {
86     pi->first = 0;
87   }
88
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) {
94           continue;
95         }
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;
101             return true;
102           }
103 LABEL_SKIP:;
104         }
105       }
106     }
107   }
108   
109   return false;
110 }
111
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;
115   long index = 0;
116
117   if (!pi->first) {
118     goto LABEL_SKIP;
119   } else {
120     int compno, resno;
121     pi->first = 0;
122     pi->dx = 0;
123     pi->dy = 0;
124     for (compno = 0; compno < pi->numcomps; compno++) {
125       comp = &pi->comps[compno];
126       for (resno = 0; resno < comp->numresolutions; resno++) {
127         int dx, dy;
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);
133       }
134     }
135   }
136
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++) {
141           int levelno;
142           int trx0, try0;
143           int trx1, try1;
144           int rpx, rpy;
145           int prci, prcj;
146           comp = &pi->comps[pi->compno];
147           if (pi->resno >= comp->numresolutions) {
148             continue;
149           }
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)))) {
159             continue;
160           }
161           if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
162             continue;
163           }
164           
165           if ((res->pw==0)||(res->pw==0)) continue;
166           
167           if ((trx0==trx1)||(try0==try1)) continue;
168           
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;
178               return true;
179             }
180 LABEL_SKIP:;
181           }
182         }
183       }
184     }
185   }
186   
187   return false;
188 }
189
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;
193   long index = 0;
194
195   if (!pi->first) {
196     comp = &pi->comps[pi->compno];
197     goto LABEL_SKIP;
198   } else {
199     int compno, resno;
200     pi->first = 0;
201     pi->dx = 0;
202     pi->dy = 0;
203     for (compno = 0; compno < pi->numcomps; compno++) {
204       comp = &pi->comps[compno];
205       for (resno = 0; resno < comp->numresolutions; resno++) {
206         int dx, dy;
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);
212       }
213     }
214   }
215
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++) {
221           int levelno;
222           int trx0, try0;
223           int trx1, try1;
224           int rpx, rpy;
225           int prci, prcj;
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)))) {
235             continue;
236           }
237           if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
238             continue;
239           }
240           
241           if ((res->pw==0)||(res->pw==0)) continue;
242           
243           if ((trx0==trx1)||(try0==try1)) continue;
244           
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;
254               return true;
255             } 
256 LABEL_SKIP:;
257           }
258         }
259       }
260     }
261   }
262   
263   return false;
264 }
265
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;
269   long index = 0;
270
271   if (!pi->first) {
272     comp = &pi->comps[pi->compno];
273     goto LABEL_SKIP;
274   } else {
275     pi->first = 0;
276   }
277
278   for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) {
279     int resno;
280     comp = &pi->comps[pi->compno];
281     pi->dx = 0;
282     pi->dy = 0;
283     for (resno = 0; resno < comp->numresolutions; resno++) {
284       int dx, dy;
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);
290     }
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++) {
294           int levelno;
295           int trx0, try0;
296           int trx1, try1;
297           int rpx, rpy;
298           int prci, prcj;
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)))) {
308             continue;
309           }
310           if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) {
311             continue;
312           }
313           
314           if ((res->pw==0)||(res->pw==0)) continue;
315           
316           if ((trx0==trx1)||(try0==try1)) continue;
317           
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;
327               return true;
328             }
329 LABEL_SKIP:;
330           }
331         }
332       }
333     }
334   }
335   
336   return false;
337 }
338
339 /* 
340 ==========================================================
341    Packet iterator interface
342 ==========================================================
343 */
344
345 opj_pi_iterator_t *pi_create(opj_image_t *image, opj_cp_t *cp, int tileno) {
346   int p, q;
347   int compno, resno, pino;
348   int maxres = 0;
349   opj_pi_iterator_t *pi = NULL;
350   opj_tcp_t *tcp = NULL;
351   opj_tccp_t *tccp = NULL;
352   size_t array_size;
353   
354   tcp = &cp->tcps[tileno];
355
356   array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t);
357   pi = (opj_pi_iterator_t *) opj_malloc(array_size);
358   if(!pi) {
359     /* TODO: throw an error */
360     return NULL;
361   }
362   
363   for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */
364     p = tileno % cp->tw;
365     q = tileno / cp->tw;
366
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;
372
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);
378       return NULL;
379     }
380     memset(pi[pino].comps, 0, array_size);
381     
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;
389
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);
395         return NULL;
396       }
397
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;
404       }
405
406       for (resno = 0; resno < comp->numresolutions; resno++) {
407         int levelno;
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];
414         } else {
415           res->pdx = 15;
416           res->pdy = 15;
417         }
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);
429       }
430     }
431     
432     tccp = &tcp->tccps[0];
433     pi[pino].step_p = 1;
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;
437     
438     if (pino == 0) {
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);
444         return NULL;
445       }
446     }
447     else {
448       pi[pino].include = pi[pino - 1].include;
449     }
450     
451     if (tcp->POC == 0) {
452       pi[pino].first = 1;
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;
459     } else {
460       pi[pino].first = 1;
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;
467     }
468   }
469   
470   return pi;
471 }
472
473 void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) {
474   int compno, pino;
475   opj_tcp_t *tcp = &cp->tcps[tileno];
476   if(pi) {
477     for (pino = 0; pino < tcp->numpocs + 1; pino++) { 
478       if(pi[pino].comps) {
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);
483           }
484         }
485         opj_free(pi[pino].comps);
486       }
487     }
488     if(pi->include) {
489       opj_free(pi->include);
490     }
491     opj_free(pi);
492   }
493 }
494
495 bool pi_next(opj_pi_iterator_t * pi) {
496   switch (pi->poc.prg) {
497     case LRCP:
498       return pi_next_lrcp(pi);
499     case RLCP:
500       return pi_next_rlcp(pi);
501     case RPCL:
502       return pi_next_rpcl(pi);
503     case PCRL:
504       return pi_next_pcrl(pi);
505     case CPRL:
506       return pi_next_cprl(pi);
507   }
508   
509   return false;
510 }
511