Initial revision
[openjpeg.git] / indexer_JPIP / pi.c
1 /*
2  * Copyright (c) 2001-2002, David Janssens
3  * Copyright (c) 2003, Yannick Verschueren
4  * Copyright (c) 2003,  Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26  * POSSIBILITY OF SUCH DAMAGE.
27  */
28  
29 #include "pi.h"
30 #include "int.h"
31 #include <stdlib.h>
32 #include <stdio.h>
33
34  
35 /// <summary>
36 /// Create a packet iterator.  
37 /// </summary>
38 pi_iterator_t *pi_create(j2k_image_t *img, j2k_cp_t *cp, int tileno) {
39     int p, q;
40     int compno, resno,pino, layno, precno;
41     int maxres=0;
42     pi_iterator_t *pi;
43     j2k_tcp_t *tcp;
44     j2k_tccp_t *tccp;
45   
46     tcp=&cp->tcps[tileno];
47     pi=(pi_iterator_t*)malloc((tcp->numpocs+1)*sizeof(pi_iterator_t));
48     
49     for (pino=0;pino<tcp->numpocs+1;pino++) // change
50       {
51         p=tileno%cp->tw;
52         q=tileno/cp->tw;
53         
54         pi[pino].tx0=int_max(cp->tx0+p*cp->tdx, img->x0);
55         pi[pino].ty0=int_max(cp->ty0+q*cp->tdy, img->y0);
56         pi[pino].tx1=int_min(cp->tx0+(p+1)*cp->tdx, img->x1);
57         pi[pino].ty1=int_min(cp->ty0+(q+1)*cp->tdy, img->y1);
58         pi[pino].numcomps=img->numcomps;
59         pi[pino].comps=(pi_comp_t*)malloc(img->numcomps*sizeof(pi_comp_t));
60         
61         for (compno=0; compno<pi->numcomps; compno++) 
62           {
63             int tcx0, tcy0, tcx1, tcy1;
64             pi_comp_t *comp=&pi[pino].comps[compno];
65             
66             tccp=&tcp->tccps[compno];
67             comp->dx=img->comps[compno].dx;
68             comp->dy=img->comps[compno].dy;
69             comp->numresolutions=tccp->numresolutions;
70             comp->resolutions=(pi_resolution_t*)malloc(comp->numresolutions*sizeof(pi_resolution_t));
71             tcx0=int_ceildiv(pi->tx0, comp->dx);
72             tcy0=int_ceildiv(pi->ty0, comp->dy);
73             tcx1=int_ceildiv(pi->tx1, comp->dx);
74             tcy1=int_ceildiv(pi->ty1, comp->dy);
75             if (comp->numresolutions>maxres) {
76               maxres=comp->numresolutions;
77             }
78             for (resno=0; resno<comp->numresolutions; resno++) 
79               {
80                 int levelno;
81                 int rx0, ry0, rx1, ry1;
82                 int px0, py0, px1, py1;
83                 pi_resolution_t *res=&comp->resolutions[resno];
84                 if (tccp->csty&J2K_CCP_CSTY_PRT) {
85                   res->pdx=tccp->prcw[resno];
86                   res->pdy=tccp->prch[resno];
87                 } else {
88                   res->pdx=15;
89                   res->pdy=15;
90                 }
91                 levelno=comp->numresolutions-1-resno;
92                 rx0=int_ceildivpow2(tcx0, levelno);
93                 ry0=int_ceildivpow2(tcy0, levelno);
94                 rx1=int_ceildivpow2(tcx1, levelno);
95                 ry1=int_ceildivpow2(tcy1, levelno);
96                 px0=int_floordivpow2(rx0, res->pdx)<<res->pdx;
97                 py0=int_floordivpow2(ry0, res->pdy)<<res->pdy;
98                 px1=int_ceildivpow2(rx1, res->pdx)<<res->pdx;
99                 py1=int_ceildivpow2(ry1, res->pdy)<<res->pdy;
100                 res->pw=(px1-px0)>>res->pdx;
101                 res->ph=(py1-py0)>>res->pdy;
102               }
103           }
104         
105         for (layno=0; layno<10; layno++) 
106           {
107             for (resno=0; resno<10; resno++) 
108               {
109                 for (compno=0; compno<3; compno++) 
110                   {
111                     for (precno=0; precno<99; precno++)
112                       {
113                         pi[pino].include[layno][resno][compno][precno]=0;
114                       }
115                   }
116               }
117           }
118         
119         if (pino==tcp->numpocs)
120           {
121             pi[pino].first=1;
122             pi[pino].poc.resno0=0;
123             pi[pino].poc.compno0=0;
124             pi[pino].poc.layno1=tcp->numlayers;
125             pi[pino].poc.resno1=maxres;
126             pi[pino].poc.compno1=img->numcomps;
127             pi[pino].poc.prg=tcp->prg;
128           } else
129             {
130               pi[pino].first=1;
131               pi[pino].poc.resno0=tcp->pocs[pino].resno0;
132               pi[pino].poc.compno0=tcp->pocs[pino].compno0;
133               pi[pino].poc.layno1=tcp->pocs[pino].layno1;
134               pi[pino].poc.resno1=tcp->pocs[pino].resno1;
135               pi[pino].poc.compno1=tcp->pocs[pino].compno1;
136               pi[pino].poc.prg=tcp->pocs[pino].prg;
137             }
138       }
139     return pi;
140 }
141
142 /// <summary>
143 /// Get next packet in layer=resolution-component-precinct order.  
144 /// </summary>
145 int pi_next_lrcp(pi_iterator_t *pi) {
146     pi_comp_t *comp;
147     pi_resolution_t *res;
148
149     if (!pi->first) 
150       {
151         comp=&pi->comps[pi->compno];
152         res=&comp->resolutions[pi->resno];
153         goto skip;
154       } else {
155         pi->first=0;
156       }
157     for (pi->layno=0; pi->layno<pi->poc.layno1; pi->layno++) 
158       {
159         for (pi->resno=pi->poc.resno0; pi->resno<pi->poc.resno1; pi->resno++) 
160           {
161             for (pi->compno=pi->poc.compno0; pi->compno<pi->poc.compno1; pi->compno++) 
162               {
163
164                 comp=&pi->comps[pi->compno];
165                 if (pi->resno>=comp->numresolutions) 
166                   {
167                     
168                     continue;
169                   }
170                 res=&comp->resolutions[pi->resno];
171
172                 for (pi->precno=0; pi->precno<res->pw*res->ph; pi->precno++) 
173                   {
174
175                      if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno])
176                       {
177                         pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1;
178                     return 1;
179                       }
180                   skip:    ;
181                   }
182               }
183           }
184       }
185     return 0;
186 }
187
188 /// <summary>
189 /// Get next packet in resolution-layer-component-precinct order.  
190 /// </summary>
191 int pi_next_rlcp(pi_iterator_t *pi) {
192     pi_comp_t *comp;
193     pi_resolution_t *res;
194     if (!pi->first) {
195         comp=&pi->comps[pi->compno];
196         res=&comp->resolutions[pi->resno];
197         goto skip;
198     } else {
199         pi->first=0;
200     }
201     for (pi->resno=pi->poc.resno0; pi->resno<pi->poc.resno1; pi->resno++) {
202         for (pi->layno=0; pi->layno<pi->poc.layno1; pi->layno++) {
203             for (pi->compno=pi->poc.compno0; pi->compno<pi->poc.compno1; pi->compno++) {
204                 comp=&pi->comps[pi->compno];
205                 if (pi->resno>=comp->numresolutions) {
206                     continue;
207                 }
208                 res=&comp->resolutions[pi->resno];
209                 for (pi->precno=0; pi->precno<res->pw*res->ph; pi->precno++) {
210                      if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno])
211                       {
212                         pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1;   
213                         return 1;
214                       }
215                 skip:   ;
216                 }
217             }
218         }
219     }
220     return 0;
221 }
222
223 /// <summary>
224 /// Get next packet in resolution-precinct-component-layer order.  
225 /// </summary>
226 int pi_next_rpcl(pi_iterator_t *pi) {
227     pi_comp_t *comp;
228     pi_resolution_t *res;
229     if (!pi->first) {
230         goto skip;
231     } else {
232         int compno, resno;
233         pi->first=0;
234         pi->dx=0;
235         pi->dy=0;
236         for (compno=0; compno<pi->numcomps; compno++) {
237             comp=&pi->comps[compno];
238             for (resno=0; resno<comp->numresolutions; resno++) {
239                 int dx, dy;
240                 res=&comp->resolutions[resno];
241                 dx=comp->dx*(1<<(res->pdx+comp->numresolutions-1-resno));
242                 dy=comp->dy*(1<<(res->pdy+comp->numresolutions-1-resno));
243                 pi->dx=!pi->dx?dx:int_min(pi->dx, dx);
244                 pi->dy=!pi->dy?dy:int_min(pi->dy, dy);
245             }
246         }
247     }
248     for (pi->resno=pi->poc.resno0; pi->resno<pi->poc.resno1; pi->resno++) {
249         for (pi->y=pi->ty0; pi->y<pi->ty1; pi->y+=pi->dy-(pi->y%pi->dy)) {
250             for (pi->x=pi->tx0; pi->x<pi->tx1; pi->x+=pi->dx-(pi->x%pi->dx)) {
251                 for (pi->compno=pi->poc.compno0; pi->compno<pi->poc.compno1; pi->compno++) {
252                     int levelno;
253                     int trx0, try0;
254                     int rpx, rpy;
255                     int prci, prcj;
256                     comp=&pi->comps[pi->compno];
257                     if (pi->resno>=comp->numresolutions) {
258                         continue;
259                     }
260                     res=&comp->resolutions[pi->resno];
261                     levelno=comp->numresolutions-1-pi->resno;
262                     trx0=int_ceildiv(pi->tx0, comp->dx<<levelno);
263                     try0=int_ceildiv(pi->ty0, comp->dy<<levelno);
264                     rpx=res->pdx+levelno;
265                     rpy=res->pdy+levelno;
266                     if (!(pi->x%(comp->dx<<rpx)==0||(pi->x==pi->tx0&&(trx0<<levelno)%(1<<rpx)))) {
267                         continue;
268                     }
269                     if (!(pi->y%(comp->dy<<rpy)==0||(pi->y==pi->ty0&&(try0<<levelno)%(1<<rpx)))) {
270                         continue;
271                     }
272                     prci=int_floordivpow2(int_ceildiv(pi->x, comp->dx<<levelno), res->pdx)-int_floordivpow2(trx0, res->pdx);
273                     prcj=int_floordivpow2(int_ceildiv(pi->y, comp->dy<<levelno), res->pdy)-int_floordivpow2(try0, res->pdy);
274                     pi->precno=prci+prcj*res->pw;
275                     for (pi->layno=0; pi->layno<pi->poc.layno1; pi->layno++) {
276                       if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno])
277                         {
278                           pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1;  
279                           return 1;
280                         }
281                     skip:       ;
282                     }
283                 }
284             }
285         }
286     }
287     return 0;
288 }
289
290 /// <summary>
291 /// Get next packet in precinct-component-resolution-layer order.  
292 /// </summary>
293 int pi_next_pcrl(pi_iterator_t *pi) {
294     pi_comp_t *comp;
295     pi_resolution_t *res;
296     if (!pi->first) {
297         comp=&pi->comps[pi->compno];
298         goto skip;
299     } else {
300         int compno, resno;
301         pi->first=0;
302         pi->dx=0;
303         pi->dy=0;
304         for (compno=0; compno<pi->numcomps; compno++) {
305             comp=&pi->comps[compno];
306             for (resno=0; resno<comp->numresolutions; resno++) {
307                 int dx, dy;
308                 res=&comp->resolutions[resno];
309                 dx=comp->dx*(1<<(res->pdx+comp->numresolutions-1-resno));
310                 dy=comp->dy*(1<<(res->pdy+comp->numresolutions-1-resno));
311                 pi->dx=!pi->dx?dx:int_min(pi->dx, dx);
312                 pi->dy=!pi->dy?dy:int_min(pi->dy, dy);
313             }
314         }
315     }
316     for (pi->y=pi->ty0; pi->y<pi->ty1; pi->y+=pi->dy-(pi->y%pi->dy)) {
317         for (pi->x=pi->tx0; pi->x<pi->tx1; pi->x+=pi->dx-(pi->x%pi->dx)) {
318             for (pi->compno=pi->poc.compno0; pi->compno<pi->poc.compno1; pi->compno++) {
319                 comp=&pi->comps[pi->compno];
320                 for (pi->resno=pi->poc.resno0; pi->resno<int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
321                     int levelno;
322                     int trx0, try0;
323                     int rpx, rpy;
324                     int prci, prcj;
325                     res=&comp->resolutions[pi->resno];
326                     levelno=comp->numresolutions-1-pi->resno;
327                     trx0=int_ceildiv(pi->tx0, comp->dx<<levelno);
328                     try0=int_ceildiv(pi->ty0, comp->dy<<levelno);
329                     rpx=res->pdx+levelno;
330                     rpy=res->pdy+levelno;
331                     if (!(pi->x%(comp->dx<<rpx)==0||(pi->x==pi->tx0&&(trx0<<levelno)%(1<<rpx)))) {
332                         continue;
333                     }
334                     if (!(pi->y%(comp->dy<<rpy)==0||(pi->y==pi->ty0&&(try0<<levelno)%(1<<rpx)))) {
335                         continue;
336                     }
337                     prci=int_floordivpow2(int_ceildiv(pi->x, comp->dx<<levelno), res->pdx)-int_floordivpow2(trx0, res->pdx);
338                     prcj=int_floordivpow2(int_ceildiv(pi->y, comp->dy<<levelno), res->pdy)-int_floordivpow2(try0, res->pdy);
339                     pi->precno=prci+prcj*res->pw;
340                     for (pi->layno=0; pi->layno<pi->poc.layno1; pi->layno++) {
341                        if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno])
342                         {
343                           pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1;
344                           return 1;
345                         }
346                     skip:       ;
347                     }
348                 }
349             }
350         }
351     }
352     return 0;
353 }
354
355 /// <summary>
356 /// Get next packet in component-precinct-resolution-layer order.  
357 /// </summary>
358 int pi_next_cprl(pi_iterator_t *pi) {
359     pi_comp_t *comp;
360     pi_resolution_t *res;
361     if (!pi->first) {
362         comp=&pi->comps[pi->compno];
363         goto skip;
364     } else {
365         pi->first=0;
366     }
367     for (pi->compno=pi->poc.compno0; pi->compno<pi->poc.compno1; pi->compno++) {
368         int resno;
369         comp=&pi->comps[pi->compno];
370         pi->dx=0;
371         pi->dy=0;
372         for (resno=0; resno<comp->numresolutions; resno++) {
373             int dx, dy;
374             res=&comp->resolutions[resno];
375             dx=comp->dx*(1<<(res->pdx+comp->numresolutions-1-resno));
376             dy=comp->dy*(1<<(res->pdy+comp->numresolutions-1-resno));
377             pi->dx=!pi->dx?dx:int_min(pi->dx, dx);
378             pi->dy=!pi->dy?dy:int_min(pi->dy, dy);
379         }
380         for (pi->y=pi->ty0; pi->y<pi->ty1; pi->y+=pi->dy-(pi->y%pi->dy)) {
381             for (pi->x=pi->tx0; pi->x<pi->tx1; pi->x+=pi->dx-(pi->x%pi->dx)) {
382                 for (pi->resno=pi->poc.resno0; pi->resno<int_min(pi->poc.resno1, comp->numresolutions); pi->resno++) {
383                     int levelno;
384                     int trx0, try0;
385                     int rpx, rpy;
386                     int prci, prcj;
387                     res=&comp->resolutions[pi->resno];
388                     levelno=comp->numresolutions-1-pi->resno;
389                     trx0=int_ceildiv(pi->tx0, comp->dx<<levelno);
390                     try0=int_ceildiv(pi->ty0, comp->dy<<levelno);
391                     rpx=res->pdx+levelno;
392                     rpy=res->pdy+levelno;
393                     if (!(pi->x%(comp->dx<<rpx)==0||(pi->x==pi->tx0&&(trx0<<levelno)%(1<<rpx)))) {
394                         continue;
395                     }
396                     if (!(pi->y%(comp->dy<<rpy)==0||(pi->y==pi->ty0&&(try0<<levelno)%(1<<rpx)))) {
397                         continue;
398                     }
399                     prci=int_floordivpow2(int_ceildiv(pi->x, comp->dx<<levelno), res->pdx)-int_floordivpow2(trx0, res->pdx);
400                     prcj=int_floordivpow2(int_ceildiv(pi->y, comp->dy<<levelno), res->pdy)-int_floordivpow2(try0, res->pdy);
401                     pi->precno=prci+prcj*res->pw;
402                     for (pi->layno=0; pi->layno<pi->poc.layno1; pi->layno++) {
403                         if (!pi->include[pi->layno][pi->resno][pi->compno][pi->precno])
404                         {
405                           pi->include[pi->layno][pi->resno][pi->compno][pi->precno]=1;
406                           return 1;
407                         }
408                     skip: ;
409                     }
410                 }
411             }
412         }
413     }
414     return 0;
415 }
416
417 /// <summary>
418 /// Get next packet.  
419 /// </summary>
420 int pi_next(pi_iterator_t *pi) {
421     switch (pi->poc.prg) {
422         case 0:
423             return pi_next_lrcp(pi);
424         case 1:
425             return pi_next_rlcp(pi);
426         case 2:
427             return pi_next_rpcl(pi);
428         case 3:
429             return pi_next_pcrl(pi);
430         case 4:
431             return pi_next_cprl(pi);
432     }
433         return 0;
434 }