Reformat whole codebase with astyle.options (#128)
[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  * chekc 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         return OPJ_FALSE;
274     }
275     pos += 1;
276
277     ioff = fetch_DBox8bytebigendian(prxy, pos);
278     if (ioff != (Byte8_t)cidx->offset) {
279         fprintf(FCGI_stderr, "Reference cidx offset in prxy box not correct\n");
280     }
281     pos += 8;
282
283     ibh = gene_childboxheader(prxy, pos);
284     if (ibh->length != cidx->length || strncmp(ibh->type, "cidx", 4) != 0) {
285         fprintf(FCGI_stderr, "Reference cidx header in prxy box not correct\n");
286     }
287     pos += ibh->headlen;
288     opj_free(ibh);
289
290     opj_free(prxy);
291
292     return OPJ_TRUE;
293 }
294
295 /**
296  * set code index parameters from cptr box
297  * I.3.2.2 Codestream Finder box
298  *
299  * @param[in]  cidx_box pointer to the reference cidx_box
300  * @param[out] jp2idx   pointer to index parameters
301  * @return              if succeeded (true) or failed (false)
302  */
303 OPJ_BOOL set_cptrdata(box_param_t *cidx_box, index_param_t *jp2idx);
304
305 /**
306  * set code index parameters from mhix box for main header
307  * I.3.2.4.3 Header Index Table box
308  *
309  * @param[in]  cidx_box   pointer to the reference cidx_box
310  * @param[in]  codestream codestream parameters
311  * @param[out] jp2idx     pointer to index parameters
312  * @return                if succeeded (true) or failed (false)
313  */
314 OPJ_BOOL set_mainmhixdata(box_param_t *cidx_box, codestream_param_t codestream,
315                           index_param_t *jp2idx);
316
317 /**
318  * set code index parameters from tpix box
319  * I.3.2.4.4 Tile-part Index Table box
320  *
321  * @param[in]  cidx_box   pointer to the reference cidx_box
322  * @param[out] jp2idx     pointer to index parameters
323  * @return                if succeeded (true) or failed (false)
324  */
325 OPJ_BOOL set_tpixdata(box_param_t *cidx_box, index_param_t *jp2idx);
326
327 /**
328  * set code index parameters from thix box
329  * I.3.2.4.5 Tile Header Index Table box
330  *
331  * @param[in]  cidx_box   pointer to the reference cidx_box
332  * @param[out] jp2idx     pointer to index parameters
333  * @return                if succeeded (true) or failed (false)
334  */
335 OPJ_BOOL set_thixdata(box_param_t *cidx_box, index_param_t *jp2idx);
336
337 /**
338  * set code index parameters from ppix box
339  * I.3.2.4.6 Precinct Packet Index Table box
340  *
341  * @param[in]  cidx_box   pointer to the reference cidx_box
342  * @param[out] jp2idx     pointer to index parameters
343  * @return                if succeeded (true) or failed (false)
344  */
345 OPJ_BOOL set_ppixdata(box_param_t *cidx_box, index_param_t *jp2idx);
346
347 OPJ_BOOL set_cidxdata(box_param_t *cidx_box, index_param_t *jp2idx)
348 {
349     box_param_t *manf_box;
350     manfbox_param_t *manf;
351     codestream_param_t codestream;
352
353     set_cptrdata(cidx_box, jp2idx);
354
355     codestream = set_codestream(cidx_box->fd, jp2idx->offset, jp2idx->length);
356
357     manf_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
358                               get_DBoxlen(cidx_box), "manf");
359     manf = gene_manfbox(manf_box);
360
361     if (!search_boxheader("mhix", manf)) {
362         fprintf(FCGI_stderr, "Error: mhix box not present in manfbox\n");
363         opj_free(jp2idx);
364         return OPJ_FALSE;
365     }
366     set_mainmhixdata(cidx_box, codestream, jp2idx);
367
368     if (!search_boxheader("tpix", manf)) {
369         fprintf(FCGI_stderr, "Error: tpix box not present in manfbox\n");
370         opj_free(jp2idx);
371         return OPJ_FALSE;
372     }
373     set_tpixdata(cidx_box, jp2idx);
374
375     if (!search_boxheader("thix", manf)) {
376         fprintf(FCGI_stderr, "Error: thix box not present in manfbox\n");
377         opj_free(jp2idx);
378         return OPJ_FALSE;
379     }
380     set_thixdata(cidx_box, jp2idx);
381
382     if (!search_boxheader("ppix", manf)) {
383         fprintf(FCGI_stderr, "Error: ppix box not present in manfbox\n");
384         opj_free(jp2idx);
385         return OPJ_FALSE;
386     }
387     set_ppixdata(cidx_box, jp2idx);
388
389     delete_manfbox(&manf);
390     opj_free(manf_box);
391
392     return OPJ_TRUE;
393 }
394
395 OPJ_BOOL set_cptrdata(box_param_t *cidx_box, index_param_t *jp2idx)
396 {
397     box_param_t *box;   /**< cptr box*/
398     Byte2_t dr, cont;
399
400     if (!(box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
401                                get_DBoxlen(cidx_box), "cptr"))) {
402         return OPJ_FALSE;
403     }
404
405     /* DR: Data Reference. */
406     /* If 0, the codestream or its Fragment Table box exists in the current file*/
407     if ((dr = fetch_DBox2bytebigendian(box, 0))) {
408         fprintf(FCGI_stderr, "Error: Codestream not present in current file\n");
409         opj_free(box);
410         return OPJ_FALSE;
411     }
412
413     /* CONT: Container Type*/
414     /* If 0, the entire codestream appears as a contiguous range of*/
415     /* bytes within its file or resource.*/
416     if ((cont = fetch_DBox2bytebigendian(box, 2))) {
417         fprintf(FCGI_stderr, "Error: Can't cope with fragmented codestreams yet\n");
418         opj_free(box);
419         return OPJ_FALSE;
420     }
421
422     jp2idx->offset = (OPJ_OFF_T)fetch_DBox8bytebigendian(box, 4);
423     jp2idx->length = fetch_DBox8bytebigendian(box, 12);
424
425     opj_free(box);
426
427     return OPJ_TRUE;
428 }
429
430
431 /**
432  * set SIZ marker information
433  * A.5 Fixed information marker segment
434  * A.5.1 Image and tile size (SIZ)
435  *
436  * @param[in]  sizmkidx   pointer to SIZ marker index in mhix box
437  * @param[in]  codestream codestream parameters
438  * @param[out] SIZ        SIZ marker parameters pointer
439  * @return                if succeeded (true) or failed (false)
440  */
441 OPJ_BOOL set_SIZmkrdata(markeridx_param_t *sizmkidx,
442                         codestream_param_t codestream, SIZmarker_param_t *SIZ);
443
444 /**
445  * set code index parameters from COD marker in codestream
446  * A.6 Functional marker segments
447  * A.6.1 Coding style default (COD)
448  *
449  * @param[in]  codmkidx   pointer to COD marker index in mhix box
450  * @param[in]  codestream codestream parameters
451  * @param[out] COD        COD marker parameters pointer
452  * @return                if succeeded (true) or failed (false)
453  */
454 OPJ_BOOL set_CODmkrdata(markeridx_param_t *codmkidx,
455                         codestream_param_t codestream, CODmarker_param_t *COD);
456
457 OPJ_BOOL set_mainmhixdata(box_param_t *cidx_box, codestream_param_t codestream,
458                           index_param_t *jp2idx)
459 {
460     box_param_t *mhix_box;
461     mhixbox_param_t *mhix;
462     markeridx_param_t *sizmkidx;
463     markeridx_param_t *codmkidx;
464
465     if (!(mhix_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
466                                     get_DBoxlen(cidx_box), "mhix"))) {
467         return OPJ_FALSE;
468     }
469
470     jp2idx->mhead_length = fetch_DBox8bytebigendian(mhix_box, 0);
471
472     mhix = gene_mhixbox(mhix_box);
473     opj_free(mhix_box);
474
475     sizmkidx = search_markeridx(0xff51, mhix);
476     set_SIZmkrdata(sizmkidx, codestream, &(jp2idx->SIZ));
477
478     codmkidx = search_markeridx(0xff52, mhix);
479     set_CODmkrdata(codmkidx, codestream, &(jp2idx->COD));
480
481     delete_mhixbox(&mhix);
482
483     return OPJ_TRUE;
484 }
485
486 OPJ_BOOL set_tpixdata(box_param_t *cidx_box, index_param_t *jp2idx)
487 {
488     box_param_t *tpix_box;   /**< tpix box*/
489     box_param_t *faix_box;   /**< faix box*/
490
491     if (!(tpix_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
492                                     get_DBoxlen(cidx_box), "tpix"))) {
493         fprintf(FCGI_stderr, "Error: tpix box not present in cidx box\n");
494         return OPJ_FALSE;
495     }
496
497     if (!(faix_box = gene_boxbyType(tpix_box->fd, get_DBoxoff(tpix_box),
498                                     get_DBoxlen(tpix_box), "faix"))) {
499         fprintf(FCGI_stderr, "Error: faix box not present in tpix box\n");
500         return OPJ_FALSE;
501     }
502
503     jp2idx->tilepart = gene_faixbox(faix_box);
504
505     opj_free(tpix_box);
506     opj_free(faix_box);
507
508     return OPJ_TRUE;
509 }
510
511 OPJ_BOOL set_thixdata(box_param_t *cidx_box, index_param_t *jp2idx)
512 {
513     box_param_t *thix_box, *manf_box, *mhix_box;
514     manfbox_param_t *manf;
515     boxheader_param_t *ptr;
516     mhixbox_param_t *mhix;
517     Byte8_t pos;
518     OPJ_OFF_T mhixseqoff;
519     Byte2_t tile_no;
520
521     if (!(thix_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
522                                     get_DBoxlen(cidx_box), "thix"))) {
523         fprintf(FCGI_stderr, "Error: thix box not present in cidx box\n");
524         return OPJ_FALSE;
525     }
526
527     if (!(manf_box = gene_boxbyType(thix_box->fd, get_DBoxoff(thix_box),
528                                     get_DBoxlen(thix_box), "manf"))) {
529         fprintf(FCGI_stderr, "Error: manf box not present in thix box\n");
530         opj_free(thix_box);
531         return OPJ_FALSE;
532     }
533
534     manf = gene_manfbox(manf_box);
535     ptr = manf->first;
536     mhixseqoff = manf_box->offset + (OPJ_OFF_T)manf_box->length;
537     pos = 0;
538     tile_no = 0;
539     jp2idx->tileheader = (mhixbox_param_t **)opj_malloc(jp2idx->SIZ.XTnum *
540                          jp2idx->SIZ.YTnum * sizeof(mhixbox_param_t *));
541
542     while (ptr) {
543         if (!(mhix_box = gene_boxbyType(thix_box->fd, mhixseqoff + (OPJ_OFF_T)pos,
544                                         get_DBoxlen(thix_box) - manf_box->length - pos, "mhix"))) {
545             fprintf(FCGI_stderr, "Error: mhix box not present in thix box\n");
546             delete_manfbox(&manf);
547             opj_free(manf_box);
548             opj_free(thix_box);
549             return OPJ_FALSE;
550         }
551         mhix = gene_mhixbox(mhix_box);
552
553         pos += mhix_box->length;
554         ptr = ptr->next;
555
556         opj_free(mhix_box);
557         jp2idx->tileheader[tile_no++] = mhix;
558     }
559
560     delete_manfbox(&manf);
561     opj_free(manf_box);
562     opj_free(thix_box);
563
564     return OPJ_TRUE;
565 }
566
567 OPJ_BOOL set_ppixdata(box_param_t *cidx_box, index_param_t *jp2idx)
568 {
569     box_param_t *ppix_box, *faix_box, *manf_box;
570     manfbox_param_t *manf;     /**< manf*/
571     boxheader_param_t *bh;     /**< box headers*/
572     faixbox_param_t *faix;     /**< faix*/
573     OPJ_OFF_T inbox_offset;
574     int comp_idx;
575
576     if (!(ppix_box = gene_boxbyType(cidx_box->fd, get_DBoxoff(cidx_box),
577                                     get_DBoxlen(cidx_box), "ppix"))) {
578         fprintf(FCGI_stderr, "Error: ppix box not present in cidx box\n");
579         return OPJ_FALSE;
580     }
581
582     inbox_offset = get_DBoxoff(ppix_box);
583     if (!(manf_box = gene_boxbyType(ppix_box->fd, inbox_offset,
584                                     get_DBoxlen(ppix_box), "manf"))) {
585         fprintf(FCGI_stderr, "Error: manf box not present in ppix box\n");
586         opj_free(ppix_box);
587         return OPJ_FALSE;
588     }
589
590     opj_free(ppix_box);
591
592     manf = gene_manfbox(manf_box);
593     bh = search_boxheader("faix", manf);
594     inbox_offset = manf_box->offset + (OPJ_OFF_T)manf_box->length;
595
596     opj_free(manf_box);
597
598     jp2idx->precpacket = (faixbox_param_t **)opj_malloc(jp2idx->SIZ.Csiz * sizeof(
599                              faixbox_param_t *));
600
601     for (comp_idx = 0; bh != NULL; bh = bh->next, comp_idx++) {
602         if (jp2idx->SIZ.Csiz <= comp_idx) {
603             fprintf(FCGI_stderr,
604                     "Error: num of faix boxes is not identical to num of components in ppix box\n");
605             return OPJ_FALSE;
606         }
607
608         if (!(faix_box = gene_boxbyOffset(cidx_box->fd, inbox_offset))) {
609             fprintf(FCGI_stderr, "Error: faix box not present in ppix box\n");
610             return OPJ_FALSE;
611         }
612
613         faix = gene_faixbox(faix_box);
614         jp2idx->precpacket[comp_idx] = faix;
615
616         inbox_offset = faix_box->offset + (OPJ_OFF_T)faix_box->length;
617         opj_free(faix_box);
618     }
619
620     delete_manfbox(&manf);
621
622     return OPJ_TRUE;
623 }
624
625 OPJ_BOOL set_SIZmkrdata(markeridx_param_t *sizmkidx,
626                         codestream_param_t codestream, SIZmarker_param_t *SIZ)
627 {
628     marker_param_t sizmkr;
629     int i;
630
631     sizmkr = set_marker(codestream, sizmkidx->code, sizmkidx->offset,
632                         sizmkidx->length);
633
634     SIZ->Lsiz = fetch_marker2bytebigendian(sizmkr, 0);
635
636     if (sizmkidx->length != SIZ->Lsiz) {
637         fprintf(FCGI_stderr, "Error: marker %#x index is not correct\n",
638                 sizmkidx->code);
639         return OPJ_FALSE;
640     }
641
642     SIZ->Rsiz   = fetch_marker2bytebigendian(sizmkr, 2);
643     SIZ->Xsiz   = fetch_marker4bytebigendian(sizmkr, 4);
644     SIZ->Ysiz   = fetch_marker4bytebigendian(sizmkr, 8);
645     SIZ->XOsiz  = fetch_marker4bytebigendian(sizmkr, 12);
646     SIZ->YOsiz  = fetch_marker4bytebigendian(sizmkr, 16);
647     SIZ->XTsiz  = fetch_marker4bytebigendian(sizmkr, 20);
648     SIZ->YTsiz  = fetch_marker4bytebigendian(sizmkr, 24);
649     SIZ->XTOsiz = fetch_marker4bytebigendian(sizmkr, 28);
650     SIZ->YTOsiz = fetch_marker4bytebigendian(sizmkr, 32);
651     SIZ->Csiz   = fetch_marker2bytebigendian(sizmkr, 36);
652
653     SIZ->XTnum  = (SIZ->Xsiz - SIZ->XTOsiz + SIZ->XTsiz - 1) / SIZ->XTsiz;
654     SIZ->YTnum  = (SIZ->Ysiz - SIZ->YTOsiz + SIZ->YTsiz - 1) / SIZ->YTsiz;
655
656     for (i = 0; i < (int)SIZ->Csiz; i++) {
657         SIZ->Ssiz[i]  = fetch_marker1byte(sizmkr, 38 + i * 3);
658         SIZ->XRsiz[i] = fetch_marker1byte(sizmkr, 39 + i * 3);
659         SIZ->YRsiz[i] = fetch_marker1byte(sizmkr, 40 + i * 3);
660     }
661     return OPJ_TRUE;
662 }
663
664 OPJ_BOOL set_CODmkrdata(markeridx_param_t *codmkidx,
665                         codestream_param_t codestream, CODmarker_param_t *COD)
666 {
667     marker_param_t codmkr;
668     int i;
669
670     codmkr = set_marker(codestream, codmkidx->code, codmkidx->offset,
671                         codmkidx->length);
672
673     COD->Lcod = fetch_marker2bytebigendian(codmkr, 0);
674
675     if (codmkidx->length != COD->Lcod) {
676         fprintf(FCGI_stderr, "Error: marker %#x index is not correct\n",
677                 codmkidx->code);
678         return OPJ_FALSE;
679     }
680
681     COD->Scod   = fetch_marker1byte(codmkr, 2);
682     COD->prog_order  = fetch_marker1byte(codmkr, 3);
683     COD->numOflayers = fetch_marker2bytebigendian(codmkr, 4);
684     COD->numOfdecomp = fetch_marker1byte(codmkr, 7);
685
686     if (COD->Scod & 0x01) {
687         COD->XPsiz = (Byte4_t *)opj_malloc((OPJ_SIZE_T)(COD->numOfdecomp + 1) * sizeof(
688                                                Byte4_t));
689         COD->YPsiz = (Byte4_t *)opj_malloc((OPJ_SIZE_T)(COD->numOfdecomp + 1) * sizeof(
690                                                Byte4_t));
691
692         for (i = 0; i <= COD->numOfdecomp; i++) {
693             /*precinct size*/
694             COD->XPsiz[i] = (Byte2_t)pow(2, fetch_marker1byte(codmkr, 12 + i) & 0x0F);
695             COD->YPsiz[i] = (Byte2_t)pow(2, (fetch_marker1byte(codmkr,
696                                              12 + i) & 0xF0) >> 4);
697         }
698     } else {
699         COD->XPsiz = (Byte4_t *)opj_malloc(sizeof(Byte4_t));
700         COD->YPsiz = (Byte4_t *)opj_malloc(sizeof(Byte4_t));
701
702         COD->XPsiz[0] = COD->YPsiz[0] = 1 << 15; /* pow(2,15); */
703     }
704     return OPJ_TRUE;
705 }
706
707
708 /* very very generic name see NOMINMAX */
709 #ifdef min
710 #undef min
711 #endif
712 #ifdef max
713 #undef max
714 #endif
715 Byte4_t max(Byte4_t n1, Byte4_t n2);
716 Byte4_t min(Byte4_t n1, Byte4_t n2);
717
718 range_param_t get_tile_range(Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz,
719                              Byte4_t Tsiz, Byte4_t tile_XYid, int level);
720
721 range_param_t get_tile_Xrange(SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
722 {
723     return get_tile_range(SIZ.XOsiz, SIZ.Xsiz, SIZ.XTOsiz, SIZ.XTsiz,
724                           tile_id % SIZ.XTnum, level);
725 }
726
727 range_param_t get_tile_Yrange(SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
728 {
729     return get_tile_range(SIZ.YOsiz, SIZ.Ysiz, SIZ.YTOsiz, SIZ.YTsiz,
730                           tile_id / SIZ.XTnum, level);
731 }
732
733 range_param_t get_tile_range(Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz,
734                              Byte4_t Tsiz, Byte4_t tile_XYid, int level)
735 {
736     range_param_t range;
737     int n;
738
739     range.minvalue = max(Osiz, TOsiz + tile_XYid * Tsiz);
740     range.maxvalue = min(siz,  TOsiz + (tile_XYid + 1) * Tsiz);
741
742     for (n = 0; n < level; n++) {
743         range.minvalue = (Byte4_t)ceil(range.minvalue / 2.0);
744         range.maxvalue = (Byte4_t)ceil(range.maxvalue / 2.0);
745     }
746     return range;
747 }
748
749 Byte4_t get_tile_XSiz(SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
750 {
751     range_param_t tile_Xrange;
752
753     tile_Xrange = get_tile_Xrange(SIZ, tile_id, level);
754     return tile_Xrange.maxvalue - tile_Xrange.minvalue;
755 }
756
757 Byte4_t get_tile_YSiz(SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
758 {
759     range_param_t tile_Yrange;
760
761     tile_Yrange = get_tile_Yrange(SIZ, tile_id, level);
762     return tile_Yrange.maxvalue - tile_Yrange.minvalue;
763 }
764
765 /* TODO: what is this code doing ? will all compiler be able to optimize the following ? */
766 Byte4_t max(Byte4_t n1, Byte4_t n2)
767 {
768     if (n1 < n2) {
769         return n2;
770     } else {
771         return n1;
772     }
773 }
774
775 Byte4_t min(Byte4_t n1, Byte4_t n2)
776 {
777     if (n1 < n2) {
778         return n1;
779     } else {
780         return n2;
781     }
782 }
783
784 OPJ_BOOL isJPTfeasible(index_param_t index)
785 {
786     if (1 < get_nmax(index.tilepart)) {
787         return OPJ_TRUE;
788     } else {
789         return OPJ_FALSE;
790     }
791 }