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