1 /*
2  * The copyright in this software is being made available under the 2-clauses
3  * BSD License, included below. This software may be subject to other third
4  * party and contributor rights, including patent rights, and no such rights
5  * are granted under this license.
6  *
7  * Copyright (c) 2001-2003, David Janssens
8  * Copyright (c) 2002-2003, Yannick Verschueren
9  * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe
10  * Copyright (c) 2005, Herve Drolon, FreeImage Team
11  * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
12  * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain
13  * All rights reserved.
14  *
15  * Redistribution and use in source and binary forms, with or without
16  * modification, are permitted provided that the following conditions
17  * are met:
18  * 1. Redistributions of source code must retain the above copyright
19  *    notice, this list of conditions and the following disclaimer.
20  * 2. Redistributions in binary form must reproduce the above copyright
21  *    notice, this list of conditions and the following disclaimer in the
22  *    documentation and/or other materials provided with the distribution.
23  *
24  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
25  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
28  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34  * POSSIBILITY OF SUCH DAMAGE.
35  */
36 
37 #include "opj_includes.h"
38 
39 /** @defgroup J3D J3D - JPEG-2000 PART 10 codestream reader/writer */
40 /*@{*/
41 
42 /** @name Funciones locales */
43 /*@{*/
44 
45 /**
46 Write the SOC marker (Start Of Codestream)
47 @param j3d J3D handle
48 */
49 static void j3d_write_soc(opj_j3d_t *j3d);
50 /**
51 Read the SOC marker (Start of Codestream)
52 @param j3d J3D handle
53 */
54 static void j3d_read_soc(opj_j3d_t *j3d);
55 /**
56 Write the SIZ marker (2D volume and tile size)
57 @param j3d J3D handle
58 */
59 static void j3d_write_siz(opj_j3d_t *j3d);
60 /**
61 Read the SIZ marker (2D volume and tile size)
62 @param j3d J3D handle
63 */
64 static void j3d_read_siz(opj_j3d_t *j3d);
65 /**
66 Write the NSI marker (3rd volume and tile size)
67 @param j3d J3D handle
68 */
69 static void j3d_write_nsi(opj_j3d_t *j3d);
70 /**
71 Read the NSI marker (3rd volume and tile size)
72 @param j3d J3D handle
73 */
74 static void j3d_read_nsi(opj_j3d_t *j3d);
75 /**
76 Write the COM marker (comment)
77 @param j3d J3D handle
78 */
79 static void j3d_write_com(opj_j3d_t *j3d);
80 /**
81 Read the COM marker (comment)
82 @param j3d J3D handle
83 */
84 static void j3d_read_com(opj_j3d_t *j3d);
85 /**
86 Write the value concerning the specified component in the marker COD and COC
87 @param j3d J3D handle
88 @param compno Number of the component concerned by the information written
89 */
90 static void j3d_write_cox(opj_j3d_t *j3d, int compno);
91 /**
92 Read the value concerning the specified component in the marker COD and COC
93 @param j3d J3D handle
94 @param compno Number of the component concerned by the information read
95 */
96 static void j3d_read_cox(opj_j3d_t *j3d, int compno);
97 /**
98 Write the COD marker (coding style default)
99 @param j3d J3D handle
100 */
101 static void j3d_write_cod(opj_j3d_t *j3d);
102 /**
103 Read the COD marker (coding style default)
104 @param j3d J3D handle
105 */
106 static void j3d_read_cod(opj_j3d_t *j3d);
107 /**
108 Write the COC marker (coding style component)
109 @param j3d J3D handle
110 @param compno Number of the component concerned by the information written
111 */
112 static void j3d_write_coc(opj_j3d_t *j3d, int compno);
113 /**
114 Read the COC marker (coding style component)
115 @param j3d J3D handle
116 */
117 static void j3d_read_coc(opj_j3d_t *j3d);
118 /**
119 Write the value concerning the specified component in the marker QCD and QCC
120 @param j3d J3D handle
121 @param compno Number of the component concerned by the information written
122 */
123 static void j3d_write_qcx(opj_j3d_t *j3d, int compno);
124 /**
125 Read the value concerning the specified component in the marker QCD and QCC
126 @param j3d J3D handle
127 @param compno Number of the component concern by the information read
128 @param len Length of the information in the QCX part of the marker QCD/QCC
129 */
130 static void j3d_read_qcx(opj_j3d_t *j3d, int compno, int len);
131 /**
132 Write the QCD marker (quantization default)
133 @param j3d J3D handle
134 */
135 static void j3d_write_qcd(opj_j3d_t *j3d);
136 /**
137 Read the QCD marker (quantization default)
138 @param j3d J3D handle
139 */
140 static void j3d_read_qcd(opj_j3d_t *j3d);
141 /**
142 Write the QCC marker (quantization component)
143 @param j3d J3D handle
144 @param compno Number of the component concerned by the information written
145 */
146 static void j3d_write_qcc(opj_j3d_t *j3d, int compno);
147 /**
148 Read the QCC marker (quantization component)
149 @param j3d J3D handle
150 */
151 static void j3d_read_qcc(opj_j3d_t *j3d);
152 /**
153 Write the POC marker (progression order change)
154 @param j3d J3D handle
155 */
156 static void j3d_write_poc(opj_j3d_t *j3d);
157 /**
158 Read the POC marker (progression order change)
159 @param j3d J3D handle
160 */
161 static void j3d_read_poc(opj_j3d_t *j3d);
162 /**
163 Read the CRG marker (component registration)
164 @param j3d J3D handle
165 */
166 static void j3d_read_crg(opj_j3d_t *j3d);
167 /**
168 Read the TLM marker (tile-part lengths)
169 @param j3d J3D handle
170 */
171 static void j3d_read_tlm(opj_j3d_t *j3d);
172 /**
173 Read the PLM marker (packet length, main header)
174 @param j3d J3D handle
175 */
176 static void j3d_read_plm(opj_j3d_t *j3d);
177 /**
178 Read the PLT marker (packet length, tile-part header)
179 @param j3d J3D handle
180 */
181 static void j3d_read_plt(opj_j3d_t *j3d);
182 /**
183 Read the PPM marker (packet packet headers, main header)
184 @param j3d J3D handle
185 */
186 static void j3d_read_ppm(opj_j3d_t *j3d);
187 /**
188 Read the PPT marker (packet packet headers, tile-part header)
189 @param j3d J3D handle
190 */
191 static void j3d_read_ppt(opj_j3d_t *j3d);
192 /**
193 Write the SOT marker (start of tile-part)
194 @param j3d J3D handle
195 */
196 static void j3d_write_sot(opj_j3d_t *j3d);
197 /**
198 Read the SOT marker (start of tile-part)
199 @param j3d J3D handle
200 */
201 static void j3d_read_sot(opj_j3d_t *j3d);
202 /**
203 Write the SOD marker (start of data)
204 @param j3d J3D handle
205 @param tile_coder Pointer to a TCD handle
206 */
207 static void j3d_write_sod(opj_j3d_t *j3d, void *tile_coder);
208 /**
209 Read the SOD marker (start of data)
210 @param j3d J3D handle
211 */
212 static void j3d_read_sod(opj_j3d_t *j3d);
213 /**
214 Write the RGN marker (region-of-interest)
215 @param j3d J3D handle
216 @param compno Number of the component concerned by the information written
217 @param tileno Number of the tile concerned by the information written
218 */
219 static void j3d_write_rgn(opj_j3d_t *j3d, int compno, int tileno);
220 /**
221 Read the RGN marker (region-of-interest)
222 @param j3d J3D handle
223 */
224 static void j3d_read_rgn(opj_j3d_t *j3d);
225 /**
226 Write the EOC marker (end of codestream)
227 @param j3d J3D handle
228 */
229 static void j3d_write_eoc(opj_j3d_t *j3d);
230 /**
231 Read the EOC marker (end of codestream)
232 @param j3d J3D handle
233 */
234 static void j3d_read_eoc(opj_j3d_t *j3d);
235 /**
236 Read an unknown marker
237 @param j3d J3D handle
238 */
239 static void j3d_read_unk(opj_j3d_t *j3d);
240 /**
241 Write the CAP marker (extended capabilities)
242 @param j3d J3D handle
243 */
244 static void j3d_write_cap(opj_j3d_t *j3d);
245 /**
246 Read the CAP marker (extended capabilities)
247 @param j3d J3D handle
248 */
249 static void j3d_read_cap(opj_j3d_t *j3d);
250 /**
251 Write the DCO marker (Variable DC offset)
252 @param j3d J3D handle
253 */
254 static void j3d_write_dco(opj_j3d_t *j3d);
255 /**
256 Read the DCO marker (Variable DC offset)
257 @param j3d J3D handle
258 */
259 static void j3d_read_dco(opj_j3d_t *j3d);
260 /**
261 Write the ATK marker (arbitrary transformation kernel)
262 @param j3d J3D handle
263 */
264 static void j3d_write_atk(opj_j3d_t *j3d);
265 /**
266 Read the ATK marker (arbitrary transformation kernel)
267 @param j3d J3D handle
268 */
269 static void j3d_read_atk(opj_j3d_t *j3d);
270 /**
271 Write the CBD marker (component bit depth definition)
272 @param j3d J3D handle
273 */
274 static void j3d_write_cbd(opj_j3d_t *j3d);
275 /**
276 Read the CBD marker (component bit depth definition)
277 @param j3d J3D handle
278 */
279 static void j3d_read_cbd(opj_j3d_t *j3d);
280 /**
281 Write the MCT marker (multiple component transfomation definition)
282 @param j3d J3D handle
283 */
284 static void j3d_write_mct(opj_j3d_t *j3d);
285 /**
286 Read the MCT marker (multiple component transfomation definition)
287 @param j3d J3D handle
288 */
289 static void j3d_read_mct(opj_j3d_t *j3d);
290 /**
291 Write the MCC marker (multiple component transfomation collection)
292 @param j3d J3D handle
293 */
294 static void j3d_write_mcc(opj_j3d_t *j3d);
295 /**
296 Read the MCC marker (multiple component transfomation collection)
297 @param j3d J3D handle
298 */
299 static void j3d_read_mcc(opj_j3d_t *j3d);
300 /**
301 Write the MCO marker (multiple component transfomation ordering)
302 @param j3d J3D handle
303 */
304 static void j3d_write_mco(opj_j3d_t *j3d);
305 /**
306 Read the MCO marker (multiple component transfomation ordering)
307 @param j3d J3D handle
308 */
309 static void j3d_read_mco(opj_j3d_t *j3d);
310 /**
311 Write the NLT marker (non-linearity point transformation)
312 @param j3d J3D handle
313 */
314 static void j3d_write_nlt(opj_j3d_t *j3d);
315 /**
316 Read the NLT marker (non-linearity point transformation)
317 @param j3d J3D handle
318 */
319 static void j3d_read_nlt(opj_j3d_t *j3d);
320 /*@}*/
321 
322 /* ----------------------------------------------------------------------- */
323 
j3d_dump_volume(FILE * fd,opj_volume_t * vol)324 static void j3d_dump_volume(FILE *fd, opj_volume_t * vol)
325 {
326     int compno;
327     fprintf(fd, "volume {\n");
328     fprintf(fd, "  x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", vol->x0, vol->y0,
329             vol->z0, vol->x1, vol->y1,  vol->z1);
330     fprintf(fd, "  numcomps=%d\n", vol->numcomps);
331     for (compno = 0; compno < vol->numcomps; compno++) {
332         opj_volume_comp_t *comp = &vol->comps[compno];
333         fprintf(fd, "  comp %d {\n", compno);
334         fprintf(fd, "    dx=%d, dy=%d, dz=%d\n", comp->dx, comp->dy, comp->dz);
335         fprintf(fd, "    prec=%d\n", comp->prec);
336         fprintf(fd, "    sgnd=%d\n", comp->sgnd);
337         fprintf(fd, "  }\n");
338     }
339     fprintf(fd, "}\n");
340 }
341 
j3d_dump_cp(FILE * fd,opj_volume_t * vol,opj_cp_t * cp)342 static void j3d_dump_cp(FILE *fd, opj_volume_t * vol, opj_cp_t * cp)
343 {
344     int tileno, compno, layno, bandno, resno, numbands;
345     fprintf(fd, "coding parameters {\n");
346     fprintf(fd, "  tx0=%d, ty0=%d, tz0=%d\n", cp->tx0, cp->ty0, cp->tz0);
347     fprintf(fd, "  tdx=%d, tdy=%d, tdz=%d\n", cp->tdx, cp->tdy, cp->tdz);
348     fprintf(fd, "  tw=%d, th=%d, tl=%d\n", cp->tw, cp->th, cp->tl);
349     fprintf(fd, "  transform format: %d\n", cp->transform_format);
350     fprintf(fd, "  encoding format: %d\n", cp->encoding_format);
351     for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) {
352         opj_tcp_t *tcp = &cp->tcps[tileno];
353         fprintf(fd, "  tile %d {\n", tileno);
354         fprintf(fd, "    csty=%x\n", tcp->csty);
355         fprintf(fd, "    prg=%d\n", tcp->prg);
356         fprintf(fd, "    numlayers=%d\n", tcp->numlayers);
357         fprintf(fd, "    mct=%d\n", tcp->mct);
358         fprintf(fd, "    rates=");
359         for (layno = 0; layno < tcp->numlayers; layno++) {
360             fprintf(fd, "%f ", tcp->rates[layno]);
361         }
362         fprintf(fd, "\n");
363         fprintf(fd, "    first=%d\n", tcp->first);
364         for (compno = 0; compno < vol->numcomps; compno++) {
365             opj_tccp_t *tccp = &tcp->tccps[compno];
366             fprintf(fd, "    comp %d {\n", compno);
367             fprintf(fd, "      csty=%x\n", tccp->csty);
368             fprintf(fd, "      numresx=%d, numresy=%d, numresz=%d\n",
369                     tccp->numresolution[0], tccp->numresolution[1], tccp->numresolution[2]);
370             fprintf(fd, "      cblkw=%d, cblkh=%d, cblkl=%d\n", tccp->cblk[0],
371                     tccp->cblk[1], tccp->cblk[2]);
372             fprintf(fd, "      cblksty=%x\n", tccp->cblksty);
373             fprintf(fd, "      qntsty=%d\n", tccp->qntsty);
374             fprintf(fd, "      numgbits=%d\n", tccp->numgbits);
375             fprintf(fd, "      roishift=%d\n", tccp->roishift);
376             fprintf(fd, "      reversible=%d\n", tccp->reversible);
377             fprintf(fd, "      dwtidx=%d dwtidy=%d dwtidz=%d\n", tccp->dwtid[0],
378                     tccp->dwtid[1], tccp->dwtid[2]);
379             if (tccp->atk != NULL) {
380                 fprintf(fd, "      atk.index=%d\n", tccp->atk->index);
381                 fprintf(fd, "      atk.coeff_typ=%d\n", tccp->atk->coeff_typ);
382                 fprintf(fd, "      atk.filt_cat=%d\n", tccp->atk->filt_cat);
383                 fprintf(fd, "      atk.exten=%d\n", tccp->atk->exten);
384                 fprintf(fd, "      atk.minit=%d\n", tccp->atk->minit);
385                 fprintf(fd, "      atk.wt_typ=%d\n", tccp->atk->wt_typ);
386             }
387             fprintf(fd, "      stepsizes of bands=");
388             numbands = (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) ? 1 :
389                        ((cp->transform_format == TRF_2D_DWT) ? (tccp->numresolution[0] * 3 - 2) :
390                         (tccp->numresolution[0] * 7 - 6) - 4 * (tccp->numresolution[0] -
391                                 tccp->numresolution[2]));
392             for (bandno = 0; bandno < numbands; bandno++) {
393                 fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant,
394                         tccp->stepsizes[bandno].expn);
395             }
396             fprintf(fd, "\n");
397 
398             if (tccp->csty & J3D_CCP_CSTY_PRT) {
399                 fprintf(fd, "      prcw=");
400                 for (resno = 0; resno < tccp->numresolution[0]; resno++) {
401                     fprintf(fd, "%d ", tccp->prctsiz[0][resno]);
402                 }
403                 fprintf(fd, "\n");
404                 fprintf(fd, "      prch=");
405                 for (resno = 0; resno < tccp->numresolution[0]; resno++) {
406                     fprintf(fd, "%d ", tccp->prctsiz[1][resno]);
407                 }
408                 fprintf(fd, "\n");
409                 fprintf(fd, "      prcl=");
410                 for (resno = 0; resno < tccp->numresolution[0]; resno++) {
411                     fprintf(fd, "%d ", tccp->prctsiz[2][resno]);
412                 }
413                 fprintf(fd, "\n");
414             }
415             fprintf(fd, "    }\n");
416         }
417         fprintf(fd, "  }\n");
418     }
419     fprintf(fd, "}\n");
420 }
421 
422 /* -----------------------------------------------------------------------
423 Extended capabilities
424 ------------------------------------------------------------------------*/
425 
j3d_write_cap(opj_j3d_t * j3d)426 static void j3d_write_cap(opj_j3d_t *j3d)
427 {
428     int len, lenp;
429 
430     opj_cio_t *cio = j3d->cio;
431     cio_write(cio, J3D_MS_CAP, 2);  /* CAP */
432     lenp = cio_tell(cio);
433     cio_skip(cio, 2);
434     cio_write(cio, J3D_CAP_10, 4);
435     if (J3D_CAP_10) {
436         cio_write(cio, 0x0, 2);
437     }
438     len = cio_tell(cio) - lenp;
439     cio_seek(cio, lenp);
440     cio_write(cio, len, 2);     /* Lsiz */
441     cio_seek(cio, lenp + len);
442 
443 }
j3d_read_cap(opj_j3d_t * j3d)444 static void j3d_read_cap(opj_j3d_t *j3d)
445 {
446     int len, Cap;
447     opj_cio_t *cio = j3d->cio;
448     /*cio_read(cio, 2);  CAP */
449     len = cio_read(cio, 2);
450     Cap = cio_read(cio, 4);
451     if (Cap) {
452         cio_read(cio, 2);
453     }
454     assert(len == 2 + 4 + 2);
455 }
j3d_write_nsi(opj_j3d_t * j3d)456 static void j3d_write_nsi(opj_j3d_t *j3d)
457 {
458     int i;
459     int lenp, len;
460     int ndim = 3;
461 
462     opj_cio_t *cio = j3d->cio;
463     opj_volume_t *volume = j3d->volume;
464     opj_cp_t *cp = j3d->cp;
465 
466     cio_write(cio, J3D_MS_NSI, 2);  /* NSI */
467     lenp = cio_tell(cio);
468     cio_skip(cio, 2);
469     cio_write(cio, ndim, 1);    /* Ndim */
470     cio_write(cio, volume->z1, 4);  /* Zsiz */
471     cio_write(cio, volume->z0, 4);  /* Z0siz */
472     cio_write(cio, cp->tdz, 4);     /* ZTsiz */
473     cio_write(cio, cp->tz0, 4);     /* ZT0siz */
474     for (i = 0; i < volume->numcomps; i++) {
475         cio_write(cio, volume->comps[i].dz, 1); /* ZRsiz_i */
476     }
477     len = cio_tell(cio) - lenp;
478     cio_seek(cio, lenp);
479     cio_write(cio, len, 2);     /* Lsiz */
480     cio_seek(cio, lenp + len);
481 }
482 
j3d_read_nsi(opj_j3d_t * j3d)483 static void j3d_read_nsi(opj_j3d_t *j3d)
484 {
485     int ndim;
486     int len, i;
487 
488     opj_cio_t *cio = j3d->cio;
489     opj_volume_t *volume = j3d->volume;
490     opj_cp_t *cp = j3d->cp;
491 
492     len = cio_read(cio, 2);         /* Lnsi */
493     ndim = cio_read(cio, 1);            /* Ndim */
494     assert(ndim == 3);
495     volume->z1 = cio_read(cio, 4);  /* Zsiz */
496     volume->z0 = cio_read(cio, 4);  /* Z0siz */
497     cp->tdz = cio_read(cio, 4);     /* ZTsiz */
498     cp->tz0 = cio_read(cio, 4);     /* ZT0siz */
499     for (i = 0; i < volume->numcomps; i++) {
500         volume->comps[i].dz = cio_read(cio, 1); /* ZRsiz_i */
501     }
502 
503     /*Initialization of volume*/
504     cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx);
505     cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy);
506     cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz);
507     cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(
508                                             opj_tcp_t));
509     cp->tileno = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int));
510     cp->tileno_size = 0;
511 
512     for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) {
513         cp->tcps[i].POC = 0;
514         cp->tcps[i].numpocs = 0;
515         cp->tcps[i].first = 1;
516     }
517 
518     /* Initialization for PPM marker (Packets header)*/
519     cp->ppm = 0;
520     cp->ppm_data = NULL;
521     cp->ppm_data_first = NULL;
522     cp->ppm_previous = 0;
523     cp->ppm_store = 0;
524 
525     j3d->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(
526                                   opj_tccp_t) * volume->numcomps);
527     for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) {
528         cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) *
529                             volume->numcomps);
530     }
531     j3d->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * cp->tl *
532                      sizeof(unsigned char *));
533     j3d->tile_len = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int));
534     j3d->state = J3D_STATE_MH;
535 
536 }
j3d_write_dco(opj_j3d_t * j3d)537 static void j3d_write_dco(opj_j3d_t *j3d)
538 {
539     int lenp, len, i;
540     int dcotype;
541 
542     opj_cio_t *cio = j3d->cio;
543     opj_volume_t *volume = j3d->volume;
544     opj_cp_t *cp = j3d->cp;
545 
546     dcotype = 1; /* Offsets are 16bit signed integers Table A21 15444-2 */
547     cio_write(cio, J3D_MS_DCO, 2);  /* DCO */
548     lenp = cio_tell(cio);
549     cio_skip(cio, 2);
550     cio_write(cio, dcotype, 1);
551     if (dcotype == 0) {
552         for (i = 0; i < volume->numcomps; i++) {
553             cio_write(cio, volume->comps[i].dcoffset, 1);    /* SPdco_i */
554         }
555     } else if (dcotype == 1) {
556         for (i = 0; i < volume->numcomps; i++) {
557             cio_write(cio, volume->comps[i].dcoffset, 1);   /* SPdco_i */
558             opj_event_msg(j3d->cinfo, EVT_INFO, "dcotype %d DCO %d \n", dcotype,
559                           volume->comps[i].dcoffset);
560         }
561     }
562     len = cio_tell(cio) - lenp;
563     cio_seek(cio, lenp);
564     cio_write(cio, len, 2);     /* Ldco */
565     cio_seek(cio, lenp + len);
566 
567 }
j3d_read_dco(opj_j3d_t * j3d)568 static void j3d_read_dco(opj_j3d_t *j3d)
569 {
570     int len, i;
571     int dcotype;
572 
573     opj_cio_t *cio = j3d->cio;
574     opj_volume_t *volume = j3d->volume;
575     opj_cp_t *cp = j3d->cp;
576 
577     len = cio_read(cio, 2);         /* Lsiz */
578     dcotype = cio_read(cio, 1); /*offset 8bit unsigned / 16bit signed integers*/
579     if (dcotype == 0) {
580         for (i = 0; i < volume->numcomps; i++) {
581             volume->comps[i].dcoffset = cio_read(cio, 1);
582             if (volume->comps[i].dcoffset > 128) {
583                 volume->comps[i].dcoffset = volume->comps[i].dcoffset - 256;
584             }
585         }
586     } else if (dcotype == 1) {
587         for (i = 0; i < volume->numcomps; i++) {
588             volume->comps[i].dcoffset = cio_read(cio, 1);
589             if (volume->comps[i].dcoffset > 128) {
590                 volume->comps[i].dcoffset = volume->comps[i].dcoffset - 256;
591             }
592         }
593     }
594 
595 }
j3d_write_atk(opj_j3d_t * j3d)596 static void j3d_write_atk(opj_j3d_t *j3d)
597 {
598     int lenp, len, s, k;
599 
600     opj_cio_t *cio = j3d->cio;
601     opj_volume_t *volume = j3d->volume;
602     opj_atk_t *atk = j3d->cp->tcps->tccps->atk;
603 
604     cio_write(cio, J3D_MS_ATK, 2);  /* ATK */
605     lenp = cio_tell(cio);
606     cio_skip(cio, 2);
607     cio_write(cio, atk->index + (atk->coeff_typ << 8) + (atk->filt_cat << 11)
608               + (atk->wt_typ << 12) + (atk->minit << 13) + (atk->exten << 14),
609               2);            /* Satk */
610     if (atk->wt_typ == J3D_ATK_IRR) {
611         cio_write(cio, (unsigned int)(atk->Katk * 8192.0), 1 << atk->coeff_typ);
612     }
613     cio_write(cio, atk->Natk, 1);
614     for (s = 0; s < atk->Natk; s++) {
615         if (atk->filt_cat == J3D_ATK_ARB) {
616             cio_write(cio, atk->Oatk[s], 1);
617         }
618         if (atk->wt_typ == J3D_ATK_REV) {
619             cio_write(cio, atk->Eatk[s], 1);
620             cio_write(cio, atk->Batk[s], 1);
621         }
622         cio_write(cio, atk->LCatk[s], 1);
623         for (k = 0; k < atk->LCatk[s]; k++) {
624             cio_write(cio, (unsigned int)(atk->Aatk[s][k] * 8192.0), 1 << atk->coeff_typ);
625         }
626     }
627     len = cio_tell(cio) - lenp;
628     cio_seek(cio, lenp);
629     cio_write(cio, len, 2);     /* Latk */
630     cio_seek(cio, lenp + len);
631 }
j3d_read_atk(opj_j3d_t * j3d)632 static void j3d_read_atk(opj_j3d_t *j3d)
633 {
634     int len, i, Satk, k;
635 
636     opj_cio_t *cio = j3d->cio;
637     opj_volume_t *volume = j3d->volume;
638     opj_cp_t *cp = j3d->cp;
639     opj_atk_t *atk = cp->tcps->tccps->atk;
640 
641     len = cio_read(cio, 2);         /* Latk */
642     Satk = cio_read(cio, 2);
643     atk->index = Satk & 0x00ff;
644     atk->coeff_typ = Satk >> 8 & 0x0007;
645     atk->filt_cat = Satk >> 11 & 0x0001;
646     atk->wt_typ = Satk >> 12  & 0x0001;
647     atk->minit = Satk >> 13 & 0x0001;
648     atk->exten = Satk >> 14 & 0x0001;
649     if (atk->wt_typ == J3D_ATK_IRR) {
650         atk->Katk = ((double) cio_read(cio, 1 << atk->coeff_typ) / 8192.0);
651     }
652     atk->Natk = cio_read(cio, 1);
653     for (i = 0; i < atk->Natk; i++) {
654         if (atk->filt_cat == J3D_ATK_ARB) {
655             atk->Oatk[i] = cio_read(cio, 1);
656         }
657         if (atk->wt_typ == J3D_ATK_REV) {
658             atk->Eatk[i] = cio_read(cio, 1);
659             atk->Batk[i] = cio_read(cio, 1);
660         }
661         atk->LCatk[i] = cio_read(cio, 1);
662         for (k = 0; k < atk->LCatk[i]; k++) {
663             atk->Aatk[i][k] = ((double) cio_read(cio, 1 << atk->coeff_typ) / 8192.0);
664         }
665     }
666 }
j3d_write_cbd(opj_j3d_t * j3d)667 static void j3d_write_cbd(opj_j3d_t *j3d)
668 {
669 }
j3d_read_cbd(opj_j3d_t * j3d)670 static void j3d_read_cbd(opj_j3d_t *j3d)
671 {
672 }
j3d_write_mct(opj_j3d_t * j3d)673 static void j3d_write_mct(opj_j3d_t *j3d)
674 {
675 }
j3d_read_mct(opj_j3d_t * j3d)676 static void j3d_read_mct(opj_j3d_t *j3d)
677 {
678 }
j3d_write_mcc(opj_j3d_t * j3d)679 static void j3d_write_mcc(opj_j3d_t *j3d)
680 {
681 }
j3d_read_mcc(opj_j3d_t * j3d)682 static void j3d_read_mcc(opj_j3d_t *j3d)
683 {
684 }
j3d_write_mco(opj_j3d_t * j3d)685 static void j3d_write_mco(opj_j3d_t *j3d)
686 {
687 }
j3d_read_mco(opj_j3d_t * j3d)688 static void j3d_read_mco(opj_j3d_t *j3d)
689 {
690 }
j3d_write_nlt(opj_j3d_t * j3d)691 static void j3d_write_nlt(opj_j3d_t *j3d)
692 {
693 }
j3d_read_nlt(opj_j3d_t * j3d)694 static void j3d_read_nlt(opj_j3d_t *j3d)
695 {
696 }
697 /* -----------------------------------------------------------------------
698 15444-1 codestream syntax
699 ------------------------------------------------------------------------*/
j3d_write_soc(opj_j3d_t * j3d)700 static void j3d_write_soc(opj_j3d_t *j3d)
701 {
702     opj_cio_t *cio = j3d->cio;
703     cio_write(cio, J3D_MS_SOC, 2);
704 }
705 
j3d_read_soc(opj_j3d_t * j3d)706 static void j3d_read_soc(opj_j3d_t *j3d)
707 {
708     j3d->state = J3D_STATE_MHSIZ;
709 }
710 
j3d_write_siz(opj_j3d_t * j3d)711 static void j3d_write_siz(opj_j3d_t *j3d)
712 {
713     int i;
714     int lenp, len;
715     int Rsiz;
716 
717     opj_cio_t *cio = j3d->cio;
718     opj_volume_t *volume = j3d->volume;
719     opj_cp_t *cp = j3d->cp;
720 
721     cio_write(cio, J3D_MS_SIZ, 2);  /* SIZ */
722     lenp = cio_tell(cio);
723     cio_skip(cio, 2);
724     /*cio_write(cio, 0, 2);*/           /* Rsiz (capabilities of 15444-1 only) */
725     Rsiz = J3D_RSIZ_DCO |
726            J3D_RSIZ_ATK; /** | J3D_RSIZ_MCT | J3D_RSIZ_NONLT (not implemented yet)*/
727     cio_write(cio, Rsiz, 2); /* capabilities of WDv5.2*/
728     cio_write(cio, volume->x1, 4);  /* Xsiz */
729     cio_write(cio, volume->y1, 4);  /* Ysiz */
730     cio_write(cio, volume->x0, 4);  /* X0siz */
731     cio_write(cio, volume->y0, 4);  /* Y0siz */
732     cio_write(cio, cp->tdx, 4);     /* XTsiz */
733     cio_write(cio, cp->tdy, 4);     /* YTsiz */
734     cio_write(cio, cp->tx0, 4);     /* XT0siz */
735     cio_write(cio, cp->ty0, 4);     /* YT0siz */
736     cio_write(cio, volume->numcomps, 2);    /* Csiz */
737     for (i = 0; i < volume->numcomps; i++) {
738         cio_write(cio, volume->comps[i].prec - 1 + (volume->comps[i].sgnd << 7),
739                   1);    /* Ssiz_i */
740         cio_write(cio, volume->comps[i].dx, 1); /* XRsiz_i */
741         cio_write(cio, volume->comps[i].dy, 1); /* YRsiz_i */
742     }
743     len = cio_tell(cio) - lenp;
744     cio_seek(cio, lenp);
745     cio_write(cio, len, 2);     /* Lsiz */
746     cio_seek(cio, lenp + len);
747 }
748 
j3d_read_siz(opj_j3d_t * j3d)749 static void j3d_read_siz(opj_j3d_t *j3d)
750 {
751     int len, i;
752 
753     opj_cio_t *cio = j3d->cio;
754     opj_volume_t *volume = j3d->volume;
755     opj_cp_t *cp = j3d->cp;
756 
757     len = cio_read(cio, 2);         /* Lsiz */
758     cp->rsiz = cio_read(cio, 2);    /* Rsiz (capabilities) */
759     volume->x1 = cio_read(cio, 4);  /* Xsiz */
760     volume->y1 = cio_read(cio, 4);  /* Ysiz */
761     volume->x0 = cio_read(cio, 4);  /* X0siz */
762     volume->y0 = cio_read(cio, 4);  /* Y0siz */
763     cp->tdx = cio_read(cio, 4);     /* XTsiz */
764     cp->tdy = cio_read(cio, 4);     /* YTsiz */
765     cp->tx0 = cio_read(cio, 4);     /* XT0siz */
766     cp->ty0 = cio_read(cio, 4);     /* YT0siz */
767 
768     volume->numcomps = cio_read(cio, 2);    /* Csiz */
769     volume->comps = (opj_volume_comp_t *) opj_malloc(volume->numcomps * sizeof(
770                         opj_volume_comp_t));
771     for (i = 0; i < volume->numcomps; i++) {
772         int tmp, j;
773         tmp = cio_read(cio, 1);     /* Ssiz_i */
774         volume->comps[i].prec = (tmp & 0x7f) + 1;
775         volume->comps[i].sgnd = tmp >> 7;
776         volume->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */
777         volume->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */
778         for (j = 0; j < 3; j++) {
779             volume->comps[i].resno_decoded[j] = 0;      /* number of resolution decoded */
780             volume->comps[i].factor[j] = 0;     /* reducing factor per component */
781         }
782     }
783 
784     if (j3d->cinfo->codec_format == CODEC_J2K) {
785         volume->z1 = 1;
786         volume->z0 = 0;
787         volume->numslices = 1;
788         cp->tdz = 1;
789         cp->tz0 = 0;
790         for (i = 0; i < volume->numcomps; i++) {
791             volume->comps[i].dz = 1;
792         }
793 
794         /*Initialization of volume*/
795         cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx);
796         cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy);
797         cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz);
798         cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(
799                                                 opj_tcp_t));
800         cp->tileno = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int));
801         cp->tileno_size = 0;
802 
803         for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) {
804             cp->tcps[i].POC = 0;
805             cp->tcps[i].numpocs = 0;
806             cp->tcps[i].first = 1;
807         }
808 
809         /* Initialization for PPM marker (Packets header)*/
810         cp->ppm = 0;
811         cp->ppm_data = NULL;
812         cp->ppm_data_first = NULL;
813         cp->ppm_previous = 0;
814         cp->ppm_store = 0;
815 
816         j3d->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(
817                                       opj_tccp_t) * volume->numcomps);
818         for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) {
819             cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) *
820                                 volume->numcomps);
821         }
822         j3d->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * cp->tl *
823                          sizeof(unsigned char *));
824         j3d->tile_len = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int));
825         j3d->state = J3D_STATE_MH;
826     }
827 }
828 
829 
830 
j3d_write_com(opj_j3d_t * j3d)831 static void j3d_write_com(opj_j3d_t *j3d)
832 {
833     unsigned int i;
834     int lenp, len;
835 
836     opj_cio_t *cio = j3d->cio;
837 
838     cio_write(cio, J3D_MS_COM, 2);
839     lenp = cio_tell(cio);
840     cio_skip(cio, 2);
841     cio_write(cio, 1, 2);
842     /*opj_event_msg(j3d->cinfo, EVT_INFO, "TRF %D ENCOD %d\n",j3d->cp->transform_format,j3d->cp->encoding_format);*/
843     if (j3d->cp->comment != NULL) {
844         char *comment = j3d->cp->comment;
845         for (i = 0; i < strlen(comment); i++) {
846             cio_write(cio, comment[i], 1);
847         }
848     }
849     len = cio_tell(cio) - lenp;
850     cio_seek(cio, lenp);
851     cio_write(cio, len, 2);
852     cio_seek(cio, lenp + len);
853 }
854 
j3d_read_com(opj_j3d_t * j3d)855 static void j3d_read_com(opj_j3d_t *j3d)
856 {
857     int len;
858     opj_cio_t *cio = j3d->cio;
859 
860     len = cio_read(cio, 2);
861     cio_read(cio, 2); // read registration
862 
863     /*opj_event_msg(j3d->cinfo, EVT_INFO, "TRF %D ENCOD %d\n",j3d->cp->transform_format,j3d->cp->encoding_format);*/
864 
865     cio_skip(cio, len - 4);  /*possible comments*/
866 }
867 
j3d_write_cox(opj_j3d_t * j3d,int compno)868 static void j3d_write_cox(opj_j3d_t *j3d, int compno)
869 {
870     int i;
871     int shift = 2;
872 
873     opj_cp_t *cp = j3d->cp;
874     opj_tcp_t *tcp = &cp->tcps[j3d->curtileno];
875     opj_tccp_t *tccp = &tcp->tccps[compno];
876     opj_cio_t *cio = j3d->cio;
877 
878     cio_write(cio, tccp->numresolution[0] - 1,
879               1);  /* SPcox (D) No of decomposition levels in x-axis*/
880     if (j3d->cinfo->codec_format == CODEC_J3D) {
881         cio_write(cio, tccp->numresolution[1] - 1,
882                   1);  /* SPcox (E) No of decomposition levels in y-axis*/
883         cio_write(cio, tccp->numresolution[2] - 1,
884                   1);  /* SPcox (F) No of decomposition levels in z-axis*/
885     }
886     if (j3d->cinfo->codec_format == CODEC_J3D) {
887         /* Table A.7 */
888         shift = 0;
889     }
890     /* (cblkw - 2) + (cblkh - 2) + (cblkl - 2) <= 18*/
891     cio_write(cio, tccp->cblk[0] - shift,
892               1);               /* SPcox (G) Cblk width entre 10 y 2 (8 y 0)*/
893     cio_write(cio, tccp->cblk[1] - shift,
894               1);               /* SPcox (H) Cblk height*/
895     if (j3d->cinfo->codec_format == CODEC_J3D) {
896         cio_write(cio, tccp->cblk[2] - shift, 1);           /* SPcox (I) Cblk depth*/
897     }
898     cio_write(cio, tccp->cblksty, 1);               /* SPcox (J) Cblk style*/
899     cio_write(cio, tccp->dwtid[0],
900               1);              /* SPcox (K) WT in x-axis 15444-2 Table A10*/
901     if (j3d->cinfo->codec_format == CODEC_J3D) {
902         cio_write(cio, tccp->dwtid[1],
903                   1);              /* SPcox (L) WT in y-axis 15444-2 Table A10*/
904         cio_write(cio, tccp->dwtid[2],
905                   1);              /* SPcox (M) WT in z-axis 15444-2 Table A10*/
906     }
907 
908     if (tccp->csty & J3D_CCP_CSTY_PRT) {
909         for (i = 0; i < tccp->numresolution[0]; i++) {
910             if (i < tccp->numresolution[2]) {
911                 cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4) +
912                           (tccp->prctsiz[2][i] << 8), 2);    /* SPcox (N_i) Table A9*/
913             } else if (j3d->cinfo->codec_format == CODEC_J3D) {
914                 cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4),
915                           2);    /* SPcox (N_i) Table A9*/
916             } else {
917                 cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4), 1);
918             }    /* SPcox (N_i) Table A9*/
919         }
920     }
921 }
922 
j3d_read_cox(opj_j3d_t * j3d,int compno)923 static void j3d_read_cox(opj_j3d_t *j3d, int compno)
924 {
925     int i;
926     int shift = 2;
927 
928     opj_cp_t *cp = j3d->cp;
929     opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] :
930                      j3d->default_tcp;
931     opj_tccp_t *tccp = &tcp->tccps[compno];
932     opj_cio_t *cio = j3d->cio;
933 
934     tccp->numresolution[0] = cio_read(cio,
935                                       1) + 1;  /* SPcox (D) No of decomposition levels in x-axis*/
936     if (j3d->cinfo->codec_format == CODEC_J3D) {
937         tccp->numresolution[1] = cio_read(cio,
938                                           1) + 1;  /* SPcox (E) No of decomposition levels in y-axis*/
939         tccp->numresolution[2] = cio_read(cio,
940                                           1) + 1;  /* SPcox (F) No of decomposition levels in z-axis*/
941     } else if (j3d->cinfo->codec_format == CODEC_J2K) {
942         tccp->numresolution[1] = tccp->numresolution[0];
943         tccp->numresolution[2] = 1;
944     }
945     /* check the reduce value */
946     cp->reduce[0] = int_min((tccp->numresolution[0]) - 1, cp->reduce[0]);
947     cp->reduce[1] = int_min((tccp->numresolution[1]) - 1, cp->reduce[1]);
948     cp->reduce[2] = int_min((tccp->numresolution[2]) - 1, cp->reduce[2]);
949 
950     if (j3d->cinfo->codec_format == CODEC_J3D) {
951         /* Table A.7 */
952         shift = 0;
953     }
954     tccp->cblk[0] = cio_read(cio, 1) + shift;   /* SPcox (G) */
955     tccp->cblk[1] = cio_read(cio, 1) + shift;   /* SPcox (H) */
956     if (j3d->cinfo->codec_format == CODEC_J3D) {
957         tccp->cblk[2] = cio_read(cio, 1) + shift;    /* SPcox (I) */
958     } else {
959         tccp->cblk[2] = tccp->cblk[0];
960     }
961 
962     tccp->cblksty = cio_read(cio, 1);   /* SPcox (J) */
963     tccp->dwtid[0] = cio_read(cio, 1);  /* SPcox (K) */
964     if (j3d->cinfo->codec_format == CODEC_J3D) {
965         tccp->dwtid[1] = cio_read(cio, 1);  /* SPcox (L) */
966         tccp->dwtid[2] = cio_read(cio, 1);  /* SPcox (M) */
967     } else {
968         tccp->dwtid[1] = tccp->dwtid[0];    /* SPcox (L) */
969         tccp->dwtid[2] = tccp->dwtid[0];    /* SPcox (M) */
970     }
971     tccp->reversible = (tccp->dwtid[0] >= 1 && tccp->dwtid[1] >= 1 &&
972                         tccp->dwtid[2] >= 1); /*TODO: only valid for irreversible 9x7 WTs*/
973     if (tccp->csty & J3D_CP_CSTY_PRT) {
974         for (i = 0; i < tccp->numresolution[0]; i++) {
975             int tmp = cio_read(cio, 2); /* SPcox (N_i) */
976             tccp->prctsiz[0][i] = tmp & 0xf;
977             tccp->prctsiz[1][i] = tmp >> 4;
978             tccp->prctsiz[2][i] = tmp >> 8;
979         }
980     }
981 }
982 
j3d_write_cod(opj_j3d_t * j3d)983 static void j3d_write_cod(opj_j3d_t *j3d)
984 {
985     opj_cp_t *cp = NULL;
986     opj_tcp_t *tcp = NULL;
987     int lenp, len;
988 
989     opj_cio_t *cio = j3d->cio;
990 
991     cio_write(cio, J3D_MS_COD, 2);  /* COD */
992 
993     lenp = cio_tell(cio);
994     cio_skip(cio, 2);
995 
996     cp = j3d->cp;
997     tcp = &cp->tcps[j3d->curtileno];
998 
999     /* Scod : Table A-4*/
1000     cio_write(cio, tcp->csty, 1);       /* Scod : Coding style parameters */
1001     /* SGcod : Table A-5*/
1002     cio_write(cio, tcp->prg, 1);        /* SGcod (A) : Progression order */
1003     cio_write(cio, tcp->numlayers, 2);  /* SGcod (B) : No of layers */
1004     cio_write(cio, tcp->mct,
1005               1);        /* SGcod (C) : Multiple component transformation usage */
1006     /* SPcod : Table A-6*/
1007     j3d_write_cox(j3d, 0);
1008     len = cio_tell(cio) - lenp;
1009     cio_seek(cio, lenp);
1010     cio_write(cio, len, 2);     /* Lcod */
1011     cio_seek(cio, lenp + len);
1012 }
1013 
j3d_read_cod(opj_j3d_t * j3d)1014 static void j3d_read_cod(opj_j3d_t *j3d)
1015 {
1016     int len, i, pos;
1017 
1018     opj_cio_t *cio = j3d->cio;
1019     opj_cp_t *cp = j3d->cp;
1020     opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] :
1021                      j3d->default_tcp;
1022     opj_volume_t *volume = j3d->volume;
1023 
1024     /* Lcod */
1025     len = cio_read(cio, 2);
1026     /* Scod : Table A-4*/
1027     tcp->csty = cio_read(cio, 1);
1028     /* SGcod : Table A-5*/
1029     tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);
1030     tcp->numlayers = cio_read(cio, 2);
1031     tcp->mct = cio_read(cio, 1);
1032 
1033     pos = cio_tell(cio);
1034     for (i = 0; i < volume->numcomps; i++) {
1035         tcp->tccps[i].csty = tcp->csty & J3D_CP_CSTY_PRT;
1036         cio_seek(cio, pos);
1037         j3d_read_cox(j3d, i);
1038     }
1039 }
1040 
j3d_write_coc(opj_j3d_t * j3d,int compno)1041 static void j3d_write_coc(opj_j3d_t *j3d, int compno)
1042 {
1043     int lenp, len;
1044 
1045     opj_cp_t *cp = j3d->cp;
1046     opj_tcp_t *tcp = &cp->tcps[j3d->curtileno];
1047     opj_volume_t *volume = j3d->volume;
1048     opj_cio_t *cio = j3d->cio;
1049 
1050     cio_write(cio, J3D_MS_COC, 2);  /* COC */
1051     lenp = cio_tell(cio);
1052     cio_skip(cio, 2);
1053     cio_write(cio, compno, volume->numcomps <= 256 ? 1 : 2);    /* Ccoc */
1054     cio_write(cio, tcp->tccps[compno].csty, 1);                 /* Scoc */
1055 
1056     j3d_write_cox(j3d, compno);
1057 
1058     len = cio_tell(cio) - lenp;
1059     cio_seek(cio, lenp);
1060     cio_write(cio, len, 2);         /* Lcoc */
1061     cio_seek(cio, lenp + len);
1062 }
1063 
j3d_read_coc(opj_j3d_t * j3d)1064 static void j3d_read_coc(opj_j3d_t *j3d)
1065 {
1066     int len, compno;
1067 
1068     opj_cp_t *cp = j3d->cp;
1069     opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] :
1070                      j3d->default_tcp;
1071     opj_volume_t *volume = j3d->volume;
1072     opj_cio_t *cio = j3d->cio;
1073 
1074     len = cio_read(cio, 2);     /* Lcoc */
1075     compno = cio_read(cio, volume->numcomps <= 256 ? 1 : 2);    /* Ccoc */
1076     tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */
1077     j3d_read_cox(j3d, compno);
1078 }
1079 
j3d_write_qcx(opj_j3d_t * j3d,int compno)1080 static void j3d_write_qcx(opj_j3d_t *j3d, int compno)
1081 {
1082     int bandno, numbands;
1083     int expn, mant;
1084 
1085     opj_cp_t *cp = j3d->cp;
1086     opj_tcp_t *tcp = &cp->tcps[j3d->curtileno];
1087     opj_tccp_t *tccp = &tcp->tccps[compno];
1088     opj_cio_t *cio = j3d->cio;
1089 
1090     cio_write(cio, tccp->qntsty + (tccp->numgbits << 5),
1091               1);    /* Sqcx : Table A28 de 15444-1*/
1092 
1093     numbands = 0; // compiler warning
1094     if (j3d->cinfo->codec_format == CODEC_J2K) {
1095         numbands = tccp->qntsty == J3D_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolution[0] * 3
1096                    - 2;
1097     } else if (j3d->cinfo->codec_format == CODEC_J3D) {
1098         int diff = tccp->numresolution[0] - tccp->numresolution[2];
1099         numbands = (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) ? 1 :
1100                    (tccp->numresolution[0] * 7 - 6) - 4 * diff; /* SIQNT vs. SEQNT */
1101     }
1102 
1103     for (bandno = 0; bandno < numbands; bandno++) {
1104         expn = tccp->stepsizes[bandno].expn;
1105         mant = tccp->stepsizes[bandno].mant;
1106 
1107         if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) {
1108             cio_write(cio, expn << 3, 1);   /* SPqcx_i */
1109         } else {
1110             cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */
1111         }
1112     }
1113 }
1114 
j3d_read_qcx(opj_j3d_t * j3d,int compno,int len)1115 static void j3d_read_qcx(opj_j3d_t *j3d, int compno, int len)
1116 {
1117     int tmp;
1118     int bandno, numbands;
1119 
1120     opj_cp_t *cp = j3d->cp;
1121     opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] :
1122                      j3d->default_tcp;
1123     opj_tccp_t *tccp = &tcp->tccps[compno];
1124     opj_cio_t *cio = j3d->cio;
1125 
1126     tmp = cio_read(cio, 1);     /* Sqcx */
1127     tccp->qntsty = tmp & 0x1f;
1128     tccp->numgbits = tmp >> 5;
1129 
1130     /*Numbands = 1              si SIQNT
1131                  len - 1        si NOQNT
1132                  (len - 1) / 2  si SEQNT */
1133     numbands = tccp->qntsty == J3D_CCP_QNTSTY_SIQNT ? 1 : ((
1134                    tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2);
1135 
1136     for (bandno = 0; bandno < numbands; bandno++) {
1137         int expn, mant;
1138         if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) {
1139             expn = cio_read(cio, 1) >> 3;   /* SPqcx_i */
1140             mant = 0;
1141         } else {
1142             tmp = cio_read(cio, 2);         /* SPqcx_i */
1143             expn = tmp >> 11;
1144             mant = tmp & 0x7ff;
1145         }
1146         tccp->stepsizes[bandno].expn = expn;
1147         tccp->stepsizes[bandno].mant = mant;
1148     }
1149 
1150     /* Add Antonin : if scalar_derived -> compute other stepsizes */
1151     if (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) {
1152         for (bandno = 1; bandno < J3D_MAXBANDS; bandno++) {
1153             int numbands = (cp->transform_format == TRF_2D_DWT) ? 3 : 7;
1154             tccp->stepsizes[bandno].expn = tccp->stepsizes[0].expn - ((
1155                                                bandno - 1) / numbands);
1156             tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant;
1157         }
1158     }
1159     /* ddA */
1160 }
1161 
j3d_write_qcd(opj_j3d_t * j3d)1162 static void j3d_write_qcd(opj_j3d_t *j3d)
1163 {
1164     int lenp, len;
1165 
1166     opj_cio_t *cio = j3d->cio;
1167 
1168     cio_write(cio, J3D_MS_QCD, 2);  /* QCD */
1169     lenp = cio_tell(cio);
1170     cio_skip(cio, 2);
1171     j3d_write_qcx(j3d, 0);          /* Sqcd*/
1172     len = cio_tell(cio) - lenp;
1173     cio_seek(cio, lenp);
1174     cio_write(cio, len, 2);         /* Lqcd */
1175     cio_seek(cio, lenp + len);
1176 }
1177 
j3d_read_qcd(opj_j3d_t * j3d)1178 static void j3d_read_qcd(opj_j3d_t *j3d)
1179 {
1180     int len, i, pos;
1181 
1182     opj_cio_t *cio = j3d->cio;
1183     opj_volume_t *volume = j3d->volume;
1184 
1185     len = cio_read(cio, 2);     /* Lqcd */
1186     pos = cio_tell(cio);
1187     for (i = 0; i < volume->numcomps; i++) {
1188         cio_seek(cio, pos);
1189         j3d_read_qcx(j3d, i, len - 2);
1190     }
1191 }
1192 
j3d_write_qcc(opj_j3d_t * j3d,int compno)1193 static void j3d_write_qcc(opj_j3d_t *j3d, int compno)
1194 {
1195     int lenp, len;
1196 
1197     opj_cio_t *cio = j3d->cio;
1198 
1199     cio_write(cio, J3D_MS_QCC, 2);  /* QCC */
1200     lenp = cio_tell(cio);
1201     cio_skip(cio, 2);
1202     cio_write(cio, compno, j3d->volume->numcomps <= 256 ? 1 : 2);   /* Cqcc */
1203     j3d_write_qcx(j3d, compno);
1204     len = cio_tell(cio) - lenp;
1205     cio_seek(cio, lenp);
1206     cio_write(cio, len, 2);         /* Lqcc */
1207     cio_seek(cio, lenp + len);
1208 }
1209 
j3d_read_qcc(opj_j3d_t * j3d)1210 static void j3d_read_qcc(opj_j3d_t *j3d)
1211 {
1212     int len, compno;
1213     int numcomp = j3d->volume->numcomps;
1214     opj_cio_t *cio = j3d->cio;
1215 
1216     len = cio_read(cio, 2); /* Lqcc */
1217     compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */
1218     j3d_read_qcx(j3d, compno, len - 2 - (numcomp <= 256 ? 1 : 2));
1219 }
1220 
j3d_write_poc(opj_j3d_t * j3d)1221 static void j3d_write_poc(opj_j3d_t *j3d)
1222 {
1223     int len, numpchgs, i;
1224 
1225     int numcomps = j3d->volume->numcomps;
1226 
1227     opj_cp_t *cp = j3d->cp;
1228     opj_tcp_t *tcp = &cp->tcps[j3d->curtileno];
1229     opj_tccp_t *tccp = &tcp->tccps[0];
1230     opj_cio_t *cio = j3d->cio;
1231 
1232     numpchgs = tcp->numpocs;
1233     cio_write(cio, J3D_MS_POC, 2);  /* POC  */
1234     len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs;
1235     cio_write(cio, len, 2);     /* Lpoc */
1236     for (i = 0; i < numpchgs; i++) {
1237         opj_poc_t *poc = &tcp->pocs[i];
1238         cio_write(cio, poc->resno0, 1); /* RSpoc_i */
1239         cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2));    /* CSpoc_i */
1240         cio_write(cio, poc->layno1, 2); /* LYEpoc_i */
1241         poc->layno1 = int_min(poc->layno1, tcp->numlayers);
1242         cio_write(cio, poc->resno1, 1); /* REpoc_i */
1243         poc->resno1 = int_min(poc->resno1, tccp->numresolution[0]);
1244         cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2));    /* CEpoc_i */
1245         poc->compno1 = int_min(poc->compno1, numcomps);
1246         cio_write(cio, poc->prg, 1);    /* Ppoc_i */
1247     }
1248 }
1249 
j3d_read_poc(opj_j3d_t * j3d)1250 static void j3d_read_poc(opj_j3d_t *j3d)
1251 {
1252     int len, numpchgs, i, old_poc;
1253 
1254     int numcomps = j3d->volume->numcomps;
1255 
1256     opj_cp_t *cp = j3d->cp;
1257     opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] :
1258                      j3d->default_tcp;
1259     opj_tccp_t *tccp = &tcp->tccps[0];
1260     opj_cio_t *cio = j3d->cio;
1261 
1262     old_poc = tcp->POC ? tcp->numpocs + 1 : 0;
1263     tcp->POC = 1;
1264     len = cio_read(cio, 2);     /* Lpoc */
1265     numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2));
1266 
1267     for (i = old_poc; i < numpchgs + old_poc; i++) {
1268         opj_poc_t *poc;
1269         poc = &tcp->pocs[i];
1270         poc->resno0 = cio_read(cio, 1); /* RSpoc_i */
1271         poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2);  /* CSpoc_i */
1272         poc->layno1 = int_min(cio_read(cio, 2),
1273                               (unsigned int) tcp->numlayers); /* LYEpoc_i */
1274         poc->resno1 = int_min(cio_read(cio, 1),
1275                               (unsigned int) tccp->numresolution[0]); /* REpoc_i */
1276         poc->compno1 = int_min(
1277                            cio_read(cio, numcomps <= 256 ? 1 : 2),
1278                            (unsigned int) numcomps);   /* CEpoc_i */
1279         poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1);    /* Ppoc_i */
1280     }
1281 
1282     tcp->numpocs = numpchgs + old_poc - 1;
1283 }
1284 
j3d_read_crg(opj_j3d_t * j3d)1285 static void j3d_read_crg(opj_j3d_t *j3d)
1286 {
1287     int len, i, Xcrg_i, Ycrg_i, Zcrg_i;
1288 
1289     opj_cio_t *cio = j3d->cio;
1290     int numcomps = j3d->volume->numcomps;
1291 
1292     len = cio_read(cio, 2);         /* Lcrg */
1293     for (i = 0; i < numcomps; i++) {
1294         Xcrg_i = cio_read(cio, 2);  /* Xcrg_i */
1295         Ycrg_i = cio_read(cio, 2);  /* Ycrg_i */
1296         Zcrg_i = cio_read(cio, 2);  /* Zcrg_i */
1297     }
1298 }
1299 
j3d_read_tlm(opj_j3d_t * j3d)1300 static void j3d_read_tlm(opj_j3d_t *j3d)
1301 {
1302     int len, Ztlm, Stlm, ST, SP, tile_tlm, i;
1303     long int Ttlm_i, Ptlm_i;
1304 
1305     opj_cio_t *cio = j3d->cio;
1306 
1307     len = cio_read(cio, 2);     /* Ltlm */
1308     Ztlm = cio_read(cio, 1);    /* Ztlm */
1309     Stlm = cio_read(cio, 1);    /* Stlm */
1310     ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02);
1311     SP = (Stlm >> 6) & 0x01;
1312     tile_tlm = (len - 4) / ((SP + 1) * 2 + ST);
1313     for (i = 0; i < tile_tlm; i++) {
1314         Ttlm_i = cio_read(cio, ST); /* Ttlm_i */
1315         Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */
1316     }
1317 }
1318 
j3d_read_plm(opj_j3d_t * j3d)1319 static void j3d_read_plm(opj_j3d_t *j3d)
1320 {
1321     int len, i, Zplm, Nplm, add, packet_len = 0;
1322 
1323     opj_cio_t *cio = j3d->cio;
1324 
1325     len = cio_read(cio, 2);     /* Lplm */
1326     Zplm = cio_read(cio, 1);    /* Zplm */
1327     len -= 3;
1328     while (len > 0) {
1329         Nplm = cio_read(cio, 4);        /* Nplm */
1330         len -= 4;
1331         for (i = Nplm; i > 0; i--) {
1332             add = cio_read(cio, 1);
1333             len--;
1334             packet_len = (packet_len << 7) + add;   /* Iplm_ij */
1335             if ((add & 0x80) == 0) {
1336                 /* New packet */
1337                 packet_len = 0;
1338             }
1339             if (len <= 0) {
1340                 break;
1341             }
1342         }
1343     }
1344 }
1345 
j3d_read_plt(opj_j3d_t * j3d)1346 static void j3d_read_plt(opj_j3d_t *j3d)
1347 {
1348     int len, i, Zplt, packet_len = 0, add;
1349 
1350     opj_cio_t *cio = j3d->cio;
1351 
1352     len = cio_read(cio, 2);     /* Lplt */
1353     Zplt = cio_read(cio, 1);    /* Zplt */
1354     for (i = len - 3; i > 0; i--) {
1355         add = cio_read(cio, 1);
1356         packet_len = (packet_len << 7) + add;   /* Iplt_i */
1357         if ((add & 0x80) == 0) {
1358             /* New packet */
1359             packet_len = 0;
1360         }
1361     }
1362 }
1363 
j3d_read_ppm(opj_j3d_t * j3d)1364 static void j3d_read_ppm(opj_j3d_t *j3d)
1365 {
1366     int len, Z_ppm, i, j;
1367     int N_ppm;
1368 
1369     opj_cp_t *cp = j3d->cp;
1370     opj_cio_t *cio = j3d->cio;
1371 
1372     len = cio_read(cio, 2);
1373     cp->ppm = 1;
1374 
1375     Z_ppm = cio_read(cio, 1);   /* Z_ppm */
1376     len -= 3;
1377     while (len > 0) {
1378         if (cp->ppm_previous == 0) {
1379             N_ppm = cio_read(cio, 4);   /* N_ppm */
1380             len -= 4;
1381         } else {
1382             N_ppm = cp->ppm_previous;
1383         }
1384         j = cp->ppm_store;
1385         if (Z_ppm == 0) {   /* First PPM marker */
1386             cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char));
1387             cp->ppm_data_first = cp->ppm_data;
1388             cp->ppm_len = N_ppm;
1389         } else {            /* NON-first PPM marker */
1390             cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data,
1391                            (N_ppm + cp->ppm_store) * sizeof(unsigned char));
1392             cp->ppm_data_first = cp->ppm_data;
1393             cp->ppm_len = N_ppm + cp->ppm_store;
1394         }
1395         for (i = N_ppm; i > 0; i--) {   /* Read packet header */
1396             cp->ppm_data[j] = cio_read(cio, 1);
1397             j++;
1398             len--;
1399             if (len == 0) {
1400                 break;    /* Case of non-finished packet header in present marker but finished in next one */
1401             }
1402         }
1403         cp->ppm_previous = i - 1;
1404         cp->ppm_store = j;
1405     }
1406 }
1407 
j3d_read_ppt(opj_j3d_t * j3d)1408 static void j3d_read_ppt(opj_j3d_t *j3d)
1409 {
1410     int len, Z_ppt, i, j = 0;
1411 
1412     opj_cp_t *cp = j3d->cp;
1413     opj_tcp_t *tcp = cp->tcps + j3d->curtileno;
1414     opj_cio_t *cio = j3d->cio;
1415 
1416     len = cio_read(cio, 2);
1417     Z_ppt = cio_read(cio, 1);
1418     tcp->ppt = 1;
1419     if (Z_ppt == 0) {       /* First PPT marker */
1420         tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char));
1421         tcp->ppt_data_first = tcp->ppt_data;
1422         tcp->ppt_store = 0;
1423         tcp->ppt_len = len - 3;
1424     } else {            /* NON-first PPT marker */
1425         tcp->ppt_data = (unsigned char *) opj_realloc(tcp->ppt_data,
1426                         (len - 3 + tcp->ppt_store) * sizeof(unsigned char));
1427         tcp->ppt_data_first = tcp->ppt_data;
1428         tcp->ppt_len = len - 3 + tcp->ppt_store;
1429     }
1430     j = tcp->ppt_store;
1431     for (i = len - 3; i > 0; i--) {
1432         tcp->ppt_data[j] = cio_read(cio, 1);
1433         j++;
1434     }
1435     tcp->ppt_store = j;
1436 }
1437 
j3d_write_sot(opj_j3d_t * j3d)1438 static void j3d_write_sot(opj_j3d_t *j3d)
1439 {
1440     int lenp, len;
1441 
1442     opj_cio_t *cio = j3d->cio;
1443 
1444     j3d->sot_start = cio_tell(cio);
1445     cio_write(cio, J3D_MS_SOT, 2);      /* SOT */
1446     lenp = cio_tell(cio);
1447     cio_skip(cio, 2);                   /* Lsot (further) */
1448     cio_write(cio, j3d->curtileno, 2);  /* Isot */
1449     cio_skip(cio, 4);                   /* Psot (further in j3d_write_sod) */
1450     cio_write(cio, 0, 1);               /* TPsot */
1451     cio_write(cio, 1,
1452               1);               /* TNsot (no of tile-parts of this tile in this codestream)*/
1453     len = cio_tell(cio) - lenp;
1454     cio_seek(cio, lenp);
1455     cio_write(cio, len, 2);             /* Lsot */
1456     cio_seek(cio, lenp + len);
1457 }
1458 
j3d_read_sot(opj_j3d_t * j3d)1459 static void j3d_read_sot(opj_j3d_t *j3d)
1460 {
1461     int len, tileno, totlen, partno, numparts, i;
1462     opj_tcp_t *tcp = NULL;
1463     char status = 0;
1464 
1465     opj_cp_t *cp = j3d->cp;
1466     opj_cio_t *cio = j3d->cio;
1467 
1468     len = cio_read(cio, 2);
1469     tileno = cio_read(cio, 2);
1470 
1471     if (cp->tileno_size == 0) {
1472         cp->tileno[cp->tileno_size] = tileno;
1473         cp->tileno_size++;
1474     } else {
1475         i = 0;
1476         while (i < cp->tileno_size && status == 0) {
1477             status = cp->tileno[i] == tileno ? 1 : 0;
1478             i++;
1479         }
1480         if (status == 0) {
1481             cp->tileno[cp->tileno_size] = tileno;
1482             cp->tileno_size++;
1483         }
1484     }
1485 
1486     totlen = cio_read(cio, 4);
1487     if (!totlen) {
1488         totlen = cio_numbytesleft(cio) + 8;
1489     }
1490 
1491     partno = cio_read(cio, 1);
1492     numparts = cio_read(cio, 1);
1493 
1494     j3d->curtileno = tileno;
1495     j3d->eot = cio_getbp(cio) - 12 + totlen;
1496     j3d->state = J3D_STATE_TPH;
1497     tcp = &cp->tcps[j3d->curtileno];
1498 
1499     if (tcp->first == 1) {
1500 
1501         /* Initialization PPT */
1502         opj_tccp_t *tmp = tcp->tccps;
1503         memcpy(tcp, j3d->default_tcp, sizeof(opj_tcp_t));
1504         tcp->ppt = 0;
1505         tcp->ppt_data = NULL;
1506         tcp->ppt_data_first = NULL;
1507         tcp->tccps = tmp;
1508 
1509         for (i = 0; i < j3d->volume->numcomps; i++) {
1510             tcp->tccps[i] = j3d->default_tcp->tccps[i];
1511         }
1512         cp->tcps[j3d->curtileno].first = 0;
1513     }
1514 }
1515 
j3d_write_sod(opj_j3d_t * j3d,void * tile_coder)1516 static void j3d_write_sod(opj_j3d_t *j3d, void *tile_coder)
1517 {
1518     int l, layno;
1519     int totlen;
1520     opj_tcp_t *tcp = NULL;
1521     opj_volume_info_t *volume_info = NULL;
1522 
1523     opj_tcd_t *tcd = (opj_tcd_t*)
1524                      tile_coder;    /* cast is needed because of conflicts in header inclusions */
1525     opj_cp_t *cp = j3d->cp;
1526     opj_cio_t *cio = j3d->cio;
1527 
1528     cio_write(cio, J3D_MS_SOD, 2);
1529     if (j3d->curtileno == 0) {
1530         j3d->sod_start = cio_tell(cio) + j3d->pos_correction;
1531     }
1532 
1533     /* INDEX >> */
1534     volume_info = j3d->volume_info;
1535     if (volume_info && volume_info->index_on) {
1536         volume_info->tile[j3d->curtileno].end_header = cio_tell(
1537                     cio) + j3d->pos_correction - 1;
1538     }
1539     /* << INDEX */
1540 
1541     tcp = &cp->tcps[j3d->curtileno];
1542     for (layno = 0; layno < tcp->numlayers; layno++) {
1543         tcp->rates[layno] -= tcp->rates[layno] ? (j3d->sod_start /
1544                              (cp->th * cp->tw * cp->tl)) : 0;
1545     }
1546 
1547     if (volume_info) {
1548         volume_info->num = 0;
1549     }
1550 
1551     l = tcd_encode_tile(tcd, j3d->curtileno, cio_getbp(cio),
1552                         cio_numbytesleft(cio) - 2, volume_info);
1553 
1554     /* Writing Psot in SOT marker */
1555     totlen = cio_tell(cio) + l - j3d->sot_start;
1556     cio_seek(cio, j3d->sot_start + 6);
1557     cio_write(cio, totlen, 4);
1558     cio_seek(cio, j3d->sot_start + totlen);
1559 }
1560 
j3d_read_sod(opj_j3d_t * j3d)1561 static void j3d_read_sod(opj_j3d_t *j3d)
1562 {
1563     int len, truncate = 0, i;
1564     unsigned char *data = NULL, *data_ptr = NULL;
1565 
1566     opj_cio_t *cio = j3d->cio;
1567     int curtileno = j3d->curtileno;
1568 
1569     len = int_min(j3d->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1);
1570 
1571     if (len == cio_numbytesleft(cio) + 1) {
1572         truncate = 1;       /* Case of a truncate codestream */
1573     }
1574 
1575     data = (unsigned char *) opj_malloc((j3d->tile_len[curtileno] + len) * sizeof(
1576                                             unsigned char));
1577 
1578     for (i = 0; i < j3d->tile_len[curtileno]; i++) {
1579         data[i] = j3d->tile_data[curtileno][i];
1580     }
1581 
1582     data_ptr = data + j3d->tile_len[curtileno];
1583     for (i = 0; i < len; i++) {
1584         data_ptr[i] = cio_read(cio, 1);
1585     }
1586 
1587     j3d->tile_len[curtileno] += len;
1588     opj_free(j3d->tile_data[curtileno]);
1589     j3d->tile_data[curtileno] = data;
1590 
1591     if (!truncate) {
1592         j3d->state = J3D_STATE_TPHSOT;
1593     } else {
1594         j3d->state = J3D_STATE_NEOC;    /* RAJOUTE !! */
1595     }
1596 }
1597 
j3d_write_rgn(opj_j3d_t * j3d,int compno,int tileno)1598 static void j3d_write_rgn(opj_j3d_t *j3d, int compno, int tileno)
1599 {
1600 
1601     opj_cp_t *cp = j3d->cp;
1602     opj_tcp_t *tcp = &cp->tcps[tileno];
1603     opj_cio_t *cio = j3d->cio;
1604     int numcomps = j3d->volume->numcomps;
1605 
1606     cio_write(cio, J3D_MS_RGN, 2);                      /* RGN  */
1607     cio_write(cio, numcomps <= 256 ? 5 : 6, 2);         /* Lrgn */
1608     cio_write(cio, compno, numcomps <= 256 ? 1 : 2);    /* Crgn */
1609     cio_write(cio, 0, 1);                               /* Srgn */
1610     cio_write(cio, tcp->tccps[compno].roishift, 1);     /* SPrgn */
1611 }
1612 
j3d_read_rgn(opj_j3d_t * j3d)1613 static void j3d_read_rgn(opj_j3d_t *j3d)
1614 {
1615     int len, compno, roisty;
1616 
1617     opj_cp_t *cp = j3d->cp;
1618     opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] :
1619                      j3d->default_tcp;
1620     opj_cio_t *cio = j3d->cio;
1621     int numcomps = j3d->volume->numcomps;
1622 
1623     len = cio_read(cio, 2);                                     /* Lrgn */
1624     compno = cio_read(cio, numcomps <= 256 ? 1 : 2);            /* Crgn */
1625     roisty = cio_read(cio, 1);                                  /* Srgn */
1626     tcp->tccps[compno].roishift = cio_read(cio, 1);             /* SPrgn */
1627 }
1628 
j3d_write_eoc(opj_j3d_t * j3d)1629 static void j3d_write_eoc(opj_j3d_t *j3d)
1630 {
1631     opj_cio_t *cio = j3d->cio;
1632     /* opj_event_msg(j3d->cinfo, "%.8x: EOC\n", cio_tell(cio) + j3d->pos_correction); */
1633     cio_write(cio, J3D_MS_EOC, 2);
1634 }
1635 
j3d_read_eoc(opj_j3d_t * j3d)1636 static void j3d_read_eoc(opj_j3d_t *j3d)
1637 {
1638     int i, tileno;
1639 
1640 #ifndef NO_PACKETS_DECODING
1641     opj_tcd_t *tcd = tcd_create(j3d->cinfo);
1642     tcd_malloc_decode(tcd, j3d->volume, j3d->cp);
1643     /*j3d_dump_volume(stdout, tcd->volume);
1644     j3d_dump_cp(stdout, tcd->volume, tcd->cp);*/
1645     for (i = 0; i < j3d->cp->tileno_size; i++) {
1646         tileno = j3d->cp->tileno[i];
1647         /*opj_event_msg(j3d->cinfo, EVT_INFO, "tcd_decode_tile \n");*/
1648         tcd_decode_tile(tcd, j3d->tile_data[tileno], j3d->tile_len[tileno], tileno);
1649         opj_free(j3d->tile_data[tileno]);
1650         j3d->tile_data[tileno] = NULL;
1651     }
1652     tcd_free_decode(tcd);
1653     tcd_destroy(tcd);
1654 #else
1655     for (i = 0; i < j3d->cp->tileno_size; i++) {
1656         tileno = j3d->cp->tileno[i];
1657         opj_free(j3d->tile_data[tileno]);
1658         j3d->tile_data[tileno] = NULL;
1659     }
1660 #endif
1661 
1662     j3d->state = J3D_STATE_MT;
1663 }
1664 
j3d_read_unk(opj_j3d_t * j3d)1665 static void j3d_read_unk(opj_j3d_t *j3d)
1666 {
1667     opj_event_msg(j3d->cinfo, EVT_WARNING, "Unknown marker\n");
1668 }
1669 
1670 static opj_atk_t atk_info_wt[] = {
1671     {0, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1.230174104, 4, {0}, {0}, {0}, {1, 1, 1, 1}, {-1.586134342059924, -0.052980118572961, 0.882911075530934, 0.443506852043971}}, /* WT 9-7 IRR*/
1672     {1, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {1, 2}, {1, 2}, {1, 1}, {-1.0, 1.0}}, /* WT 5-3 REV*/
1673     {2, 0, J3D_ATK_ARB, J3D_ATK_REV, 0, J3D_ATK_CON, 0, 2, {0, 0}, {0, 1}, {0, 1}, {1, 1}, {{-1.0}, {1.0}}}, /* WT 2-2 REV*/
1674     {3, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0, 0, -1}, {0, 1, 2}, {0, 1, 2}, {1, 1, 3}, {{-1.0}, {1.0}, {1.0, 0.0, -1.0}}}, /* WT 2-6 REV*/
1675     {4, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0, 0, -2}, {0, 1, 6}, {0, 1, 32}, {1, 1, 5}, {{-1}, {1}, {-3.0, 22.0, 0.0, -22.0, 3.0}}}, /* WT 2-10 REV*/
1676     {5, 1, J3D_ATK_ARB, J3D_ATK_IRR, 1, J3D_ATK_WS, 1, 7, {0}, {0}, {0}, {1, 1, 2, 1, 2, 1, 3}, {{-1}, {1.58613434206}, {-0.460348209828, 0.460348209828}, {0.25}, {0.374213867768, -0.374213867768}, {-1.33613434206}, {0.29306717103, 0, -0.29306717103}}}, /* WT 6-10 IRR*/
1677     {
1678         6, 1, J3D_ATK_ARB, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 11, {0}, {0}, {0}, {1, 1, 2, 1, 2, 1, 2, 1, 2, 1, 5}, {{-1}, {0, 99715069105}, {-1.00573127827, 1.00573127827}, {-0.27040357631}, {2.20509972343, -2.20509972343}, {0.08059995736},
1679             {-1.62682532350, 1.62682532350}, {0.52040357631}, {0.60404664250, -0.60404664250}, {-0.82775064841}, {-0.06615812964, 0.29402137720, 0, -0.29402137720, 0.06615812964}
1680         }
1681     }, /* WT 10-18 IRR*/
1682     {7, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 2, {0}, {0}, {0}, {1, 1}, {-0.5, 0.25}},  /* WT 5-3 IRR*/
1683     {8, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {4, 4}, {8, 8}, {2, 2}, {{-9, 1}, {5, -1}}} /* WT 13-7 REV*/
1684 };
1685 
1686 typedef struct opj_dec_mstabent {
1687     /** marker value */
1688     int id;
1689     /** value of the state when the marker can appear */
1690     int states;
1691     /** action linked to the marker */
1692     void (*handler)(opj_j3d_t *j3d);
1693 } opj_dec_mstabent_t;
1694 
1695 opj_dec_mstabent_t j3d_dec_mstab[] = {
1696     {J3D_MS_SOC, J3D_STATE_MHSOC, j3d_read_soc},
1697     {J3D_MS_SOT, J3D_STATE_MH | J3D_STATE_TPHSOT, j3d_read_sot},
1698     {J3D_MS_SOD, J3D_STATE_TPH, j3d_read_sod},
1699     {J3D_MS_EOC, J3D_STATE_TPHSOT, j3d_read_eoc},
1700     {J3D_MS_CAP, J3D_STATE_MHSIZ, j3d_read_cap},
1701     {J3D_MS_SIZ, J3D_STATE_MHSIZ, j3d_read_siz},
1702     {J3D_MS_NSI, J3D_STATE_MHSIZ, j3d_read_nsi},
1703     {J3D_MS_COD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_cod},
1704     {J3D_MS_COC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_coc},
1705     {J3D_MS_RGN, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_rgn},
1706     {J3D_MS_QCD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_qcd},
1707     {J3D_MS_QCC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_qcc},
1708     {J3D_MS_POC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_poc},
1709     {J3D_MS_TLM, J3D_STATE_MH, j3d_read_tlm},
1710     {J3D_MS_PLM, J3D_STATE_MH, j3d_read_plm},
1711     {J3D_MS_PLT, J3D_STATE_TPH, j3d_read_plt},
1712     {J3D_MS_PPM, J3D_STATE_MH, j3d_read_ppm},
1713     {J3D_MS_PPT, J3D_STATE_TPH, j3d_read_ppt},
1714     {J3D_MS_SOP, 0, 0},
1715     {J3D_MS_CRG, J3D_STATE_MH, j3d_read_crg},
1716     {J3D_MS_COM, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_com},
1717     {J3D_MS_DCO, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_dco},
1718     {J3D_MS_ATK, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_atk},
1719     {0, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_unk}
1720     /*, -->must define the j3d_read functions
1721     {J3D_MS_CBD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_cbd},
1722     {J3D_MS_MCT, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mct},
1723     {J3D_MS_MCC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mcc},
1724     {J3D_MS_MCO, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mco},
1725     {J3D_MS_NLT, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_nlt},
1726     {J3D_MS_VMS, J3D_STATE_MH, j3d_read_vms},
1727     {J3D_MS_DFS, J3D_STATE_MH, j3d_read_dfs},
1728     {J3D_MS_ADS, J3D_STATE_MH, j3d_read_ads},
1729     {J3D_MS_QPD, J3D_STATE_MH, j3d_read_qpd},
1730     {J3D_MS_QPC, J3D_STATE_TPH, j3d_read_qpc}*/
1731 };
1732 
1733 /**
1734 Read the lookup table containing all the marker, status and action
1735 @param id Marker value
1736 */
j3d_dec_mstab_lookup(int id)1737 static opj_dec_mstabent_t *j3d_dec_mstab_lookup(int id)
1738 {
1739     opj_dec_mstabent_t *e;
1740     for (e = j3d_dec_mstab; e->id != 0; e++) {
1741         if (e->id == id) {
1742             break;
1743         }
1744     }
1745     return e;
1746 }
1747 
1748 /* ----------------------------------------------------------------------- */
1749 /* J3D / JPT decoder interface                                             */
1750 /* ----------------------------------------------------------------------- */
1751 
j3d_create_decompress(opj_common_ptr cinfo)1752 opj_j3d_t* j3d_create_decompress(opj_common_ptr cinfo)
1753 {
1754     opj_j3d_t *j3d = (opj_j3d_t*)opj_malloc(sizeof(opj_j3d_t));
1755     if (j3d) {
1756         j3d->cinfo = cinfo;
1757         j3d->default_tcp = (opj_tcp_t*)opj_malloc(sizeof(opj_tcp_t));
1758         if (!j3d->default_tcp) {
1759             opj_free(j3d);
1760             return NULL;
1761         }
1762     }
1763     return j3d;
1764 }
1765 
j3d_destroy_decompress(opj_j3d_t * j3d)1766 void j3d_destroy_decompress(opj_j3d_t *j3d)
1767 {
1768     int i = 0;
1769 
1770     if (j3d->tile_len != NULL) {
1771         opj_free(j3d->tile_len);
1772     }
1773     if (j3d->tile_data != NULL) {
1774         opj_free(j3d->tile_data);
1775     }
1776     if (j3d->default_tcp != NULL) {
1777         opj_tcp_t *default_tcp = j3d->default_tcp;
1778         if (default_tcp->ppt_data_first != NULL) {
1779             opj_free(default_tcp->ppt_data_first);
1780         }
1781         if (j3d->default_tcp->tccps != NULL) {
1782             opj_free(j3d->default_tcp->tccps);
1783         }
1784         opj_free(j3d->default_tcp);
1785     }
1786     if (j3d->cp != NULL) {
1787         opj_cp_t *cp = j3d->cp;
1788         if (cp->tcps != NULL) {
1789             for (i = 0; i < cp->tw * cp->th * cp->tl; i++) {
1790                 if (cp->tcps[i].ppt_data_first != NULL) {
1791                     opj_free(cp->tcps[i].ppt_data_first);
1792                 }
1793                 if (cp->tcps[i].tccps != NULL) {
1794                     opj_free(cp->tcps[i].tccps);
1795                 }
1796             }
1797             opj_free(cp->tcps);
1798         }
1799         if (cp->ppm_data_first != NULL) {
1800             opj_free(cp->ppm_data_first);
1801         }
1802         if (cp->tileno != NULL) {
1803             opj_free(cp->tileno);
1804         }
1805         if (cp->comment != NULL) {
1806             opj_free(cp->comment);
1807         }
1808 
1809         opj_free(cp);
1810     }
1811 
1812     opj_free(j3d);
1813 }
1814 
j3d_setup_decoder(opj_j3d_t * j3d,opj_dparameters_t * parameters)1815 void j3d_setup_decoder(opj_j3d_t *j3d, opj_dparameters_t *parameters)
1816 {
1817     if (j3d && parameters) {
1818         /* create and initialize the coding parameters structure */
1819         opj_cp_t *cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t));
1820         cp->reduce[0] = parameters->cp_reduce[0];
1821         cp->reduce[1] = parameters->cp_reduce[1];
1822         cp->reduce[2] = parameters->cp_reduce[2];
1823         cp->layer = parameters->cp_layer;
1824         cp->bigendian = parameters->bigendian;
1825 
1826         /* MM: Settings of the following two member variables would take
1827           place during j3d_read_com. FIXME */
1828         cp->encoding_format = ENCOD_3EB;
1829         cp->transform_format = TRF_2D_DWT;
1830 
1831         /* keep a link to cp so that we can destroy it later in j3d_destroy_decompress */
1832         j3d->cp = cp;
1833     }
1834 }
1835 
j3d_decode(opj_j3d_t * j3d,opj_cio_t * cio)1836 opj_volume_t* j3d_decode(opj_j3d_t *j3d, opj_cio_t *cio)
1837 {
1838     opj_volume_t *volume = NULL;
1839 
1840     opj_common_ptr cinfo = j3d->cinfo;
1841 
1842     j3d->cio = cio;
1843 
1844     /* create an empty volume */
1845     volume = (opj_volume_t*)opj_malloc(sizeof(opj_volume_t));
1846     j3d->volume = volume;
1847 
1848     j3d->state = J3D_STATE_MHSOC;
1849 
1850     for (;;) {
1851         opj_dec_mstabent_t *e;
1852         int id = cio_read(cio, 2);
1853         if (id >> 8 != 0xff) {
1854             opj_volume_destroy(volume);
1855             opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n",
1856                           cio_tell(cio) - 2, id);
1857             return 0;
1858         }
1859         e = j3d_dec_mstab_lookup(id);
1860         /*opj_event_msg(cinfo, EVT_INFO, "MARKER %x PREVSTATE %d E->STATE %d\n",e->id,j3d->state,e->states);*/
1861         if (!(j3d->state & e->states)) {
1862             opj_volume_destroy(volume);
1863             opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n",
1864                           cio_tell(cio) - 2, id);
1865             return 0;
1866         }
1867         if (e->handler) {
1868             (*e->handler)(j3d);
1869         }
1870         /*opj_event_msg(cinfo, EVT_INFO, "POSTSTATE %d\n",j3d->state);*/
1871         if (j3d->state == J3D_STATE_MT) {
1872             break;
1873         }
1874         if (j3d->state == J3D_STATE_NEOC) {
1875             break;
1876         }
1877     }
1878     if (j3d->state == J3D_STATE_NEOC) {
1879         j3d_read_eoc(j3d);
1880     }
1881 
1882     if (j3d->state != J3D_STATE_MT) {
1883         opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n");
1884     }
1885 
1886     return volume;
1887 }
1888 
1889 /* ----------------------------------------------------------------------- */
1890 /* J3D encoder interface                                                       */
1891 /* ----------------------------------------------------------------------- */
1892 
j3d_create_compress(opj_common_ptr cinfo)1893 opj_j3d_t* j3d_create_compress(opj_common_ptr cinfo)
1894 {
1895     opj_j3d_t *j3d = (opj_j3d_t*)opj_malloc(sizeof(opj_j3d_t));
1896     if (j3d) {
1897         j3d->cinfo = cinfo;
1898     }
1899     return j3d;
1900 }
1901 
j3d_destroy_compress(opj_j3d_t * j3d)1902 void j3d_destroy_compress(opj_j3d_t *j3d)
1903 {
1904     int tileno;
1905 
1906     if (!j3d) {
1907         return;
1908     }
1909 
1910     if (j3d->volume_info != NULL) {
1911         opj_volume_info_t *volume_info = j3d->volume_info;
1912         if (volume_info->index_on && j3d->cp) {
1913             opj_cp_t *cp = j3d->cp;
1914             for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
1915                 opj_tile_info_t *tile_info = &volume_info->tile[tileno];
1916                 opj_free(tile_info->thresh);
1917                 opj_free(tile_info->packet);
1918             }
1919             opj_free(volume_info->tile);
1920         }
1921         opj_free(volume_info);
1922     }
1923     if (j3d->cp != NULL) {
1924         opj_cp_t *cp = j3d->cp;
1925 
1926         if (cp->comment) {
1927             opj_free(cp->comment);
1928         }
1929         if (cp->matrice) {
1930             opj_free(cp->matrice);
1931         }
1932         for (tileno = 0; tileno < cp->tw * cp->th; tileno++) {
1933             opj_free(cp->tcps[tileno].tccps);
1934         }
1935         opj_free(cp->tcps);
1936         opj_free(cp);
1937     }
1938 
1939     opj_free(j3d);
1940 }
1941 
j3d_setup_encoder(opj_j3d_t * j3d,opj_cparameters_t * parameters,opj_volume_t * volume)1942 void j3d_setup_encoder(opj_j3d_t *j3d, opj_cparameters_t *parameters,
1943                        opj_volume_t *volume)
1944 {
1945     int i, j, tileno, numpocs_tile;
1946     opj_cp_t *cp = NULL;
1947 
1948     if (!j3d || !parameters || ! volume) {
1949         return;
1950     }
1951 
1952     /* create and initialize the coding parameters structure */
1953     cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t));
1954 
1955     /* keep a link to cp so that we can destroy it later in j3d_destroy_compress */
1956     j3d->cp = cp;
1957 
1958     /* set default values for cp */
1959     cp->tw = 1;
1960     cp->th = 1;
1961     cp->tl = 1;
1962 
1963     /* copy user encoding parameters */
1964     cp->disto_alloc = parameters->cp_disto_alloc;
1965     cp->fixed_alloc = parameters->cp_fixed_alloc;
1966     cp->fixed_quality = parameters->cp_fixed_quality;
1967 
1968     /* transform and coding method */
1969     cp->transform_format = parameters->transform_format;
1970     cp->encoding_format = parameters->encoding_format;
1971 
1972     /* mod fixed_quality */
1973     if (parameters->cp_matrice) {
1974         size_t array_size = parameters->tcp_numlayers * 3 * parameters->numresolution[0]
1975                             * sizeof(int);
1976         cp->matrice = (int *) opj_malloc(array_size);
1977         memcpy(cp->matrice, parameters->cp_matrice, array_size);
1978     }
1979 
1980     /* creation of an index file ? */
1981     cp->index_on = parameters->index_on;
1982     if (cp->index_on) {
1983         j3d->volume_info = (opj_volume_info_t*)opj_malloc(sizeof(opj_volume_info_t));
1984     }
1985 
1986     /* tiles */
1987     cp->tdx = parameters->cp_tdx;
1988     cp->tdy = parameters->cp_tdy;
1989     cp->tdz = parameters->cp_tdz;
1990     /* tile offset */
1991     cp->tx0 = parameters->cp_tx0;
1992     cp->ty0 = parameters->cp_ty0;
1993     cp->tz0 = parameters->cp_tz0;
1994     /* comment string */
1995     if (parameters->cp_comment) {
1996         cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1);
1997         if (cp->comment) {
1998             strcpy(cp->comment, parameters->cp_comment);
1999         }
2000     }
2001 
2002     /*calculate other encoding parameters*/
2003     if (parameters->tile_size_on) {
2004         cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx);
2005         cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy);
2006         cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz);
2007     } else {
2008         cp->tdx = volume->x1 - cp->tx0;
2009         cp->tdy = volume->y1 - cp->ty0;
2010         cp->tdz = volume->z1 - cp->tz0;
2011     }
2012 
2013     /* initialize the multiple tiles */
2014     /* ---------------------------- */
2015     cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(
2016                                             opj_tcp_t));
2017 
2018     for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) {
2019         opj_tcp_t *tcp = &cp->tcps[tileno];
2020         tcp->numlayers = parameters->tcp_numlayers;
2021         for (j = 0; j < tcp->numlayers; j++) {
2022             if (cp->fixed_quality) {    /* add fixed_quality */
2023                 tcp->distoratio[j] = parameters->tcp_distoratio[j];
2024             } else {
2025                 tcp->rates[j] = parameters->tcp_rates[j];
2026             }
2027         }
2028         tcp->csty = parameters->csty;
2029         tcp->prg = parameters->prog_order;
2030         tcp->mct = volume->numcomps == 3 ? 1 : 0;
2031 
2032         numpocs_tile = 0;
2033         tcp->POC = 0;
2034         if (parameters->numpocs) {
2035             /* initialisation of POC */
2036             tcp->POC = 1;
2037             for (i = 0; i < parameters->numpocs; i++) {
2038                 if ((tileno == parameters->POC[i].tile - 1) ||
2039                         (parameters->POC[i].tile == -1)) {
2040                     opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile];
2041                     tcp_poc->resno0     = parameters->POC[numpocs_tile].resno0;
2042                     tcp_poc->compno0    = parameters->POC[numpocs_tile].compno0;
2043                     tcp_poc->layno1     = parameters->POC[numpocs_tile].layno1;
2044                     tcp_poc->resno1     = parameters->POC[numpocs_tile].resno1;
2045                     tcp_poc->compno1    = parameters->POC[numpocs_tile].compno1;
2046                     tcp_poc->prg        = parameters->POC[numpocs_tile].prg;
2047                     tcp_poc->tile       = parameters->POC[numpocs_tile].tile;
2048                     numpocs_tile++;
2049                 }
2050             }
2051         }
2052         tcp->numpocs = numpocs_tile;
2053 
2054         tcp->tccps = (opj_tccp_t *) opj_malloc(volume->numcomps * sizeof(opj_tccp_t));
2055 
2056         for (i = 0; i < volume->numcomps; i++) {
2057             opj_tccp_t *tccp = &tcp->tccps[i];
2058             tccp->csty = parameters->csty &
2059                          J3D_CCP_CSTY_PRT;   /* 0 => standard precint || 1 => custom-defined precinct  */
2060             tccp->numresolution[0] = parameters->numresolution[0];
2061             tccp->numresolution[1] = parameters->numresolution[1];
2062             tccp->numresolution[2] = parameters->numresolution[2];
2063             assert(parameters->cblock_init[0] <= T1_MAXCBLKW);
2064             assert(parameters->cblock_init[0] >= T1_MINCBLKW);
2065             assert(parameters->cblock_init[1] <= T1_MAXCBLKH);
2066             assert(parameters->cblock_init[1] >= T1_MINCBLKH);
2067             assert(parameters->cblock_init[2] <= T1_MAXCBLKD);
2068             assert(parameters->cblock_init[2] >= T1_MINCBLKD);
2069             tccp->cblk[0] = int_floorlog2(parameters->cblock_init[0]);
2070             tccp->cblk[1] = int_floorlog2(parameters->cblock_init[1]);
2071             tccp->cblk[2] = int_floorlog2(parameters->cblock_init[2]);
2072             assert(tccp->cblk[0] + tccp->cblk[1] + tccp->cblk[1] <= T1_MAXWHD);
2073             tccp->cblksty = parameters->mode; /*Codeblock style --> Table A.19 (default 0)*/
2074 
2075             /*ATK / transform */
2076             tccp->reversible = parameters->irreversible ? 0 :
2077                                1; /* 0 => DWT 9-7 || 1 => DWT 5-3  */
2078             for (j = 0; j < 3; j++) {
2079                 tccp->dwtid[j] = parameters->irreversible ? 0 :
2080                                  1; /* 0 => DWT 9-7 || 1 => DWT 5-3  */
2081             }
2082 
2083             /* Quantification: SEQNT (Scalar Expounded, value for each subband) / NOQNT (no quant)*/
2084             tccp->qntsty = parameters->irreversible ? J3D_CCP_QNTSTY_SEQNT :
2085                            J3D_CCP_QNTSTY_NOQNT;
2086             tccp->numgbits = 2;
2087             if (i == parameters->roi_compno) {
2088                 tccp->roishift = parameters->roi_shift;
2089             } else {
2090                 tccp->roishift = 0;
2091             }
2092             /* Custom defined precints */
2093             if (parameters->csty & J3D_CCP_CSTY_PRT) {
2094                 int k;
2095                 for (k = 0; k < 3; k++) {
2096                     int p = 0;
2097                     for (j = tccp->numresolution[k] - 1; j >= 0; j--) {
2098                         if (p < parameters->res_spec) {/* p < number of precinct size specifications */
2099                             if (parameters->prct_init[k][p] < 1) {
2100                                 tccp->prctsiz[k][j] = 1;
2101                             } else {
2102                                 tccp->prctsiz[k][j] = int_floorlog2(parameters->prct_init[k][p]);
2103                             }
2104                         } else {
2105                             int res_spec = parameters->res_spec;
2106                             int size_prct = parameters->prct_init[k][res_spec - 1] >> (p - (res_spec - 1));
2107                             if (size_prct < 1) {
2108                                 tccp->prctsiz[k][j] = 1;
2109                             } else {
2110                                 tccp->prctsiz[k][j] = int_floorlog2(size_prct);
2111                             }
2112                         }
2113                     }
2114                     p++;
2115                 }
2116             } else {
2117                 int k;
2118                 for (k = 0; k < 3; k++) {
2119                     for (j = 0; j < tccp->numresolution[k]; j++) {
2120                         tccp->prctsiz[k][j] = 15;
2121                     }
2122                 }
2123             }
2124             /*Calcular stepsize for each subband (if NOQNT -->stepsize = 1.0)*/
2125             dwt_calc_explicit_stepsizes(tccp, volume->comps[i].prec);
2126         }
2127     }
2128 }
2129 
2130 /**
2131 Create an index file
2132 @param j3d
2133 @param cio
2134 @param volume_info
2135 @param index Index filename
2136 @return Returns 1 if successful, returns 0 otherwise
2137 */
j3d_create_index(opj_j3d_t * j3d,opj_cio_t * cio,opj_volume_info_t * volume_info,char * index)2138 static int j3d_create_index(opj_j3d_t *j3d, opj_cio_t *cio,
2139                             opj_volume_info_t *volume_info, char *index)
2140 {
2141 
2142     int tileno, compno, layno, resno, precno, pack_nb, x, y, z;
2143     FILE *stream = NULL;
2144     double total_disto = 0;
2145 
2146     volume_info->codestream_size = cio_tell(cio) +
2147                                    j3d->pos_correction; /* Correction 14/4/03 suite rmq de Patrick */
2148 
2149     stream = fopen(index, "w");
2150     if (!stream) {
2151         opj_event_msg(j3d->cinfo, EVT_ERROR, "failed to open %s for writing\n", index);
2152         return 0;
2153     }
2154 
2155     fprintf(stream, "w %d\t h %d\t l %d\n", volume_info->volume_w,
2156             volume_info->volume_h, volume_info->volume_l);
2157     fprintf(stream, "TRASNFORM\t%d\n", volume_info->transform_format);
2158     fprintf(stream, "ENTROPY CODING\t%d\n", volume_info->encoding_format);
2159     fprintf(stream, "PROG\t%d\n", volume_info->prog);
2160     fprintf(stream, "TILE\tx %d y %d z %d\n", volume_info->tile_x,
2161             volume_info->tile_y, volume_info->tile_z);
2162     fprintf(stream, "NOTILE\tx %d y %d z %d\n", volume_info->tw, volume_info->th,
2163             volume_info->tl);
2164     fprintf(stream, "COMPONENTS\t%d\n", volume_info->comp);
2165     fprintf(stream, "LAYER\t%d\n", volume_info->layer);
2166     fprintf(stream, "RESOLUTIONS\tx %d y %d z %d\n", volume_info->decomposition[0],
2167             volume_info->decomposition[1], volume_info->decomposition[2]);
2168 
2169     fprintf(stream, "Precint sizes for each resolution:\n");
2170     for (resno = volume_info->decomposition[0]; resno >= 0; resno--) {
2171         fprintf(stream, "Resno %d \t [%d,%d,%d] \n", resno,
2172                 (1 << volume_info->tile[0].prctsiz[0][resno]),
2173                 (1 << volume_info->tile[0].prctsiz[0][resno]),
2174                 (1 << volume_info->tile[0].prctsiz[2][resno]));   /* based on tile 0 */
2175     }
2176     fprintf(stream, "HEADER_END\t%d\n", volume_info->main_head_end);
2177     fprintf(stream, "CODESTREAM\t%d\n", volume_info->codestream_size);
2178     fprintf(stream,
2179             "Num_tile Start_pos End_header End_pos Distotile Nbpix Ratio\n");
2180     for (tileno = 0; tileno < (volume_info->tw * volume_info->th * volume_info->tl);
2181             tileno++) {
2182         fprintf(stream, "%4d\t%9d\t%9d\t%9d\t%9e\t%9d\t%9e\n",
2183                 volume_info->tile[tileno].num_tile,
2184                 volume_info->tile[tileno].start_pos,
2185                 volume_info->tile[tileno].end_header,
2186                 volume_info->tile[tileno].end_pos,
2187                 volume_info->tile[tileno].distotile, volume_info->tile[tileno].nbpix,
2188                 volume_info->tile[tileno].distotile / volume_info->tile[tileno].nbpix);
2189     }
2190 
2191     for (tileno = 0; tileno < (volume_info->tw * volume_info->th * volume_info->tl);
2192             tileno++) {
2193         int start_pos, end_pos;
2194         double disto = 0;
2195         pack_nb = 0;
2196         if (volume_info->prog == LRCP) {    /* LRCP */
2197             fprintf(stream,
2198                     "pack_nb tileno layno resno compno precno start_pos  end_pos   disto\n");
2199             for (layno = 0; layno < volume_info->layer; layno++) {
2200                 for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
2201                     for (compno = 0; compno < volume_info->comp; compno++) {
2202                         int prec_max = volume_info->tile[tileno].prctno[0][resno] *
2203                                        volume_info->tile[tileno].prctno[1][resno] *
2204                                        volume_info->tile[tileno].prctno[2][resno];
2205                         for (precno = 0; precno < prec_max; precno++) {
2206                             start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
2207                             end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
2208                             disto = volume_info->tile[tileno].packet[pack_nb].disto;
2209                             fprintf(stream, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n", pack_nb, tileno, layno,
2210                                     resno, compno, precno, start_pos, end_pos, disto);
2211                             total_disto += disto;
2212                             pack_nb++;
2213                         }
2214                     }
2215                 }
2216             }
2217         } /* LRCP */
2218         else if (volume_info->prog == RLCP) {   /* RLCP */
2219             /*
2220             fprintf(stream, "pack_nb tileno resno layno compno precno start_pos  end_pos   disto");
2221             */
2222             for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
2223                 for (layno = 0; layno < volume_info->layer; layno++) {
2224                     for (compno = 0; compno < volume_info->comp; compno++) {
2225                         int prec_max = volume_info->tile[tileno].prctno[0][resno] *
2226                                        volume_info->tile[tileno].prctno[1][resno] *
2227                                        volume_info->tile[tileno].prctno[2][resno];
2228                         for (precno = 0; precno < prec_max; precno++) {
2229                             start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
2230                             end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
2231                             disto = volume_info->tile[tileno].packet[pack_nb].disto;
2232                             fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %8e\n",
2233                                     pack_nb, tileno, resno, layno, compno, precno, start_pos, end_pos, disto);
2234                             total_disto += disto;
2235                             pack_nb++;
2236                         }
2237                     }
2238                 }
2239             }
2240         } /* RLCP */
2241         else if (volume_info->prog == RPCL) {   /* RPCL */
2242             /*
2243             fprintf(stream, "\npack_nb tileno resno precno compno layno start_pos  end_pos   disto\n");
2244             */
2245             for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
2246                 /* I suppose components have same XRsiz, YRsiz */
2247                 /*int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x;*/
2248                 /*int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y;*/
2249                 int x0 = volume_info->tile_Ox + (int)floor((float)tileno /
2250                          (float)volume_info->tw) * volume_info->tile_x;
2251                 int y0 = volume_info->tile_Oy + (int)floor((float)tileno /
2252                          (float)volume_info->th) * volume_info->tile_y;
2253                 int z0 = volume_info->tile_Ox + (int)floor((float)tileno /
2254                          (float)volume_info->tl) * volume_info->tile_z;
2255                 int x1 = x0 + volume_info->tile_x;
2256                 int y1 = y0 + volume_info->tile_y;
2257                 int z1 = z0 + volume_info->tile_z;
2258                 for (z = z0; z < z1; z++) {
2259                     for (y = y0; y < y1; y++) {
2260                         for (x = x0; x < x1; x++) {
2261                             for (compno = 0; compno < volume_info->comp; compno++) {
2262                                 int prec_max = volume_info->tile[tileno].prctno[0][resno] *
2263                                                volume_info->tile[tileno].prctno[1][resno] *
2264                                                volume_info->tile[tileno].prctno[2][resno];
2265                                 for (precno = 0; precno < prec_max; precno++) {
2266                                     int pcnx = volume_info->tile[tileno].prctno[0][resno];
2267                                     int pcx = (int) pow(2, volume_info->tile[tileno].prctsiz[0][resno] +
2268                                                         volume_info->decomposition[0] - resno);
2269                                     int pcy = (int) pow(2, volume_info->tile[tileno].prctsiz[1][resno] +
2270                                                         volume_info->decomposition[1] - resno);
2271                                     int pcz = (int) pow(2, volume_info->tile[tileno].prctsiz[2][resno] +
2272                                                         volume_info->decomposition[2] - resno);
2273                                     int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
2274                                     int precno_y = (int) floor((float)precno / (float)pcnx);
2275                                     if (precno_y * pcy == y) {
2276                                         if (precno_x * pcx == x) {
2277                                             for (layno = 0; layno < volume_info->layer; layno++) {
2278                                                 start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
2279                                                 end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
2280                                                 disto = volume_info->tile[tileno].packet[pack_nb].disto;
2281                                                 fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %8e\n",
2282                                                         pack_nb, tileno, resno, precno, compno, layno, start_pos, end_pos, disto);
2283                                                 total_disto += disto;
2284                                                 pack_nb++;
2285                                             }
2286                                         }
2287                                     }
2288                                 } /* precno */
2289                             } /* compno */
2290                         } /* x = x0..x1 */
2291                     } /* y = y0..y1 */
2292                 } /* z = z0..z1 */
2293             } /* resno */
2294         } /* RPCL */
2295         else if (volume_info->prog == PCRL) {   /* PCRL */
2296             /* I suppose components have same XRsiz, YRsiz */
2297             int x0 = volume_info->tile_Ox + tileno - (int)floor((float)tileno /
2298                      (float)volume_info->tw) * volume_info->tw * volume_info->tile_x;
2299             int y0 = volume_info->tile_Ox + (int)floor((float)tileno /
2300                      (float)volume_info->tw) * volume_info->tile_y;
2301             int z0 = volume_info->tile_Oz + (int)floor((float)tileno /
2302                      (float)volume_info->tw) * volume_info->tile_z;
2303             int x1 = x0 + volume_info->tile_x;
2304             int y1 = y0 + volume_info->tile_y;
2305             int z1 = z0 + volume_info->tile_z;
2306             /*
2307             fprintf(stream, "\npack_nb tileno precno compno resno layno start_pos  end_pos   disto\n");
2308             */
2309             for (z = z0; z < z1; z++) {
2310                 for (y = y0; y < y1; y++) {
2311                     for (x = x0; x < x1; x++) {
2312                         for (compno = 0; compno < volume_info->comp; compno++) {
2313                             for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
2314                                 int prec_max = volume_info->tile[tileno].prctno[0][resno] *
2315                                                volume_info->tile[tileno].prctno[1][resno];
2316                                 for (precno = 0; precno < prec_max; precno++) {
2317                                     int pcnx = volume_info->tile[tileno].prctno[0][resno];
2318                                     int pcx = (int) pow(2, volume_info->tile[tileno].prctsiz[0][resno] +
2319                                                         volume_info->decomposition[0] - resno);
2320                                     int pcy = (int) pow(2, volume_info->tile[tileno].prctsiz[1][resno] +
2321                                                         volume_info->decomposition[1] - resno);
2322                                     int pcz = (int) pow(2, volume_info->tile[tileno].prctsiz[2][resno] +
2323                                                         volume_info->decomposition[2] - resno);
2324                                     int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
2325                                     int precno_y = (int) floor((float)precno / (float)pcnx);
2326                                     int precno_z = (int) floor((float)precno / (float)pcnx);
2327                                     if (precno_z * pcz == z) {
2328                                         if (precno_y * pcy == y) {
2329                                             if (precno_x * pcx == x) {
2330                                                 for (layno = 0; layno < volume_info->layer; layno++) {
2331                                                     start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
2332                                                     end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
2333                                                     disto = volume_info->tile[tileno].packet[pack_nb].disto;
2334                                                     fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n",
2335                                                             pack_nb, tileno, precno, compno, resno, layno, start_pos, end_pos, disto);
2336                                                     total_disto += disto;
2337                                                     pack_nb++;
2338                                                 }
2339                                             }
2340                                         }
2341                                     }
2342                                 } /* precno */
2343                             } /* resno */
2344                         } /* compno */
2345                     } /* x = x0..x1 */
2346                 } /* y = y0..y1 */
2347             }
2348         } /* PCRL */
2349         else {  /* CPRL */
2350             /*
2351             fprintf(stream, "\npack_nb tileno compno precno resno layno start_pos  end_pos   disto\n");
2352             */
2353             for (compno = 0; compno < volume_info->comp; compno++) {
2354                 /* I suppose components have same XRsiz, YRsiz */
2355                 int x0 = volume_info->tile_Ox + tileno - (int)floor((float)tileno /
2356                          (float)volume_info->tw) * volume_info->tw * volume_info->tile_x;
2357                 int y0 = volume_info->tile_Ox + (int)floor((float)tileno /
2358                          (float)volume_info->tw) * volume_info->tile_y;
2359                 int z0 = volume_info->tile_Oz + (int)floor((float)tileno /
2360                          (float)volume_info->tw) * volume_info->tile_z;
2361                 int x1 = x0 + volume_info->tile_x;
2362                 int y1 = y0 + volume_info->tile_y;
2363                 int z1 = z0 + volume_info->tile_z;
2364                 for (z = z0; z < z1; z++) {
2365                     for (y = y0; y < y1; y++) {
2366                         for (x = x0; x < x1; x++) {
2367                             for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) {
2368                                 int prec_max = volume_info->tile[tileno].prctno[0][resno] *
2369                                                volume_info->tile[tileno].prctno[1][resno] *
2370                                                volume_info->tile[tileno].prctno[2][resno];
2371                                 for (precno = 0; precno < prec_max; precno++) {
2372                                     int pcnx = volume_info->tile[tileno].prctno[0][resno];
2373                                     int pcny = volume_info->tile[tileno].prctno[1][resno];
2374                                     int pcx = (int) pow(2, volume_info->tile[tileno].prctsiz[0][resno] +
2375                                                         volume_info->decomposition[0] - resno);
2376                                     int pcy = (int) pow(2, volume_info->tile[tileno].prctsiz[1][resno] +
2377                                                         volume_info->decomposition[1] - resno);
2378                                     int pcz = (int) pow(2, volume_info->tile[tileno].prctsiz[2][resno] +
2379                                                         volume_info->decomposition[2] - resno);
2380                                     int precno_x = precno - (int) floor((float)precno / (float)pcnx) * pcnx;
2381                                     int precno_y = (int) floor((float)precno / (float)pcnx);
2382                                     int precno_z = 0; /*???*/
2383                                     if (precno_z * pcz == z) {
2384                                         if (precno_y * pcy == y) {
2385                                             if (precno_x * pcx == x) {
2386                                                 for (layno = 0; layno < volume_info->layer; layno++) {
2387                                                     start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos;
2388                                                     end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos;
2389                                                     disto = volume_info->tile[tileno].packet[pack_nb].disto;
2390                                                     fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n",
2391                                                             pack_nb, tileno, compno, precno, resno, layno, start_pos, end_pos, disto);
2392                                                     total_disto += disto;
2393                                                     pack_nb++;
2394                                                 }
2395                                             }
2396                                         }
2397                                     }
2398                                 } /* precno */
2399                             } /* resno */
2400                         } /* x = x0..x1 */
2401                     } /* y = y0..y1 */
2402                 } /* z = z0..z1 */
2403             } /* comno */
2404         } /* CPRL */
2405     } /* tileno */
2406 
2407     fprintf(stream, "SE_MAX\t%8e\n", volume_info->D_max);   /* SE max */
2408     fprintf(stream, "SE_TOTAL\t%.8e\n", total_disto);           /* SE totale */
2409 
2410 
2411     fclose(stream);
2412 
2413     return 1;
2414 }
2415 
j3d_encode(opj_j3d_t * j3d,opj_cio_t * cio,opj_volume_t * volume,char * index)2416 bool j3d_encode(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_t *volume,
2417                 char *index)
2418 {
2419     int tileno, compno;
2420     opj_volume_info_t *volume_info = NULL;
2421     opj_cp_t *cp = NULL;
2422     opj_tcd_t *tcd = NULL;  /* TCD component */
2423 
2424     j3d->cio = cio;
2425     j3d->volume = volume;
2426     cp = j3d->cp;
2427 
2428     /*j3d_dump_volume(stdout, volume);
2429     j3d_dump_cp(stdout, volume, cp);*/
2430 
2431     /* INDEX >> */
2432     volume_info = j3d->volume_info;
2433     if (volume_info && cp->index_on) {
2434         volume_info->index_on = cp->index_on;
2435         volume_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * cp->tl *
2436                             sizeof(opj_tile_info_t));
2437         volume_info->volume_w = volume->x1 - volume->x0;
2438         volume_info->volume_h = volume->y1 - volume->y0;
2439         volume_info->volume_l = volume->z1 - volume->z0;
2440         volume_info->prog = (&cp->tcps[0])->prg;
2441         volume_info->tw = cp->tw;
2442         volume_info->th = cp->th;
2443         volume_info->tl = cp->tl;
2444         volume_info->tile_x = cp->tdx;  /* new version parser */
2445         volume_info->tile_y = cp->tdy;  /* new version parser */
2446         volume_info->tile_z = cp->tdz;  /* new version parser */
2447         volume_info->tile_Ox = cp->tx0; /* new version parser */
2448         volume_info->tile_Oy = cp->ty0; /* new version parser */
2449         volume_info->tile_Oz = cp->tz0; /* new version parser */
2450         volume_info->transform_format = cp->transform_format;
2451         volume_info->encoding_format = cp->encoding_format;
2452         volume_info->comp = volume->numcomps;
2453         volume_info->layer = (&cp->tcps[0])->numlayers;
2454         volume_info->decomposition[0] = (&cp->tcps[0])->tccps->numresolution[0] - 1;
2455         volume_info->decomposition[1] = (&cp->tcps[0])->tccps->numresolution[1] - 1;
2456         volume_info->decomposition[2] = (&cp->tcps[0])->tccps->numresolution[2] - 1;
2457         volume_info->D_max = 0;     /* ADD Marcela */
2458     }
2459     /* << INDEX */
2460 
2461     j3d_write_soc(j3d);
2462     j3d_write_siz(j3d);
2463     if (j3d->cinfo->codec_format == CODEC_J3D) {
2464         j3d_write_cap(j3d);
2465         j3d_write_nsi(j3d);
2466     }
2467 
2468     /*if (j3d->cp->transform_format != TRF_2D_DWT || j3d->cp->encoding_format != ENCOD_2EB)*/
2469     j3d_write_com(j3d);
2470 
2471     j3d_write_cod(j3d);
2472     j3d_write_qcd(j3d);
2473     for (compno = 0; compno < volume->numcomps; compno++) {
2474         opj_tcp_t *tcp = &cp->tcps[0];
2475         if (tcp->tccps[compno].roishift) {
2476             j3d_write_rgn(j3d, compno, 0);
2477         }
2478     }
2479     /*Optional 15444-2 markers*/
2480     if (j3d->cp->tcps->tccps[0].atk != NULL) {
2481         j3d_write_atk(j3d);
2482     }
2483     if (j3d->volume->comps[0].dcoffset != 0) {
2484         j3d_write_dco(j3d);
2485     }
2486 
2487     /* INDEX >> */
2488     if (volume_info && volume_info->index_on) {
2489         volume_info->main_head_end = cio_tell(cio) - 1;
2490     }
2491     /* << INDEX */
2492 
2493     /* create the tile encoder */
2494     tcd = tcd_create(j3d->cinfo);
2495 
2496     /* encode each tile */
2497     for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) {
2498         opj_event_msg(j3d->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1,
2499                       cp->tw * cp->th * cp->tl);
2500 
2501         j3d->curtileno = tileno;
2502 
2503         /* initialisation before tile encoding  */
2504         if (tileno == 0) {
2505             tcd_malloc_encode(tcd, volume, cp, j3d->curtileno);
2506         } else {
2507             tcd_init_encode(tcd, volume, cp, j3d->curtileno);
2508         }
2509 
2510         /* INDEX >> */
2511         if (volume_info && volume_info->index_on) {
2512             volume_info->tile[j3d->curtileno].num_tile = j3d->curtileno;
2513             volume_info->tile[j3d->curtileno].start_pos = cio_tell(cio) +
2514                     j3d->pos_correction;
2515         }
2516         /* << INDEX */
2517 
2518         j3d_write_sot(j3d);
2519 
2520         for (compno = 1; compno < volume->numcomps; compno++) {
2521             j3d_write_coc(j3d, compno);
2522             j3d_write_qcc(j3d, compno);
2523         }
2524 
2525         if (cp->tcps[tileno].numpocs) {
2526             j3d_write_poc(j3d);
2527         }
2528         j3d_write_sod(j3d, tcd); /*--> tcd_encode_tile*/
2529 
2530         /* INDEX >> */
2531         if (volume_info && volume_info->index_on) {
2532             volume_info->tile[j3d->curtileno].end_pos = cio_tell(cio) + j3d->pos_correction
2533                     - 1;
2534         }
2535         /* << INDEX */
2536     }
2537 
2538     /* destroy the tile encoder */
2539     tcd_free_encode(tcd);
2540     tcd_destroy(tcd);
2541 
2542     j3d_write_eoc(j3d);
2543 
2544     /* Creation of the index file */
2545     if (volume_info && volume_info->index_on) {
2546         if (!j3d_create_index(j3d, cio, volume_info, index)) {
2547             opj_event_msg(j3d->cinfo, EVT_ERROR, "failed to create index file %s\n", index);
2548             return false;
2549         }
2550     }
2551 
2552     return true;
2553 }
2554 
2555 /* ----------------------------------------------------------------------- */
2556 /*@}*/
2557 
2558 /*@}*/
2559 
2560