[trunk] Remove some warnings about missing prototypes (gcc)
[openjpeg.git] / src / lib / openjp3d / tcd.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 void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_volume_t * vol) {\r
35         int tileno, compno, resno, bandno, precno, cblkno;\r
36 \r
37         fprintf(fd, "volume {\n");\r
38         fprintf(fd, "  tw=%d, th=%d, tl=%d, x0=%d x1=%d y0=%d y1=%d z0=%d z1=%d\n", \r
39                 vol->tw, vol->th, vol->tl, tcd->volume->x0, tcd->volume->x1, tcd->volume->y0, tcd->volume->y1, tcd->volume->z0, tcd->volume->z1);\r
40 \r
41         for (tileno = 0; tileno < vol->th * vol->tw * vol->tl; tileno++) {\r
42                 opj_tcd_tile_t *tile = &tcd->tcd_volume->tiles[tileno];\r
43                 fprintf(fd, "  tile {\n");\r
44                 fprintf(fd, "    x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numcomps=%d\n",\r
45                         tile->x0, tile->y0, tile->z0, tile->x1, tile->y1, tile->z1, tile->numcomps);\r
46                 for (compno = 0; compno < tile->numcomps; compno++) {\r
47                         opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
48                         fprintf(fd, "    tilecomp %d {\n",compno);\r
49                         fprintf(fd,     "     x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numresx=%d, numresy=%d, numresz=%d\n",\r
50                                 tilec->x0, tilec->y0, tilec->z0, tilec->x1, tilec->y1, tilec->z1, tilec->numresolution[0], tilec->numresolution[1], tilec->numresolution[2]);\r
51                         for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
52                                 opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
53                                 fprintf(fd, "     res %d{\n",resno);\r
54                                 fprintf(fd,"      x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, pw=%d, ph=%d, pl=%d, numbands=%d\n",\r
55                                         res->x0, res->y0, res->z0, res->x1, res->y1, res->z1, res->prctno[0], res->prctno[1], res->prctno[2], res->numbands);\r
56                                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
57                                         opj_tcd_band_t *band = &res->bands[bandno];\r
58                                         fprintf(fd, "       band %d{\n", bandno);\r
59                                         fprintf(fd,     "                x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, stepsize=%f, numbps=%d\n",\r
60                                                 band->x0, band->y0, band->z0, band->x1, band->y1, band->z1, band->stepsize, band->numbps);\r
61                                         for (precno = 0; precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); precno++) {\r
62                                                 opj_tcd_precinct_t *prec = &band->precincts[precno];\r
63                                                 fprintf(fd, "             prec %d{\n",precno);\r
64                                                 fprintf(fd,     "                  x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, cw=%d, ch=%d, cl=%d,\n",\r
65                                                         prec->x0, prec->y0, prec->z0, prec->x1, prec->y1, prec->z1, prec->cblkno[0], prec->cblkno[1], prec->cblkno[2]);\r
66                                                 for (cblkno = 0; cblkno < (prec->cblkno[0] * prec->cblkno[1] * prec->cblkno[2]); cblkno++) {\r
67                                                         opj_tcd_cblk_t *cblk = &prec->cblks[cblkno];\r
68                                                         fprintf(fd, "               cblk %d{\n",cblkno);\r
69                                                         fprintf(fd,     "                    x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", cblk->x0, cblk->y0, cblk->z0, cblk->x1, cblk->y1, cblk->z1);\r
70                                                         fprintf(fd, "            }\n");\r
71                                                 }\r
72                                                 fprintf(fd, "          }\n");\r
73                                         }\r
74                                         fprintf(fd, "        }\n");\r
75                                 }\r
76                                 fprintf(fd, "      }\n");\r
77                         }\r
78                         fprintf(fd, "    }\n");\r
79                 }\r
80                 fprintf(fd, "  }\n");\r
81         }\r
82         fprintf(fd, "}\n");\r
83 }\r
84 \r
85 static void tilec_dump(FILE *fd, opj_tcd_tilecomp_t *tilec) {\r
86 \r
87         int i=0,k;\r
88         int datalen;\r
89         int *a;\r
90 \r
91         fprintf(fd, "    tilecomp{\n");\r
92         fprintf(fd,     "     x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numresx=%d, numresy=%d, numresz=%d\n",\r
93                 tilec->x0, tilec->y0, tilec->z0, tilec->x1, tilec->y1, tilec->z1, tilec->numresolution[0], tilec->numresolution[1], tilec->numresolution[2]);\r
94         fprintf(fd, "     data {\n");\r
95         datalen = (tilec->z1 - tilec->z0) * (tilec->y1 - tilec->y0) * (tilec->x1 - tilec->x0);\r
96         a = tilec->data;\r
97         for (k = 0; k < datalen; k++) {\r
98                 if (!(k % tilec->x1)){\r
99                         fprintf(fd, "\n");\r
100                 }\r
101                 if (!(k % (tilec->y1 * tilec->x1))){\r
102                         fprintf(fd, "Slice %d\n",i++);\r
103                 }\r
104                 fprintf(fd," %d",a[k]);\r
105                 \r
106                 \r
107         }                       \r
108         fprintf(fd, "     }\n");\r
109         /*i=0;\r
110         fprintf(fd, "Slice %d\n");\r
111         if (tilec->prediction->prederr) {\r
112                 fprintf(fd, "     prederror {\n");\r
113                 a = tilec->prediction->prederr;\r
114                 for (k = 0; k < datalen; k++) {\r
115                         fprintf(fd," %d",*(a++));\r
116                         if (!(k % (tilec->y1 - tilec->y0) * (tilec->x1 - tilec->x0))){\r
117                                 fprintf(fd, "\n");fprintf(fd, "Slice %d\n",i++);\r
118                         }\r
119                         if (!(k % (tilec->x1 - tilec->x0))){\r
120                                 fprintf(fd, "\n");\r
121                         }\r
122                 }\r
123         }\r
124         fprintf(fd, "     }\n");*/\r
125         fprintf(fd, "}\n");\r
126 }\r
127 \r
128 /* ----------------------------------------------------------------------- */\r
129 \r
130 /**\r
131 Create a new TCD handle\r
132 */\r
133 opj_tcd_t* tcd_create(opj_common_ptr cinfo) {\r
134         /* create the tcd structure */\r
135         opj_tcd_t *tcd = (opj_tcd_t*)opj_malloc(sizeof(opj_tcd_t));\r
136         if(!tcd) return NULL;\r
137         tcd->cinfo = cinfo;\r
138         tcd->tcd_volume = (opj_tcd_volume_t*)opj_malloc(sizeof(opj_tcd_volume_t));\r
139         if(!tcd->tcd_volume) {\r
140                 opj_free(tcd);\r
141                 return NULL;\r
142         }\r
143 \r
144         return tcd;\r
145 }\r
146 \r
147 /**\r
148 Destroy a previously created TCD handle\r
149 */\r
150 void tcd_destroy(opj_tcd_t *tcd) {\r
151         if(tcd) {\r
152                 opj_free(tcd->tcd_volume);\r
153                 opj_free(tcd);\r
154         }\r
155 }\r
156 \r
157 /* ----------------------------------------------------------------------- */\r
158 void tcd_malloc_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno) {\r
159         int compno, resno, bandno, precno, cblkno, i, j;/*, k;*/\r
160 \r
161         opj_tcd_tile_t          *tile = NULL;           /* pointer to tcd->tile */\r
162         opj_tcd_tilecomp_t      *tilec = NULL;          /* pointer to tcd->tilec */\r
163         opj_tcd_resolution_t    *res = NULL;            /* pointer to tcd->res */\r
164         opj_tcd_band_t          *band = NULL;           /* pointer to tcd->band */\r
165         opj_tcd_precinct_t      *prc = NULL;            /* pointer to tcd->prc */\r
166         opj_tcd_cblk_t          *cblk = NULL;           /* pointer to tcd->cblk */\r
167         opj_tcp_t               *tcp = &cp->tcps[curtileno];\r
168         int p,q,r;\r
169 \r
170         tcd->volume = volume;\r
171         tcd->cp = cp;\r
172         tcd->tcd_volume->tw = cp->tw;\r
173         tcd->tcd_volume->th = cp->th;\r
174         tcd->tcd_volume->tl = cp->tl;\r
175         tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t));\r
176         tcd->tile = tcd->tcd_volume->tiles;\r
177         tile = tcd->tile;\r
178         \r
179 \r
180         /* p61 ISO/IEC IS15444-1 : 2002 */\r
181         /* curtileno --> raster scanned index of tiles */\r
182         /* p,q,r --> matricial index of tiles */\r
183         p = curtileno % cp->tw; \r
184         q = curtileno / cp->tw; \r
185         r = curtileno / (cp->tw * cp->th); /* extension to 3-D */\r
186 \r
187         /* 4 borders of the tile rescale on the volume if necessary (B.3)*/\r
188         tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0);\r
189         tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0);\r
190         tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0);\r
191         tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1);\r
192         tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1);\r
193         tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1);\r
194         tile->numcomps = volume->numcomps;\r
195 \r
196         /* Modification of the RATE >> */\r
197         for (j = 0; j < tcp->numlayers; j++) {\r
198                 if (tcp->rates[j] <= 1) {\r
199                         tcp->rates[j] = 0;\r
200                 } else {\r
201                         float num = (float) (tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec);\r
202                         float den = (float) (8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz);\r
203                         den = tcp->rates[j] * den;\r
204                         tcp->rates[j] = (num + den - 1) / den;\r
205                 }\r
206                 /*tcp->rates[j] = tcp->rates[j] ? int_ceildiv(\r
207                         tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec,\r
208             (tcp->rates[j] * 8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz)) : 0;*/\r
209                 if (tcp->rates[j]) {\r
210                         if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {\r
211                                 tcp->rates[j] = tcp->rates[j - 1] + 20;\r
212                         } else if (!j && tcp->rates[j] < 30){\r
213                                 tcp->rates[j] = 30;\r
214                         }\r
215                 }\r
216         }\r
217         /* << Modification of the RATE */\r
218 \r
219         tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t));\r
220         for (compno = 0; compno < tile->numcomps; compno++) {\r
221                 opj_tccp_t *tccp = &tcp->tccps[compno];\r
222                 int res_max;\r
223                 int prevnumbands = 0;\r
224 \r
225                 /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */\r
226                 tcd->tilec = &tile->comps[compno];\r
227                 tilec = tcd->tilec;\r
228 \r
229                 /* border of each tile component (global) (B.3) */\r
230                 tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx);\r
231                 tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy);\r
232                 tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz);\r
233                 tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx);\r
234                 tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy);\r
235                 tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz);\r
236 \r
237                 tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int));\r
238                 \r
239                 res_max = 0;\r
240                 for (i = 0;i < 3; i++){\r
241                         tilec->numresolution[i] = tccp->numresolution[i];\r
242                         /*Greater of 3 resolutions contains all information*/\r
243                         res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max;\r
244                 }\r
245                 \r
246 \r
247                 tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t));\r
248                 for (resno = 0; resno < res_max; resno++) {\r
249                         \r
250                         int pdx, pdy, pdz;\r
251                         int tlprcxstart, tlprcystart, tlprczstart;\r
252                         int brprcxend, brprcyend, brprczend;\r
253                         int tlcbgxstart, tlcbgystart, tlcbgzstart;\r
254                         int brcbgxend, brcbgyend, brcbgzend;\r
255                         int cbgwidthexpn, cbgheightexpn, cbglengthexpn;\r
256                         int cblkwidthexpn, cblkheightexpn, cblklengthexpn;\r
257 \r
258                         int diff = tccp->numresolution[0] - tccp->numresolution[2]; \r
259                         int levelnox = tilec->numresolution[0] - 1 - resno; \r
260                         int levelnoy = tilec->numresolution[1] - 1 - resno;\r
261                         int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff));\r
262                                 if (levelnoz < 0) levelnoz = 0;\r
263 \r
264                         /* opj_tcd_resolution_t *res=&tilec->resolutions[resno]; */\r
265                         tcd->res = &tilec->resolutions[resno];\r
266                         res = tcd->res;\r
267                         \r
268                         /* border for each resolution level (global) (B.14)*/\r
269                         res->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
270                         res->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
271                         res->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
272                         res->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
273                         res->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
274                         res->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
275                         /*if (res->z1 < 0)fprintf(stdout,"Res: %d       %d/%d --> %d\n",resno,tilec->z1, levelnoz, int_ceildivpow2(tilec->z1, levelnoz));*/\r
276 \r
277                         res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */\r
278 \r
279                         /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */\r
280                         if (tccp->csty & J3D_CCP_CSTY_PRT) {\r
281                                 pdx = tccp->prctsiz[0][resno];\r
282                                 pdy = tccp->prctsiz[1][resno];\r
283                                 pdz = tccp->prctsiz[2][resno];\r
284                         } else {\r
285                                 pdx = 15;\r
286                                 pdy = 15;\r
287                                 pdz = 15;\r
288                         }\r
289                         \r
290                         /* p. 66, B.16, ISO/IEC IS15444-1 : 2002  */\r
291                         tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;\r
292                         tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;\r
293                         tlprczstart = int_floordivpow2(res->z0, pdz) << pdz;\r
294                         brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;\r
295                         brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;\r
296                         brprczend = int_ceildivpow2(res->z1, pdz) << pdz;\r
297                         \r
298                         res->prctno[0] = (brprcxend - tlprcxstart) >> pdx;\r
299                         res->prctno[1] = (brprcyend - tlprcystart) >> pdy;\r
300                         res->prctno[2] = (brprczend - tlprczstart) >> pdz;\r
301                                 if (res->prctno[2] == 0) res->prctno[2] = 1;\r
302                                 \r
303                         /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002  */\r
304                         if (resno == 0) {\r
305                                 tlcbgxstart = tlprcxstart;\r
306                                 tlcbgystart = tlprcystart;\r
307                                 tlcbgzstart = tlprczstart;\r
308                                 brcbgxend = brprcxend;\r
309                                 brcbgyend = brprcyend;\r
310                                 brcbgzend = brprczend;\r
311                                 cbgwidthexpn = pdx;\r
312                                 cbgheightexpn = pdy;\r
313                                 cbglengthexpn = pdz;\r
314                         } else {\r
315                                 tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);\r
316                                 tlcbgystart = int_ceildivpow2(tlprcystart, 1);\r
317                                 tlcbgzstart = int_ceildivpow2(tlprczstart, 1);\r
318                                 brcbgxend = int_ceildivpow2(brprcxend, 1);\r
319                                 brcbgyend = int_ceildivpow2(brprcyend, 1);\r
320                                 brcbgzend = int_ceildivpow2(brprczend, 1);\r
321                                 cbgwidthexpn = pdx - 1;\r
322                                 cbgheightexpn = pdy - 1;\r
323                                 cbglengthexpn = pdz - 1;\r
324                         }\r
325                         \r
326                         cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); /*6*/\r
327                         cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); /*6*/\r
328                         cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); /*6*/\r
329                         \r
330                         res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t));\r
331                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
332                                 int x0b, y0b, z0b, i;\r
333                                 int gain, numbps;\r
334                                 opj_stepsize_t *ss = NULL;\r
335 \r
336                                 tcd->band = &res->bands[bandno];\r
337                                 band = tcd->band;\r
338 \r
339                                 band->bandno = (resno == 0) ? 0 : bandno + 1;\r
340                                 /* Bandno:      0 - LLL         2 - LHL \r
341                                                         1 - HLL         3 - HHL\r
342                                                         4 - LLH         6 - LHH\r
343                                                         5 - HLH         7 - HHH         */\r
344                                 x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; \r
345                                 y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;\r
346                                 z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; \r
347                                 \r
348                                 /* p. 65, B.15, ISO/IEC IS15444-1 : 2002  */\r
349                                 if (band->bandno == 0) {\r
350                                         /* band border (global) */\r
351                                         band->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
352                                         band->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
353                                         band->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
354                                         band->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
355                                         band->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
356                                         band->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
357                                 } else {\r
358                                         band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1);\r
359                                         band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1);\r
360                                         band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
361                                         band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1);\r
362                                         band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1);\r
363                                         band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
364                                 }\r
365                                 \r
366                                 ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)];\r
367                                 if (bandno == (res->numbands - 1)) \r
368                                         prevnumbands += (resno == 0) ? 0 : res->numbands;\r
369                                 gain = dwt_getgain(band->bandno,tccp->reversible);                                      \r
370                                 numbps = volume->comps[compno].prec + gain;\r
371                                 band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));\r
372                                 band->numbps = ss->expn + tccp->numgbits - 1;   /* WHY -1 ? */\r
373                                 \r
374                                 band->precincts = (opj_tcd_precinct_t *) opj_malloc((res->prctno[0] * res->prctno[1] * res->prctno[2]) * sizeof(opj_tcd_precinct_t));\r
375                                 \r
376                                 for (i = 0; i < (res->prctno[0] * res->prctno[1] * res->prctno[2]); i++) {\r
377                                         band->precincts[i].imsbtree = NULL;\r
378                                         band->precincts[i].incltree = NULL;\r
379                                 }\r
380 \r
381                                 for (precno = 0; precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); precno++) {\r
382                                         int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend;\r
383                                         int cbgxstart, cbgystart, cbgzstart, cbgxend, cbgyend, cbgzend;\r
384 \r
385                                         cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn);\r
386                                         cbgystart = tlcbgystart + ((precno % (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn);\r
387                                         cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn);\r
388                                         cbgxend = cbgxstart + (1 << cbgwidthexpn);\r
389                                         cbgyend = cbgystart + (1 << cbgheightexpn);\r
390                                         cbgzend = cbgzstart + (1 << cbglengthexpn);\r
391                                         \r
392                                         tcd->prc = &band->precincts[precno];\r
393                                         prc = tcd->prc;\r
394 \r
395                                         /* precinct size (global) */\r
396                                         prc->x0 = int_max(cbgxstart, band->x0);\r
397                                         prc->y0 = int_max(cbgystart, band->y0);\r
398                                         prc->z0 = int_max(cbgzstart, band->z0);\r
399                                         prc->x1 = int_min(cbgxend, band->x1);\r
400                                         prc->y1 = int_min(cbgyend, band->y1);\r
401                                         prc->z1 = int_min(cbgzend, band->z1);\r
402                                         \r
403                                         tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;\r
404                                         tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;\r
405                                         tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn;\r
406                                         brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;\r
407                                         brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;\r
408                                         brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn;\r
409                                         prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;\r
410                                         prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn;\r
411                                         prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn;\r
412                                         prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2];\r
413 \r
414                                         prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t));\r
415                                         prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
416                                         prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
417                                         /*tgt_tree_dump(stdout,prc->incltree);*/\r
418                                         for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) {\r
419                                                 int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn);\r
420                                                 int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn);\r
421                                                 int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn);\r
422                                                 int cblkxend = cblkxstart + (1 << cblkwidthexpn);\r
423                                                 int cblkyend = cblkystart + (1 << cblkheightexpn);\r
424                                                 int cblkzend = cblkzstart + (1 << cblklengthexpn);\r
425                                                 int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1));\r
426                                                 \r
427                                                 tcd->cblk = &prc->cblks[cblkno];\r
428                                                 cblk = tcd->cblk;\r
429 \r
430                                                 /* code-block size (global) */\r
431                                                 cblk->x0 = int_max(cblkxstart, prc->x0);\r
432                                                 cblk->y0 = int_max(cblkystart, prc->y0);\r
433                                                 cblk->z0 = int_max(cblkzstart, prc->z0);\r
434                                                 cblk->x1 = int_min(cblkxend, prc->x1);\r
435                                                 cblk->y1 = int_min(cblkyend, prc->y1);\r
436                                                 cblk->z1 = int_min(cblkzend, prc->z1);\r
437                                         }                                       \r
438                                 }\r
439                         }\r
440                 }\r
441         }\r
442         /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/\r
443 \r
444 }\r
445 void tcd_init_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno) {\r
446         int compno, resno, bandno, precno, cblkno;\r
447         int j, p, q, r;\r
448 \r
449         opj_tcd_tile_t          *tile = NULL;           /* pointer to tcd->tile */\r
450         opj_tcd_tilecomp_t      *tilec = NULL;          /* pointer to tcd->tilec */\r
451         opj_tcd_resolution_t    *res = NULL;    /* pointer to tcd->res */\r
452         opj_tcd_band_t          *band = NULL;           /* pointer to tcd->band */\r
453         opj_tcd_precinct_t      *prc = NULL;            /* pointer to tcd->prc */\r
454         opj_tcd_cblk_t          *cblk = NULL;           /* pointer to tcd->cblk */\r
455         opj_tcp_t *tcp = &cp->tcps[curtileno];\r
456 \r
457         tcd->tile = tcd->tcd_volume->tiles;\r
458         tile = tcd->tile;\r
459 \r
460         /* p61 ISO/IEC IS15444-1 : 2002 */\r
461         /* curtileno --> raster scanned index of tiles */\r
462         /* p,q,r --> matricial index of tiles */\r
463         p = curtileno % cp->tw; \r
464         q = curtileno / cp->tw; \r
465         r = curtileno / (cp->tw * cp->th); /* extension to 3-D */\r
466         \r
467         /* 4 borders of the tile rescale on the volume if necessary (B.3)*/\r
468         tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0);\r
469         tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0);\r
470         tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0);\r
471         tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1);\r
472         tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1);\r
473         tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1);\r
474         tile->numcomps = volume->numcomps;\r
475 \r
476         /* Modification of the RATE >> */\r
477         for (j = 0; j < tcp->numlayers; j++) {\r
478                 if (tcp->rates[j] <= 1) {\r
479                         tcp->rates[j] = 0;\r
480                 } else {\r
481                         float num = (float) (tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec);\r
482                         float den = (float) (8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz);\r
483                         den = tcp->rates[j] * den;\r
484                         tcp->rates[j] = (num + den - 1) / den;\r
485                 }\r
486                 /*tcp->rates[j] = tcp->rates[j] ? int_ceildiv(\r
487                         tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec,\r
488             (tcp->rates[j] * 8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz)) : 0;*/\r
489                 if (tcp->rates[j]) {\r
490                         if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) {\r
491                                 tcp->rates[j] = tcp->rates[j - 1] + 20;\r
492                         } else if (!j && tcp->rates[j] < 30){\r
493                                 tcp->rates[j] = 30;\r
494                         }\r
495                 }\r
496         }\r
497         /* << Modification of the RATE */\r
498 \r
499         for (compno = 0; compno < tile->numcomps; compno++) {\r
500                 opj_tccp_t *tccp = &tcp->tccps[compno];\r
501                 int res_max, i;\r
502                 int prevnumbands = 0;\r
503 \r
504                 /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */\r
505                 tcd->tilec = &tile->comps[compno];\r
506                 tilec = tcd->tilec;\r
507 \r
508                 /* border of each tile component (global) (B.3) */\r
509                 tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx);\r
510                 tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy);\r
511                 tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz);\r
512                 tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx);\r
513                 tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy);\r
514                 tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz);\r
515 \r
516                 tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int));\r
517                 \r
518                 res_max = 0;\r
519                 for (i = 0;i < 3; i++){\r
520                         tilec->numresolution[i] = tccp->numresolution[i];\r
521                         /*Greater of 3 resolutions contains all information*/\r
522                         res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max;\r
523                 }\r
524 \r
525                 tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t));\r
526                 for (resno = 0; resno < res_max; resno++) {\r
527                         int pdx, pdy, pdz;\r
528                         int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend;\r
529                         int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend;\r
530                         int cbgwidthexpn, cbgheightexpn, cbglengthexpn;\r
531                         int cblkwidthexpn, cblkheightexpn, cblklengthexpn;\r
532                         \r
533                         int levelnox = tilec->numresolution[0] - 1 - resno; \r
534                         int levelnoy = tilec->numresolution[1] - 1 - resno;\r
535                         int diff = tccp->numresolution[0] - tccp->numresolution[2]; \r
536                         int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff));\r
537                                 if (levelnoz < 0) levelnoz = 0;\r
538 \r
539                         tcd->res = &tilec->resolutions[resno];\r
540                         res = tcd->res;\r
541                         \r
542                         /* border for each resolution level (global) (B.14)*/\r
543                         res->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
544                         res->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
545                         res->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
546                         res->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
547                         res->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
548                         res->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
549 \r
550                         /* res->numbands = resno == 0 ? 1 : 3; *//* --> 2D */\r
551 \r
552                         res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */\r
553 \r
554                         /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */                      \r
555                         if (tccp->csty & J3D_CCP_CSTY_PRT) {\r
556                                 pdx = tccp->prctsiz[0][resno];\r
557                                 pdy = tccp->prctsiz[1][resno];\r
558                                 pdz = tccp->prctsiz[2][resno];\r
559                         } else {\r
560                                 pdx = 15;\r
561                                 pdy = 15;\r
562                                 pdz = 15;\r
563                         }\r
564                         /* p. 66, B.16, ISO/IEC IS15444-1 : 2002  */\r
565                         tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;\r
566                         tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;\r
567                         tlprczstart = int_floordivpow2(res->z0, pdz) << pdz;\r
568                         brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;\r
569                         brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;\r
570                         brprczend = int_ceildivpow2(res->z1, pdz) << pdz;\r
571                         \r
572                         res->prctno[0] = (brprcxend - tlprcxstart) >> pdx;\r
573                         res->prctno[1] = (brprcyend - tlprcystart) >> pdy;\r
574                         res->prctno[2] = (brprczend - tlprczstart) >> pdz;\r
575                         if (res->prctno[2] == 0) res->prctno[2] = 1;\r
576 \r
577                         /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002  */\r
578                         if (resno == 0) {\r
579                                 tlcbgxstart = tlprcxstart;\r
580                                 tlcbgystart = tlprcystart;\r
581                                 tlcbgzstart = tlprczstart;\r
582                                 brcbgxend = brprcxend;\r
583                                 brcbgyend = brprcyend;\r
584                                 brcbgzend = brprczend;\r
585                                 cbgwidthexpn = pdx;\r
586                                 cbgheightexpn = pdy;\r
587                                 cbglengthexpn = pdz;\r
588                         } else {\r
589                                 tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);\r
590                                 tlcbgystart = int_ceildivpow2(tlprcystart, 1);\r
591                                 tlcbgzstart = int_ceildivpow2(tlprczstart, 1);\r
592                                 brcbgxend = int_ceildivpow2(brprcxend, 1);\r
593                                 brcbgyend = int_ceildivpow2(brprcyend, 1);\r
594                                 brcbgzend = int_ceildivpow2(brprczend, 1);\r
595                                 cbgwidthexpn = pdx - 1;\r
596                                 cbgheightexpn = pdy - 1;\r
597                                 cbglengthexpn = pdz - 1;\r
598                         }\r
599                         \r
600                         cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn);\r
601                         cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn);\r
602                         cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn);\r
603                         \r
604                         res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t));\r
605                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
606                                 int x0b, y0b, z0b;\r
607                                 int gain, numbps;\r
608                                 opj_stepsize_t *ss = NULL;\r
609 \r
610                                 tcd->band = &res->bands[bandno];\r
611                                 band = tcd->band;\r
612 \r
613                                 band->bandno = resno == 0 ? 0 : bandno + 1;\r
614                                 /* Bandno:      0 - LLL         2 - LHL \r
615                                                         1 - HLL         3 - HHL\r
616                                                         4 - LLH         6 - LHH\r
617                                                         5 - HLH         7 - HHH         */\r
618                                 x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; \r
619                                 y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;\r
620                                 z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; \r
621                                 \r
622                                 /* p. 65, B.15, ISO/IEC IS15444-1 : 2002  */\r
623                                 if (band->bandno == 0) {\r
624                                         /* band border (global) */\r
625                                         band->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
626                                         band->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
627                                         band->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
628                                         band->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
629                                         band->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
630                                         band->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
631                                 } else {\r
632                                         band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1);\r
633                                         band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1);\r
634                                         band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
635                                         band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1);\r
636                                         band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1);\r
637                                         band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
638                                 }\r
639                                                                 \r
640                                 ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)];\r
641                                 if (bandno == (res->numbands - 1)) \r
642                                         prevnumbands += (resno == 0) ? 0 : res->numbands;\r
643                                 gain = dwt_getgain(band->bandno,tccp->reversible);                                      \r
644                                 numbps = volume->comps[compno].prec + gain;\r
645                                 \r
646                                 band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));\r
647                                 band->numbps = ss->expn + tccp->numgbits - 1;   /* WHY -1 ? */\r
648                                 \r
649                                 for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
650                                         int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend;\r
651 \r
652                                         int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn);\r
653                                         int cbgystart = tlcbgystart + ((precno / (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn);\r
654                                         int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn);\r
655                                         int cbgxend = cbgxstart + (1 << cbgwidthexpn);\r
656                                         int cbgyend = cbgystart + (1 << cbgheightexpn);\r
657                                         int cbgzend = cbgzstart + (1 << cbglengthexpn);\r
658 \r
659                                         /* opj_tcd_precinct_t *prc=&band->precincts[precno]; */\r
660                                         tcd->prc = &band->precincts[precno];\r
661                                         prc = tcd->prc;\r
662 \r
663                                         /* precinct size (global) */\r
664                                         prc->x0 = int_max(cbgxstart, band->x0);\r
665                                         prc->y0 = int_max(cbgystart, band->y0);\r
666                                         prc->z0 = int_max(cbgzstart, band->z0);\r
667                                         prc->x1 = int_min(cbgxend, band->x1);\r
668                                         prc->y1 = int_min(cbgyend, band->y1);\r
669                                         prc->z1 = int_min(cbgzend, band->z1);\r
670 \r
671                                         tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;\r
672                                         tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;\r
673                                         tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn;\r
674                                         brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;\r
675                                         brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;\r
676                                         brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn;\r
677                                         prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;\r
678                                         prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn;\r
679                                         prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn;\r
680                                         prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2];\r
681 \r
682                                         opj_free(prc->cblks);\r
683                                         prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t));\r
684                                         prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
685                                         prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
686 \r
687                                         for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) {\r
688                                                         int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn);\r
689                                                         int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn);\r
690                                                         int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn);\r
691                                                         int cblkxend = cblkxstart + (1 << cblkwidthexpn);\r
692                                                         int cblkyend = cblkystart + (1 << cblkheightexpn);\r
693                                                         int cblkzend = cblkzstart + (1 << cblklengthexpn);\r
694                                                         int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1));\r
695 \r
696                                                         tcd->cblk = &prc->cblks[cblkno];\r
697                                                         cblk = tcd->cblk;\r
698 \r
699                                                         /* code-block size (global) */\r
700                                                         cblk->x0 = int_max(cblkxstart, prc->x0);\r
701                                                         cblk->y0 = int_max(cblkystart, prc->y0);\r
702                                                         cblk->z0 = int_max(cblkzstart, prc->z0);\r
703                                                         cblk->x1 = int_min(cblkxend, prc->x1);\r
704                                                         cblk->y1 = int_min(cblkyend, prc->y1);\r
705                                                         cblk->z1 = int_min(cblkzend, prc->z1);\r
706                                         }\r
707                                 } /* precno */\r
708                         } /* bandno */\r
709                 } /* resno */\r
710         } /* compno */\r
711         /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/\r
712 }\r
713 \r
714 \r
715 void tcd_free_encode(opj_tcd_t *tcd) {\r
716         int tileno, compno, resno, bandno, precno;\r
717 \r
718         opj_tcd_tile_t *tile = NULL;            /* pointer to tcd->tile         */\r
719 /*      opj_tcd_slice_t *slice = NULL; */               /* pointer to tcd->slice */\r
720         opj_tcd_tilecomp_t *tilec = NULL;       /* pointer to tcd->tilec        */\r
721         opj_tcd_resolution_t *res = NULL;       /* pointer to tcd->res          */\r
722         opj_tcd_band_t *band = NULL;            /* pointer to tcd->band         */\r
723         opj_tcd_precinct_t *prc = NULL;         /* pointer to tcd->prc          */\r
724 \r
725         for (tileno = 0; tileno < 1; tileno++) {\r
726                 tcd->tile = tcd->tcd_volume->tiles;\r
727                 tile = tcd->tile;\r
728 \r
729                 for (compno = 0; compno < tile->numcomps; compno++) {\r
730                         tcd->tilec = &tile->comps[compno];\r
731                         tilec = tcd->tilec;\r
732 \r
733                         for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
734                                 tcd->res = &tilec->resolutions[resno];\r
735                                 res = tcd->res;\r
736 \r
737                                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
738                                         tcd->band = &res->bands[bandno];\r
739                                         band = tcd->band;\r
740 \r
741                                         for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
742                                                 tcd->prc = &band->precincts[precno];\r
743                                                 prc = tcd->prc;\r
744 \r
745                                                 if (prc->incltree != NULL) {\r
746                             tgt_destroy(prc->incltree);\r
747                             prc->incltree = NULL;\r
748                                                 }\r
749                                                 if (prc->imsbtree != NULL) {\r
750                             tgt_destroy(prc->imsbtree);\r
751                             prc->imsbtree = NULL;\r
752                                                 }\r
753                                                 opj_free(prc->cblks);\r
754                                                 prc->cblks = NULL;\r
755                                         } /* for (precno */\r
756                                         opj_free(band->precincts);\r
757                                         band->precincts = NULL;\r
758                                 } /* for (bandno */\r
759                         } /* for (resno */\r
760                         opj_free(tilec->resolutions);\r
761                         tilec->resolutions = NULL;\r
762                 } /* for (compno */\r
763                 opj_free(tile->comps);\r
764                 tile->comps = NULL;\r
765         } /* for (tileno */\r
766         opj_free(tcd->tcd_volume->tiles);\r
767         tcd->tcd_volume->tiles = NULL;\r
768 }\r
769 \r
770 /* ----------------------------------------------------------------------- */\r
771 void tcd_malloc_decode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp) {\r
772         int tileno, compno, resno, bandno, precno, cblkno, res_max,\r
773                 i, j, p, q, r;\r
774         unsigned int x0 = 0, y0 = 0, z0 = 0, \r
775                 x1 = 0, y1 = 0, z1 = 0, \r
776                 w, h, l;\r
777 \r
778         tcd->volume = volume;\r
779         tcd->cp = cp;\r
780         tcd->tcd_volume->tw = cp->tw;\r
781         tcd->tcd_volume->th = cp->th;\r
782         tcd->tcd_volume->tl = cp->tl;\r
783         tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcd_tile_t));\r
784         \r
785         for (i = 0; i < cp->tileno_size; i++) {\r
786                 opj_tcp_t *tcp = &(cp->tcps[cp->tileno[i]]);\r
787                 opj_tcd_tile_t *tile = &(tcd->tcd_volume->tiles[cp->tileno[i]]);\r
788         \r
789                 /* p61 ISO/IEC IS15444-1 : 2002 */\r
790                 /* curtileno --> raster scanned index of tiles */\r
791                 /* p,q,r --> matricial index of tiles */\r
792                 tileno = cp->tileno[i];\r
793                 p = tileno % cp->tw;    \r
794                 q = tileno / cp->tw;    \r
795                 r = tileno / (cp->tw * cp->th); /* extension to 3-D */\r
796 \r
797                 /* 4 borders of the tile rescale on the volume if necessary (B.3)*/\r
798                 tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0);\r
799                 tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0);\r
800                 tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0);\r
801                 tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1);\r
802                 tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1);\r
803                 tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1);\r
804                 tile->numcomps = volume->numcomps;              \r
805                 \r
806                 tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t));\r
807                 for (compno = 0; compno < tile->numcomps; compno++) {\r
808                         opj_tccp_t *tccp = &tcp->tccps[compno];\r
809                         opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
810                         int prevnumbands = 0;\r
811 \r
812                         /* border of each tile component (global) */\r
813                         tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx);\r
814                         tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy);\r
815                         tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz);\r
816                         tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx);\r
817                         tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy);\r
818                         tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz);\r
819                         \r
820                         tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int));\r
821 \r
822                         res_max = 0;\r
823                         for (i = 0;i < 3; i++){\r
824                                 tilec->numresolution[i] = tccp->numresolution[i];\r
825                                 /*Greater of 3 resolutions contains all information*/\r
826                                 res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max;\r
827                         }\r
828 \r
829                         tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t));\r
830 \r
831                         for (resno = 0; resno < res_max; resno++) {\r
832                                 opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
833                                 int pdx, pdy, pdz;\r
834                                 int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend;\r
835                                 int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend;\r
836                                 int cbgwidthexpn, cbgheightexpn, cbglengthexpn;\r
837                                 int cblkwidthexpn, cblkheightexpn, cblklengthexpn;\r
838                                 int levelnox = tilec->numresolution[0] - 1 - resno; \r
839                                 int levelnoy = tilec->numresolution[1] - 1 - resno;\r
840                                 int diff = tccp->numresolution[0] - tccp->numresolution[2]; \r
841                                 int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff));\r
842                                         if (levelnoz < 0) levelnoz = 0;\r
843 \r
844                                 /* border for each resolution level (global) */\r
845                                 res->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
846                                 res->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
847                                 res->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
848                                 res->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
849                                 res->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
850                                 res->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
851                                 res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */\r
852                                 \r
853                                 /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */\r
854                                 if (tccp->csty & J3D_CCP_CSTY_PRT) {\r
855                                         pdx = tccp->prctsiz[0][resno];\r
856                                         pdy = tccp->prctsiz[1][resno];\r
857                                         pdz = tccp->prctsiz[2][resno];\r
858                                 } else {\r
859                                         pdx = 15;\r
860                                         pdy = 15;\r
861                                         pdz = 15;\r
862                                 }\r
863                                 \r
864                                 /* p. 66, B.16, ISO/IEC IS15444-1 : 2002  */\r
865                                 tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;\r
866                                 tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;\r
867                                 tlprczstart = int_floordivpow2(res->z0, pdz) << pdz;\r
868                                 brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;\r
869                                 brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;\r
870                                 brprczend = int_ceildivpow2(res->z1, pdz) << pdz;\r
871                                 \r
872                                 res->prctno[0] = (brprcxend - tlprcxstart) >> pdx;\r
873                                 res->prctno[1] = (brprcyend - tlprcystart) >> pdy;\r
874                                 res->prctno[2] = (brprczend - tlprczstart) >> pdz;\r
875                                 \r
876                                 /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002  */\r
877                                 if (resno == 0) {\r
878                                         tlcbgxstart = tlprcxstart;/*0*/\r
879                                         tlcbgystart = tlprcystart;\r
880                                         tlcbgzstart = tlprczstart;\r
881                                         brcbgxend = brprcxend;/*1*/\r
882                                         brcbgyend = brprcyend;\r
883                                         brcbgzend = brprczend;\r
884                                         cbgwidthexpn = pdx; /*15*/\r
885                                         cbgheightexpn = pdy;\r
886                                         cbglengthexpn = pdz;\r
887                                 } else {\r
888                                         tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);\r
889                                         tlcbgystart = int_ceildivpow2(tlprcystart, 1);\r
890                                         tlcbgzstart = int_ceildivpow2(tlprczstart, 1);\r
891                                         brcbgxend = int_ceildivpow2(brprcxend, 1);\r
892                                         brcbgyend = int_ceildivpow2(brprcyend, 1);\r
893                                         brcbgzend = int_ceildivpow2(brprczend, 1);\r
894                                         cbgwidthexpn = pdx - 1;\r
895                                         cbgheightexpn = pdy - 1;\r
896                                         cbglengthexpn = pdz - 1;\r
897                                 }\r
898                                 \r
899                                 cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); /*6*/\r
900                                 cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); /*6*/\r
901                                 cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); /*6*/\r
902 \r
903                                 res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t));\r
904                                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
905                                         int x0b, y0b, z0b;\r
906                                         int gain, numbps;\r
907                                         opj_stepsize_t *ss = NULL;\r
908 \r
909                                         opj_tcd_band_t *band = &res->bands[bandno];\r
910                                         band->bandno = resno == 0 ? 0 : bandno + 1;\r
911                                         /* Bandno:      0 - LLL         2 - LHL \r
912                                                                 1 - HLL         3 - HHL\r
913                                                                 4 - LLH         6 - LHH\r
914                                                                 5 - HLH         7 - HHH         */\r
915                                         x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; \r
916                                         y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;\r
917                                         z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; \r
918                                         \r
919                                         /* p. 65, B.15, ISO/IEC IS15444-1 : 2002  */\r
920                                         if (band->bandno == 0) {\r
921                                                 /* band border (global) */\r
922                                                 band->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
923                                                 band->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
924                                                 band->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
925                                                 band->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
926                                                 band->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
927                                                 band->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
928                                         } else {\r
929                                                 band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1);\r
930                                                 band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1);\r
931                                                 band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
932                                                 band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1);\r
933                                                 band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1);\r
934                                                 band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
935                                         }       \r
936 \r
937                                         ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)];\r
938                                         if (bandno == (res->numbands - 1)) \r
939                                                 prevnumbands += (resno == 0) ? 0 : res->numbands;\r
940                                         gain = dwt_getgain(band->bandno,tccp->reversible);                                      \r
941                                         numbps = volume->comps[compno].prec + gain;\r
942 \r
943                                         band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));\r
944                                         band->numbps = ss->expn + tccp->numgbits - 1;   /* WHY -1 ? */\r
945                                         \r
946                                         band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->prctno[0] * res->prctno[1] * res->prctno[2] * sizeof(opj_tcd_precinct_t));\r
947                                         \r
948                                         for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
949                                                 int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend;\r
950 \r
951                                                 int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn);\r
952                                                 int cbgystart = tlcbgystart + (precno / res->prctno[0]) * (1 << cbgheightexpn);\r
953                                                 int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn);\r
954                                                 int cbgxend = cbgxstart + (1 << cbgwidthexpn);\r
955                                                 int cbgyend = cbgystart + (1 << cbgheightexpn);\r
956                                                 int cbgzend = cbgzstart + (1 << cbglengthexpn);\r
957 \r
958                                                 opj_tcd_precinct_t *prc = &band->precincts[precno];\r
959                                                 /* precinct size (global) */\r
960                                                 prc->x0 = int_max(cbgxstart, band->x0);\r
961                                                 prc->y0 = int_max(cbgystart, band->y0);\r
962                                                 prc->z0 = int_max(cbgzstart, band->z0);\r
963                                                 prc->x1 = int_min(cbgxend, band->x1);\r
964                                                 prc->y1 = int_min(cbgyend, band->y1);\r
965                                                 prc->z1 = int_min(cbgzend, band->z1);\r
966 \r
967                                                 tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;\r
968                                                 tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;\r
969                                                 tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn;\r
970                                                 brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;\r
971                                                 brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;\r
972                                                 brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn;\r
973                                                 prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;\r
974                                                 prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn;\r
975                                                 prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn;\r
976                                                 prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2];\r
977 \r
978                                                 prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t));\r
979                                                 prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
980                                                 prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
981                                                 \r
982                                                 for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
983                                                         int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn);\r
984                                                         int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn);\r
985                                                         int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn);\r
986                                                         int cblkxend = cblkxstart + (1 << cblkwidthexpn);\r
987                                                         int cblkyend = cblkystart + (1 << cblkheightexpn);\r
988                                                         int cblkzend = cblkzstart + (1 << cblklengthexpn);\r
989                                                         int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1));\r
990                                                         /* code-block size (global) */\r
991                                                         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
992                                                         \r
993                                                         /* code-block size (global) */\r
994                                                         cblk->x0 = int_max(cblkxstart, prc->x0);\r
995                                                         cblk->y0 = int_max(cblkystart, prc->y0);\r
996                                                         cblk->z0 = int_max(cblkzstart, prc->z0);\r
997                                                         cblk->x1 = int_min(cblkxend, prc->x1);\r
998                                                         cblk->y1 = int_min(cblkyend, prc->y1);\r
999                                                         cblk->z1 = int_min(cblkzend, prc->z1);\r
1000                                                 }\r
1001                                         } /* precno */\r
1002                                 } /* bandno */\r
1003                         } /* resno */\r
1004                 } /* compno */\r
1005         } /* i = 0..cp->tileno_size */\r
1006 \r
1007         /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/\r
1008 \r
1009         /* \r
1010         Allocate place to store the decoded data = final volume\r
1011         Place limited by the tile really present in the codestream \r
1012         */\r
1013         \r
1014         for (i = 0; i < volume->numcomps; i++) {\r
1015                 for (j = 0; j < cp->tileno_size; j++) {\r
1016                         tileno = cp->tileno[j];\r
1017                         x0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].x0 : int_min(x0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].x0);\r
1018                         y0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].y0 : int_min(y0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].y0);\r
1019                         z0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].z0 : int_min(z0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].z0);\r
1020                         x1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].x1 : int_max(x1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].x1);\r
1021                         y1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].y1 : int_max(y1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].y1);\r
1022                         z1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].z1 : int_max(z1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].z1);\r
1023                 }\r
1024                 \r
1025                 w = x1 - x0;\r
1026                 h = y1 - y0;\r
1027                 l = z1 - z0;\r
1028                 \r
1029                 volume->comps[i].data = (int *) opj_malloc(w * h * l * sizeof(int));\r
1030                 volume->comps[i].w = w;\r
1031                 volume->comps[i].h = h;\r
1032                 volume->comps[i].l = l;\r
1033                 volume->comps[i].x0 = x0;\r
1034                 volume->comps[i].y0 = y0;\r
1035                 volume->comps[i].z0 = z0;\r
1036                 volume->comps[i].bigendian = cp->bigendian;\r
1037         }\r
1038 }\r
1039 \r
1040 void tcd_free_decode(opj_tcd_t *tcd) {\r
1041         int tileno,compno,resno,bandno,precno;\r
1042 \r
1043         opj_tcd_volume_t *tcd_volume = tcd->tcd_volume;\r
1044         \r
1045         for (tileno = 0; tileno < tcd_volume->tw * tcd_volume->th * tcd_volume->tl; tileno++) {\r
1046                 opj_tcd_tile_t *tile = &tcd_volume->tiles[tileno];\r
1047                 for (compno = 0; compno < tile->numcomps; compno++) {\r
1048                         opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1049                         for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
1050                                 opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
1051                                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
1052                                         opj_tcd_band_t *band = &res->bands[bandno];\r
1053                                         for (precno = 0; precno < res->prctno[1] * res->prctno[0] * res->prctno[2]; precno++) {\r
1054                                                 opj_tcd_precinct_t *prec = &band->precincts[precno];\r
1055                                                 if (prec->cblks != NULL) opj_free(prec->cblks);\r
1056                                                 if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);\r
1057                         if (prec->incltree != NULL) tgt_destroy(prec->incltree);\r
1058                                                 /*for (treeno = 0; treeno < prec->numtrees; treeno++){\r
1059                             if (prec->imsbtree[treeno] != NULL) tgt_destroy(prec->imsbtree[treeno]);\r
1060                             if (prec->incltree[treeno] != NULL) tgt_destroy(prec->incltree[treeno]);\r
1061                                                 }*/\r
1062                                         }\r
1063                                         if (band->precincts != NULL) opj_free(band->precincts);\r
1064                                 }\r
1065                         }\r
1066                         if (tilec->resolutions != NULL) opj_free(tilec->resolutions);\r
1067                 }\r
1068                 if (tile->comps != NULL) opj_free(tile->comps);\r
1069         }\r
1070 \r
1071         if (tcd_volume->tiles != NULL) opj_free(tcd_volume->tiles);\r
1072 }\r
1073 \r
1074 \r
1075 \r
1076 /* ----------------------------------------------------------------------- */\r
1077 void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final) {\r
1078         int compno, resno, bandno, precno, cblkno;\r
1079         int value;                      /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolution[0]][3]; */\r
1080         int matrice[10][10][3];\r
1081         int i, j, k;\r
1082 \r
1083         opj_cp_t *cp = tcd->cp;\r
1084         opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;\r
1085         opj_tcp_t *tcd_tcp = tcd->tcp;\r
1086 \r
1087         /*matrice=(int*)opj_malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolution[0]*3*sizeof(int)); */\r
1088         \r
1089         for (compno = 0; compno < tcd_tile->numcomps; compno++) {\r
1090                 opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];\r
1091                 for (i = 0; i < tcd_tcp->numlayers; i++) {\r
1092                         for (j = 0; j < tilec->numresolution[0]; j++) {\r
1093                                 for (k = 0; k < 3; k++) {\r
1094                                         matrice[i][j][k] =\r
1095                                                 (int) (cp->matrice[i * tilec->numresolution[0] * 3 + j * 3 + k] \r
1096                                                 * (float) (tcd->volume->comps[compno].prec / 16.0));\r
1097                                 }\r
1098                         }\r
1099                 }\r
1100         \r
1101                 for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
1102                         opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
1103                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
1104                                 opj_tcd_band_t *band = &res->bands[bandno];\r
1105                                 for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
1106                                         opj_tcd_precinct_t *prc = &band->precincts[precno];\r
1107                                         for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
1108                                                 opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
1109                                                 opj_tcd_layer_t *layer = &cblk->layers[layno];\r
1110                                                 int n;\r
1111                                                 int imsb = tcd->volume->comps[compno].prec - cblk->numbps;      /* number of bit-plan equal to zero */\r
1112                                                 /* Correction of the matrix of coefficient to include the IMSB information */\r
1113                                                 if (layno == 0) {\r
1114                                                         value = matrice[layno][resno][bandno];\r
1115                                                         if (imsb >= value) {\r
1116                                                                 value = 0;\r
1117                                                         } else {\r
1118                                                                 value -= imsb;\r
1119                                                         }\r
1120                                                 } else {\r
1121                                                         value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno];\r
1122                                                         if (imsb >= matrice[layno - 1][resno][bandno]) {\r
1123                                                                 value -= (imsb - matrice[layno - 1][resno][bandno]);\r
1124                                                                 if (value < 0) {\r
1125                                                                         value = 0;\r
1126                                                                 }\r
1127                                                         }\r
1128                                                 }\r
1129                                                 \r
1130                                                 if (layno == 0) {\r
1131                                                         cblk->numpassesinlayers = 0;\r
1132                                                 }\r
1133                                                 \r
1134                                                 n = cblk->numpassesinlayers;\r
1135                                                 if (cblk->numpassesinlayers == 0) {\r
1136                                                         if (value != 0) {\r
1137                                                                 n = 3 * value - 2 + cblk->numpassesinlayers;\r
1138                                                         } else {\r
1139                                                                 n = cblk->numpassesinlayers;\r
1140                                                         }\r
1141                                                 } else {\r
1142                                                         n = 3 * value + cblk->numpassesinlayers;\r
1143                                                 }\r
1144                                                 \r
1145                                                 layer->numpasses = n - cblk->numpassesinlayers;\r
1146                                                 \r
1147                                                 if (!layer->numpasses)\r
1148                                                         continue;\r
1149                                                 \r
1150                                                 if (cblk->numpassesinlayers == 0) {\r
1151                                                         layer->len = cblk->passes[n - 1].rate;\r
1152                                                         layer->data = cblk->data;\r
1153                                                 } else {\r
1154                                                         layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;\r
1155                                                         layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;\r
1156                                                 }\r
1157                                                 if (final)\r
1158                                                         cblk->numpassesinlayers = n;\r
1159                                         }\r
1160                                 }\r
1161                         }\r
1162                 }\r
1163         }\r
1164 }\r
1165 \r
1166 void tcd_rateallocate_fixed(opj_tcd_t *tcd) {\r
1167         int layno;\r
1168         for (layno = 0; layno < tcd->tcp->numlayers; layno++) {\r
1169                 tcd_makelayer_fixed(tcd, layno, 1);\r
1170         }\r
1171 }\r
1172 \r
1173 void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {\r
1174         int compno, resno, bandno, precno, cblkno, passno;\r
1175         \r
1176         opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;\r
1177 \r
1178         tcd_tile->distolayer[layno] = 0;        /* fixed_quality */\r
1179         \r
1180         for (compno = 0; compno < tcd_tile->numcomps; compno++) {\r
1181                 opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];\r
1182                 for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
1183                         opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
1184                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
1185                                 opj_tcd_band_t *band = &res->bands[bandno];\r
1186                                 for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
1187                                         opj_tcd_precinct_t *prc = &band->precincts[precno];\r
1188                                         for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
1189                                                 opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
1190                                                 opj_tcd_layer_t *layer = &cblk->layers[layno];\r
1191                                                 \r
1192                                                 int n;\r
1193                                                 if (layno == 0) {\r
1194                                                         cblk->numpassesinlayers = 0;\r
1195                                                 }\r
1196                                                 n = cblk->numpassesinlayers;\r
1197                                                 for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {\r
1198                                                         int dr;\r
1199                                                         double dd;\r
1200                                                         opj_tcd_pass_t *pass = &cblk->passes[passno];\r
1201                                                         if (n == 0) {\r
1202                                                                 dr = pass->rate;\r
1203                                                                 dd = pass->distortiondec;\r
1204                                                         } else {\r
1205                                                                 dr = pass->rate - cblk->passes[n - 1].rate;\r
1206                                                                 dd = pass->distortiondec - cblk->passes[n - 1].distortiondec;\r
1207                                                         }\r
1208                                                         if (!dr) {\r
1209                                                                 if (dd)\r
1210                                                                         n = passno + 1;\r
1211                                                                 continue;\r
1212                                                         }\r
1213                                                         if (dd / dr >= thresh){\r
1214                                                                 n = passno + 1;\r
1215                                                         }\r
1216                                                 }\r
1217                                                 layer->numpasses = n - cblk->numpassesinlayers;\r
1218                                                 \r
1219                                                 if (!layer->numpasses) {\r
1220                                                         layer->disto = 0;\r
1221                                                         continue;\r
1222                                                 }\r
1223                                                 if (cblk->numpassesinlayers == 0) {\r
1224                                                         layer->len = cblk->passes[n - 1].rate;\r
1225                                                         layer->data = cblk->data;\r
1226                                                         layer->disto = cblk->passes[n - 1].distortiondec;\r
1227                                                 } else {\r
1228                                                         layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;\r
1229                                                         layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;\r
1230                                                         layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec;\r
1231                                                 }\r
1232                                                 \r
1233                                                 tcd_tile->distolayer[layno] += layer->disto;    /* fixed_quality */\r
1234                                                 \r
1235                                                 if (final)\r
1236                                                         cblk->numpassesinlayers = n;\r
1237 \r
1238                                         /*      fprintf(stdout,"MakeLayer : %d %f %d %d \n",layer->len, layer->disto, layer->numpasses, n);*/\r
1239                                         }\r
1240                                 }\r
1241                         }\r
1242                 }\r
1243         }\r
1244 }\r
1245 \r
1246 bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_volume_info_t * volume_info) {\r
1247         int compno, resno, bandno, precno, cblkno, passno, layno;\r
1248         double min, max;\r
1249         double cumdisto[100];   /* fixed_quality */\r
1250         const double K = 1;             /* 1.1; // fixed_quality */\r
1251         double maxSE = 0;\r
1252 \r
1253         opj_cp_t *cp = tcd->cp;\r
1254         opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;\r
1255         opj_tcp_t *tcd_tcp = tcd->tcp;\r
1256 \r
1257         min = DBL_MAX;\r
1258         max = 0;\r
1259         \r
1260         tcd_tile->nbpix = 0;            /* fixed_quality */\r
1261         \r
1262         for (compno = 0; compno < tcd_tile->numcomps; compno++) {\r
1263                 opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];\r
1264                 tilec->nbpix = 0;\r
1265                 for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
1266                         opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
1267                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
1268                                 opj_tcd_band_t *band = &res->bands[bandno];\r
1269                                 for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
1270                                         opj_tcd_precinct_t *prc = &band->precincts[precno];\r
1271                                         for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
1272                                                 opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
1273                                                 for (passno = 0; passno < cblk->totalpasses; passno++) {\r
1274                                                         opj_tcd_pass_t *pass = &cblk->passes[passno];\r
1275                                                         int dr;\r
1276                                                         double dd, rdslope;\r
1277                                                         if (passno == 0) {\r
1278                                                                 dr = pass->rate;\r
1279                                                                 dd = pass->distortiondec;\r
1280                                                         } else {\r
1281                                                                 dr = pass->rate - cblk->passes[passno - 1].rate;\r
1282                                                                 dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec;\r
1283                                                         }\r
1284                                                         if (dr == 0) {\r
1285                                                                 continue;\r
1286                                                         }\r
1287                                                         rdslope = dd / dr;\r
1288                                                         if (rdslope < min) {\r
1289                                                                 min = rdslope;\r
1290                                                         }\r
1291                                                         if (rdslope > max) {\r
1292                                                                 max = rdslope;\r
1293                                                         }\r
1294 \r
1295                                                 } /* passno */\r
1296                                                 \r
1297                                                 /* fixed_quality */\r
1298                                                 tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0));\r
1299                         tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0));\r
1300                                         } /* cbklno */ \r
1301                                 } /* precno */\r
1302                         } /* bandno */\r
1303                 } /* resno */\r
1304                 \r
1305                 maxSE += (((double)(1 << tcd->volume->comps[compno].prec) - 1.0) \r
1306                         * ((double)(1 << tcd->volume->comps[compno].prec) -1.0)) \r
1307                         * ((double)(tilec->nbpix));\r
1308         } /* compno */\r
1309         \r
1310         /* add antonin index */\r
1311         if(volume_info && volume_info->index_on) {\r
1312                 opj_tile_info_t *info_TL = &volume_info->tile[tcd->tcd_tileno];\r
1313                 info_TL->nbpix = tcd_tile->nbpix;\r
1314                 info_TL->distotile = tcd_tile->distotile;\r
1315                 info_TL->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double));\r
1316         }\r
1317         /* dda */\r
1318         \r
1319         for (layno = 0; layno < tcd_tcp->numlayers; layno++) {\r
1320                 double lo = min;\r
1321                 double hi = max;\r
1322                 int success = 0;\r
1323                 int maxlen = tcd_tcp->rates[layno] ? int_min(((int) tcd_tcp->rates[layno]), len) : len;\r
1324                 double goodthresh;\r
1325                 double distotarget;             /* fixed_quality */\r
1326                 int i = 0;\r
1327                 \r
1328         /* fixed_quality */\r
1329                 distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10));\r
1330         \r
1331                 if ((tcd_tcp->rates[layno]) || (cp->disto_alloc==0)) {\r
1332                         opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->volume, cp);\r
1333                         int oldl = 0, oldoldl = 0;\r
1334                         for (i = 0; i < 128; i++) {\r
1335                                 double thresh = (lo + hi) / 2;\r
1336                                 int l = 0;\r
1337                                 double distoachieved = 0;       /* fixed_quality -q */\r
1338                         \r
1339                                 tcd_makelayer(tcd, layno, thresh, 0);\r
1340                 \r
1341                                 if (cp->fixed_quality) {        /* fixed_quality -q */\r
1342                                         distoachieved = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];\r
1343                                         if (distoachieved < distotarget) {\r
1344                                                 hi = thresh; \r
1345                                                 continue;\r
1346                                         }\r
1347                                         lo = thresh;\r
1348                                 } else {                /* disto_alloc -r, fixed_alloc -f */\r
1349                                         l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, volume_info);\r
1350                                         /*fprintf(stdout, "layno %d i %d len=%d max=%d \n",layno,i,l,maxlen);*/\r
1351                                         if (l == -999) {\r
1352                                                 lo = thresh; \r
1353                                                 continue;\r
1354                                         } else if (l == oldl && oldl == oldoldl && tcd_tile->distolayer[layno] > 0.0 && i>32)\r
1355                                                 break;\r
1356                                         hi = thresh;\r
1357                                         oldoldl = oldl;\r
1358                                         oldl = l;\r
1359                                 }\r
1360                                 success = 1;\r
1361                                 goodthresh = thresh;\r
1362                         } \r
1363                         t2_destroy(t2);\r
1364                 } else {\r
1365                         success = 1;\r
1366                         goodthresh = min;\r
1367                 }\r
1368                 if (!success) {\r
1369                         return false;\r
1370                 }\r
1371                 \r
1372                 if(volume_info && volume_info->index_on) {      /* Threshold for Marcela Index */\r
1373                         volume_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;\r
1374                 }\r
1375                 tcd_makelayer(tcd, layno, goodthresh, 1);\r
1376                 \r
1377                 /* fixed_quality */\r
1378                 cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];   \r
1379         }\r
1380 \r
1381         return true;\r
1382 }\r
1383 \r
1384 /* ----------------------------------------------------------------------- */\r
1385 int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_volume_info_t * volume_info) {\r
1386         int compno;\r
1387         int l, i, npck = 0;\r
1388         double encoding_time;\r
1389         \r
1390         opj_tcd_tile_t  *tile = NULL;\r
1391         opj_tcp_t               *tcd_tcp = NULL;\r
1392         opj_cp_t                *cp = NULL;\r
1393 \r
1394         opj_tcp_t               *tcp = &tcd->cp->tcps[0];\r
1395         opj_tccp_t              *tccp = &tcp->tccps[0];\r
1396         opj_volume_t    *volume = tcd->volume;\r
1397         opj_t2_t                *t2 = NULL;             /* T2 component */\r
1398 \r
1399         tcd->tcd_tileno = tileno;                       /* current encoded/decoded tile */\r
1400         \r
1401         tcd->tcd_tile = tcd->tcd_volume->tiles; /* tile information */\r
1402         tile = tcd->tcd_tile;\r
1403         \r
1404         tcd->tcp = &tcd->cp->tcps[tileno];      /* coding/decoding params of tileno */  \r
1405         tcd_tcp = tcd->tcp;\r
1406         \r
1407         cp = tcd->cp;           /* coding parameters */\r
1408 \r
1409         /* INDEX >> */\r
1410         if(volume_info && volume_info->index_on) {\r
1411                 opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0];        /* based on component 0 */\r
1412                 for (i = 0; i < tilec_idx->numresolution[0]; i++) {\r
1413                         opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i];\r
1414 \r
1415                         volume_info->tile[tileno].prctno[0][i] = res_idx->prctno[0];\r
1416                         volume_info->tile[tileno].prctno[1][i] = res_idx->prctno[1];\r
1417                         volume_info->tile[tileno].prctno[2][i] = res_idx->prctno[2];\r
1418 \r
1419                         npck += res_idx->prctno[0] * res_idx->prctno[1] * res_idx->prctno[2];\r
1420 \r
1421                         volume_info->tile[tileno].prctsiz[0][i] = tccp->prctsiz[0][i];\r
1422                         volume_info->tile[tileno].prctsiz[1][i] = tccp->prctsiz[1][i];\r
1423                         volume_info->tile[tileno].prctsiz[2][i] = tccp->prctsiz[2][i];\r
1424                 }\r
1425                 volume_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(volume_info->comp * volume_info->layer * npck * sizeof(opj_packet_info_t));\r
1426         }\r
1427         /* << INDEX */\r
1428         \r
1429         /*---------------TILE-------------------*/\r
1430         encoding_time = opj_clock();    /* time needed to encode a tile */\r
1431         \r
1432         for (compno = 0; compno < tile->numcomps; compno++) {\r
1433                 int x, y, z;\r
1434                 opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1435                 \r
1436                 int adjust;\r
1437                 int offset_x = int_ceildiv(volume->x0, volume->comps[compno].dx); /*ceil(x0 / subsampling_dx)*/\r
1438                 int offset_y = int_ceildiv(volume->y0, volume->comps[compno].dy);\r
1439                 int offset_z = int_ceildiv(volume->z0, volume->comps[compno].dz);\r
1440                 \r
1441                 int tw = tilec->x1 - tilec->x0;\r
1442                 int w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx);\r
1443                 int th = tilec->y1 - tilec->y0;\r
1444                 int h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy);\r
1445                 int tl = tilec->z1 - tilec->z0;\r
1446                 int l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz);\r
1447 \r
1448                 \r
1449                 \r
1450                 /* extract tile data from volume.comps[0].data to tile.comps[0].data */\r
1451                 /*fprintf(stdout,"[INFO] Extract tile data\n");*/\r
1452                 if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) {\r
1453                         adjust = 0;\r
1454                 } else {\r
1455             adjust = volume->comps[compno].sgnd ? 0 : 1 << (volume->comps[compno].prec - 1); /*sign=='+' --> 2^(prec-1)*/\r
1456                         if (volume->comps[compno].dcoffset != 0){\r
1457                                 adjust += volume->comps[compno].dcoffset;\r
1458                                 fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",volume->comps[compno].dcoffset,adjust);\r
1459                         }\r
1460                 }               \r
1461 \r
1462                 if (tcd_tcp->tccps[compno].reversible == 1) { /*IF perfect reconstruction (DWT.5-3)*/\r
1463                         for (z = tilec->z0; z < tilec->z1; z++) {\r
1464                                 for (y = tilec->y0; y < tilec->y1; y++) {\r
1465                                         /* start of the src tile scanline */\r
1466                                         int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h];\r
1467                                         /* start of the dst tile scanline */\r
1468                                         int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th];\r
1469                                         for (x = tilec->x0; x < tilec->x1; x++) {\r
1470                                                 *tile_data++ = *data++ - adjust;\r
1471                                         }\r
1472                                 }\r
1473                         }\r
1474                 } else if (tcd_tcp->tccps[compno].reversible == 0) { /*IF not (DWT.9-7)*/\r
1475                         for (z = tilec->z0; z < tilec->z1; z++) {\r
1476                                 for (y = tilec->y0; y < tilec->y1; y++) {\r
1477                                         /* start of the src tile scanline */\r
1478                                         int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h];\r
1479                                         /* start of the dst tile scanline */\r
1480                                         int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th];\r
1481                                         for (x = tilec->x0; x < tilec->x1; x++) {\r
1482                                                 *tile_data++ = (*data++ - adjust) << 13;\r
1483                                         }\r
1484                                 }\r
1485                         }\r
1486                 }\r
1487         \r
1488         }\r
1489 \r
1490         /*----------------MCT-------------------*/\r
1491         if (tcd_tcp->mct) {\r
1492                 int samples = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) * (tile->comps[0].z1 - tile->comps[0].z0);\r
1493                 fprintf(stdout,"[INFO] Tcd_encode_tile: mct\n");\r
1494                 if (tcd_tcp->tccps[0].reversible == 0) {\r
1495                         mct_encode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples);\r
1496                 } else {\r
1497                         mct_encode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples);\r
1498                 }\r
1499         }\r
1500         /*----------------TRANSFORM---------------------------------*/\r
1501         fprintf(stdout,"[INFO] Tcd_encode_tile: Transform\n");\r
1502         for (compno = 0; compno < tile->numcomps; compno++) {\r
1503                 opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1504                 dwt_encode(tilec, tcd_tcp->tccps[compno].dwtid);\r
1505         } \r
1506 \r
1507         /*-------------------ENTROPY CODING-----------------------------*/\r
1508         fprintf(stdout,"[INFO] Tcd_encode_tile: Entropy coding\n");\r
1509         if ((cp->encoding_format == ENCOD_2EB)||(cp->encoding_format == ENCOD_3EB))\r
1510         {\r
1511                 if (cp->encoding_format == ENCOD_2EB) {\r
1512                         opj_t1_t *t1 = NULL;\r
1513                         t1 = t1_create(tcd->cinfo);\r
1514                         t1_encode_cblks(t1, tile, tcd_tcp);\r
1515                         t1_destroy(t1); \r
1516                 } else if (cp->encoding_format == ENCOD_3EB) {\r
1517                         opj_t1_3d_t *t1 = NULL;         \r
1518                         t1 = t1_3d_create(tcd->cinfo);\r
1519                         t1_3d_encode_cblks(t1, tile, tcd_tcp);\r
1520                         t1_3d_destroy(t1);      \r
1521                 }\r
1522                 /*-----------RATE-ALLOCATE------------------*/\r
1523                 /* INDEX */\r
1524                 if(volume_info) {\r
1525                         volume_info->index_write = 0;\r
1526                 }\r
1527                 if (cp->disto_alloc || cp->fixed_quality) {     \r
1528                         fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate\n");\r
1529                         tcd_rateallocate(tcd, dest, len, volume_info);                  /* Normal Rate/distortion allocation */\r
1530                 } else {/* fixed_alloc */\r
1531             fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate fixed\n");\r
1532             tcd_rateallocate_fixed(tcd);                                                        /* Fixed layer allocation */\r
1533                 }\r
1534 \r
1535                 /*--------------TIER2------------------*/\r
1536                 /* INDEX */\r
1537                 if(volume_info) {\r
1538                         volume_info->index_write = 1;\r
1539                 }\r
1540                 fprintf(stdout,"[INFO] Tcd_encode_tile: Tier - 2\n");\r
1541         t2 = t2_create(tcd->cinfo, volume, cp);\r
1542                 l = t2_encode_packets(t2, tileno, tile, tcd_tcp->numlayers, dest, len, volume_info);\r
1543         t2_destroy(t2);\r
1544         } else if ((cp->encoding_format == ENCOD_2GR)||(cp->encoding_format == ENCOD_3GR)) {\r
1545                 /*if(volume_info) {\r
1546                         volume_info->index_write = 1;\r
1547                 }\r
1548                 gr = golomb_create(tcd->cinfo, volume, cp);\r
1549                 l = golomb_encode(gr, tileno, tile, dest, len, volume_info);\r
1550                 golomb_destroy(gr);*/\r
1551         }\r
1552 \r
1553         \r
1554         /*---------------CLEAN-------------------*/\r
1555         fprintf(stdout,"[INFO] Tcd_encode_tile: %d bytes coded\n",l);\r
1556         encoding_time = opj_clock() - encoding_time;\r
1557         opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time);\r
1558         \r
1559         /* cleaning memory */\r
1560         for (compno = 0; compno < tile->numcomps; compno++) {\r
1561                 tcd->tilec = &tile->comps[compno];\r
1562                 opj_free(tcd->tilec->data);\r
1563         }\r
1564         \r
1565         if (l == -999){\r
1566                 fprintf(stdout,"[ERROR] Unable to perform T2 tier. Return -999.\n");\r
1567                 return 0;\r
1568         }\r
1569 \r
1570         return l;\r
1571 }\r
1572 \r
1573 \r
1574 bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno) {\r
1575         int l, i;\r
1576         int compno, eof = 0;\r
1577         double tile_time, t1_time, dwt_time;\r
1578 \r
1579         opj_tcd_tile_t *tile = NULL;\r
1580         opj_t2_t *t2 = NULL;            /* T2 component */\r
1581         \r
1582         tcd->tcd_tileno = tileno;\r
1583         tcd->tcd_tile = &(tcd->tcd_volume->tiles[tileno]);\r
1584         tcd->tcp = &(tcd->cp->tcps[tileno]);\r
1585         tile = tcd->tcd_tile;\r
1586         \r
1587         tile_time = opj_clock();        /* time needed to decode a tile */\r
1588         opj_event_msg(tcd->cinfo, EVT_INFO, "tile %d / %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th * tcd->cp->tl);\r
1589 \r
1590         if ((tcd->cp->encoding_format == ENCOD_2EB) || (tcd->cp->encoding_format == ENCOD_3EB)) {\r
1591                 /*--------------TIER2------------------*/\r
1592                 t2 = t2_create(tcd->cinfo, tcd->volume, tcd->cp);\r
1593                 l = t2_decode_packets(t2, src, len, tileno, tile);\r
1594                 t2_destroy(t2);\r
1595                 opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: %d bytes decoded\n",l);\r
1596                 \r
1597                 if (l == -999) {\r
1598                         eof = 1;\r
1599                         opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n");\r
1600                 }\r
1601         \r
1602                 /*------------------TIER1-----------------*/\r
1603                 opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding %d \n",tcd->cp->encoding_format);\r
1604                 t1_time = opj_clock();  /* time needed to decode a tile */\r
1605                 if (tcd->cp->encoding_format == ENCOD_2EB) {\r
1606                         opj_t1_t *t1 = NULL;            /* T1 component */\r
1607                         t1 = t1_create(tcd->cinfo);\r
1608                         t1_decode_cblks(t1, tile, tcd->tcp);\r
1609                         t1_destroy(t1);\r
1610                 }else if (tcd->cp->encoding_format == ENCOD_3EB) {\r
1611                         opj_t1_3d_t *t1 = NULL;         /* T1 component */\r
1612                         t1 = t1_3d_create(tcd->cinfo);\r
1613                         t1_3d_decode_cblks(t1, tile, tcd->tcp);\r
1614                         t1_3d_destroy(t1);\r
1615                 }\r
1616 \r
1617                 t1_time = opj_clock() - t1_time;\r
1618                 #ifdef VERBOSE\r
1619                                 opj_event_msg(tcd->cinfo, EVT_INFO, "- tier-1 took %f s\n", t1_time);\r
1620                 #endif\r
1621         } else if ((tcd->cp->encoding_format == ENCOD_2GR)||(tcd->cp->encoding_format == ENCOD_3GR)) {\r
1622                 opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding -- Does nothing :-D\n");\r
1623                 /*\r
1624                 gr = golomb_create(tcd->cinfo, tcd->volume, tcd->cp);\r
1625                 l = golomb_decode(gr, tileno, tile, src, len);\r
1626                 golomb_destroy(gr);\r
1627                 if (l == -999) {\r
1628                         eof = 1;\r
1629                         opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n");\r
1630                 }\r
1631                 */\r
1632         } \r
1633 \r
1634         /*----------------DWT---------------------*/\r
1635         fprintf(stdout,"[INFO] Tcd_decode_tile: Inverse DWT\n");\r
1636         dwt_time = opj_clock(); /* time needed to decode a tile */\r
1637         for (compno = 0; compno < tile->numcomps; compno++) {\r
1638                 opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1639                 int stops[3], dwtid[3];\r
1640         \r
1641                 for (i = 0; i < 3; i++) {\r
1642                         if (tcd->cp->reduce[i] != 0) \r
1643                                 tcd->volume->comps[compno].resno_decoded[i] = tile->comps[compno].numresolution[i] - tcd->cp->reduce[i] - 1;\r
1644                         stops[i] = tilec->numresolution[i] - 1 - tcd->volume->comps[compno].resno_decoded[i];\r
1645                         if (stops[i] < 0) stops[i]=0;\r
1646                         dwtid[i] = tcd->cp->tcps->tccps[compno].dwtid[i];\r
1647                 }\r
1648                 \r
1649                 dwt_decode(tilec, stops, dwtid);\r
1650 \r
1651                 for (i = 0; i < 3; i++) {\r
1652                         if (tile->comps[compno].numresolution[i] > 0) {\r
1653                                 tcd->volume->comps[compno].factor[i] = tile->comps[compno].numresolution[i] - (tcd->volume->comps[compno].resno_decoded[i] + 1);\r
1654                                 if ( (tcd->volume->comps[compno].factor[i]) < 0 )\r
1655                                         tcd->volume->comps[compno].factor[i] = 0;\r
1656                         }\r
1657                 }\r
1658         }\r
1659         dwt_time = opj_clock() - dwt_time;\r
1660         #ifdef VERBOSE\r
1661                         opj_event_msg(tcd->cinfo, EVT_INFO, "- dwt took %f s\n", dwt_time);\r
1662         #endif\r
1663 \r
1664         /*----------------MCT-------------------*/\r
1665         \r
1666         if (tcd->tcp->mct) {\r
1667                 if (tcd->tcp->tccps[0].reversible == 1) {\r
1668                         mct_decode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, \r
1669                                 (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) * (tile->comps[0].z1 - tile->comps[0].z0));\r
1670                 } else {\r
1671                         mct_decode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, \r
1672                                 (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0)* (tile->comps[0].z1 - tile->comps[0].z0));\r
1673                 }\r
1674         }\r
1675         \r
1676         /*---------------TILE-------------------*/\r
1677         \r
1678         for (compno = 0; compno < tile->numcomps; compno++) {\r
1679                 opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1680                 opj_tcd_resolution_t *res =     &tilec->resolutions[tcd->volume->comps[compno].resno_decoded[0]];\r
1681                 int adjust;\r
1682                 int minval = tcd->volume->comps[compno].sgnd ? -(1 << (tcd->volume->comps[compno].prec - 1)) : 0;\r
1683                 int maxval = tcd->volume->comps[compno].sgnd ? (1 << (tcd->volume->comps[compno].prec - 1)) - 1 : (1 << tcd->volume->comps[compno].prec) - 1;\r
1684                 \r
1685                 int tw = tilec->x1 - tilec->x0;\r
1686                 int w = tcd->volume->comps[compno].w;\r
1687                 int th = tilec->y1 - tilec->y0;\r
1688                 int h = tcd->volume->comps[compno].h;\r
1689 \r
1690                 int i, j, k;\r
1691                 int offset_x = int_ceildivpow2(tcd->volume->comps[compno].x0, tcd->volume->comps[compno].factor[0]);\r
1692                 int offset_y = int_ceildivpow2(tcd->volume->comps[compno].y0, tcd->volume->comps[compno].factor[1]);\r
1693                 int offset_z = int_ceildivpow2(tcd->volume->comps[compno].z0, tcd->volume->comps[compno].factor[2]);\r
1694                 \r
1695                 if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) {\r
1696                         adjust = 0;\r
1697                 } else {\r
1698             adjust = tcd->volume->comps[compno].sgnd ? 0 : 1 << (tcd->volume->comps[compno].prec - 1); /*sign=='+' --> 2^(prec-1)*/\r
1699                         if (tcd->volume->comps[compno].dcoffset != 0){\r
1700                                 adjust += tcd->volume->comps[compno].dcoffset;\r
1701                                 fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",tcd->volume->comps[compno].dcoffset,adjust);\r
1702                         }\r
1703                 }\r
1704 \r
1705                 for (k = res->z0; k < res->z1; k++) {\r
1706                         for (j = res->y0; j < res->y1; j++) {\r
1707                                 for (i = res->x0; i < res->x1; i++) {\r
1708                                         int v;\r
1709                                         float tmp = (float)((tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th]) / 8192.0);\r
1710 \r
1711                                         if (tcd->tcp->tccps[compno].reversible == 1) {\r
1712                                                 v = tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th];\r
1713                                         } else {\r
1714                                                 int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2);\r
1715                                                 v = ((tmp < 0) ? -tmp2:tmp2);\r
1716                                         }\r
1717                                         v += adjust;\r
1718                                         \r
1719                                         tcd->volume->comps[compno].data[(i - offset_x) + (j - offset_y) * w + (k - offset_z) * w * h] = int_clamp(v, minval, maxval);\r
1720                                 }\r
1721                         }\r
1722                 }\r
1723         }\r
1724         \r
1725         tile_time = opj_clock() - tile_time;    /* time needed to decode a tile */\r
1726         opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time);\r
1727                 \r
1728         for (compno = 0; compno < tile->numcomps; compno++) {\r
1729                 opj_free(tcd->tcd_volume->tiles[tileno].comps[compno].data);\r
1730                 tcd->tcd_volume->tiles[tileno].comps[compno].data = NULL;\r
1731         }\r
1732         \r
1733         if (eof) {\r
1734                 return false;\r
1735         }\r
1736         \r
1737         return true;\r
1738 }\r
1739 \r