Update for version 1.0
[openjpeg.git] / indexer_JPIP / jpip.c
1 /*
2  * Copyright (c) 2003, Yannick Verschueren
3  * Copyright (c) 2003,  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
41 #define JPIP_CPTR 0x63707472
42 #define JPIP_MANF 0x6d616e66
43 #define JPIP_FAIX 0x66616978
44 #define JPIP_MHIX 0x6d686978
45 #define JPIP_TPIX 0x74706978
46 #define JPIP_THIX 0x74686978
47 #define JPIP_PPIX 0x70706978
48 #define JPIP_PHIX 0x70686978
49 #define JPIP_FIDX 0x66696478
50 #define JPIP_FPTR 0x66707472
51 #define JPIP_PRXY 0x70727879
52 #define JPIP_IPTR 0x69707472
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 void jpip_write_cptr(int offset, info_image_t img) // Codestream finder box (box)
60 {
61   int len, lenp;
62
63   lenp=cio_tell(); 
64   cio_skip(4);              // L [at the end]
65   cio_write(JPIP_CPTR,4);   // T
66   cio_write(0,2);           // DR  A PRECISER !!
67   cio_write(0,2);           // CONT
68   cio_write(offset,8);           // COFF A PRECISER !!
69   cio_write(img.codestream_size,8);     // CLEN
70   len=cio_tell()-lenp;
71   cio_seek(lenp);
72   cio_write(len, 4);        // L
73   cio_seek(lenp+len);
74 }
75
76 void jpip_write_manf(int second, int v, info_marker_t *marker) // Manifest box (box)
77 {
78   int len, lenp, i;
79   lenp=cio_tell(); 
80   cio_skip(4);              // L [at the end]
81   cio_write(JPIP_MANF,4);   // T
82
83   if (second) // Write only during the second pass
84     {
85       for(i=0;i<v;i++)
86         {
87           cio_write(marker[i].len,4);
88           cio_write(marker[i].type,4);
89         }
90     }
91
92   len=cio_tell()-lenp;
93   cio_seek(lenp);
94   cio_write(len, 4);        // L
95   cio_seek(lenp+len);
96 }
97
98 int jpip_write_mhix(info_image_t img) // Main Header Index Table (box)
99 {
100   int len, lenp, i;
101   lenp=cio_tell();
102   cio_skip(4);              // L [at the end]
103   cio_write(JPIP_MHIX, 4);  // CIDX
104
105   cio_write(img.Main_head_end,8); // TLEN 
106   
107   for(i=0;i<img.num_marker;i++) // Marker restricted to 1 apparition
108     {
109       cio_write(img.marker[i].type,2);
110       cio_write(0,2);
111       cio_write(img.marker[i].start_pos,8);
112       cio_write(img.marker[i].len,2);
113     }
114
115   // Marker NOT restricted to 1 apparition
116   for(i=img.marker_mul.num_COD-1;i>=0;i--) // COD
117     {
118       cio_write(img.marker_mul.COD[i].type,2);
119       cio_write(i,2);
120       cio_write(img.marker_mul.COD[i].start_pos,8);
121       cio_write(img.marker_mul.COD[i].len,2);
122     }
123
124   for(i=img.marker_mul.num_COC-1;i>=0;i--) // COC
125     {
126       cio_write(img.marker_mul.COC[i].type,2);
127       cio_write(i,2);
128       cio_write(img.marker_mul.COC[i].start_pos,8);
129       cio_write(img.marker_mul.COC[i].len,2);
130     }
131
132   for(i=img.marker_mul.num_RGN-1;i>=0;i--) // RGN
133     {
134       cio_write(img.marker_mul.RGN[i].type,2);
135       cio_write(i,2);
136       cio_write(img.marker_mul.RGN[i].start_pos,8);
137       cio_write(img.marker_mul.RGN[i].len,2);
138     }
139
140   for(i=img.marker_mul.num_QCC-1;i>=0;i--) // QCC
141     {
142       cio_write(img.marker_mul.QCC[i].type,2);
143       cio_write(i,2);
144       cio_write(img.marker_mul.QCC[i].start_pos,8);
145       cio_write(img.marker_mul.QCC[i].len,2);
146     }
147
148   for(i=img.marker_mul.num_TLM-1;i>=0;i--) // TLM
149     {
150       cio_write(img.marker_mul.TLM[i].type,2);
151       cio_write(i,2);
152       cio_write(img.marker_mul.TLM[i].start_pos,8);
153       cio_write(img.marker_mul.TLM[i].len,2);
154     }
155
156   for(i=img.marker_mul.num_PLM-1;i>=0;i--) // PLM
157     {
158       cio_write(img.marker_mul.PLM[i].type,2);
159       cio_write(i,2);
160       cio_write(img.marker_mul.PLM[i].start_pos,8);
161       cio_write(img.marker_mul.PLM[i].len,2);
162     }
163
164   for(i=img.marker_mul.num_COM-1;i>=0;i--) // COM
165     {
166       cio_write(img.marker_mul.COM[i].type,2);
167       cio_write(i,2);
168       cio_write(img.marker_mul.COM[i].start_pos,8);
169       cio_write(img.marker_mul.COM[i].len,2);
170     }
171
172   len=cio_tell()-lenp;
173   cio_seek(lenp);
174   cio_write(len, 4);        // L
175   cio_seek(lenp+len);
176
177   return len;
178 }
179
180 int jpip_write_faix(int v, int compno, info_image_t img, j2k_cp_t *j2k_cp) // Fragment array Index box
181 {
182   int len, lenp, i;
183   int version = 0;
184   int tileno, resno, precno, layno, num_packet=0;
185
186   lenp=cio_tell();
187   cio_skip(4);              // L [at the end]
188   cio_write(JPIP_FAIX, 4);  // MHIX
189   cio_write(version,1);     // Version 0 = 4 bytes
190   
191   switch(v)
192     {
193     case 0:   // TPIX
194       cio_write(1,version?8:4); // NMAX
195       cio_write(img.tw*img.th,version?8:4); // M
196       for (i=0;i<img.tw*img.th;i++)
197         {
198           cio_write(img.tile[i].start_pos,version?8:4);
199           cio_write(img.tile[i].end_pos-img.tile[i].start_pos,version?8:4);
200         }
201       break;
202       
203     case 1:   // THIX
204       cio_write(1,version?8:4); // NMAX
205       cio_write(img.tw*img.th,version?8:4); // M
206       for (i=0;i<img.tw*img.th;i++)
207         {
208           cio_write(img.tile[i].start_pos,version?8:4);
209           cio_write(img.tile[i].end_header-img.tile[i].start_pos,version?8:4);
210         }
211       break;
212
213     case 2:  // PPIX  NOT FINISHED !!
214       cio_write(img.num_packet_max,version?8:4); // NMAX
215       cio_write(img.tw*img.th,version?8:4); // M
216       for(tileno=0;tileno<img.tw*img.th;tileno++)
217         {
218           info_tile_t *tile_Idx = &img.tile[tileno];
219           info_compo_t *compo_Idx = &tile_Idx->compo[compno];
220           int correction;
221           if(j2k_cp->tcps[tileno].csty&J2K_CP_CSTY_EPH)
222             correction=3;
223           else
224             correction=1;
225           for(resno=0;resno<img.Decomposition+1;resno++)
226             {
227               info_reso_t *reso_Idx = &compo_Idx->reso[resno];
228               for (precno=0;precno<img.tile[tileno].pw*img.tile[tileno].ph;precno++)
229                 {
230                   info_prec_t *prec_Idx = &reso_Idx->prec[precno];
231                   for(layno=0;layno<img.Layer;layno++)
232                     {
233                       info_layer_t *layer_Idx = &prec_Idx->layer[layno];
234                       cio_write(layer_Idx->offset,version?8:4);
235                       cio_write((layer_Idx->len_header-correction)?0:layer_Idx->len,version?8:4);
236                       num_packet++;
237                     }
238                 }
239             }
240         }
241       // PADDING
242       while (num_packet<img.num_packet_max)
243         {
244           cio_write(0,version?8:4);
245           cio_write(0,version?8:4);
246           num_packet++;
247         }
248       break;
249       
250     case 3:  // PHIX NOT FINISHED !!
251       cio_write(img.num_packet_max,version?8:4); // NMAX
252       cio_write(img.tw*img.th,version?8:4); // M
253       for(tileno=0;tileno<img.tw*img.th;tileno++)
254         {
255           info_tile_t *tile_Idx = &img.tile[tileno];
256           info_compo_t *compo_Idx = &tile_Idx->compo[compno];
257           int correction;
258           if(j2k_cp->tcps[tileno].csty&J2K_CP_CSTY_EPH)
259             correction=3;
260           else
261             correction=1;
262           for(resno=0;resno<img.Decomposition+1;resno++)
263             {
264               info_reso_t *reso_Idx = &compo_Idx->reso[resno];
265               for (precno=0;precno<img.tile[tileno].pw*img.tile[tileno].ph;precno++)
266                 {
267                   info_prec_t *prec_Idx = &reso_Idx->prec[precno];
268                   for(layno=0;layno<img.Layer;layno++)
269                     {
270                       info_layer_t *layer_Idx = &prec_Idx->layer[layno];
271                       cio_write(layer_Idx->offset,version?8:4);
272                       cio_write((layer_Idx->len_header-correction)?0:layer_Idx->len_header,version?8:4);
273                       num_packet++;
274                     }
275                 }
276             }
277         }
278       // PADDING
279       while (num_packet<img.num_packet_max)
280         {
281           cio_write(0,version?8:4);
282           cio_write(0,version?8:4);
283           num_packet++;
284         }
285       break;
286     }
287   
288   len=cio_tell()-lenp;
289   cio_seek(lenp);
290   cio_write(len, 4);        // L
291   cio_seek(lenp+len);
292
293   return len;
294 }
295
296 int jpip_write_tpix(info_image_t img, j2k_cp_t *j2k_cp) // Tile-part Index Table box (superbox)
297 {
298   int len, lenp;
299   lenp=cio_tell();
300   cio_skip(4);              // L [at the end]
301   cio_write(JPIP_TPIX, 4);  // TPIX
302   
303   jpip_write_faix(0,0,img, j2k_cp);
304
305   len=cio_tell()-lenp;
306   cio_seek(lenp);
307   cio_write(len, 4);        // L
308   cio_seek(lenp+len);
309
310   return len;
311 }
312
313 int jpip_write_thix(info_image_t img, j2k_cp_t *j2k_cp) // Tile header Index Table box (superbox)
314 {
315   int len, lenp;
316   lenp=cio_tell();
317   cio_skip(4);              // L [at the end]
318   cio_write(JPIP_THIX, 4);  // THIX
319   
320   jpip_write_faix(1,0,img, j2k_cp);
321
322   len=cio_tell()-lenp;
323   cio_seek(lenp);
324   cio_write(len, 4);        // L
325   cio_seek(lenp+len);
326
327   return len;
328 }
329
330 int jpip_write_ppix(info_image_t img,j2k_cp_t *j2k_cp) // Precinct Packet Index Table box (superbox)
331 {
332   int len, lenp, compno, i;
333   
334   for (i=0;i<2;i++)
335     {
336       if (i) cio_seek(lenp);
337       
338       lenp=cio_tell();
339       cio_skip(4);              // L [at the end]
340       cio_write(JPIP_PPIX, 4);  // PPIX
341       jpip_write_manf(i,img.Comp,marker_local_jpip);
342       
343       num_marker_local_jpip=img.Comp;
344       
345       for (compno=0; compno<img.Comp; compno++)
346         {
347           marker_local_jpip[compno].len=jpip_write_faix(2,compno,img, j2k_cp);
348           marker_local_jpip[compno].type=JPIP_FAIX;
349         }
350    
351       len=cio_tell()-lenp;
352       cio_seek(lenp);
353       cio_write(len, 4);        // L
354       cio_seek(lenp+len);
355     }
356   return len;
357 }  
358
359 int jpip_write_phix(info_image_t img, j2k_cp_t *j2k_cp) // Packet Header Index Table Box (superbox)
360 {
361   int len, lenp=0, compno, i;
362   
363   for (i=0;i<2;i++)
364     {
365       if (i) cio_seek(lenp);
366       
367       lenp=cio_tell();
368       cio_skip(4);              // L [at the end]
369       cio_write(JPIP_PHIX, 4);  // PHIX
370       
371       jpip_write_manf(i,img.Comp,marker_local_jpip);
372
373       for (compno=0; compno<img.Comp; compno++)
374         {       
375           marker_local_jpip[compno].len=jpip_write_faix(3,compno,img, j2k_cp);
376           marker_local_jpip[compno].type=JPIP_FAIX;
377         }
378
379       len=cio_tell()-lenp;
380       cio_seek(lenp);
381       cio_write(len, 4);        // L
382       cio_seek(lenp+len);
383     }
384   return len;
385 }
386
387 int jpip_write_cidx(int offset, info_image_t img, j2k_cp_t *j2k_cp) // Codestream index box (superbox)
388 {
389   int len, lenp=0, i;
390   num_marker_jpip=0;
391
392   for (i=0;i<2;i++)
393     {
394       if(i)
395         cio_seek(lenp);
396
397       lenp=cio_tell();
398
399       cio_skip(4);              // L [at the end]
400       cio_write(JPIP_CIDX, 4);  // CIDX
401       jpip_write_cptr(offset, img);
402       jpip_write_manf(i,num_marker_jpip, marker_jpip);  // A definir
403
404       num_marker_jpip=0;
405       marker_jpip[num_marker_jpip].len=jpip_write_mhix(img);
406       marker_jpip[num_marker_jpip].type=JPIP_MHIX;
407       num_marker_jpip++;
408
409       marker_jpip[num_marker_jpip].len=jpip_write_tpix(img, j2k_cp);
410       marker_jpip[num_marker_jpip].type=JPIP_TPIX;
411       num_marker_jpip++;
412       
413       marker_jpip[num_marker_jpip].len=jpip_write_thix(img, j2k_cp);
414       marker_jpip[num_marker_jpip].type=JPIP_THIX;
415       num_marker_jpip++;
416       
417       marker_jpip[num_marker_jpip].len=jpip_write_ppix(img, j2k_cp);
418       marker_jpip[num_marker_jpip].type=JPIP_PPIX;
419       num_marker_jpip++;
420       
421       marker_jpip[num_marker_jpip].len=jpip_write_phix(img, j2k_cp);
422       marker_jpip[num_marker_jpip].type=JPIP_PHIX;
423       num_marker_jpip++;
424       
425       len=cio_tell()-lenp;
426       cio_seek(lenp);
427       cio_write(len, 4);        // L
428       cio_seek(lenp+len);
429     }
430   
431   return len;
432
433 }
434
435 void jpip_write_iptr(int offset, int length)
436 {
437   int len, lenp;
438   lenp=cio_tell();
439   cio_skip(4);              // L [at the end]
440   cio_write(JPIP_IPTR, 4);  // IPTR
441   
442   cio_write(offset,8);
443   cio_write(length,8);
444
445   len=cio_tell()-lenp;
446   cio_seek(lenp);
447   cio_write(len, 4);        // L
448   cio_seek(lenp+len);
449 }
450
451 void jpip_write_prxy(int offset_jp2c, int length_jp2c, int offset_idx, int length_idx)
452 {
453   int len, lenp;
454   lenp=cio_tell();
455   cio_skip(4);              // L [at the end]
456   cio_write(JPIP_PRXY, 4);  // IPTR
457   
458   cio_write(offset_jp2c,8); // OOFF
459   cio_write(length_jp2c,4); // OBH part 1
460   cio_write(JP2C,4);        // OBH part 2
461   
462   cio_write(1,1);           // NI
463
464   cio_write(offset_idx,8); // IOFF
465   cio_write(length_idx,4); // IBH part 1
466   cio_write(JPIP_CIDX,4);  // IBH part 2
467
468   len=cio_tell()-lenp;
469   cio_seek(lenp);
470   cio_write(len, 4);        // L
471   cio_seek(lenp+len);
472
473
474 int jpip_write_fidx(int offset_jp2c, int length_jp2c, int offset_idx, int length_idx)
475 {
476   int len, lenp;
477   lenp=cio_tell();
478   cio_skip(4);              // L [at the end]
479   cio_write(JPIP_FIDX, 4);  // IPTR
480   
481   jpip_write_prxy(offset_jp2c, length_jp2c, offset_idx, offset_jp2c);
482
483   len=cio_tell()-lenp;
484   cio_seek(lenp);
485   cio_write(len, 4);        // L
486   cio_seek(lenp+len);
487
488   return len;
489 }