fixed lt_version in configure.ac
[openjpeg.git] / libjp3dvm / 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 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                         res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */\r
552 \r
553                         /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */                      \r
554                         if (tccp->csty & J3D_CCP_CSTY_PRT) {\r
555                                 pdx = tccp->prctsiz[0][resno];\r
556                                 pdy = tccp->prctsiz[1][resno];\r
557                                 pdz = tccp->prctsiz[2][resno];\r
558                         } else {\r
559                                 pdx = 15;\r
560                                 pdy = 15;\r
561                                 pdz = 15;\r
562                         }\r
563                         /* p. 66, B.16, ISO/IEC IS15444-1 : 2002  */\r
564                         tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;\r
565                         tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;\r
566                         tlprczstart = int_floordivpow2(res->z0, pdz) << pdz;\r
567                         brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;\r
568                         brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;\r
569                         brprczend = int_ceildivpow2(res->z1, pdz) << pdz;\r
570                         \r
571                         res->prctno[0] = (brprcxend - tlprcxstart) >> pdx;\r
572                         res->prctno[1] = (brprcyend - tlprcystart) >> pdy;\r
573                         res->prctno[2] = (brprczend - tlprczstart) >> pdz;\r
574                         if (res->prctno[2] == 0) res->prctno[2] = 1;\r
575 \r
576                         /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002  */\r
577                         if (resno == 0) {\r
578                                 tlcbgxstart = tlprcxstart;\r
579                                 tlcbgystart = tlprcystart;\r
580                                 tlcbgzstart = tlprczstart;\r
581                                 brcbgxend = brprcxend;\r
582                                 brcbgyend = brprcyend;\r
583                                 brcbgzend = brprczend;\r
584                                 cbgwidthexpn = pdx;\r
585                                 cbgheightexpn = pdy;\r
586                                 cbglengthexpn = pdz;\r
587                         } else {\r
588                                 tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);\r
589                                 tlcbgystart = int_ceildivpow2(tlprcystart, 1);\r
590                                 tlcbgzstart = int_ceildivpow2(tlprczstart, 1);\r
591                                 brcbgxend = int_ceildivpow2(brprcxend, 1);\r
592                                 brcbgyend = int_ceildivpow2(brprcyend, 1);\r
593                                 brcbgzend = int_ceildivpow2(brprczend, 1);\r
594                                 cbgwidthexpn = pdx - 1;\r
595                                 cbgheightexpn = pdy - 1;\r
596                                 cbglengthexpn = pdz - 1;\r
597                         }\r
598                         \r
599                         cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn);\r
600                         cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn);\r
601                         cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn);\r
602                         \r
603                         res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t));\r
604                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
605                                 int x0b, y0b, z0b;\r
606                                 int gain, numbps;\r
607                                 opj_stepsize_t *ss = NULL;\r
608 \r
609                                 tcd->band = &res->bands[bandno];\r
610                                 band = tcd->band;\r
611 \r
612                                 band->bandno = resno == 0 ? 0 : bandno + 1;\r
613                                 /* Bandno:      0 - LLL         2 - LHL \r
614                                                         1 - HLL         3 - HHL\r
615                                                         4 - LLH         6 - LHH\r
616                                                         5 - HLH         7 - HHH         */\r
617                                 x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; \r
618                                 y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;\r
619                                 z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; \r
620                                 \r
621                                 /* p. 65, B.15, ISO/IEC IS15444-1 : 2002  */\r
622                                 if (band->bandno == 0) {\r
623                                         /* band border (global) */\r
624                                         band->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
625                                         band->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
626                                         band->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
627                                         band->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
628                                         band->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
629                                         band->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
630                                 } else {\r
631                                         band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1);\r
632                                         band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1);\r
633                                         band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
634                                         band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1);\r
635                                         band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1);\r
636                                         band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
637                                 }\r
638                                                                 \r
639                                 ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)];\r
640                                 if (bandno == (res->numbands - 1)) \r
641                                         prevnumbands += (resno == 0) ? 0 : res->numbands;\r
642                                 gain = dwt_getgain(band->bandno,tccp->reversible);                                      \r
643                                 numbps = volume->comps[compno].prec + gain;\r
644                                 \r
645                                 band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));\r
646                                 band->numbps = ss->expn + tccp->numgbits - 1;   /* WHY -1 ? */\r
647                                 \r
648                                 for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
649                                         int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend;\r
650 \r
651                                         int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn);\r
652                                         int cbgystart = tlcbgystart + ((precno / (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn);\r
653                                         int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn);\r
654                                         int cbgxend = cbgxstart + (1 << cbgwidthexpn);\r
655                                         int cbgyend = cbgystart + (1 << cbgheightexpn);\r
656                                         int cbgzend = cbgzstart + (1 << cbglengthexpn);\r
657 \r
658                                         /* opj_tcd_precinct_t *prc=&band->precincts[precno]; */\r
659                                         tcd->prc = &band->precincts[precno];\r
660                                         prc = tcd->prc;\r
661 \r
662                                         /* precinct size (global) */\r
663                                         prc->x0 = int_max(cbgxstart, band->x0);\r
664                                         prc->y0 = int_max(cbgystart, band->y0);\r
665                                         prc->z0 = int_max(cbgzstart, band->z0);\r
666                                         prc->x1 = int_min(cbgxend, band->x1);\r
667                                         prc->y1 = int_min(cbgyend, band->y1);\r
668                                         prc->z1 = int_min(cbgzend, band->z1);\r
669 \r
670                                         tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;\r
671                                         tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;\r
672                                         tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn;\r
673                                         brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;\r
674                                         brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;\r
675                                         brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn;\r
676                                         prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;\r
677                                         prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn;\r
678                                         prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn;\r
679                                         prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2];\r
680 \r
681                                         opj_free(prc->cblks);\r
682                                         prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t));\r
683                                         prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
684                                         prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
685 \r
686                                         for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) {\r
687                                                         int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn);\r
688                                                         int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn);\r
689                                                         int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn);\r
690                                                         int cblkxend = cblkxstart + (1 << cblkwidthexpn);\r
691                                                         int cblkyend = cblkystart + (1 << cblkheightexpn);\r
692                                                         int cblkzend = cblkzstart + (1 << cblklengthexpn);\r
693                                                         int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1));\r
694 \r
695                                                         tcd->cblk = &prc->cblks[cblkno];\r
696                                                         cblk = tcd->cblk;\r
697 \r
698                                                         /* code-block size (global) */\r
699                                                         cblk->x0 = int_max(cblkxstart, prc->x0);\r
700                                                         cblk->y0 = int_max(cblkystart, prc->y0);\r
701                                                         cblk->z0 = int_max(cblkzstart, prc->z0);\r
702                                                         cblk->x1 = int_min(cblkxend, prc->x1);\r
703                                                         cblk->y1 = int_min(cblkyend, prc->y1);\r
704                                                         cblk->z1 = int_min(cblkzend, prc->z1);\r
705                                         }\r
706                                 } /* precno */\r
707                         } /* bandno */\r
708                 } /* resno */\r
709         } /* compno */\r
710         //tcd_dump(stdout, tcd, tcd->tcd_volume);\r
711 }\r
712 \r
713 \r
714 void tcd_free_encode(opj_tcd_t *tcd) {\r
715         int tileno, compno, resno, bandno, precno;\r
716 \r
717         opj_tcd_tile_t *tile = NULL;            /* pointer to tcd->tile         */\r
718 //      opj_tcd_slice_t *slice = NULL;          /* pointer to tcd->slice */\r
719         opj_tcd_tilecomp_t *tilec = NULL;       /* pointer to tcd->tilec        */\r
720         opj_tcd_resolution_t *res = NULL;       /* pointer to tcd->res          */\r
721         opj_tcd_band_t *band = NULL;            /* pointer to tcd->band         */\r
722         opj_tcd_precinct_t *prc = NULL;         /* pointer to tcd->prc          */\r
723 \r
724         for (tileno = 0; tileno < 1; tileno++) {\r
725                 tcd->tile = tcd->tcd_volume->tiles;\r
726                 tile = tcd->tile;\r
727 \r
728                 for (compno = 0; compno < tile->numcomps; compno++) {\r
729                         tcd->tilec = &tile->comps[compno];\r
730                         tilec = tcd->tilec;\r
731 \r
732                         for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
733                                 tcd->res = &tilec->resolutions[resno];\r
734                                 res = tcd->res;\r
735 \r
736                                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
737                                         tcd->band = &res->bands[bandno];\r
738                                         band = tcd->band;\r
739 \r
740                                         for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
741                                                 tcd->prc = &band->precincts[precno];\r
742                                                 prc = tcd->prc;\r
743 \r
744                                                 if (prc->incltree != NULL) {\r
745                             tgt_destroy(prc->incltree);\r
746                             prc->incltree = NULL;\r
747                                                 }\r
748                                                 if (prc->imsbtree != NULL) {\r
749                             tgt_destroy(prc->imsbtree);\r
750                             prc->imsbtree = NULL;\r
751                                                 }\r
752                                                 opj_free(prc->cblks);\r
753                                                 prc->cblks = NULL;\r
754                                         } /* for (precno */\r
755                                         opj_free(band->precincts);\r
756                                         band->precincts = NULL;\r
757                                 } /* for (bandno */\r
758                         } /* for (resno */\r
759                         opj_free(tilec->resolutions);\r
760                         tilec->resolutions = NULL;\r
761                 } /* for (compno */\r
762                 opj_free(tile->comps);\r
763                 tile->comps = NULL;\r
764         } /* for (tileno */\r
765         opj_free(tcd->tcd_volume->tiles);\r
766         tcd->tcd_volume->tiles = NULL;\r
767 }\r
768 \r
769 /* ----------------------------------------------------------------------- */\r
770 void tcd_malloc_decode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp) {\r
771         int tileno, compno, resno, bandno, precno, cblkno, res_max,\r
772                 i, j, p, q, r;\r
773         unsigned int x0 = 0, y0 = 0, z0 = 0, \r
774                 x1 = 0, y1 = 0, z1 = 0, \r
775                 w, h, l;\r
776 \r
777         tcd->volume = volume;\r
778         tcd->cp = cp;\r
779         tcd->tcd_volume->tw = cp->tw;\r
780         tcd->tcd_volume->th = cp->th;\r
781         tcd->tcd_volume->tl = cp->tl;\r
782         tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcd_tile_t));\r
783         \r
784         for (i = 0; i < cp->tileno_size; i++) {\r
785                 opj_tcp_t *tcp = &(cp->tcps[cp->tileno[i]]);\r
786                 opj_tcd_tile_t *tile = &(tcd->tcd_volume->tiles[cp->tileno[i]]);\r
787         \r
788                 /* p61 ISO/IEC IS15444-1 : 2002 */\r
789                 /* curtileno --> raster scanned index of tiles */\r
790                 /* p,q,r --> matricial index of tiles */\r
791                 tileno = cp->tileno[i];\r
792                 p = tileno % cp->tw;    \r
793                 q = tileno / cp->tw;    \r
794                 r = tileno / (cp->tw * cp->th); /* extension to 3-D */\r
795 \r
796                 /* 4 borders of the tile rescale on the volume if necessary (B.3)*/\r
797                 tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0);\r
798                 tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0);\r
799                 tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0);\r
800                 tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1);\r
801                 tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1);\r
802                 tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1);\r
803                 tile->numcomps = volume->numcomps;              \r
804                 \r
805                 tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t));\r
806                 for (compno = 0; compno < tile->numcomps; compno++) {\r
807                         opj_tccp_t *tccp = &tcp->tccps[compno];\r
808                         opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
809                         int prevnumbands = 0;\r
810 \r
811                         /* border of each tile component (global) */\r
812                         tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx);\r
813                         tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy);\r
814                         tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz);\r
815                         tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx);\r
816                         tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy);\r
817                         tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz);\r
818                         \r
819                         tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int));\r
820 \r
821                         res_max = 0;\r
822                         for (i = 0;i < 3; i++){\r
823                                 tilec->numresolution[i] = tccp->numresolution[i];\r
824                                 //Greater of 3 resolutions contains all information\r
825                                 res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max;\r
826                         }\r
827 \r
828                         tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t));\r
829 \r
830                         for (resno = 0; resno < res_max; resno++) {\r
831                                 opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
832                                 int pdx, pdy, pdz;\r
833                                 int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend;\r
834                                 int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend;\r
835                                 int cbgwidthexpn, cbgheightexpn, cbglengthexpn;\r
836                                 int cblkwidthexpn, cblkheightexpn, cblklengthexpn;\r
837                                 int levelnox = tilec->numresolution[0] - 1 - resno; \r
838                                 int levelnoy = tilec->numresolution[1] - 1 - resno;\r
839                                 int diff = tccp->numresolution[0] - tccp->numresolution[2]; \r
840                                 int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff));\r
841                                         if (levelnoz < 0) levelnoz = 0;\r
842 \r
843                                 /* border for each resolution level (global) */\r
844                                 res->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
845                                 res->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
846                                 res->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
847                                 res->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
848                                 res->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
849                                 res->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
850                                 res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */\r
851                                 \r
852                                 /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */\r
853                                 if (tccp->csty & J3D_CCP_CSTY_PRT) {\r
854                                         pdx = tccp->prctsiz[0][resno];\r
855                                         pdy = tccp->prctsiz[1][resno];\r
856                                         pdz = tccp->prctsiz[2][resno];\r
857                                 } else {\r
858                                         pdx = 15;\r
859                                         pdy = 15;\r
860                                         pdz = 15;\r
861                                 }\r
862                                 \r
863                                 /* p. 66, B.16, ISO/IEC IS15444-1 : 2002  */\r
864                                 tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx;\r
865                                 tlprcystart = int_floordivpow2(res->y0, pdy) << pdy;\r
866                                 tlprczstart = int_floordivpow2(res->z0, pdz) << pdz;\r
867                                 brprcxend = int_ceildivpow2(res->x1, pdx) << pdx;\r
868                                 brprcyend = int_ceildivpow2(res->y1, pdy) << pdy;\r
869                                 brprczend = int_ceildivpow2(res->z1, pdz) << pdz;\r
870                                 \r
871                                 res->prctno[0] = (brprcxend - tlprcxstart) >> pdx;\r
872                                 res->prctno[1] = (brprcyend - tlprcystart) >> pdy;\r
873                                 res->prctno[2] = (brprczend - tlprczstart) >> pdz;\r
874                                 \r
875                                 /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002  */\r
876                                 if (resno == 0) {\r
877                                         tlcbgxstart = tlprcxstart;//0\r
878                                         tlcbgystart = tlprcystart;\r
879                                         tlcbgzstart = tlprczstart;\r
880                                         brcbgxend = brprcxend;//1\r
881                                         brcbgyend = brprcyend;\r
882                                         brcbgzend = brprczend;\r
883                                         cbgwidthexpn = pdx; //15\r
884                                         cbgheightexpn = pdy;\r
885                                         cbglengthexpn = pdz;\r
886                                 } else {\r
887                                         tlcbgxstart = int_ceildivpow2(tlprcxstart, 1);\r
888                                         tlcbgystart = int_ceildivpow2(tlprcystart, 1);\r
889                                         tlcbgzstart = int_ceildivpow2(tlprczstart, 1);\r
890                                         brcbgxend = int_ceildivpow2(brprcxend, 1);\r
891                                         brcbgyend = int_ceildivpow2(brprcyend, 1);\r
892                                         brcbgzend = int_ceildivpow2(brprczend, 1);\r
893                                         cbgwidthexpn = pdx - 1;\r
894                                         cbgheightexpn = pdy - 1;\r
895                                         cbglengthexpn = pdz - 1;\r
896                                 }\r
897                                 \r
898                                 cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); //6\r
899                                 cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); //6\r
900                                 cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); //6\r
901 \r
902                                 res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t));\r
903                                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
904                                         int x0b, y0b, z0b;\r
905                                         int gain, numbps;\r
906                                         opj_stepsize_t *ss = NULL;\r
907 \r
908                                         opj_tcd_band_t *band = &res->bands[bandno];\r
909                                         band->bandno = resno == 0 ? 0 : bandno + 1;\r
910                                         /* Bandno:      0 - LLL         2 - LHL \r
911                                                                 1 - HLL         3 - HHL\r
912                                                                 4 - LLH         6 - LHH\r
913                                                                 5 - HLH         7 - HHH         */\r
914                                         x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; \r
915                                         y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0;\r
916                                         z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; \r
917                                         \r
918                                         /* p. 65, B.15, ISO/IEC IS15444-1 : 2002  */\r
919                                         if (band->bandno == 0) {\r
920                                                 /* band border (global) */\r
921                                                 band->x0 = int_ceildivpow2(tilec->x0, levelnox);\r
922                                                 band->y0 = int_ceildivpow2(tilec->y0, levelnoy);\r
923                                                 band->z0 = int_ceildivpow2(tilec->z0, levelnoz);\r
924                                                 band->x1 = int_ceildivpow2(tilec->x1, levelnox);\r
925                                                 band->y1 = int_ceildivpow2(tilec->y1, levelnoy);\r
926                                                 band->z1 = int_ceildivpow2(tilec->z1, levelnoz);\r
927                                         } else {\r
928                                                 band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1);\r
929                                                 band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1);\r
930                                                 band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
931                                                 band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1);\r
932                                                 band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1);\r
933                                                 band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1);\r
934                                         }       \r
935 \r
936                                         ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)];\r
937                                         if (bandno == (res->numbands - 1)) \r
938                                                 prevnumbands += (resno == 0) ? 0 : res->numbands;\r
939                                         gain = dwt_getgain(band->bandno,tccp->reversible);                                      \r
940                                         numbps = volume->comps[compno].prec + gain;\r
941 \r
942                                         band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn));\r
943                                         band->numbps = ss->expn + tccp->numgbits - 1;   /* WHY -1 ? */\r
944                                         \r
945                                         band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->prctno[0] * res->prctno[1] * res->prctno[2] * sizeof(opj_tcd_precinct_t));\r
946                                         \r
947                                         for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
948                                                 int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend;\r
949 \r
950                                                 int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn);\r
951                                                 int cbgystart = tlcbgystart + (precno / res->prctno[0]) * (1 << cbgheightexpn);\r
952                                                 int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn);\r
953                                                 int cbgxend = cbgxstart + (1 << cbgwidthexpn);\r
954                                                 int cbgyend = cbgystart + (1 << cbgheightexpn);\r
955                                                 int cbgzend = cbgzstart + (1 << cbglengthexpn);\r
956 \r
957                                                 opj_tcd_precinct_t *prc = &band->precincts[precno];\r
958                                                 /* precinct size (global) */\r
959                                                 prc->x0 = int_max(cbgxstart, band->x0);\r
960                                                 prc->y0 = int_max(cbgystart, band->y0);\r
961                                                 prc->z0 = int_max(cbgzstart, band->z0);\r
962                                                 prc->x1 = int_min(cbgxend, band->x1);\r
963                                                 prc->y1 = int_min(cbgyend, band->y1);\r
964                                                 prc->z1 = int_min(cbgzend, band->z1);\r
965 \r
966                                                 tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn;\r
967                                                 tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn;\r
968                                                 tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn;\r
969                                                 brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn;\r
970                                                 brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn;\r
971                                                 brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn;\r
972                                                 prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn;\r
973                                                 prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn;\r
974                                                 prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn;\r
975                                                 prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2];\r
976 \r
977                                                 prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t));\r
978                                                 prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
979                                                 prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]);\r
980                                                 \r
981                                                 for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
982                                                         int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn);\r
983                                                         int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn);\r
984                                                         int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn);\r
985                                                         int cblkxend = cblkxstart + (1 << cblkwidthexpn);\r
986                                                         int cblkyend = cblkystart + (1 << cblkheightexpn);\r
987                                                         int cblkzend = cblkzstart + (1 << cblklengthexpn);\r
988                                                         int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1));\r
989                                                         /* code-block size (global) */\r
990                                                         opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
991                                                         \r
992                                                         /* code-block size (global) */\r
993                                                         cblk->x0 = int_max(cblkxstart, prc->x0);\r
994                                                         cblk->y0 = int_max(cblkystart, prc->y0);\r
995                                                         cblk->z0 = int_max(cblkzstart, prc->z0);\r
996                                                         cblk->x1 = int_min(cblkxend, prc->x1);\r
997                                                         cblk->y1 = int_min(cblkyend, prc->y1);\r
998                                                         cblk->z1 = int_min(cblkzend, prc->z1);\r
999                                                 }\r
1000                                         } /* precno */\r
1001                                 } /* bandno */\r
1002                         } /* resno */\r
1003                 } /* compno */\r
1004         } /* i = 0..cp->tileno_size */\r
1005 \r
1006         //tcd_dump(stdout, tcd, tcd->tcd_volume);\r
1007 \r
1008         /* \r
1009         Allocate place to store the decoded data = final volume\r
1010         Place limited by the tile really present in the codestream \r
1011         */\r
1012         \r
1013         for (i = 0; i < volume->numcomps; i++) {\r
1014                 for (j = 0; j < cp->tileno_size; j++) {\r
1015                         tileno = cp->tileno[j];\r
1016                         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
1017                         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
1018                         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
1019                         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
1020                         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
1021                         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
1022                 }\r
1023                 \r
1024                 w = x1 - x0;\r
1025                 h = y1 - y0;\r
1026                 l = z1 - z0;\r
1027                 \r
1028                 volume->comps[i].data = (int *) opj_malloc(w * h * l * sizeof(int));\r
1029                 volume->comps[i].w = w;\r
1030                 volume->comps[i].h = h;\r
1031                 volume->comps[i].l = l;\r
1032                 volume->comps[i].x0 = x0;\r
1033                 volume->comps[i].y0 = y0;\r
1034                 volume->comps[i].z0 = z0;\r
1035                 volume->comps[i].bigendian = cp->bigendian;\r
1036         }\r
1037 }\r
1038 \r
1039 void tcd_free_decode(opj_tcd_t *tcd) {\r
1040         int tileno,compno,resno,bandno,precno;\r
1041 \r
1042         opj_tcd_volume_t *tcd_volume = tcd->tcd_volume;\r
1043         \r
1044         for (tileno = 0; tileno < tcd_volume->tw * tcd_volume->th * tcd_volume->tl; tileno++) {\r
1045                 opj_tcd_tile_t *tile = &tcd_volume->tiles[tileno];\r
1046                 for (compno = 0; compno < tile->numcomps; compno++) {\r
1047                         opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1048                         for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
1049                                 opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
1050                                 for (bandno = 0; bandno < res->numbands; bandno++) {\r
1051                                         opj_tcd_band_t *band = &res->bands[bandno];\r
1052                                         for (precno = 0; precno < res->prctno[1] * res->prctno[0] * res->prctno[2]; precno++) {\r
1053                                                 opj_tcd_precinct_t *prec = &band->precincts[precno];\r
1054                                                 if (prec->cblks != NULL) opj_free(prec->cblks);\r
1055                                                 if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree);\r
1056                         if (prec->incltree != NULL) tgt_destroy(prec->incltree);\r
1057                                                 /*for (treeno = 0; treeno < prec->numtrees; treeno++){\r
1058                             if (prec->imsbtree[treeno] != NULL) tgt_destroy(prec->imsbtree[treeno]);\r
1059                             if (prec->incltree[treeno] != NULL) tgt_destroy(prec->incltree[treeno]);\r
1060                                                 }*/\r
1061                                         }\r
1062                                         if (band->precincts != NULL) opj_free(band->precincts);\r
1063                                 }\r
1064                         }\r
1065                         if (tilec->resolutions != NULL) opj_free(tilec->resolutions);\r
1066                 }\r
1067                 if (tile->comps != NULL) opj_free(tile->comps);\r
1068         }\r
1069 \r
1070         if (tcd_volume->tiles != NULL) opj_free(tcd_volume->tiles);\r
1071 }\r
1072 \r
1073 \r
1074 \r
1075 /* ----------------------------------------------------------------------- */\r
1076 void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final) {\r
1077         int compno, resno, bandno, precno, cblkno;\r
1078         int value;                      /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolution[0]][3]; */\r
1079         int matrice[10][10][3];\r
1080         int i, j, k;\r
1081 \r
1082         opj_cp_t *cp = tcd->cp;\r
1083         opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;\r
1084         opj_tcp_t *tcd_tcp = tcd->tcp;\r
1085 \r
1086         /*matrice=(int*)opj_malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolution[0]*3*sizeof(int)); */\r
1087         \r
1088         for (compno = 0; compno < tcd_tile->numcomps; compno++) {\r
1089                 opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];\r
1090                 for (i = 0; i < tcd_tcp->numlayers; i++) {\r
1091                         for (j = 0; j < tilec->numresolution[0]; j++) {\r
1092                                 for (k = 0; k < 3; k++) {\r
1093                                         matrice[i][j][k] =\r
1094                                                 (int) (cp->matrice[i * tilec->numresolution[0] * 3 + j * 3 + k] \r
1095                                                 * (float) (tcd->volume->comps[compno].prec / 16.0));\r
1096                                 }\r
1097                         }\r
1098                 }\r
1099         \r
1100                 for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
1101                         opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
1102                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
1103                                 opj_tcd_band_t *band = &res->bands[bandno];\r
1104                                 for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
1105                                         opj_tcd_precinct_t *prc = &band->precincts[precno];\r
1106                                         for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
1107                                                 opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
1108                                                 opj_tcd_layer_t *layer = &cblk->layers[layno];\r
1109                                                 int n;\r
1110                                                 int imsb = tcd->volume->comps[compno].prec - cblk->numbps;      /* number of bit-plan equal to zero */\r
1111                                                 /* Correction of the matrix of coefficient to include the IMSB information */\r
1112                                                 if (layno == 0) {\r
1113                                                         value = matrice[layno][resno][bandno];\r
1114                                                         if (imsb >= value) {\r
1115                                                                 value = 0;\r
1116                                                         } else {\r
1117                                                                 value -= imsb;\r
1118                                                         }\r
1119                                                 } else {\r
1120                                                         value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno];\r
1121                                                         if (imsb >= matrice[layno - 1][resno][bandno]) {\r
1122                                                                 value -= (imsb - matrice[layno - 1][resno][bandno]);\r
1123                                                                 if (value < 0) {\r
1124                                                                         value = 0;\r
1125                                                                 }\r
1126                                                         }\r
1127                                                 }\r
1128                                                 \r
1129                                                 if (layno == 0) {\r
1130                                                         cblk->numpassesinlayers = 0;\r
1131                                                 }\r
1132                                                 \r
1133                                                 n = cblk->numpassesinlayers;\r
1134                                                 if (cblk->numpassesinlayers == 0) {\r
1135                                                         if (value != 0) {\r
1136                                                                 n = 3 * value - 2 + cblk->numpassesinlayers;\r
1137                                                         } else {\r
1138                                                                 n = cblk->numpassesinlayers;\r
1139                                                         }\r
1140                                                 } else {\r
1141                                                         n = 3 * value + cblk->numpassesinlayers;\r
1142                                                 }\r
1143                                                 \r
1144                                                 layer->numpasses = n - cblk->numpassesinlayers;\r
1145                                                 \r
1146                                                 if (!layer->numpasses)\r
1147                                                         continue;\r
1148                                                 \r
1149                                                 if (cblk->numpassesinlayers == 0) {\r
1150                                                         layer->len = cblk->passes[n - 1].rate;\r
1151                                                         layer->data = cblk->data;\r
1152                                                 } else {\r
1153                                                         layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;\r
1154                                                         layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;\r
1155                                                 }\r
1156                                                 if (final)\r
1157                                                         cblk->numpassesinlayers = n;\r
1158                                         }\r
1159                                 }\r
1160                         }\r
1161                 }\r
1162         }\r
1163 }\r
1164 \r
1165 void tcd_rateallocate_fixed(opj_tcd_t *tcd) {\r
1166         int layno;\r
1167         for (layno = 0; layno < tcd->tcp->numlayers; layno++) {\r
1168                 tcd_makelayer_fixed(tcd, layno, 1);\r
1169         }\r
1170 }\r
1171 \r
1172 void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) {\r
1173         int compno, resno, bandno, precno, cblkno, passno;\r
1174         \r
1175         opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;\r
1176 \r
1177         tcd_tile->distolayer[layno] = 0;        /* fixed_quality */\r
1178         \r
1179         for (compno = 0; compno < tcd_tile->numcomps; compno++) {\r
1180                 opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];\r
1181                 for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
1182                         opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
1183                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
1184                                 opj_tcd_band_t *band = &res->bands[bandno];\r
1185                                 for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
1186                                         opj_tcd_precinct_t *prc = &band->precincts[precno];\r
1187                                         for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
1188                                                 opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
1189                                                 opj_tcd_layer_t *layer = &cblk->layers[layno];\r
1190                                                 \r
1191                                                 int n;\r
1192                                                 if (layno == 0) {\r
1193                                                         cblk->numpassesinlayers = 0;\r
1194                                                 }\r
1195                                                 n = cblk->numpassesinlayers;\r
1196                                                 for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) {\r
1197                                                         int dr;\r
1198                                                         double dd;\r
1199                                                         opj_tcd_pass_t *pass = &cblk->passes[passno];\r
1200                                                         if (n == 0) {\r
1201                                                                 dr = pass->rate;\r
1202                                                                 dd = pass->distortiondec;\r
1203                                                         } else {\r
1204                                                                 dr = pass->rate - cblk->passes[n - 1].rate;\r
1205                                                                 dd = pass->distortiondec - cblk->passes[n - 1].distortiondec;\r
1206                                                         }\r
1207                                                         if (!dr) {\r
1208                                                                 if (dd)\r
1209                                                                         n = passno + 1;\r
1210                                                                 continue;\r
1211                                                         }\r
1212                                                         if (dd / dr >= thresh){\r
1213                                                                 n = passno + 1;\r
1214                                                         }\r
1215                                                 }\r
1216                                                 layer->numpasses = n - cblk->numpassesinlayers;\r
1217                                                 \r
1218                                                 if (!layer->numpasses) {\r
1219                                                         layer->disto = 0;\r
1220                                                         continue;\r
1221                                                 }\r
1222                                                 if (cblk->numpassesinlayers == 0) {\r
1223                                                         layer->len = cblk->passes[n - 1].rate;\r
1224                                                         layer->data = cblk->data;\r
1225                                                         layer->disto = cblk->passes[n - 1].distortiondec;\r
1226                                                 } else {\r
1227                                                         layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate;\r
1228                                                         layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate;\r
1229                                                         layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec;\r
1230                                                 }\r
1231                                                 \r
1232                                                 tcd_tile->distolayer[layno] += layer->disto;    /* fixed_quality */\r
1233                                                 \r
1234                                                 if (final)\r
1235                                                         cblk->numpassesinlayers = n;\r
1236 \r
1237                                         //      fprintf(stdout,"MakeLayer : %d %f %d %d \n",layer->len, layer->disto, layer->numpasses, n);\r
1238                                         }\r
1239                                 }\r
1240                         }\r
1241                 }\r
1242         }\r
1243 }\r
1244 \r
1245 bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_volume_info_t * volume_info) {\r
1246         int compno, resno, bandno, precno, cblkno, passno, layno;\r
1247         double min, max;\r
1248         double cumdisto[100];   /* fixed_quality */\r
1249         const double K = 1;             /* 1.1; // fixed_quality */\r
1250         double maxSE = 0;\r
1251 \r
1252         opj_cp_t *cp = tcd->cp;\r
1253         opj_tcd_tile_t *tcd_tile = tcd->tcd_tile;\r
1254         opj_tcp_t *tcd_tcp = tcd->tcp;\r
1255 \r
1256         min = DBL_MAX;\r
1257         max = 0;\r
1258         \r
1259         tcd_tile->nbpix = 0;            /* fixed_quality */\r
1260         \r
1261         for (compno = 0; compno < tcd_tile->numcomps; compno++) {\r
1262                 opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno];\r
1263                 tilec->nbpix = 0;\r
1264                 for (resno = 0; resno < tilec->numresolution[0]; resno++) {\r
1265                         opj_tcd_resolution_t *res = &tilec->resolutions[resno];\r
1266                         for (bandno = 0; bandno < res->numbands; bandno++) {\r
1267                                 opj_tcd_band_t *band = &res->bands[bandno];\r
1268                                 for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) {\r
1269                                         opj_tcd_precinct_t *prc = &band->precincts[precno];\r
1270                                         for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) {\r
1271                                                 opj_tcd_cblk_t *cblk = &prc->cblks[cblkno];\r
1272                                                 for (passno = 0; passno < cblk->totalpasses; passno++) {\r
1273                                                         opj_tcd_pass_t *pass = &cblk->passes[passno];\r
1274                                                         int dr;\r
1275                                                         double dd, rdslope;\r
1276                                                         if (passno == 0) {\r
1277                                                                 dr = pass->rate;\r
1278                                                                 dd = pass->distortiondec;\r
1279                                                         } else {\r
1280                                                                 dr = pass->rate - cblk->passes[passno - 1].rate;\r
1281                                                                 dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec;\r
1282                                                         }\r
1283                                                         if (dr == 0) {\r
1284                                                                 continue;\r
1285                                                         }\r
1286                                                         rdslope = dd / dr;\r
1287                                                         if (rdslope < min) {\r
1288                                                                 min = rdslope;\r
1289                                                         }\r
1290                                                         if (rdslope > max) {\r
1291                                                                 max = rdslope;\r
1292                                                         }\r
1293 \r
1294                                                 } /* passno */\r
1295                                                 \r
1296                                                 /* fixed_quality */\r
1297                                                 tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0));\r
1298                         tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0));\r
1299                                         } /* cbklno */ \r
1300                                 } /* precno */\r
1301                         } /* bandno */\r
1302                 } /* resno */\r
1303                 \r
1304                 maxSE += (((double)(1 << tcd->volume->comps[compno].prec) - 1.0) \r
1305                         * ((double)(1 << tcd->volume->comps[compno].prec) -1.0)) \r
1306                         * ((double)(tilec->nbpix));\r
1307         } /* compno */\r
1308         \r
1309         /* add antonin index */\r
1310         if(volume_info && volume_info->index_on) {\r
1311                 opj_tile_info_t *info_TL = &volume_info->tile[tcd->tcd_tileno];\r
1312                 info_TL->nbpix = tcd_tile->nbpix;\r
1313                 info_TL->distotile = tcd_tile->distotile;\r
1314                 info_TL->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double));\r
1315         }\r
1316         /* dda */\r
1317         \r
1318         for (layno = 0; layno < tcd_tcp->numlayers; layno++) {\r
1319                 double lo = min;\r
1320                 double hi = max;\r
1321                 int success = 0;\r
1322                 int maxlen = tcd_tcp->rates[layno] ? int_min(((int) tcd_tcp->rates[layno]), len) : len;\r
1323                 double goodthresh;\r
1324                 double distotarget;             /* fixed_quality */\r
1325                 int i = 0;\r
1326                 \r
1327         /* fixed_quality */\r
1328                 distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10));\r
1329         \r
1330                 if ((tcd_tcp->rates[layno]) || (cp->disto_alloc==0)) {\r
1331                         opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->volume, cp);\r
1332                         int oldl = 0, oldoldl = 0;\r
1333                         for (i = 0; i < 128; i++) {\r
1334                                 double thresh = (lo + hi) / 2;\r
1335                                 int l = 0;\r
1336                                 double distoachieved = 0;       /* fixed_quality -q */\r
1337                         \r
1338                                 tcd_makelayer(tcd, layno, thresh, 0);\r
1339                 \r
1340                                 if (cp->fixed_quality) {        /* fixed_quality -q */\r
1341                                         distoachieved = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];\r
1342                                         if (distoachieved < distotarget) {\r
1343                                                 hi = thresh; \r
1344                                                 continue;\r
1345                                         }\r
1346                                         lo = thresh;\r
1347                                 } else {                /* disto_alloc -r, fixed_alloc -f */\r
1348                                         l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, volume_info);\r
1349                                         //fprintf(stdout, "layno %d i %d len=%d max=%d \n",layno,i,l,maxlen);\r
1350                                         if (l == -999) {\r
1351                                                 lo = thresh; \r
1352                                                 continue;\r
1353                                         } else if (l == oldl && oldl == oldoldl && tcd_tile->distolayer[layno] > 0.0 && i>32)\r
1354                                                 break;\r
1355                                         hi = thresh;\r
1356                                         oldoldl = oldl;\r
1357                                         oldl = l;\r
1358                                 }\r
1359                                 success = 1;\r
1360                                 goodthresh = thresh;\r
1361                         } \r
1362                         t2_destroy(t2);\r
1363                 } else {\r
1364                         success = 1;\r
1365                         goodthresh = min;\r
1366                 }\r
1367                 if (!success) {\r
1368                         return false;\r
1369                 }\r
1370                 \r
1371                 if(volume_info && volume_info->index_on) {      /* Threshold for Marcela Index */\r
1372                         volume_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh;\r
1373                 }\r
1374                 tcd_makelayer(tcd, layno, goodthresh, 1);\r
1375                 \r
1376                 /* fixed_quality */\r
1377                 cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno];   \r
1378         }\r
1379 \r
1380         return true;\r
1381 }\r
1382 \r
1383 /* ----------------------------------------------------------------------- */\r
1384 int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_volume_info_t * volume_info) {\r
1385         int compno;\r
1386         int l, i, npck = 0;\r
1387         double encoding_time;\r
1388         \r
1389         opj_tcd_tile_t  *tile = NULL;\r
1390         opj_tcp_t               *tcd_tcp = NULL;\r
1391         opj_cp_t                *cp = NULL;\r
1392 \r
1393         opj_tcp_t               *tcp = &tcd->cp->tcps[0];\r
1394         opj_tccp_t              *tccp = &tcp->tccps[0];\r
1395         opj_volume_t    *volume = tcd->volume;\r
1396         opj_t2_t                *t2 = NULL;             /* T2 component */\r
1397 \r
1398         tcd->tcd_tileno = tileno;                       /* current encoded/decoded tile */\r
1399         \r
1400         tcd->tcd_tile = tcd->tcd_volume->tiles; /* tile information */\r
1401         tile = tcd->tcd_tile;\r
1402         \r
1403         tcd->tcp = &tcd->cp->tcps[tileno];      /* coding/decoding params of tileno */  \r
1404         tcd_tcp = tcd->tcp;\r
1405         \r
1406         cp = tcd->cp;           /* coding parameters */\r
1407 \r
1408         /* INDEX >> */\r
1409         if(volume_info && volume_info->index_on) {\r
1410                 opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0];        /* based on component 0 */\r
1411                 for (i = 0; i < tilec_idx->numresolution[0]; i++) {\r
1412                         opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i];\r
1413 \r
1414                         volume_info->tile[tileno].prctno[0][i] = res_idx->prctno[0];\r
1415                         volume_info->tile[tileno].prctno[1][i] = res_idx->prctno[1];\r
1416                         volume_info->tile[tileno].prctno[2][i] = res_idx->prctno[2];\r
1417 \r
1418                         npck += res_idx->prctno[0] * res_idx->prctno[1] * res_idx->prctno[2];\r
1419 \r
1420                         volume_info->tile[tileno].prctsiz[0][i] = tccp->prctsiz[0][i];\r
1421                         volume_info->tile[tileno].prctsiz[1][i] = tccp->prctsiz[1][i];\r
1422                         volume_info->tile[tileno].prctsiz[2][i] = tccp->prctsiz[2][i];\r
1423                 }\r
1424                 volume_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(volume_info->comp * volume_info->layer * npck * sizeof(opj_packet_info_t));\r
1425         }\r
1426         /* << INDEX */\r
1427         \r
1428         /*---------------TILE-------------------*/\r
1429         encoding_time = opj_clock();    /* time needed to encode a tile */\r
1430         \r
1431         for (compno = 0; compno < tile->numcomps; compno++) {\r
1432                 int x, y, z;\r
1433                 opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1434                 \r
1435                 int adjust;\r
1436                 int offset_x = int_ceildiv(volume->x0, volume->comps[compno].dx); //ceil(x0 / subsampling_dx)\r
1437                 int offset_y = int_ceildiv(volume->y0, volume->comps[compno].dy);\r
1438                 int offset_z = int_ceildiv(volume->z0, volume->comps[compno].dz);\r
1439                 \r
1440                 int tw = tilec->x1 - tilec->x0;\r
1441                 int w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx);\r
1442                 int th = tilec->y1 - tilec->y0;\r
1443                 int h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy);\r
1444                 int tl = tilec->z1 - tilec->z0;\r
1445                 int l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz);\r
1446 \r
1447                 \r
1448                 \r
1449                 /* extract tile data from volume.comps[0].data to tile.comps[0].data */\r
1450                 //fprintf(stdout,"[INFO] Extract tile data\n");\r
1451                 if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) {\r
1452                         adjust = 0;\r
1453                 } else {\r
1454             adjust = volume->comps[compno].sgnd ? 0 : 1 << (volume->comps[compno].prec - 1); //sign=='+' --> 2^(prec-1)\r
1455                         if (volume->comps[compno].dcoffset != 0){\r
1456                                 adjust += volume->comps[compno].dcoffset;\r
1457                                 fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",volume->comps[compno].dcoffset,adjust);\r
1458                         }\r
1459                 }               \r
1460 \r
1461                 if (tcd_tcp->tccps[compno].reversible == 1) { //IF perfect reconstruction (DWT.5-3)\r
1462                         for (z = tilec->z0; z < tilec->z1; z++) {\r
1463                                 for (y = tilec->y0; y < tilec->y1; y++) {\r
1464                                         /* start of the src tile scanline */\r
1465                                         int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h];\r
1466                                         /* start of the dst tile scanline */\r
1467                                         int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th];\r
1468                                         for (x = tilec->x0; x < tilec->x1; x++) {\r
1469                                                 *tile_data++ = *data++ - adjust;\r
1470                                         }\r
1471                                 }\r
1472                         }\r
1473                 } else if (tcd_tcp->tccps[compno].reversible == 0) { //IF not (DWT.9-7)\r
1474                         for (z = tilec->z0; z < tilec->z1; z++) {\r
1475                                 for (y = tilec->y0; y < tilec->y1; y++) {\r
1476                                         /* start of the src tile scanline */\r
1477                                         int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h];\r
1478                                         /* start of the dst tile scanline */\r
1479                                         int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th];\r
1480                                         for (x = tilec->x0; x < tilec->x1; x++) {\r
1481                                                 *tile_data++ = (*data++ - adjust) << 13;\r
1482                                         }\r
1483                                 }\r
1484                         }\r
1485                 }\r
1486         \r
1487         }\r
1488 \r
1489         /*----------------MCT-------------------*/\r
1490         if (tcd_tcp->mct) {\r
1491                 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
1492                 fprintf(stdout,"[INFO] Tcd_encode_tile: mct\n");\r
1493                 if (tcd_tcp->tccps[0].reversible == 0) {\r
1494                         mct_encode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples);\r
1495                 } else {\r
1496                         mct_encode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples);\r
1497                 }\r
1498         }\r
1499         /*----------------TRANSFORM---------------------------------*/\r
1500         fprintf(stdout,"[INFO] Tcd_encode_tile: Transform\n");\r
1501         for (compno = 0; compno < tile->numcomps; compno++) {\r
1502                 opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1503                 dwt_encode(tilec, tcd_tcp->tccps[compno].dwtid);\r
1504         } \r
1505 \r
1506         /*-------------------ENTROPY CODING-----------------------------*/\r
1507         fprintf(stdout,"[INFO] Tcd_encode_tile: Entropy coding\n");\r
1508         if ((cp->encoding_format == ENCOD_2EB)||(cp->encoding_format == ENCOD_3EB))\r
1509         {\r
1510                 if (cp->encoding_format == ENCOD_2EB) {\r
1511                         opj_t1_t *t1 = NULL;\r
1512                         t1 = t1_create(tcd->cinfo);\r
1513                         t1_encode_cblks(t1, tile, tcd_tcp);\r
1514                         t1_destroy(t1); \r
1515                 } else if (cp->encoding_format == ENCOD_3EB) {\r
1516                         opj_t1_3d_t *t1 = NULL;         \r
1517                         t1 = t1_3d_create(tcd->cinfo);\r
1518                         t1_3d_encode_cblks(t1, tile, tcd_tcp);\r
1519                         t1_3d_destroy(t1);      \r
1520                 }\r
1521                 /*-----------RATE-ALLOCATE------------------*/\r
1522                 /* INDEX */\r
1523                 if(volume_info) {\r
1524                         volume_info->index_write = 0;\r
1525                 }\r
1526                 if (cp->disto_alloc || cp->fixed_quality) {     \r
1527                         fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate\n");\r
1528                         tcd_rateallocate(tcd, dest, len, volume_info);                  /* Normal Rate/distortion allocation */\r
1529                 } else {/* fixed_alloc */\r
1530             fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate fixed\n");\r
1531             tcd_rateallocate_fixed(tcd);                                                        /* Fixed layer allocation */\r
1532                 }\r
1533 \r
1534                 /*--------------TIER2------------------*/\r
1535                 /* INDEX */\r
1536                 if(volume_info) {\r
1537                         volume_info->index_write = 1;\r
1538                 }\r
1539                 fprintf(stdout,"[INFO] Tcd_encode_tile: Tier - 2\n");\r
1540         t2 = t2_create(tcd->cinfo, volume, cp);\r
1541                 l = t2_encode_packets(t2, tileno, tile, tcd_tcp->numlayers, dest, len, volume_info);\r
1542         t2_destroy(t2);\r
1543         } else if ((cp->encoding_format == ENCOD_2GR)||(cp->encoding_format == ENCOD_3GR)) {\r
1544                 /*if(volume_info) {\r
1545                         volume_info->index_write = 1;\r
1546                 }\r
1547                 gr = golomb_create(tcd->cinfo, volume, cp);\r
1548                 l = golomb_encode(gr, tileno, tile, dest, len, volume_info);\r
1549                 golomb_destroy(gr);*/\r
1550         }\r
1551 \r
1552         \r
1553         /*---------------CLEAN-------------------*/\r
1554         fprintf(stdout,"[INFO] Tcd_encode_tile: %d bytes coded\n",l);\r
1555         encoding_time = opj_clock() - encoding_time;\r
1556         opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time);\r
1557         \r
1558         /* cleaning memory */\r
1559         for (compno = 0; compno < tile->numcomps; compno++) {\r
1560                 tcd->tilec = &tile->comps[compno];\r
1561                 opj_free(tcd->tilec->data);\r
1562         }\r
1563         \r
1564         if (l == -999){\r
1565                 fprintf(stdout,"[ERROR] Unable to perform T2 tier. Return -999.\n");\r
1566                 return 0;\r
1567         }\r
1568 \r
1569         return l;\r
1570 }\r
1571 \r
1572 \r
1573 bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno) {\r
1574         int l, i;\r
1575         int compno, eof = 0;\r
1576         double tile_time, t1_time, dwt_time;\r
1577 \r
1578         opj_tcd_tile_t *tile = NULL;\r
1579         opj_t2_t *t2 = NULL;            /* T2 component */\r
1580         \r
1581         tcd->tcd_tileno = tileno;\r
1582         tcd->tcd_tile = &(tcd->tcd_volume->tiles[tileno]);\r
1583         tcd->tcp = &(tcd->cp->tcps[tileno]);\r
1584         tile = tcd->tcd_tile;\r
1585         \r
1586         tile_time = opj_clock();        /* time needed to decode a tile */\r
1587         opj_event_msg(tcd->cinfo, EVT_INFO, "tile %d / %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th * tcd->cp->tl);\r
1588 \r
1589         if ((tcd->cp->encoding_format == ENCOD_2EB) || (tcd->cp->encoding_format == ENCOD_3EB)) {\r
1590                 /*--------------TIER2------------------*/\r
1591                 t2 = t2_create(tcd->cinfo, tcd->volume, tcd->cp);\r
1592                 l = t2_decode_packets(t2, src, len, tileno, tile);\r
1593                 t2_destroy(t2);\r
1594                 opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: %d bytes decoded\n",l);\r
1595                 \r
1596                 if (l == -999) {\r
1597                         eof = 1;\r
1598                         opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n");\r
1599                 }\r
1600         \r
1601                 /*------------------TIER1-----------------*/\r
1602                 opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding %d \n",tcd->cp->encoding_format);\r
1603                 t1_time = opj_clock();  /* time needed to decode a tile */\r
1604                 if (tcd->cp->encoding_format == ENCOD_2EB) {\r
1605                         opj_t1_t *t1 = NULL;            /* T1 component */\r
1606                         t1 = t1_create(tcd->cinfo);\r
1607                         t1_decode_cblks(t1, tile, tcd->tcp);\r
1608                         t1_destroy(t1);\r
1609                 }else if (tcd->cp->encoding_format == ENCOD_3EB) {\r
1610                         opj_t1_3d_t *t1 = NULL;         /* T1 component */\r
1611                         t1 = t1_3d_create(tcd->cinfo);\r
1612                         t1_3d_decode_cblks(t1, tile, tcd->tcp);\r
1613                         t1_3d_destroy(t1);\r
1614                 }\r
1615 \r
1616                 t1_time = opj_clock() - t1_time;\r
1617                 #ifdef VERBOSE\r
1618                                 opj_event_msg(tcd->cinfo, EVT_INFO, "- tier-1 took %f s\n", t1_time);\r
1619                 #endif\r
1620         } else if ((tcd->cp->encoding_format == ENCOD_2GR)||(tcd->cp->encoding_format == ENCOD_3GR)) {\r
1621                 opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding -- Does nothing :-D\n");\r
1622                 /*\r
1623                 gr = golomb_create(tcd->cinfo, tcd->volume, tcd->cp);\r
1624                 l = golomb_decode(gr, tileno, tile, src, len);\r
1625                 golomb_destroy(gr);\r
1626                 if (l == -999) {\r
1627                         eof = 1;\r
1628                         opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n");\r
1629                 }\r
1630                 */\r
1631         } \r
1632 \r
1633         /*----------------DWT---------------------*/\r
1634         fprintf(stdout,"[INFO] Tcd_decode_tile: Inverse DWT\n");\r
1635         dwt_time = opj_clock(); /* time needed to decode a tile */\r
1636         for (compno = 0; compno < tile->numcomps; compno++) {\r
1637                 opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1638                 int stops[3], dwtid[3];\r
1639         \r
1640                 for (i = 0; i < 3; i++) {\r
1641                         if (tcd->cp->reduce[i] != 0) \r
1642                                 tcd->volume->comps[compno].resno_decoded[i] = tile->comps[compno].numresolution[i] - tcd->cp->reduce[i] - 1;\r
1643                         stops[i] = tilec->numresolution[i] - 1 - tcd->volume->comps[compno].resno_decoded[i];\r
1644                         if (stops[i] < 0) stops[i]=0;\r
1645                         dwtid[i] = tcd->cp->tcps->tccps[compno].dwtid[i];\r
1646                 }\r
1647                 \r
1648                 dwt_decode(tilec, stops, dwtid);\r
1649 \r
1650                 for (i = 0; i < 3; i++) {\r
1651                         if (tile->comps[compno].numresolution[i] > 0) {\r
1652                                 tcd->volume->comps[compno].factor[i] = tile->comps[compno].numresolution[i] - (tcd->volume->comps[compno].resno_decoded[i] + 1);\r
1653                                 if ( (tcd->volume->comps[compno].factor[i]) < 0 )\r
1654                                         tcd->volume->comps[compno].factor[i] = 0;\r
1655                         }\r
1656                 }\r
1657         }\r
1658         dwt_time = opj_clock() - dwt_time;\r
1659         #ifdef VERBOSE\r
1660                         opj_event_msg(tcd->cinfo, EVT_INFO, "- dwt took %f s\n", dwt_time);\r
1661         #endif\r
1662 \r
1663         /*----------------MCT-------------------*/\r
1664         \r
1665         if (tcd->tcp->mct) {\r
1666                 if (tcd->tcp->tccps[0].reversible == 1) {\r
1667                         mct_decode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, \r
1668                                 (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
1669                 } else {\r
1670                         mct_decode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, \r
1671                                 (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
1672                 }\r
1673         }\r
1674         \r
1675         /*---------------TILE-------------------*/\r
1676         \r
1677         for (compno = 0; compno < tile->numcomps; compno++) {\r
1678                 opj_tcd_tilecomp_t *tilec = &tile->comps[compno];\r
1679                 opj_tcd_resolution_t *res =     &tilec->resolutions[tcd->volume->comps[compno].resno_decoded[0]];\r
1680                 int adjust;\r
1681                 int minval = tcd->volume->comps[compno].sgnd ? -(1 << (tcd->volume->comps[compno].prec - 1)) : 0;\r
1682                 int maxval = tcd->volume->comps[compno].sgnd ? (1 << (tcd->volume->comps[compno].prec - 1)) - 1 : (1 << tcd->volume->comps[compno].prec) - 1;\r
1683                 \r
1684                 int tw = tilec->x1 - tilec->x0;\r
1685                 int w = tcd->volume->comps[compno].w;\r
1686                 int th = tilec->y1 - tilec->y0;\r
1687                 int h = tcd->volume->comps[compno].h;\r
1688 \r
1689                 int i, j, k;\r
1690                 int offset_x = int_ceildivpow2(tcd->volume->comps[compno].x0, tcd->volume->comps[compno].factor[0]);\r
1691                 int offset_y = int_ceildivpow2(tcd->volume->comps[compno].y0, tcd->volume->comps[compno].factor[1]);\r
1692                 int offset_z = int_ceildivpow2(tcd->volume->comps[compno].z0, tcd->volume->comps[compno].factor[2]);\r
1693                 \r
1694                 if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) {\r
1695                         adjust = 0;\r
1696                 } else {\r
1697             adjust = tcd->volume->comps[compno].sgnd ? 0 : 1 << (tcd->volume->comps[compno].prec - 1); //sign=='+' --> 2^(prec-1)\r
1698                         if (tcd->volume->comps[compno].dcoffset != 0){\r
1699                                 adjust += tcd->volume->comps[compno].dcoffset;\r
1700                                 fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",tcd->volume->comps[compno].dcoffset,adjust);\r
1701                         }\r
1702                 }\r
1703 \r
1704                 for (k = res->z0; k < res->z1; k++) {\r
1705                         for (j = res->y0; j < res->y1; j++) {\r
1706                                 for (i = res->x0; i < res->x1; i++) {\r
1707                                         int v;\r
1708                                         float tmp = (float)((tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th]) / 8192.0);\r
1709 \r
1710                                         if (tcd->tcp->tccps[compno].reversible == 1) {\r
1711                                                 v = tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th];\r
1712                                         } else {\r
1713                                                 int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2);\r
1714                                                 v = ((tmp < 0) ? -tmp2:tmp2);\r
1715                                         }\r
1716                                         v += adjust;\r
1717                                         \r
1718                                         tcd->volume->comps[compno].data[(i - offset_x) + (j - offset_y) * w + (k - offset_z) * w * h] = int_clamp(v, minval, maxval);\r
1719                                 }\r
1720                         }\r
1721                 }\r
1722         }\r
1723         \r
1724         tile_time = opj_clock() - tile_time;    /* time needed to decode a tile */\r
1725         opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time);\r
1726                 \r
1727         for (compno = 0; compno < tile->numcomps; compno++) {\r
1728                 opj_free(tcd->tcd_volume->tiles[tileno].comps[compno].data);\r
1729                 tcd->tcd_volume->tiles[tileno].comps[compno].data = NULL;\r
1730         }\r
1731         \r
1732         if (eof) {\r
1733                 return false;\r
1734         }\r
1735         \r
1736         return true;\r
1737 }\r
1738 \r