[trunk] Remove bool.h, use opj_bool instead
[openjpeg.git] / src / lib / openjpip / index_manager.c
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
5  * Copyright (c) 2002-2011, 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   if( !(toplev_boxlist = get_boxstructure( fd, 0, filesize))){
85     fprintf( FCGI_stderr, "Error: Not correctl JP2 format\n");
86     return NULL;
87   }
88   
89   if( !check_JP2boxidx( toplev_boxlist)){
90     fprintf( FCGI_stderr, "Index format not supported\n");
91     delete_boxlist( &toplev_boxlist);
92     return NULL;
93   }
94
95   if( !(cidx = search_box( "cidx", toplev_boxlist))){
96     fprintf( FCGI_stderr, "Box cidx not found\n");
97     delete_boxlist( &toplev_boxlist);
98     return NULL;
99   }
100
101   jp2idx = (index_param_t *)opj_malloc( sizeof(index_param_t));
102   
103   if( !set_cidxdata( cidx, jp2idx)){
104     fprintf( FCGI_stderr, "Error: Not correctl format in cidx box\n");
105     opj_free(jp2idx);
106     delete_boxlist( &toplev_boxlist);
107     return NULL;
108   }
109   delete_boxlist( &toplev_boxlist);
110   
111   metadatalist = const_metadatalist( fd);
112   jp2idx->metadatalist = metadatalist;
113
114 #ifndef SERVER
115     fprintf( logstream, "local log: code index created\n");
116 #endif
117   
118   return jp2idx;
119 }
120
121 void print_index( index_param_t index)
122 {
123   int i;
124
125   fprintf( logstream, "index info:\n");
126   fprintf( logstream, "\tCodestream  Offset: %#" PRIx64 "\n", index.offset);
127   fprintf( logstream, "\t            Length: %#" PRIx64 "\n", index.length);
128   fprintf( logstream, "\tMain header Length: %#" PRIx64 "\n", index.mhead_length);
129   
130   print_SIZ( index.SIZ);
131   print_COD( index.COD);
132   
133   fprintf( logstream, "Tile part information: \n");
134   print_faixbox( index.tilepart);
135
136   fprintf( logstream, "Tile header information: \n");
137   for( i=0; i<(int)(index.SIZ.XTnum*index.SIZ.YTnum);i++)
138     print_mhixbox( index.tileheader[i]);
139
140   fprintf( logstream, "Precinct packet information: \n");
141   for( i=0; i<index.SIZ.Csiz; i++){
142     fprintf( logstream, "Component %d\n", i);
143     print_faixbox( index.precpacket[i]);
144   }
145
146   print_allmetadata( index.metadatalist);
147 }
148
149 void print_SIZ( SIZmarker_param_t SIZ)
150 {
151   int i;
152
153   fprintf( logstream, "\tImage and Tile SIZ parameters\n");
154   fprintf( logstream, "\t              Rsiz: %#x\n", SIZ.Rsiz);
155   fprintf( logstream, "\t        Xsiz, Ysiz: (%d,%d) = (%#x, %#x)\n", SIZ.Xsiz, SIZ.Ysiz, SIZ.Xsiz, SIZ.Ysiz);
156   fprintf( logstream, "\t      XOsiz, YOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XOsiz, SIZ.YOsiz, SIZ.XOsiz, SIZ.YOsiz);
157   fprintf( logstream, "\t      XTsiz, YTsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTsiz, SIZ.YTsiz, SIZ.XTsiz, SIZ.YTsiz);
158   fprintf( logstream, "\t    XTOsiz, YTOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTOsiz, SIZ.YTOsiz, SIZ.XTOsiz, SIZ.YTOsiz);
159   fprintf( logstream, "\t    XTnum, YTnum: (%d,%d)\n", SIZ.XTnum, SIZ.YTnum);
160   fprintf( logstream, "\t Num of Components: %d\n", SIZ.Csiz);
161   
162   for( i=0; i<SIZ.Csiz; i++)
163     fprintf( logstream, "\t[%d] (Ssiz, XRsiz, YRsiz): (%d, %d, %d) = (%#x, %#x, %#x)\n", i, SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i], SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i]);
164 }
165
166 void print_COD( CODmarker_param_t COD)
167 {
168   int i;
169
170   fprintf( logstream, "\tCoding style default COD parameters\n");
171   fprintf( logstream, "\t Progression order: %d [ LRCP=0, RLCP=1, RPCL=2, PCRL=3, CPRL=4]\n", COD.prog_order);
172   fprintf( logstream, "\t     Num of layers: %d\n", COD.numOflayers);
173   fprintf( logstream, "\t Decomposition lvl: %d\n", COD.numOfdecomp);
174   
175   for( i=0; i<=((COD.Scod & 0x01) ? COD.numOfdecomp:0); i++){
176     fprintf( logstream, "\t  [%d] XPsiz, YPsiz: (%d,%d) = (%#x, %#x)\n",i, COD.XPsiz[i], COD.YPsiz[i], COD.XPsiz[i], COD.YPsiz[i]);
177   }
178 }
179
180 void delete_index( index_param_t **index)
181 {
182   int i;
183
184   delete_metadatalist( &((*index)->metadatalist));
185
186   delete_COD( (*index)->COD);
187   
188   delete_faixbox( &((*index)->tilepart));
189
190   for( i=0; i< (int)((*index)->SIZ.XTnum*(*index)->SIZ.YTnum);i++)
191     delete_mhixbox( &((*index)->tileheader[i]));
192   opj_free( (*index)->tileheader);
193   
194   for( i=0; i<(*index)->SIZ.Csiz; i++)
195     delete_faixbox( &((*index)->precpacket[i]));
196   opj_free( (*index)->precpacket);
197   
198   opj_free(*index);
199 }
200
201 void delete_COD( CODmarker_param_t COD)
202 {
203   if( COD.XPsiz)    opj_free( COD.XPsiz);
204   if( COD.YPsiz)    opj_free( COD.YPsiz);
205 }
206
207 opj_bool check_JP2boxidx( boxlist_param_t *toplev_boxlist)
208 {
209   box_param_t *iptr, *fidx, *prxy;
210   box_param_t *cidx, *jp2c;
211   Byte8_t off;
212   Byte8_t len;
213   int pos;
214   Byte8_t ooff;
215   boxheader_param_t *obh;
216   Byte_t ni;
217   Byte8_t ioff;
218   boxheader_param_t *ibh;
219
220   iptr = search_box( "iptr", toplev_boxlist);
221   fidx = search_box( "fidx", toplev_boxlist);
222   cidx = search_box( "cidx", toplev_boxlist);
223   jp2c = search_box( "jp2c", toplev_boxlist);
224   prxy = gene_childboxbyType( fidx, 0, "prxy");
225
226   off = fetch_DBox8bytebigendian( iptr, 0);
227   if( off != (Byte8_t)fidx->offset)
228     fprintf( FCGI_stderr, "Reference File Index box offset in Index Finder box not correct\n");
229
230   len = fetch_DBox8bytebigendian( iptr, 8);
231   if( len != fidx->length)
232     fprintf( FCGI_stderr, "Reference File Index box length in Index Finder box not correct\n");
233
234   pos = 0;
235   ooff = fetch_DBox8bytebigendian( prxy, pos);
236   if( ooff != (Byte8_t)jp2c->offset)
237     fprintf( FCGI_stderr, "Reference jp2c offset in prxy box not correct\n");
238   pos += 8;
239
240   obh = gene_childboxheader( prxy, pos);
241   if( obh->length != jp2c->length || strncmp( obh->type, "jp2c",4)!=0)
242     fprintf( FCGI_stderr, "Reference jp2c header in prxy box not correct\n");
243   pos += obh->headlen;
244   opj_free(obh);
245   
246   ni = fetch_DBox1byte( prxy, pos);
247   if( ni != 1){
248     fprintf( FCGI_stderr, "Multiple indexes not supported\n");
249     return OPJ_FALSE;
250   }  
251   pos += 1;
252   
253   ioff = fetch_DBox8bytebigendian( prxy, pos);
254   if( ioff != (Byte8_t)cidx->offset)
255     fprintf( FCGI_stderr, "Reference cidx offset in prxy box not correct\n");
256   pos += 8;
257
258   ibh = gene_childboxheader( prxy, pos);
259   if( ibh->length != cidx->length || strncmp( ibh->type, "cidx",4)!=0)
260     fprintf( FCGI_stderr, "Reference cidx header in prxy box not correct\n");
261   pos += ibh->headlen;
262   opj_free(ibh);
263   
264   opj_free(prxy);
265
266   return OPJ_TRUE;
267 }
268
269 /**
270  * set code index parameters from cptr box
271  * I.3.2.2 Codestream Finder box
272  *
273  * @param[in]  cidx_box pointer to the reference cidx_box
274  * @param[out] jp2idx   pointer to index parameters
275  * @return              if succeeded (true) or failed (false)
276  */
277 opj_bool set_cptrdata( box_param_t *cidx_box, index_param_t *jp2idx);
278
279 /**
280  * set code index parameters from mhix box for main header
281  * I.3.2.4.3 Header Index Table box
282  *
283  * @param[in]  cidx_box   pointer to the reference cidx_box
284  * @param[in]  codestream codestream parameters
285  * @param[out] jp2idx     pointer to index parameters
286  * @return                if succeeded (true) or failed (false)
287  */
288 opj_bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, index_param_t *jp2idx);
289
290 /**
291  * set code index parameters from tpix box
292  * I.3.2.4.4 Tile-part Index Table box
293  *
294  * @param[in]  cidx_box   pointer to the reference cidx_box
295  * @param[out] jp2idx     pointer to index parameters
296  * @return                if succeeded (true) or failed (false)
297  */
298 opj_bool set_tpixdata( box_param_t *cidx_box, index_param_t *jp2idx);
299
300 /**
301  * set code index parameters from thix box
302  * I.3.2.4.5 Tile Header Index Table box
303  *
304  * @param[in]  cidx_box   pointer to the reference cidx_box
305  * @param[out] jp2idx     pointer to index parameters
306  * @return                if succeeded (true) or failed (false)
307  */
308 opj_bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx);
309
310 /**
311  * set code index parameters from ppix box
312  * I.3.2.4.6 Precinct Packet Index Table box
313  *
314  * @param[in]  cidx_box   pointer to the reference cidx_box
315  * @param[out] jp2idx     pointer to index parameters
316  * @return                if succeeded (true) or failed (false)
317  */
318 opj_bool set_ppixdata( box_param_t *cidx_box, index_param_t *jp2idx);
319
320 opj_bool set_cidxdata( box_param_t *cidx_box, index_param_t *jp2idx)
321 {
322   box_param_t *manf_box;
323   manfbox_param_t *manf;
324   codestream_param_t codestream;
325
326   set_cptrdata( cidx_box, jp2idx);
327
328   codestream = set_codestream( cidx_box->fd, jp2idx->offset, jp2idx->length);
329
330   manf_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "manf");
331   manf = gene_manfbox( manf_box);
332
333   if( !search_boxheader( "mhix", manf)){
334     fprintf( FCGI_stderr, "Error: mhix box not present in manfbox\n");
335     opj_free(jp2idx);
336     return OPJ_FALSE;
337   }
338   set_mainmhixdata( cidx_box, codestream, jp2idx);
339
340   if( !search_boxheader( "tpix", manf)){
341     fprintf( FCGI_stderr, "Error: tpix box not present in manfbox\n");
342     opj_free(jp2idx);
343     return OPJ_FALSE;
344   }
345   set_tpixdata( cidx_box, jp2idx);
346
347   if( !search_boxheader( "thix", manf)){
348     fprintf( FCGI_stderr, "Error: thix box not present in manfbox\n");
349     opj_free(jp2idx);
350     return OPJ_FALSE;
351   }
352   set_thixdata( cidx_box, jp2idx);
353
354   if( !search_boxheader( "ppix", manf)){
355     fprintf( FCGI_stderr, "Error: ppix box not present in manfbox\n");
356     opj_free(jp2idx);
357     return OPJ_FALSE;
358   }
359   set_ppixdata( cidx_box, jp2idx);
360
361   delete_manfbox( &manf);
362   opj_free( manf_box);
363
364   return OPJ_TRUE;
365 }
366
367 opj_bool set_cptrdata( box_param_t *cidx_box, index_param_t *jp2idx)
368 {
369   box_param_t *box;   /**< cptr box*/
370   Byte2_t dr, cont;
371
372   if( !(box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "cptr")))
373     return OPJ_FALSE;
374   
375   /* DR: Data Reference. */
376   /* If 0, the codestream or its Fragment Table box exists in the current file*/
377   if(( dr = fetch_DBox2bytebigendian( box, 0))){
378     fprintf( FCGI_stderr, "Error: Codestream not present in current file\n");
379     opj_free( box);
380     return OPJ_FALSE;  
381   }
382   
383   /* CONT: Container Type*/
384   /* If 0, the entire codestream appears as a contiguous range of*/
385   /* bytes within its file or resource.*/
386   if(( cont = fetch_DBox2bytebigendian( box, 2))){
387     fprintf( FCGI_stderr, "Error: Can't cope with fragmented codestreams yet\n");
388     opj_free( box);
389     return OPJ_FALSE;  
390   }
391     
392   jp2idx->offset = (OPJ_OFF_T)fetch_DBox8bytebigendian( box, 4);
393   jp2idx->length = fetch_DBox8bytebigendian( box, 12);
394
395   opj_free( box);
396
397   return OPJ_TRUE;
398 }
399
400
401 /**
402  * set SIZ marker information
403  * A.5 Fixed information marker segment
404  * A.5.1 Image and tile size (SIZ)
405  *
406  * @param[in]  sizmkidx   pointer to SIZ marker index in mhix box
407  * @param[in]  codestream codestream parameters
408  * @param[out] SIZ        SIZ marker parameters pointer
409  * @return                if succeeded (true) or failed (false)
410  */
411 opj_bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, SIZmarker_param_t *SIZ);
412
413 /**
414  * set code index parameters from COD marker in codestream
415  * A.6 Functional marker segments
416  * A.6.1 Coding style default (COD)
417  *
418  * @param[in]  codmkidx   pointer to COD marker index in mhix box
419  * @param[in]  codestream codestream parameters
420  * @param[out] COD        COD marker parameters pointer
421  * @return                if succeeded (true) or failed (false)
422  */
423 opj_bool set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestream, CODmarker_param_t *COD);
424
425 opj_bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, index_param_t *jp2idx)
426 {
427   box_param_t *mhix_box;
428   mhixbox_param_t *mhix;
429   markeridx_param_t *sizmkidx;
430   markeridx_param_t *codmkidx;
431
432   if( !(mhix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "mhix")))
433     return OPJ_FALSE;
434
435   jp2idx->mhead_length = fetch_DBox8bytebigendian( mhix_box, 0);
436
437   mhix = gene_mhixbox( mhix_box);
438   opj_free( mhix_box);
439
440   sizmkidx = search_markeridx( 0xff51, mhix);
441   set_SIZmkrdata( sizmkidx, codestream, &(jp2idx->SIZ));
442
443   codmkidx = search_markeridx( 0xff52, mhix);
444   set_CODmkrdata( codmkidx, codestream, &(jp2idx->COD));
445
446   delete_mhixbox( &mhix);
447
448   return OPJ_TRUE;
449 }
450
451 opj_bool set_tpixdata( box_param_t *cidx_box, index_param_t *jp2idx)
452 {
453   box_param_t *tpix_box;   /**< tpix box*/
454   box_param_t *faix_box;   /**< faix box*/
455   
456   if( !(tpix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "tpix"))){
457     fprintf( FCGI_stderr, "Error: tpix box not present in cidx box\n");
458     return OPJ_FALSE;
459   }
460
461   if( !(faix_box = gene_boxbyType( tpix_box->fd, get_DBoxoff( tpix_box), get_DBoxlen( tpix_box), "faix"))){
462     fprintf( FCGI_stderr, "Error: faix box not present in tpix box\n");
463     return OPJ_FALSE;
464   }
465
466   jp2idx->tilepart = gene_faixbox( faix_box);
467   
468   opj_free( tpix_box);
469   opj_free( faix_box);
470
471   return OPJ_TRUE;
472 }
473
474 opj_bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
475 {
476   box_param_t *thix_box, *manf_box, *mhix_box;
477   manfbox_param_t *manf;
478   boxheader_param_t *ptr;
479   mhixbox_param_t *mhix;
480   Byte8_t pos;
481   OPJ_OFF_T mhixseqoff;
482   Byte2_t tile_no;
483   
484   if( !(thix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "thix"))){
485     fprintf( FCGI_stderr, "Error: thix box not present in cidx box\n");
486     return OPJ_FALSE;
487   }
488   
489   if( !(manf_box = gene_boxbyType( thix_box->fd, get_DBoxoff( thix_box), get_DBoxlen( thix_box), "manf"))){
490     fprintf( FCGI_stderr, "Error: manf box not present in thix box\n");
491     opj_free( thix_box);
492     return OPJ_FALSE;
493   }
494   
495   manf = gene_manfbox( manf_box);
496   ptr = manf->first;
497   mhixseqoff = manf_box->offset+(OPJ_OFF_T)manf_box->length;
498   pos = 0;
499   tile_no = 0;
500   jp2idx->tileheader = (mhixbox_param_t **)opj_malloc( jp2idx->SIZ.XTnum*jp2idx->SIZ.YTnum*sizeof(mhixbox_param_t *));
501     
502   while( ptr){
503     if( !(mhix_box = gene_boxbyType( thix_box->fd, mhixseqoff+(OPJ_OFF_T)pos, get_DBoxlen( thix_box)-manf_box->length-pos, "mhix"))){
504       fprintf( FCGI_stderr, "Error: mhix box not present in thix box\n");
505       delete_manfbox( &manf);
506       opj_free( manf_box);
507       opj_free( thix_box);
508       return OPJ_FALSE;
509     }
510     mhix = gene_mhixbox( mhix_box);
511
512     pos += mhix_box->length;
513     ptr = ptr->next;
514
515     opj_free( mhix_box);
516     jp2idx->tileheader[tile_no++] = mhix;
517   }
518
519   delete_manfbox( &manf);
520   opj_free( manf_box);
521   opj_free( thix_box);
522
523   return OPJ_TRUE;
524 }
525
526 opj_bool set_ppixdata( box_param_t *cidx_box, index_param_t *jp2idx)
527 {
528   box_param_t *ppix_box, *faix_box, *manf_box;
529   manfbox_param_t *manf;     /**< manf*/
530   boxheader_param_t *bh;     /**< box headers*/
531   faixbox_param_t *faix;     /**< faix*/
532   OPJ_OFF_T inbox_offset;
533   int comp_idx;
534
535   if( !(ppix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "ppix"))){
536     fprintf( FCGI_stderr, "Error: ppix box not present in cidx box\n");
537     return OPJ_FALSE;
538   }
539
540   inbox_offset = get_DBoxoff( ppix_box);
541   if( !(manf_box = gene_boxbyType( ppix_box->fd, inbox_offset, get_DBoxlen( ppix_box), "manf"))){
542     fprintf( FCGI_stderr, "Error: manf box not present in ppix box\n");
543     opj_free( ppix_box);
544     return OPJ_FALSE;
545   }
546
547   opj_free( ppix_box);
548
549   manf = gene_manfbox( manf_box);
550   bh = search_boxheader( "faix", manf);
551   inbox_offset = manf_box->offset + (OPJ_OFF_T)manf_box->length;
552   
553   opj_free( manf_box);
554
555   jp2idx->precpacket = (faixbox_param_t **)opj_malloc( jp2idx->SIZ.Csiz*sizeof(faixbox_param_t *));
556
557   for( comp_idx=0; bh!=NULL; bh=bh->next, comp_idx++){
558     if( jp2idx->SIZ.Csiz <= comp_idx ){
559       fprintf( FCGI_stderr, "Error: num of faix boxes is not identical to num of components in ppix box\n");
560       return OPJ_FALSE;
561     }
562
563     if( !(faix_box = gene_boxbyOffset( cidx_box->fd, inbox_offset))){
564       fprintf( FCGI_stderr, "Error: faix box not present in ppix box\n");
565       return OPJ_FALSE;
566     }
567   
568     faix = gene_faixbox( faix_box);
569     jp2idx->precpacket[comp_idx] = faix;
570
571     inbox_offset = faix_box->offset + (OPJ_OFF_T)faix_box->length;
572     opj_free( faix_box);   
573   }
574   
575   delete_manfbox( &manf);
576
577   return OPJ_TRUE;
578 }
579
580 opj_bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, SIZmarker_param_t *SIZ)
581 {
582   marker_param_t sizmkr;
583   int i;
584
585   sizmkr = set_marker( codestream, sizmkidx->code, sizmkidx->offset, sizmkidx->length);
586
587   SIZ->Lsiz = fetch_marker2bytebigendian( sizmkr, 0);
588
589   if( sizmkidx->length != SIZ->Lsiz){
590     fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", sizmkidx->code);
591     return OPJ_FALSE;
592   }
593   
594   SIZ->Rsiz   = fetch_marker2bytebigendian( sizmkr, 2);
595   SIZ->Xsiz   = fetch_marker4bytebigendian( sizmkr, 4);
596   SIZ->Ysiz   = fetch_marker4bytebigendian( sizmkr, 8);
597   SIZ->XOsiz  = fetch_marker4bytebigendian( sizmkr, 12);
598   SIZ->YOsiz  = fetch_marker4bytebigendian( sizmkr, 16);
599   SIZ->XTsiz  = fetch_marker4bytebigendian( sizmkr, 20);
600   SIZ->YTsiz  = fetch_marker4bytebigendian( sizmkr, 24);
601   SIZ->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28);
602   SIZ->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32);
603   SIZ->Csiz   = fetch_marker2bytebigendian( sizmkr, 36);
604
605   SIZ->XTnum  = ( SIZ->Xsiz-SIZ->XTOsiz+SIZ->XTsiz-1)/SIZ->XTsiz;
606   SIZ->YTnum  = ( SIZ->Ysiz-SIZ->YTOsiz+SIZ->YTsiz-1)/SIZ->YTsiz;
607   
608   for( i=0; i<(int)SIZ->Csiz; i++){
609     SIZ->Ssiz[i]  = fetch_marker1byte( sizmkr, 38+i*3);
610     SIZ->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3);
611     SIZ->YRsiz[i] = fetch_marker1byte( sizmkr, 40+i*3);
612   }
613   return OPJ_TRUE;
614 }
615
616 opj_bool set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestream, CODmarker_param_t *COD)
617 {
618   marker_param_t codmkr;
619   int i;
620
621   codmkr = set_marker( codestream, codmkidx->code, codmkidx->offset, codmkidx->length);
622
623   COD->Lcod = fetch_marker2bytebigendian( codmkr, 0);
624
625   if( codmkidx->length != COD->Lcod){
626     fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", codmkidx->code);
627     return OPJ_FALSE;
628   }
629
630   COD->Scod   = fetch_marker1byte( codmkr, 2);
631   COD->prog_order  = fetch_marker1byte( codmkr, 3);
632   COD->numOflayers = fetch_marker2bytebigendian( codmkr, 4);
633   COD->numOfdecomp = fetch_marker1byte( codmkr, 7);
634   
635   if(COD->Scod & 0x01){
636     COD->XPsiz = (Byte4_t *)opj_malloc( (OPJ_SIZE_T)(COD->numOfdecomp+1)*sizeof(Byte4_t));
637     COD->YPsiz = (Byte4_t *)opj_malloc( (OPJ_SIZE_T)(COD->numOfdecomp+1)*sizeof(Byte4_t));
638
639     for( i=0; i<=COD->numOfdecomp; i++){
640       /*precinct size*/
641       COD->XPsiz[i] = (Byte2_t)pow( 2, fetch_marker1byte( codmkr, 12+i) & 0x0F);
642       COD->YPsiz[i] = (Byte2_t)pow( 2,(fetch_marker1byte( codmkr, 12+i) & 0xF0) >> 4);
643     }
644   }
645   else{
646     COD->XPsiz = (Byte4_t *)opj_malloc( sizeof(Byte4_t));
647     COD->YPsiz = (Byte4_t *)opj_malloc( sizeof(Byte4_t));
648
649     COD->XPsiz[0] = COD->YPsiz[0] = pow(2,15);
650   }
651   return OPJ_TRUE;
652 }
653
654
655 /* very very generic name see NOMINMAX */
656 #ifdef min
657 #undef min
658 #endif
659 #ifdef max
660 #undef max
661 #endif
662 Byte4_t max( Byte4_t n1, Byte4_t n2);
663 Byte4_t min( Byte4_t n1, Byte4_t n2);
664
665 range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_XYid, int level);
666
667 range_param_t get_tile_Xrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
668 {
669   return get_tile_range( SIZ.XOsiz, SIZ.Xsiz, SIZ.XTOsiz, SIZ.XTsiz, tile_id%SIZ.XTnum, level);
670 }
671
672 range_param_t get_tile_Yrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
673 {
674   return get_tile_range( SIZ.YOsiz, SIZ.Ysiz, SIZ.YTOsiz, SIZ.YTsiz, tile_id/SIZ.XTnum, level);
675 }
676
677 range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_XYid, int level)
678 {
679   range_param_t range;
680   int n;
681
682   range.minvalue = max( Osiz, TOsiz+tile_XYid*Tsiz);
683   range.maxvalue = min( siz,  TOsiz+(tile_XYid+1)*Tsiz);
684
685   for( n=0; n<level; n++){
686     range.minvalue = (Byte4_t)ceil(range.minvalue/2.0);
687     range.maxvalue = (Byte4_t)ceil(range.maxvalue/2.0);
688   }
689   return range;
690 }
691
692 Byte4_t get_tile_XSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
693 {
694   range_param_t tile_Xrange;
695
696   tile_Xrange = get_tile_Xrange( SIZ, tile_id, level);
697   return tile_Xrange.maxvalue - tile_Xrange.minvalue;
698 }
699
700 Byte4_t get_tile_YSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
701 {
702   range_param_t tile_Yrange;
703
704   tile_Yrange = get_tile_Yrange( SIZ, tile_id, level);
705   return tile_Yrange.maxvalue - tile_Yrange.minvalue;
706 }
707
708 /* TODO: what is this code doing ? will all compiler be able to optimize the following ? */
709 Byte4_t max( Byte4_t n1, Byte4_t n2)
710 {
711   if( n1 < n2)
712     return n2;
713   else
714     return n1;
715 }
716
717 Byte4_t min( Byte4_t n1, Byte4_t n2)
718 {
719   if( n1 < n2)
720     return n1;
721   else
722     return n2;
723 }
724
725 opj_bool isJPTfeasible( index_param_t index)
726 {
727   if( 1 < get_nmax( index.tilepart))
728     return OPJ_TRUE;
729   else
730     return OPJ_FALSE;
731 }