Update for version 1.0
[openjpeg.git] / indexer_JPIP / jpip.c
1 /*
2  * Copyright (c) 2003-2004, Yannick Verschueren
3  * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25  * POSSIBILITY OF SUCH DAMAGE.
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <setjmp.h>
32 #include <math.h>
33 #include <unistd.h>
34
35 #include "j2k.h"
36 #include "cio.h"
37 #include "tcd.h"
38 #include "int.h"
39
40 #define JPIP_CIDX 0x63696478   /* Codestream index                */
41 #define JPIP_CPTR 0x63707472   /* Codestream Finder Box           */
42 #define JPIP_MANF 0x6d616e66   /* Manifest Box                    */
43 #define JPIP_FAIX 0x66616978   /* Fragment array Index box        */
44 #define JPIP_MHIX 0x6d686978   /* Main Header Index Table         */
45 #define JPIP_TPIX 0x74706978   /* Tile-part Index Table box       */
46 #define JPIP_THIX 0x74686978   /* Tile header Index Table box     */
47 #define JPIP_PPIX 0x70706978   /* Precinct Packet Index Table box */
48 #define JPIP_PHIX 0x70686978   /* Packet Header index Table       */
49 #define JPIP_FIDX 0x66696478   /* File Index                      */
50 #define JPIP_FPTR 0x66707472   /* File Finder                     */
51 #define JPIP_PRXY 0x70727879   /* Proxy boxes                     */
52 #define JPIP_IPTR 0x69707472   /* Index finder box                */
53 #define JPIP_PHLD 0x70686c64   /* Place holder                    */
54
55 #define JP2C      0x6a703263
56
57 //static info_marker_t marker_jpip[32], marker_local_jpip[32];  /* SIZE to precise ! */
58 //static int num_marker_jpip, num_marker_local_jpip;
59
60 /* 
61  * Write the CPTR box
62  *
63  * Codestream finder box (box)
64  *
65  */
66 void jpip_write_cptr(int offset, info_image_t img)
67 {
68   int len, lenp;
69
70   lenp=cio_tell(); 
71   cio_skip(4);                       /* L [at the end]     */
72   cio_write(JPIP_CPTR,4);            /* T                  */
73   cio_write(0,2);                    /* DR  A PRECISER !!  */
74   cio_write(0,2);                    /* CONT               */
75   cio_write(offset,8);               /* COFF A PRECISER !! */
76   cio_write(img.codestream_size,8);  /* CLEN               */
77   len=cio_tell()-lenp;
78   cio_seek(lenp);
79   cio_write(len, 4);                 /* L                  */
80   cio_seek(lenp+len);
81 }
82
83 /* 
84  * Read the CPTR box
85  *
86  * Codestream finder box (box)
87  *
88  */
89 void jpip_read_cptr()
90 {
91   int DR, CONT;
92   long long Coff, codestream_size;
93
94   DR = cio_read(2);               /* DR   */
95   CONT = cio_read(2);             /* CONT */
96   Coff = cio_read(8);             /* COFF */
97   codestream_size = cio_read(8);  /* CLEN */
98 }
99
100 /* 
101  * Write the MANF box
102  *
103  * Manifest box (box)
104  *
105  */
106 void jpip_write_manf(int second, int v, info_marker_t *marker)
107 {
108   int len, lenp, i;
109   lenp=cio_tell(); 
110   cio_skip(4);                         /* L [at the end]                    */
111   cio_write(JPIP_MANF,4);              /* T                                 */
112
113   if (second)                          /* Write only during the second pass */
114     {
115       for(i=0;i<v;i++)
116         {
117           cio_write(marker[i].len,4);  /* Marker length                     */ 
118           cio_write(marker[i].type,4); /* Marker type                       */
119         }
120     }
121
122   len=cio_tell()-lenp;
123   cio_seek(lenp);
124   cio_write(len, 4);                   /* L                                 */
125   cio_seek(lenp+len);
126 }
127
128 /* 
129  * Read the MANF box
130  *
131  * Manifest box (box)
132  *
133  */
134 void jpip_read_manf(int len)
135 {
136   int i, v, marker_len, marker_type;
137   
138   v = (len - 8)/ 8;
139   
140   for(i=0;i<v;i++)
141     {
142       marker_len = cio_read(4);       /* Marker length */ 
143       marker_type = cio_read(4);      /* Marker type   */
144     }
145 }
146
147 /* 
148  * Write the MHIX box
149  *
150  * Main Header Index Table (box)
151  *
152  */
153 int jpip_write_mhix(info_image_t img, int status, int tileno)
154 {
155   int len, lenp, i;
156   info_tile_t *tile;
157   lenp=cio_tell();
158   cio_skip(4);                               /* L [at the end]                    */
159   cio_write(JPIP_MHIX, 4);                   /* MHIX                              */
160
161   if (status) /* MAIN HEADER */
162     {
163       cio_write(img.Main_head_end,8);        /* TLEN                              */
164       
165       for(i = 0; i < img.num_marker; i++)    /* Marker restricted to 1 apparition */
166         {
167           cio_write(img.marker[i].type, 2);
168           cio_write(0, 2);
169           cio_write(img.marker[i].start_pos, 8);
170           cio_write(img.marker[i].len, 2);
171         }
172       
173       /* Marker NOT restricted to 1 apparition */
174       for(i = img.marker_mul.num_COC - 1; i >= 0; i--) /* COC */
175         {
176           cio_write(img.marker_mul.COC[i].type, 2);
177           cio_write(i, 2);
178           cio_write(img.marker_mul.COC[i].start_pos, 8);
179           cio_write(img.marker_mul.COC[i].len, 2);
180         }
181       
182       for(i = img.marker_mul.num_RGN - 1; i >= 0; i--) /* RGN */
183         {
184           cio_write(img.marker_mul.RGN[i].type, 2);
185           cio_write(i, 2);
186           cio_write(img.marker_mul.RGN[i].start_pos, 8);
187           cio_write(img.marker_mul.RGN[i].len, 2);
188         }
189       
190       for(i = img.marker_mul.num_QCC - 1; i >= 0; i--) /* QCC */
191         {
192           cio_write(img.marker_mul.QCC[i].type, 2);
193           cio_write(i, 2);
194           cio_write(img.marker_mul.QCC[i].start_pos, 8);
195           cio_write(img.marker_mul.QCC[i].len, 2);
196         }
197       
198       for(i = img.marker_mul.num_TLM - 1; i >= 0; i--) /* TLM */
199         {
200           cio_write(img.marker_mul.TLM[i].type, 2);
201           cio_write(i, 2);
202           cio_write(img.marker_mul.TLM[i].start_pos, 8);
203           cio_write(img.marker_mul.TLM[i].len, 2);
204         }
205       
206       for(i = img.marker_mul.num_PLM - 1; i >= 0; i--) /* PLM */
207         {
208           cio_write(img.marker_mul.PLM[i].type, 2);
209           cio_write(i, 2);
210           cio_write(img.marker_mul.PLM[i].start_pos, 8);
211           cio_write(img.marker_mul.PLM[i].len, 2);
212         }
213       
214       for(i = img.marker_mul.num_PPM - 1; i >= 0; i--) /* PPM */
215         {
216           cio_write(img.marker_mul.PPM[i].type, 2);
217           cio_write(i, 2);
218           cio_write(img.marker_mul.PPM[i].start_pos, 8);
219           cio_write(img.marker_mul.PPM[i].len, 2);
220         }
221
222       for(i = img.marker_mul.num_COM - 1; i >= 0; i--) /* COM */
223         {
224           cio_write(img.marker_mul.COM[i].type, 2);
225           cio_write(i, 2);
226           cio_write(img.marker_mul.COM[i].start_pos, 8);
227           cio_write(img.marker_mul.COM[i].len, 2);
228         }
229     } 
230   else /* TILE HEADER */
231     {
232       tile = &img.tile[tileno];
233       cio_write(tile->tile_parts[0].length_header, 8);  /* TLEN                              */ 
234       
235       for(i = 0; i < tile->num_marker; i++)             /* Marker restricted to 1 apparition */
236         {
237           cio_write(tile->marker[i].type, 2);
238           cio_write(0, 2);
239           cio_write(tile->marker[i].start_pos, 8);
240           cio_write(tile->marker[i].len, 2);
241         }
242       
243       /* Marker NOT restricted to 1 apparition */
244       for(i = tile->marker_mul.num_COC - 1; i >= 0; i--) /* COC */
245         {
246           cio_write(tile->marker_mul.COC[i].type, 2);
247           cio_write(i, 2);
248           cio_write(tile->marker_mul.COC[i].start_pos, 8);
249           cio_write(tile->marker_mul.COC[i].len, 2);
250         }
251       
252       for(i = tile->marker_mul.num_RGN - 1; i >= 0; i--) /* RGN */
253         {
254           cio_write(tile->marker_mul.RGN[i].type, 2);
255           cio_write(i, 2);
256           cio_write(tile->marker_mul.RGN[i].start_pos, 8);
257           cio_write(tile->marker_mul.RGN[i].len, 2);
258         }
259       
260       for(i = tile->marker_mul.num_QCC - 1; i >= 0; i--) /* QCC */
261         {
262           cio_write(tile->marker_mul.QCC[i].type, 2);
263           cio_write(i, 2);
264           cio_write(tile->marker_mul.QCC[i].start_pos, 8);
265           cio_write(tile->marker_mul.QCC[i].len, 2);
266         }
267       
268       for(i = tile->marker_mul.num_PLT - 1; i >= 0; i--) /* PLT */
269         {
270           cio_write(tile->marker_mul.PLT[i].type,2);
271           cio_write(i,2);
272           cio_write(tile->marker_mul.PLT[i].start_pos,8);
273           cio_write(tile->marker_mul.PLT[i].len,2);
274         }
275       
276       for(i = tile->marker_mul.num_PPT - 1; i >= 0; i--) /* PPT */
277         {
278           cio_write(tile->marker_mul.PPT[i].type, 2);
279           cio_write(i, 2);
280           cio_write(tile->marker_mul.PPT[i].start_pos, 8);
281           cio_write(tile->marker_mul.PPT[i].len, 2);
282         }
283       
284       for(i = tile->marker_mul.num_COM - 1; i >= 0; i--) /* COM */
285         {
286           cio_write(tile->marker_mul.COM[i].type, 2);
287           cio_write(i, 2);
288           cio_write(tile->marker_mul.COM[i].start_pos, 8);
289           cio_write(tile->marker_mul.COM[i].len, 2);
290         } 
291     }      
292   
293   len=cio_tell()-lenp;
294   cio_seek(lenp);
295   cio_write(len, 4);        /* L           */
296   cio_seek(lenp+len);
297   
298   return len;
299 }
300
301 /* 
302  * Read the MHIX box
303  *
304  * Main Header Index Table (box)
305  *
306  */
307 void jpip_read_mhix(int len)
308 {
309   int i, v, marker_type, marker_start_pos, marker_len, marker_remains;
310
311   v = (len - 8) / 14;
312
313   for (i=0; i<v ; i++)
314     {
315       marker_type = cio_read(2);       /* Type of the marker               */ 
316       marker_remains = cio_read(2);    /* Number of same markers following */
317       marker_start_pos = cio_read(2);  /* Start position of the marker     */
318       marker_len = cio_read(2);        /* Length of the marker             */
319     }
320 }
321
322 /* 
323  * Write the FAIX box
324  *
325  * Fragment array Index box (box)
326  *
327  */
328 int jpip_write_faix(int v, int compno, info_image_t img, j2k_cp_t *j2k_cp, int version)
329 {
330   int len, lenp, i, j;
331   /*int version = 0;*/
332   int tileno, resno, precno, layno, num_packet=0;
333
334   lenp=cio_tell();
335   cio_skip(4);              /* L [at the end]      */
336   cio_write(JPIP_FAIX, 4);  /* FAIX                */ 
337   cio_write(version,1);     /* Version 0 = 4 bytes */
338   
339   switch(v)
340     {
341     case 0:   /* TPIX */
342       cio_write(img.num_max_tile_parts,(version & 0x01)?8:4);                      /* NMAX           */
343       cio_write(img.tw*img.th,(version & 0x01)?8:4);                               /* M              */
344       for (i = 0; i < img.tw*img.th; i++)
345         {
346           for (j = 0; j < img.tile[i].numparts ; j++)
347             {
348               cio_write(img.tile[i].tile_parts[j].start_pos,(version & 0x01)?8:4); /* start position */
349               cio_write(img.tile[i].tile_parts[j].length,(version & 0x01)?8:4);    /* length         */
350               if (version & 0x02)
351                 cio_write(img.tile[i].tile_parts[j].num_reso_AUX,4); /* Aux_i,j : Auxiliary value */
352               //cio_write(0,4);
353             }
354           /* PADDING */
355           while (j < img.num_max_tile_parts)
356             {
357               cio_write(0,(version & 0x01)?8:4); /* start position            */
358               cio_write(0,(version & 0x01)?8:4); /* length                    */
359               if (version & 0x02)
360                 cio_write(0,4);                  /* Aux_i,j : Auxiliary value */
361               j++;
362             }
363         }
364       break;
365       
366       /*   case 1: */   /* THIX */
367       /* cio_write(1,(version & 0x01)?8:4);  */           /* NMAX */
368       /* cio_write(img.tw*img.th,(version & 0x01)?8:4); */ /* M    */
369       /* for (i=0;i<img.tw*img.th;i++) */
370       /* { */
371       /* cio_write(img.tile[i].start_pos,(version & 0x01)?8:4); */                         /* start position */
372       /* cio_write(img.tile[i].end_header-img.tile[i].start_pos,(version & 0x01)?8:4); */  /* length         */
373       /* if (version & 0x02)*/
374       /* cio_write(0,4); */ /* Aux_i,j : Auxiliary value */
375       /* } */
376       /* break; */
377
378     case 2:  /* PPIX  NOT FINISHED !! */
379       cio_write(img.num_packet_max,(version & 0x01)?8:4); /* NMAX */
380       cio_write(img.tw*img.th,(version & 0x01)?8:4);      /* M    */
381       for(tileno=0;tileno<img.tw*img.th;tileno++)
382         {
383           info_tile_t *tile_Idx = &img.tile[tileno];
384           info_compo_t *compo_Idx = &tile_Idx->compo[compno];
385           int correction;
386           
387           num_packet=0;
388           
389           if(j2k_cp->tcps[tileno].csty&J2K_CP_CSTY_EPH)
390             correction=3;
391           else
392             correction=1;
393           for(resno=0;resno<img.Decomposition+1;resno++)
394             {
395               info_reso_t *reso_Idx = &compo_Idx->reso[resno];
396               for (precno=0;precno<img.tile[tileno].pw*img.tile[tileno].ph;precno++)
397                 {
398                   info_prec_t *prec_Idx = &reso_Idx->prec[precno];
399                   for(layno=0;layno<img.Layer;layno++)
400                     {
401                       info_layer_t *layer_Idx = &prec_Idx->layer[layno];
402                       cio_write(layer_Idx->offset,(version & 0x01)?8:4);                                   /* start position */
403                       cio_write((layer_Idx->len_header-correction)?0:layer_Idx->len,(version & 0x01)?8:4); /* length         */
404                       if (version & 0x02)
405                         cio_write(0,4); /* Aux_i,j : Auxiliary value */
406                       num_packet++;
407                     }
408                 }
409             }
410           /* PADDING */
411           while (num_packet < img.num_packet_max)
412             {
413               cio_write(0,(version & 0x01)?8:4); /* start position            */
414               cio_write(0,(version & 0x01)?8:4); /* length                    */
415               if (version & 0x02)
416                 cio_write(0,4);                  /* Aux_i,j : Auxiliary value */
417               num_packet++;
418             }
419         }
420       
421       break;
422       
423     case 3:  /* PHIX NOT FINISHED !! */
424       cio_write(img.num_packet_max,(version & 0x01)?8:4); /* NMAX */
425       cio_write(img.tw*img.th,(version & 0x01)?8:4);      /* M    */
426       for(tileno=0;tileno<img.tw*img.th;tileno++)
427         {
428           info_tile_t *tile_Idx = &img.tile[tileno];
429           info_compo_t *compo_Idx = &tile_Idx->compo[compno];
430           int correction;
431
432           num_packet = 0;
433           if(j2k_cp->tcps[tileno].csty&J2K_CP_CSTY_EPH)
434             correction=3;
435           else
436             correction=1;
437           for(resno=0;resno<img.Decomposition+1;resno++)
438             {
439               info_reso_t *reso_Idx = &compo_Idx->reso[resno];
440               for (precno=0;precno<img.tile[tileno].pw*img.tile[tileno].ph;precno++)
441                 {
442                   info_prec_t *prec_Idx = &reso_Idx->prec[precno];
443                   for(layno=0;layno<img.Layer;layno++)
444                     {
445                       info_layer_t *layer_Idx = &prec_Idx->layer[layno];
446                       cio_write(layer_Idx->offset_header,(version & 0x01)?8:4);                                   /* start position */
447                       cio_write((layer_Idx->len_header-correction)?0:layer_Idx->len_header,(version & 0x01)?8:4); /* length         */
448                       if (version & 0x02)
449                         cio_write(0,4); /* Aux_i,j : Auxiliary value */
450                       num_packet++;
451                     }
452                 }
453             }
454           /* PADDING */
455           while (num_packet<img.num_packet_max)
456             {
457               cio_write(0,(version & 0x01)?8:4); /* start position            */
458               cio_write(0,(version & 0x01)?8:4); /* length                    */
459               if (version & 0x02)
460                 cio_write(0,4);                  /* Aux_i,j : Auxiliary value */
461               num_packet++;
462             }
463         }
464       break;
465     }
466   
467   len=cio_tell()-lenp;
468   cio_seek(lenp);
469   cio_write(len, 4);        /* L  */
470   cio_seek(lenp+len);
471
472   return len;
473 }
474
475 /* 
476  * Write the TPIX box
477  *
478  * Tile-part Index table box (superbox)
479  *
480  */
481 int jpip_write_tpix(info_image_t img, j2k_cp_t *j2k_cp, int version)
482 {
483   int len, lenp;
484   lenp=cio_tell();
485   cio_skip(4);              /* L [at the end] */
486   cio_write(JPIP_TPIX, 4);  /* TPIX           */
487   
488   jpip_write_faix(0,0,img, j2k_cp, version);
489
490   len=cio_tell()-lenp;
491   cio_seek(lenp);
492   cio_write(len, 4);        /* L              */
493   cio_seek(lenp+len);
494
495   return len;
496 }
497
498 /* 
499  * Write the THIX box
500  *
501  * Tile header Index table box (superbox)
502  *
503  */
504 //int jpip_write_thix(info_image_t img, j2k_cp_t *j2k_cp)
505 //  {
506 //  int len, lenp;
507 //  lenp=cio_tell();
508 //  cio_skip(4);              /* L [at the end] */
509 //  cio_write(JPIP_THIX, 4);  /* THIX           */
510   
511 //  jpip_write_faix(1,0,img, j2k_cp);
512
513 //  len=cio_tell()-lenp;
514 //  cio_seek(lenp);
515 //  cio_write(len, 4);        /* L              */
516 //  cio_seek(lenp+len);
517
518 //  return len;
519 //}
520
521 int jpip_write_thix(info_image_t img, j2k_cp_t *j2k_cp)
522 {
523   int len, lenp, i;
524   int tileno;
525   info_marker_t *marker;
526   int num_marker_local_jpip;
527
528   marker = (info_marker_t*)calloc(sizeof(info_marker_t), j2k_cp->tw*j2k_cp->th);
529
530   for ( i = 0; i < 2 ; i++ )
531     {
532       if (i) cio_seek(lenp);
533       
534       lenp = cio_tell();
535       cio_skip(4);              /* L [at the end] */
536       cio_write(JPIP_THIX, 4);  /* THIX           */
537       jpip_write_manf(i, j2k_cp->tw*j2k_cp->th, marker);
538       num_marker_local_jpip=img.Comp;
539       
540       for (tileno = 0; tileno < j2k_cp->tw*j2k_cp->th; tileno++)
541         {
542           marker[tileno].len = jpip_write_mhix(img, 1, tileno);
543           marker[tileno].type = JPIP_MHIX;
544         }
545       
546       len=cio_tell()-lenp;
547       cio_seek(lenp);
548       cio_write(len, 4);        /* L              */
549       cio_seek(lenp+len);
550     }
551
552   free(marker);
553
554   return len;
555 }
556 /* 
557  * Write the PPIX box
558  *
559  * Precinct Packet Index table box (superbox)
560  *
561  */
562 int jpip_write_ppix(info_image_t img,j2k_cp_t *j2k_cp)
563 {
564   int len, lenp, compno, i;
565   info_marker_t *marker;
566   int num_marker_local_jpip;
567   marker = (info_marker_t*)calloc(sizeof(info_marker_t), img.Comp);
568   
569   for (i=0;i<2;i++)
570     {
571       if (i) cio_seek(lenp);
572       
573       lenp=cio_tell();
574       cio_skip(4);              /* L [at the end] */
575       cio_write(JPIP_PPIX, 4);  /* PPIX           */
576       jpip_write_manf(i,img.Comp,marker);
577       num_marker_local_jpip=img.Comp;
578       
579       for (compno=0; compno<img.Comp; compno++)
580         {
581           marker[compno].len=jpip_write_faix(2,compno,img, j2k_cp, 0);
582           marker[compno].type=JPIP_FAIX;
583         }
584    
585       len=cio_tell()-lenp;
586       cio_seek(lenp);
587       cio_write(len, 4);        /* L              */
588       cio_seek(lenp+len);
589     }
590   
591   free(marker);
592
593   return len;
594 }
595
596 /* 
597  * Write the PHIX box
598  *
599  * Packet Header Index table box (superbox)
600  *
601  */
602 int jpip_write_phix(info_image_t img, j2k_cp_t *j2k_cp)
603 {
604   int len, lenp=0, compno, i;
605   info_marker_t *marker;
606
607   marker = (info_marker_t*)calloc(sizeof(info_marker_t), img.Comp);
608
609   for (i=0;i<2;i++)
610     {
611       if (i) cio_seek(lenp);
612       
613       lenp=cio_tell();
614       cio_skip(4);              /* L [at the end] */
615       cio_write(JPIP_PHIX, 4);  /* PHIX           */
616       
617       jpip_write_manf(i,img.Comp,marker);
618
619       for (compno=0; compno<img.Comp; compno++)
620         {       
621           marker[compno].len=jpip_write_faix(3,compno,img, j2k_cp, 0);
622           marker[compno].type=JPIP_FAIX;
623         }
624
625       len=cio_tell()-lenp;
626       cio_seek(lenp);
627       cio_write(len, 4);        /* L              */
628       cio_seek(lenp+len);
629     }
630
631   free(marker);
632
633   return len;
634 }
635
636 /* 
637  * Write the CIDX box
638  *
639  * Codestream Index box (superbox)
640  *
641  */
642 int jpip_write_cidx(int offset, info_image_t img, j2k_cp_t *j2k_cp, int version)
643 {
644   int len, lenp = 0, i;
645   info_marker_t *marker_jpip;
646   int num_marker_jpip = 0;
647
648   marker_jpip = (info_marker_t*)calloc(sizeof(info_marker_t), 32);
649
650   for (i=0;i<2;i++)
651     {
652       if(i)
653         cio_seek(lenp);
654
655       lenp=cio_tell();
656
657       cio_skip(4);              /* L [at the end] */
658       cio_write(JPIP_CIDX, 4);  /* CIDX           */
659       jpip_write_cptr(offset, img);
660
661       jpip_write_manf(i,num_marker_jpip, marker_jpip);
662
663       num_marker_jpip=0;
664       marker_jpip[num_marker_jpip].len=jpip_write_mhix(img, 0, 0);
665       marker_jpip[num_marker_jpip].type=JPIP_MHIX;
666       num_marker_jpip++;
667
668       marker_jpip[num_marker_jpip].len=jpip_write_tpix(img, j2k_cp, version);
669       marker_jpip[num_marker_jpip].type=JPIP_TPIX;
670       num_marker_jpip++;
671
672       marker_jpip[num_marker_jpip].len=jpip_write_thix(img, j2k_cp);
673       marker_jpip[num_marker_jpip].type=JPIP_THIX;
674       num_marker_jpip++;
675
676       marker_jpip[num_marker_jpip].len=jpip_write_ppix(img, j2k_cp);
677       marker_jpip[num_marker_jpip].type=JPIP_PPIX;
678       num_marker_jpip++;
679
680       marker_jpip[num_marker_jpip].len=jpip_write_phix(img, j2k_cp);
681       marker_jpip[num_marker_jpip].type=JPIP_PHIX;
682       num_marker_jpip++;
683
684       len=cio_tell()-lenp;
685       cio_seek(lenp);
686       cio_write(len, 4);        /* L             */
687       cio_seek(lenp+len);
688     }
689
690   free(marker_jpip);
691
692   return len;
693
694 }
695
696 /* 
697  * Write the IPTR box
698  *
699  * Index Finder box
700  *
701  */
702 void jpip_write_iptr(int offset, int length)
703 {
704   int len, lenp;
705   lenp=cio_tell();
706   cio_skip(4);              /* L [at the end] */
707   cio_write(JPIP_IPTR, 4);  /* IPTR           */
708   
709   cio_write(offset,8);
710   cio_write(length,8);
711
712   len=cio_tell()-lenp;
713   cio_seek(lenp);
714   cio_write(len, 4);        /* L             */
715   cio_seek(lenp+len);
716 }
717
718 /* 
719  * Write the PRXY box
720  *
721  * proxy (box)
722  *
723  */
724 void jpip_write_prxy(int offset_jp2c, int length_jp2c, int offset_idx, int length_idx)
725 {
726   int len, lenp;
727   lenp=cio_tell();
728   cio_skip(4);              /* L [at the end] */
729   cio_write(JPIP_PRXY, 4);  /* IPTR           */
730   
731   cio_write(offset_jp2c,8); /* OOFF           */
732   cio_write(length_jp2c,4); /* OBH part 1     */
733   cio_write(JP2C,4);        /* OBH part 2     */
734   
735   cio_write(1,1);           /* NI             */
736
737   cio_write(offset_idx,8);  /* IOFF           */
738   cio_write(length_idx,4);  /* IBH part 1     */
739   cio_write(JPIP_CIDX,4);   /* IBH part 2     */
740
741   len=cio_tell()-lenp;
742   cio_seek(lenp);
743   cio_write(len, 4);        /* L              */
744   cio_seek(lenp+len);
745 }
746
747
748 /* 
749  * Write the FIDX box
750  *
751  * File Index (superbox)
752  *
753  */
754 int jpip_write_fidx(int offset_jp2c, int length_jp2c, int offset_idx, int length_idx)
755 {
756   int len, lenp;
757   lenp=cio_tell();
758   cio_skip(4);              /* L [at the end] */
759   cio_write(JPIP_FIDX, 4);  /* IPTR           */
760   
761   jpip_write_prxy(offset_jp2c, length_jp2c, offset_idx, offset_jp2c);
762
763   len=cio_tell()-lenp;
764   cio_seek(lenp);
765   cio_write(len, 4);        /* L              */
766   cio_seek(lenp+len);
767
768   return len;
769 }