Fix some typos (found by codespell)
[openjpeg.git] / src / lib / openjpip / index_manager.c
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
5  * Copyright (c) 2002-2014, Professor Benoit Macq
6  * Copyright (c) 2010-2011, Kaori Hagihara
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <math.h>
34 #include <string.h>
35
36 #include "opj_inttypes.h"
37 #include "index_manager.h"
38 #include "box_manager.h"
39 #include "manfbox_manager.h"
40 #include "mhixbox_manager.h"
41 #include "codestream_manager.h"
42 #include "marker_manager.h"
43 #include "faixbox_manager.h"
44 #include "boxheader_manager.h"
45
46 #ifdef SERVER
47 #include "fcgi_stdio.h"
48 #define logstream FCGI_stdout
49 #else
50 #define FCGI_stdout stdout
51 #define FCGI_stderr stderr
52 #define logstream stderr
53 #endif /*SERVER*/
54
55 /**
56  * check JP2 box indexing
57  *
58  * @param[in] toplev_boxlist top level box list
59  * @return                   if correct (true) or wrong (false)
60  */
61 OPJ_BOOL check_JP2boxidx(boxlist_param_t *toplev_boxlist);
62
63 /**
64  * set code index parameters (parse cidx box)
65  * Annex I
66  *
67  * @param[in]  cidx_box pointer to the reference cidx_box
68  * @param[out] codeidx  pointer to index parameters
69  * @return              if succeeded (true) or failed (false)
70  */
71 OPJ_BOOL set_cidxdata(box_param_t *cidx_box, index_param_t *codeidx);
72
73 index_param_t * parse_jp2file(int fd)
74 {
75     index_param_t *jp2idx;
76     box_param_t *cidx;
77     metadatalist_param_t *metadatalist;
78     boxlist_param_t *toplev_boxlist;
79     Byte8_t filesize;
80
81     if (!(filesize = (Byte8_t)get_filesize(fd))) {
82         return NULL;
83     }
84
85     if (!(toplev_boxlist = get_boxstructure(fd, 0, filesize))) {
86         fprintf(FCGI_stderr, "Error: Not correctl JP2 format\n");
87         return NULL;
88     }
89
90     if (!check_JP2boxidx(toplev_boxlist)) {
91         fprintf(FCGI_stderr, "Index format not supported\n");
92         delete_boxlist(&toplev_boxlist);
93         return NULL;
94     }
95
96     if (!(cidx = search_box("cidx", toplev_boxlist))) {
97         fprintf(FCGI_stderr, "Box cidx not found\n");
98         delete_boxlist(&toplev_boxlist);
99         return NULL;
100     }
101
102     jp2idx = (index_param_t *)opj_malloc(sizeof(index_param_t));
103
104     if (!set_cidxdata(cidx, jp2idx)) {
105         fprintf(FCGI_stderr, "Error: Not correctl format in cidx box\n");
106         opj_free(jp2idx);
107         delete_boxlist(&toplev_boxlist);
108         return NULL;
109     }
110     delete_boxlist(&toplev_boxlist);
111
112     metadatalist = const_metadatalist(fd);
113     jp2idx->metadatalist = metadatalist;
114
115 #ifndef SERVER
116     fprintf(logstream, "local log: code index created\n");
117 #endif
118
119     return jp2idx;
120 }
121
122 void print_index(index_param_t index)
123 {
124     int i;
125
126     fprintf(logstream, "index info:\n");
127     fprintf(logstream, "\tCodestream  Offset: %#" PRIx64 "\n", index.offset);
128     fprintf(logstream, "\t            Length: %#" PRIx64 "\n", index.length);
129     fprintf(logstream, "\tMain header Length: %#" PRIx64 "\n", index.mhead_length);
130
131     print_SIZ(index.SIZ);
132     print_COD(index.COD);
133
134     fprintf(logstream, "Tile part information: \n");
135     print_faixbox(index.tilepart);
136
137     fprintf(logstream, "Tile header information: \n");
138     for (i = 0; i < (int)(index.SIZ.XTnum * index.SIZ.YTnum); i++) {
139         print_mhixbox(index.tileheader[i]);
140     }
141
142     fprintf(logstream, "Precinct packet information: \n");
143     for (i = 0; i < index.SIZ.Csiz; i++) {
144         fprintf(logstream, "Component %d\n", i);
145         print_faixbox(index.precpacket[i]);
146     }
147
148     print_allmetadata(index.metadatalist);
149 }
150
151 void print_SIZ(SIZmarker_param_t SIZ)
152 {
153     int i;
154
155     fprintf(logstream, "\tImage and Tile SIZ parameters\n");
156     fprintf(logstream, "\t              Rsiz: %#x\n", SIZ.Rsiz);
157     fprintf(logstream, "\t        Xsiz, Ysiz: (%d,%d) = (%#x, %#x)\n", SIZ.Xsiz,
158             SIZ.Ysiz, SIZ.Xsiz, SIZ.Ysiz);
159     fprintf(logstream, "\t      XOsiz, YOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XOsiz,
160             SIZ.YOsiz, SIZ.XOsiz, SIZ.YOsiz);
161     fprintf(logstream, "\t      XTsiz, YTsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTsiz,
162             SIZ.YTsiz, SIZ.XTsiz, SIZ.YTsiz);
163     fprintf(logstream, "\t    XTOsiz, YTOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTOsiz,
164             SIZ.YTOsiz, SIZ.XTOsiz, SIZ.YTOsiz);
165     fprintf(logstream, "\t    XTnum, YTnum: (%d,%d)\n", SIZ.XTnum, SIZ.YTnum);
166     fprintf(logstream, "\t Num of Components: %d\n", SIZ.Csiz);
167
168     for (i = 0; i < SIZ.Csiz; i++) {
169         fprintf(logstream,
170                 "\t[%d] (Ssiz, XRsiz, YRsiz): (%d, %d, %d) = (%#x, %#x, %#x)\n", i, SIZ.Ssiz[i],
171                 SIZ.XRsiz[i], SIZ.YRsiz[i], SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i]);
172     }
173 }
174
175 void print_COD(CODmarker_param_t COD)
176 {
177     int i;
178
179     fprintf(logstream, "\tCoding style default COD parameters\n");
180     fprintf(logstream,
181             "\t Progression order: %d [ LRCP=0, RLCP=1, RPCL=2, PCRL=3, CPRL=4]\n",
182             COD.prog_order);
183     fprintf(logstream, "\t     Num of layers: %d\n", COD.numOflayers);
184     fprintf(logstream, "\t Decomposition lvl: %d\n", COD.numOfdecomp);
185
186     for (i = 0; i <= ((COD.Scod & 0x01) ? COD.numOfdecomp : 0); i++) {
187         fprintf(logstream, "\t  [%d] XPsiz, YPsiz: (%d,%d) = (%#x, %#x)\n", i,
188                 COD.XPsiz[i], COD.YPsiz[i], COD.XPsiz[i], COD.YPsiz[i]);
189     }
190 }
191
192 void delete_index(index_param_t **index)
193 {
194     int i;
195
196     delete_metadatalist(&((*index)->metadatalist));
197
198     delete_COD((*index)->COD);
199
200     delete_faixbox(&((*index)->tilepart));
201
202     for (i = 0; i < (int)((*index)->SIZ.XTnum * (*index)->SIZ.YTnum); i++) {
203         delete_mhixbox(&((*index)->tileheader[i]));
204     }
205     opj_free((*index)->tileheader);
206
207     for (i = 0; i < (*index)->SIZ.Csiz; i++) {
208         delete_faixbox(&((*index)->precpacket[i]));
209     }
210     opj_free((*index)->precpacket);
211
212     opj_free(*index);
213 }
214
215 void delete_COD(CODmarker_param_t COD)
216 {
217     if (COD.XPsiz) {
218         opj_free(COD.XPsiz);
219     }
220     if (COD.YPsiz) {
221         opj_free(COD.YPsiz);
222     }
223 }
224
225 OPJ_BOOL check_JP2boxidx(boxlist_param_t *toplev_boxlist)
226 {
227     box_param_t *iptr, *fidx, *prxy;
228     box_param_t *cidx, *jp2c;
229     Byte8_t off;
230     Byte8_t len;
231     int pos;
232     Byte8_t ooff;
233     boxheader_param_t *obh;
234     Byte_t ni;
235     Byte8_t ioff;
236     boxheader_param_t *ibh;
237
238     iptr = search_box("iptr", toplev_boxlist);
239     fidx = search_box("fidx", toplev_boxlist);
240     cidx = search_box("cidx", toplev_boxlist);
241     jp2c = search_box("jp2c", toplev_boxlist);
242     prxy = gene_childboxbyType(fidx, 0, "prxy");
243
244     off = fetch_DBox8bytebigendian(iptr, 0);
245     if (off != (Byte8_t)fidx->offset) {
246         fprintf(FCGI_stderr,
247                 "Reference File Index box offset in Index Finder box not correct\n");
248     }
249
250     len = fetch_DBox8bytebigendian(iptr, 8);
251     if (len != fidx->length) {
252         fprintf(FCGI_stderr,
253                 "Reference File Index box length in Index Finder box not correct\n");
254     }
255
256     pos = 0;
257     ooff = fetch_DBox8bytebigendian(prxy, pos);
258     if (ooff != (Byte8_t)jp2c->offset) {
259         fprintf(FCGI_stderr, "Reference jp2c offset in prxy box not correct\n");
260     }
261     pos += 8;
262
263     obh = gene_childboxheader(prxy, pos);
264     if (obh->length != jp2c->length || strncmp(obh->type, "jp2c", 4) != 0) {
265         fprintf(FCGI_stderr, "Reference jp2c header in prxy box not correct\n");
266     }
267     pos += obh->headlen;
268     opj_free(obh);
269
270     ni = fetch_DBox1byte(prxy, pos);
271     if (ni != 1) {
272         fprintf(FCGI_stderr, "Multiple indexes not supported\n");
273         opj_free(prxy);
274         return OPJ_FALSE;
275     }
276     pos += 1;
277
278     ioff = fetch_DBox8bytebigendian(prxy, pos);
279     if (ioff != (Byte8_t)cidx->offset) {
280         fprintf(FCGI_stderr, "Reference cidx offset in prxy box not correct\n");
281     }
282     pos += 8;
283
284     ibh = gene_childboxheader(prxy, pos);
285     if (ibh->length != cidx->length || strncmp(ibh->type, "cidx", 4) != 0) {
286         fprintf(FCGI_stderr, "Reference cidx header in prxy box not correct\n");
287     }
288     pos += ibh->headlen;
289     opj_free(ibh);
290
291     opj_free(prxy);
292
293     return OPJ_TRUE;
294 }
295
296 /**
297  * set code index parameters from cptr box
298  * I.3.2.2 Codestream Finder box
299  *
300  * @param[in]  cidx_box pointer to the reference cidx_box
301  * @param[out] jp2idx   pointer to index parameters
302  * @return              if succeeded (true) or failed (false)
303  */
304 OPJ_BOOL set_cptrdata(box_param_t *cidx_box, index_param_t *jp2idx);
305
306 /**
307  * set code index parameters from mhix box for main header
308  * I.3.2.4.3 Header Index Table box
309  *
310  * @param[in]  cidx_box   pointer to the reference cidx_box
311  * @param[in]  codestream codestream parameters
312  * @param[out] jp2idx     pointer to index parameters
313  * @return                if succeeded (true) or failed (false)
314  */
315 OPJ_BOOL set_mainmhixdata(box_param_t *cidx_box, codestream_param_t codestream,
316                           index_param_t *jp2idx);
317
318 /**
319  * set code index parameters from tpix box
320  * I.3.2.4.4 Tile-part Index Table box
321  *
322  * @param[in]  cidx_box   pointer to the reference cidx_box
323  * @param[out] jp2idx     pointer to index parameters
324  * @return                if succeeded (true) or failed (false)
325  */
326 OPJ_BOOL set_tpixdata(box_param_t *cidx_box, index_param_t *jp2idx);
327
328 /**
329  * set code index parameters from thix box
330  * I.3.2.4.5 Tile Header Index Table box
331  *
332  * @param[in]  cidx_box   pointer to the reference cidx_box
333  * @param[out] jp2idx     pointer to index parameters
334  * @return                if succeeded (true) or failed (false)
335  */
336 OPJ_BOOL set_thixdata(box_param_t *cidx_box, index_param_t *jp2idx);
337
338 /**
339  * set code index parameters from ppix box
340  * I.3.2.4.6 Precinct Packet Index Table box
341  *
342  * @param[in]  cidx_box   pointer to the reference cidx_box
343  * @param[out] jp2idx     pointer to index parameters
344  * @return                if succeeded (true) or failed (false)
345  */
346 OPJ_BOOL set_ppixdata(box_param_t *cidx_box, index_param_t *jp2idx);
347
348 OPJ_BOOL set_cidxdata(box_param_t *cidx_box, index_param_t *jp2idx)
349 {
350     box_param_t *manf_box;
351     manfbox_param_t *manf;
352     codestream_param_t codestream;
353
354     set_cptrdata(cidx_box, jp2idx);
355
356     codestream = set_codestream(cidx_box->fd, jp2idx->offset, jp2idx->length);
357
358     manf_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
359                               get_DBoxlen(cidx_box), "manf");
360     manf = gene_manfbox(manf_box);
361
362     if (!search_boxheader("mhix", manf)) {
363         fprintf(FCGI_stderr, "Error: mhix box not present in manfbox\n");
364         opj_free(jp2idx);
365         delete_manfbox(&manf);
366         return OPJ_FALSE;
367     }
368     set_mainmhixdata(cidx_box, codestream, jp2idx);
369
370     if (!search_boxheader("tpix", manf)) {
371         fprintf(FCGI_stderr, "Error: tpix box not present in manfbox\n");
372         opj_free(jp2idx);
373         delete_manfbox(&manf);
374         return OPJ_FALSE;
375     }
376     set_tpixdata(cidx_box, jp2idx);
377
378     if (!search_boxheader("thix", manf)) {
379         fprintf(FCGI_stderr, "Error: thix box not present in manfbox\n");
380         opj_free(jp2idx);
381         delete_manfbox(&manf);
382         return OPJ_FALSE;
383     }
384     set_thixdata(cidx_box, jp2idx);
385
386     if (!search_boxheader("ppix", manf)) {
387         fprintf(FCGI_stderr, "Error: ppix box not present in manfbox\n");
388         opj_free(jp2idx);
389         delete_manfbox(&manf);
390         return OPJ_FALSE;
391     }
392     set_ppixdata(cidx_box, jp2idx);
393
394     delete_manfbox(&manf);
395     opj_free(manf_box);
396
397     return OPJ_TRUE;
398 }
399
400 OPJ_BOOL set_cptrdata(box_param_t *cidx_box, index_param_t *jp2idx)
401 {
402     box_param_t *box;   /**< cptr box*/
403     Byte2_t dr, cont;
404
405     if (!(box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
406                                get_DBoxlen(cidx_box), "cptr"))) {
407         return OPJ_FALSE;
408     }
409
410     /* DR: Data Reference. */
411     /* If 0, the codestream or its Fragment Table box exists in the current file*/
412     if ((dr = fetch_DBox2bytebigendian(box, 0))) {
413         fprintf(FCGI_stderr, "Error: Codestream not present in current file\n");
414         opj_free(box);
415         return OPJ_FALSE;
416     }
417
418     /* CONT: Container Type*/
419     /* If 0, the entire codestream appears as a contiguous range of*/
420     /* bytes within its file or resource.*/
421     if ((cont = fetch_DBox2bytebigendian(box, 2))) {
422         fprintf(FCGI_stderr, "Error: Can't cope with fragmented codestreams yet\n");
423         opj_free(box);
424         return OPJ_FALSE;
425     }
426
427     jp2idx->offset = (OPJ_OFF_T)fetch_DBox8bytebigendian(box, 4);
428     jp2idx->length = fetch_DBox8bytebigendian(box, 12);
429
430     opj_free(box);
431
432     return OPJ_TRUE;
433 }
434
435
436 /**
437  * set SIZ marker information
438  * A.5 Fixed information marker segment
439  * A.5.1 Image and tile size (SIZ)
440  *
441  * @param[in]  sizmkidx   pointer to SIZ marker index in mhix box
442  * @param[in]  codestream codestream parameters
443  * @param[out] SIZ        SIZ marker parameters pointer
444  * @return                if succeeded (true) or failed (false)
445  */
446 OPJ_BOOL set_SIZmkrdata(markeridx_param_t *sizmkidx,
447                         codestream_param_t codestream, SIZmarker_param_t *SIZ);
448
449 /**
450  * set code index parameters from COD marker in codestream
451  * A.6 Functional marker segments
452  * A.6.1 Coding style default (COD)
453  *
454  * @param[in]  codmkidx   pointer to COD marker index in mhix box
455  * @param[in]  codestream codestream parameters
456  * @param[out] COD        COD marker parameters pointer
457  * @return                if succeeded (true) or failed (false)
458  */
459 OPJ_BOOL set_CODmkrdata(markeridx_param_t *codmkidx,
460                         codestream_param_t codestream, CODmarker_param_t *COD);
461
462 OPJ_BOOL set_mainmhixdata(box_param_t *cidx_box, codestream_param_t codestream,
463                           index_param_t *jp2idx)
464 {
465     box_param_t *mhix_box;
466     mhixbox_param_t *mhix;
467     markeridx_param_t *sizmkidx;
468     markeridx_param_t *codmkidx;
469
470     if (!(mhix_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
471                                     get_DBoxlen(cidx_box), "mhix"))) {
472         return OPJ_FALSE;
473     }
474
475     jp2idx->mhead_length = fetch_DBox8bytebigendian(mhix_box, 0);
476
477     mhix = gene_mhixbox(mhix_box);
478     opj_free(mhix_box);
479
480     sizmkidx = search_markeridx(0xff51, mhix);
481     set_SIZmkrdata(sizmkidx, codestream, &(jp2idx->SIZ));
482
483     codmkidx = search_markeridx(0xff52, mhix);
484     set_CODmkrdata(codmkidx, codestream, &(jp2idx->COD));
485
486     delete_mhixbox(&mhix);
487
488     return OPJ_TRUE;
489 }
490
491 OPJ_BOOL set_tpixdata(box_param_t *cidx_box, index_param_t *jp2idx)
492 {
493     box_param_t *tpix_box;   /**< tpix box*/
494     box_param_t *faix_box;   /**< faix box*/
495
496     if (!(tpix_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
497                                     get_DBoxlen(cidx_box), "tpix"))) {
498         fprintf(FCGI_stderr, "Error: tpix box not present in cidx box\n");
499         return OPJ_FALSE;
500     }
501
502     if (!(faix_box = gene_boxbyType(tpix_box->fd, get_DBoxoff(tpix_box),
503                                     get_DBoxlen(tpix_box), "faix"))) {
504         fprintf(FCGI_stderr, "Error: faix box not present in tpix box\n");
505         opj_free(tpix_box);
506         return OPJ_FALSE;
507     }
508
509     jp2idx->tilepart = gene_faixbox(faix_box);
510
511     opj_free(tpix_box);
512     opj_free(faix_box);
513
514     return OPJ_TRUE;
515 }
516
517 OPJ_BOOL set_thixdata(box_param_t *cidx_box, index_param_t *jp2idx)
518 {
519     box_param_t *thix_box, *manf_box, *mhix_box;
520     manfbox_param_t *manf;
521     boxheader_param_t *ptr;
522     mhixbox_param_t *mhix;
523     Byte8_t pos;
524     OPJ_OFF_T mhixseqoff;
525     Byte2_t tile_no;
526
527     if (!(thix_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
528                                     get_DBoxlen(cidx_box), "thix"))) {
529         fprintf(FCGI_stderr, "Error: thix box not present in cidx box\n");
530         return OPJ_FALSE;
531     }
532
533     if (!(manf_box = gene_boxbyType(thix_box->fd, get_DBoxoff(thix_box),
534                                     get_DBoxlen(thix_box), "manf"))) {
535         fprintf(FCGI_stderr, "Error: manf box not present in thix box\n");
536         opj_free(thix_box);
537         return OPJ_FALSE;
538     }
539
540     manf = gene_manfbox(manf_box);
541     ptr = manf->first;
542     mhixseqoff = manf_box->offset + (OPJ_OFF_T)manf_box->length;
543     pos = 0;
544     tile_no = 0;
545     jp2idx->tileheader = (mhixbox_param_t **)opj_malloc(jp2idx->SIZ.XTnum *
546                          jp2idx->SIZ.YTnum * sizeof(mhixbox_param_t *));
547
548     while (ptr) {
549         if (!(mhix_box = gene_boxbyType(thix_box->fd, mhixseqoff + (OPJ_OFF_T)pos,
550                                         get_DBoxlen(thix_box) - manf_box->length - pos, "mhix"))) {
551             fprintf(FCGI_stderr, "Error: mhix box not present in thix box\n");
552             delete_manfbox(&manf);
553             opj_free(manf_box);
554             opj_free(thix_box);
555             return OPJ_FALSE;
556         }
557         mhix = gene_mhixbox(mhix_box);
558
559         pos += mhix_box->length;
560         ptr = ptr->next;
561
562         opj_free(mhix_box);
563         jp2idx->tileheader[tile_no++] = mhix;
564     }
565
566     delete_manfbox(&manf);
567     opj_free(manf_box);
568     opj_free(thix_box);
569
570     return OPJ_TRUE;
571 }
572
573 OPJ_BOOL set_ppixdata(box_param_t *cidx_box, index_param_t *jp2idx)
574 {
575     box_param_t *ppix_box, *faix_box, *manf_box;
576     manfbox_param_t *manf;     /**< manf*/
577     boxheader_param_t *bh;     /**< box headers*/
578     faixbox_param_t *faix;     /**< faix*/
579     OPJ_OFF_T inbox_offset;
580     int comp_idx;
581
582     if (!(ppix_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
583                                     get_DBoxlen(cidx_box), "ppix"))) {
584         fprintf(FCGI_stderr, "Error: ppix box not present in cidx box\n");
585         return OPJ_FALSE;
586     }
587
588     inbox_offset = get_DBoxoff(ppix_box);
589     if (!(manf_box = gene_boxbyType(ppix_box->fd, inbox_offset,
590                                     get_DBoxlen(ppix_box), "manf"))) {
591         fprintf(FCGI_stderr, "Error: manf box not present in ppix box\n");
592         opj_free(ppix_box);
593         return OPJ_FALSE;
594     }
595
596     opj_free(ppix_box);
597
598     manf = gene_manfbox(manf_box);
599     bh = search_boxheader("faix", manf);
600     inbox_offset = manf_box->offset + (OPJ_OFF_T)manf_box->length;
601
602     opj_free(manf_box);
603
604     jp2idx->precpacket = (faixbox_param_t **)opj_malloc(jp2idx->SIZ.Csiz * sizeof(
605                              faixbox_param_t *));
606
607     for (comp_idx = 0; bh != NULL; bh = bh->next, comp_idx++) {
608         if (jp2idx->SIZ.Csiz <= comp_idx) {
609             fprintf(FCGI_stderr,
610                     "Error: num of faix boxes is not identical to num of components in ppix box\n");
611             delete_manfbox(&manf);
612             return OPJ_FALSE;
613         }
614
615         if (!(faix_box = gene_boxbyOffset(cidx_box->fd, inbox_offset))) {
616             fprintf(FCGI_stderr, "Error: faix box not present in ppix box\n");
617             delete_manfbox(&manf);
618             return OPJ_FALSE;
619         }
620
621         faix = gene_faixbox(faix_box);
622         jp2idx->precpacket[comp_idx] = faix;
623
624         inbox_offset = faix_box->offset + (OPJ_OFF_T)faix_box->length;
625         opj_free(faix_box);
626     }
627
628     delete_manfbox(&manf);
629
630     return OPJ_TRUE;
631 }
632
633 OPJ_BOOL set_SIZmkrdata(markeridx_param_t *sizmkidx,
634                         codestream_param_t codestream, SIZmarker_param_t *SIZ)
635 {
636     marker_param_t sizmkr;
637     int i;
638
639     sizmkr = set_marker(codestream, sizmkidx->code, sizmkidx->offset,
640                         sizmkidx->length);
641
642     SIZ->Lsiz = fetch_marker2bytebigendian(sizmkr, 0);
643
644     if (sizmkidx->length != SIZ->Lsiz) {
645         fprintf(FCGI_stderr, "Error: marker %#x index is not correct\n",
646                 sizmkidx->code);
647         return OPJ_FALSE;
648     }
649
650     SIZ->Rsiz   = fetch_marker2bytebigendian(sizmkr, 2);
651     SIZ->Xsiz   = fetch_marker4bytebigendian(sizmkr, 4);
652     SIZ->Ysiz   = fetch_marker4bytebigendian(sizmkr, 8);
653     SIZ->XOsiz  = fetch_marker4bytebigendian(sizmkr, 12);
654     SIZ->YOsiz  = fetch_marker4bytebigendian(sizmkr, 16);
655     SIZ->XTsiz  = fetch_marker4bytebigendian(sizmkr, 20);
656     SIZ->YTsiz  = fetch_marker4bytebigendian(sizmkr, 24);
657     SIZ->XTOsiz = fetch_marker4bytebigendian(sizmkr, 28);
658     SIZ->YTOsiz = fetch_marker4bytebigendian(sizmkr, 32);
659     SIZ->Csiz   = fetch_marker2bytebigendian(sizmkr, 36);
660
661     SIZ->XTnum  = (SIZ->Xsiz - SIZ->XTOsiz + SIZ->XTsiz - 1) / SIZ->XTsiz;
662     SIZ->YTnum  = (SIZ->Ysiz - SIZ->YTOsiz + SIZ->YTsiz - 1) / SIZ->YTsiz;
663
664     for (i = 0; i < (int)SIZ->Csiz; i++) {
665         SIZ->Ssiz[i]  = fetch_marker1byte(sizmkr, 38 + i * 3);
666         SIZ->XRsiz[i] = fetch_marker1byte(sizmkr, 39 + i * 3);
667         SIZ->YRsiz[i] = fetch_marker1byte(sizmkr, 40 + i * 3);
668     }
669     return OPJ_TRUE;
670 }
671
672 OPJ_BOOL set_CODmkrdata(markeridx_param_t *codmkidx,
673                         codestream_param_t codestream, CODmarker_param_t *COD)
674 {
675     marker_param_t codmkr;
676     int i;
677
678     codmkr = set_marker(codestream, codmkidx->code, codmkidx->offset,
679                         codmkidx->length);
680
681     COD->Lcod = fetch_marker2bytebigendian(codmkr, 0);
682
683     if (codmkidx->length != COD->Lcod) {
684         fprintf(FCGI_stderr, "Error: marker %#x index is not correct\n",
685                 codmkidx->code);
686         return OPJ_FALSE;
687     }
688
689     COD->Scod   = fetch_marker1byte(codmkr, 2);
690     COD->prog_order  = fetch_marker1byte(codmkr, 3);
691     COD->numOflayers = fetch_marker2bytebigendian(codmkr, 4);
692     COD->numOfdecomp = fetch_marker1byte(codmkr, 7);
693
694     if (COD->Scod & 0x01) {
695         COD->XPsiz = (Byte4_t *)opj_malloc((OPJ_SIZE_T)(COD->numOfdecomp + 1) * sizeof(
696                                                Byte4_t));
697         COD->YPsiz = (Byte4_t *)opj_malloc((OPJ_SIZE_T)(COD->numOfdecomp + 1) * sizeof(
698                                                Byte4_t));
699
700         for (i = 0; i <= COD->numOfdecomp; i++) {
701             /*precinct size*/
702             COD->XPsiz[i] = (Byte2_t)pow(2, fetch_marker1byte(codmkr, 12 + i) & 0x0F);
703             COD->YPsiz[i] = (Byte2_t)pow(2, (fetch_marker1byte(codmkr,
704                                              12 + i) & 0xF0) >> 4);
705         }
706     } else {
707         COD->XPsiz = (Byte4_t *)opj_malloc(sizeof(Byte4_t));
708         COD->YPsiz = (Byte4_t *)opj_malloc(sizeof(Byte4_t));
709
710         COD->XPsiz[0] = COD->YPsiz[0] = 1 << 15; /* pow(2,15); */
711     }
712     return OPJ_TRUE;
713 }
714
715
716 /* very very generic name see NOMINMAX */
717 #ifdef min
718 #undef min
719 #endif
720 #ifdef max
721 #undef max
722 #endif
723 Byte4_t max(Byte4_t n1, Byte4_t n2);
724 Byte4_t min(Byte4_t n1, Byte4_t n2);
725
726 range_param_t get_tile_range(Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz,
727                              Byte4_t Tsiz, Byte4_t tile_XYid, int level);
728
729 range_param_t get_tile_Xrange(SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
730 {
731     return get_tile_range(SIZ.XOsiz, SIZ.Xsiz, SIZ.XTOsiz, SIZ.XTsiz,
732                           tile_id % SIZ.XTnum, level);
733 }
734
735 range_param_t get_tile_Yrange(SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
736 {
737     return get_tile_range(SIZ.YOsiz, SIZ.Ysiz, SIZ.YTOsiz, SIZ.YTsiz,
738                           tile_id / SIZ.XTnum, level);
739 }
740
741 range_param_t get_tile_range(Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz,
742                              Byte4_t Tsiz, Byte4_t tile_XYid, int level)
743 {
744     range_param_t range;
745     int n;
746
747     range.minvalue = max(Osiz, TOsiz + tile_XYid * Tsiz);
748     range.maxvalue = min(siz,  TOsiz + (tile_XYid + 1) * Tsiz);
749
750     for (n = 0; n < level; n++) {
751         range.minvalue = (Byte4_t)ceil(range.minvalue / 2.0);
752         range.maxvalue = (Byte4_t)ceil(range.maxvalue / 2.0);
753     }
754     return range;
755 }
756
757 Byte4_t get_tile_XSiz(SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
758 {
759     range_param_t tile_Xrange;
760
761     tile_Xrange = get_tile_Xrange(SIZ, tile_id, level);
762     return tile_Xrange.maxvalue - tile_Xrange.minvalue;
763 }
764
765 Byte4_t get_tile_YSiz(SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
766 {
767     range_param_t tile_Yrange;
768
769     tile_Yrange = get_tile_Yrange(SIZ, tile_id, level);
770     return tile_Yrange.maxvalue - tile_Yrange.minvalue;
771 }
772
773 /* TODO: what is this code doing ? will all compiler be able to optimize the following ? */
774 Byte4_t max(Byte4_t n1, Byte4_t n2)
775 {
776     if (n1 < n2) {
777         return n2;
778     } else {
779         return n1;
780     }
781 }
782
783 Byte4_t min(Byte4_t n1, Byte4_t n2)
784 {
785     if (n1 < n2) {
786         return n1;
787     } else {
788         return n2;
789     }
790 }
791
792 OPJ_BOOL isJPTfeasible(index_param_t index)
793 {
794     if (1 < get_nmax(index.tilepart)) {
795         return OPJ_TRUE;
796     } else {
797         return OPJ_FALSE;
798     }
799 }