[trunk] Update JPIP (FolderReorgProposal task)
[openjpeg.git] / src / lib / openjpip / cidx_manager.c
1 /*
2  * $Id: cidx_manager.c 897 2011-08-28 21:43:57Z Kaori.Hagihara@gmail.com $
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) 2003-2004, Yannick Verschueren
7  * Copyright (c) 2010-2011, Kaori Hagihara
8  * All rights reserved.
9  *
10  * Redistribution and use in source and binary forms, with or without
11  * modification, are permitted provided that the following conditions
12  * are met:
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in the
17  *    documentation and/or other materials provided with the distribution.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
20  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
23  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29  * POSSIBILITY OF SUCH DAMAGE.
30  */
31
32 #include "opj_includes.h"
33
34
35 /* 
36  * Write CPTR Codestream finder box
37  *
38  * @param[in] coff offset of j2k codestream
39  * @param[in] clen length of j2k codestream
40  * @param[in] cio  file output handle
41  */
42 void write_cptr(int coff, int clen, opj_cio_t *cio);
43
44 void write_cptr_v2(int coff, int clen, opj_stream_private_t *cio,
45               opj_event_mgr_t * p_manager );
46
47 void write_manf_v2(int second, int v, opj_jp2_box_t *box, opj_stream_private_t *cio,
48               opj_event_mgr_t * p_manager );
49
50 /* 
51  * Write main header index table (box)
52  *
53  * @param[in] coff offset of j2k codestream
54  * @param[in] cstr_info codestream information
55  * @param[in] cio  file output handle
56  * @return         length of mainmhix box
57  */
58 int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
59
60
61 /* 
62  * Check if EPH option is used
63  *
64  * @param[in] coff    offset of j2k codestream
65  * @param[in] markers marker information
66  * @param[in] marknum number of markers
67  * @param[in] cio     file output handle
68  * @return            true if EPH is used
69  */
70 opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio);
71
72
73 int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen)
74 {
75   int len, i, lenp;
76   opj_jp2_box_t *box;
77   int num_box = 0;
78   opj_bool  EPHused;
79   (void)image; /* unused ? */
80
81   lenp = -1;
82   box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
83
84   for (i=0;i<2;i++){
85   
86     if(i)
87       cio_seek( cio, lenp);
88
89     lenp = cio_tell( cio);
90
91     cio_skip( cio, 4);              /* L [at the end] */
92     cio_write( cio, JPIP_CIDX, 4);  /* CIDX           */
93     write_cptr( offset, cstr_info.codestream_size, cio);
94
95     write_manf( i, num_box, box, cio);
96     
97     num_box = 0;
98     box[num_box].length = write_mainmhix( offset, cstr_info, cio);
99     box[num_box].type = JPIP_MHIX;
100     num_box++;
101
102     box[num_box].length = write_tpix( offset, cstr_info, j2klen, cio);
103     box[num_box].type = JPIP_TPIX;
104     num_box++;
105       
106     box[num_box].length = write_thix( offset, cstr_info, cio);
107     box[num_box].type = JPIP_THIX;
108     num_box++;
109
110     EPHused = check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio);
111       
112     box[num_box].length = write_ppix( offset, cstr_info, EPHused, j2klen, cio);
113     box[num_box].type = JPIP_PPIX;
114     num_box++;
115     
116     box[num_box].length = write_phix( offset, cstr_info, EPHused, j2klen, cio);
117     box[num_box].type = JPIP_PHIX;
118     num_box++;
119       
120     len = cio_tell( cio)-lenp;
121     cio_seek( cio, lenp);
122     cio_write( cio, len, 4);        /* L             */
123     cio_seek( cio, lenp+len);
124   }
125
126   opj_free( box);
127   
128   return len;
129 }
130
131 int write_cidx_v2( int offset, opj_stream_private_t *cio, opj_codestream_info_t cstr_info, int j2klen,
132               opj_event_mgr_t * p_manager )
133 {
134   int len, i, lenp;
135   opj_jp2_box_t *box;
136   int num_box = 0;
137   opj_bool  EPHused;
138   OPJ_BYTE l_data_header [4];
139
140   lenp = -1;
141   box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
142
143   for (i=0;i<2;i++){
144   
145     if(i)
146       opj_stream_seek(cio,lenp,p_manager);
147
148
149     lenp = opj_stream_tell (cio);
150
151     opj_stream_skip(cio, 4, p_manager); /* L [at the end] */
152 #if 0
153     cio_write( cio, JPIP_CIDX, 4);  /* CIDX           */
154 #else
155     opj_write_bytes(l_data_header,JPIP_CIDX,4); /* CIDX */
156     opj_stream_write_data(cio,l_data_header,4,p_manager);
157 #endif
158     write_cptr_v2( offset, cstr_info.codestream_size, cio,p_manager);
159
160     write_manf_v2( i, num_box, box, cio,p_manager);
161     
162     num_box = 0;
163     box[num_box].length = write_mainmhix_v2( offset, cstr_info, cio,p_manager);
164     box[num_box].type = JPIP_MHIX;
165     num_box++;
166
167     box[num_box].length = write_tpix_v2( offset, cstr_info, j2klen, cio);
168     box[num_box].type = JPIP_TPIX;
169     num_box++;
170       
171     box[num_box].length = write_thix_v2( offset, cstr_info, cio);
172     box[num_box].type = JPIP_THIX;
173     num_box++;
174
175     EPHused = check_EPHuse_v2( offset, cstr_info.marker, cstr_info.marknum, cio);
176       
177     box[num_box].length = write_ppix_v2( offset, cstr_info, EPHused, j2klen, cio);
178     box[num_box].type = JPIP_PPIX;
179     num_box++;
180     
181     box[num_box].length = write_phix_v2( offset, cstr_info, EPHused, j2klen, cio);
182     box[num_box].type = JPIP_PHIX;
183     num_box++;
184       
185 #if 0
186     len = cio_tell( cio)-lenp;
187     cio_seek( cio, lenp);
188     cio_write( cio, len, 4);        /* L             */
189     cio_seek( cio, lenp+len);
190 #else
191     len = opj_stream_tell(cio)-lenp;
192     opj_stream_seek(cio, lenp,p_manager);
193     opj_write_bytes(l_data_header,len,4);/* L  */
194     opj_stream_write_data(cio,l_data_header,4,p_manager);
195     opj_stream_seek(cio, lenp+len,p_manager);
196 #endif
197   }
198
199   opj_free( box);
200   
201   return len;
202 }
203
204 void write_cptr(int coff, int clen, opj_cio_t *cio)
205 {
206   int len, lenp;
207
208   lenp = cio_tell( cio);
209   cio_skip( cio, 4);               /* L [at the end]     */
210   cio_write( cio, JPIP_CPTR, 4);   /* T                  */
211   cio_write( cio, 0, 2);           /* DR  A PRECISER !!  */
212   cio_write( cio, 0, 2);           /* CONT               */
213   cio_write( cio, coff, 8);    /* COFF A PRECISER !! */
214   cio_write( cio, clen, 8);    /* CLEN               */
215   len = cio_tell( cio) - lenp;
216   cio_seek( cio, lenp);
217   cio_write( cio, len, 4);         /* L                  */
218   cio_seek( cio, lenp+len);
219 }
220
221 void write_cptr_v2(int coff, int clen, opj_stream_private_t *cio,
222               opj_event_mgr_t * p_manager )
223 {
224   OPJ_BYTE l_data_header [3*8];
225   int len, lenp;
226
227 #if 0
228   lenp = cio_tell( cio);
229   cio_skip( cio, 4);               /* L [at the end]     */
230   cio_write( cio, JPIP_CPTR, 4);   /* T                  */
231   cio_write( cio, 0, 2);           /* DR  A PRECISER !!  */
232   cio_write( cio, 0, 2);           /* CONT               */
233   cio_write( cio, coff, 8);    /* COFF A PRECISER !! */
234   cio_write( cio, clen, 8);    /* CLEN               */
235   len = cio_tell( cio) - lenp;
236   cio_seek( cio, lenp);
237   cio_write( cio, len, 4);         /* L                  */
238   cio_seek( cio, lenp+len);
239 #else
240   lenp = opj_stream_tell(cio);
241   opj_stream_skip( cio, 4, p_manager);               /* L [at the end]     */
242   opj_write_bytes( l_data_header, JPIP_CPTR, 4);   /* T                  */
243   opj_write_bytes( l_data_header+4, 0, 2);           /* DR  A PRECISER !!  */
244   opj_write_bytes( l_data_header+6, 0, 2);           /* CONT               */
245   opj_write_bytes( l_data_header+8, coff, 8);    /* COFF A PRECISER !! */
246   opj_write_bytes( l_data_header+16, clen, 8);    /* CLEN               */
247   opj_stream_write_data(cio,l_data_header,3*8,p_manager);
248
249   len = opj_stream_tell(cio) - lenp;
250   opj_stream_seek(cio,lenp,p_manager);
251   opj_write_bytes(l_data_header, len, 4);         /* L                  */
252   opj_stream_write_data(cio,l_data_header,4,p_manager);
253   opj_stream_seek(cio, lenp+len,p_manager);
254 #endif
255 }
256
257 void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio)
258 {
259   int len, lenp, i;
260   
261   lenp = cio_tell( cio); 
262   cio_skip( cio, 4);                         /* L [at the end]                    */
263   cio_write( cio, JPIP_MANF,4);              /* T                                 */
264
265   if (second){                          /* Write only during the second pass */
266     for( i=0; i<v; i++){
267       cio_write( cio, box[i].length, 4);  /* Box length                     */ 
268       cio_write( cio, box[i].type, 4); /* Box type                       */
269     }
270   }
271
272   len = cio_tell( cio) - lenp;
273   cio_seek( cio, lenp);
274   cio_write( cio, len, 4);                   /* L                                 */
275   cio_seek( cio, lenp+len);
276 }
277
278 void write_manf_v2(int second, int v, opj_jp2_box_t *box, opj_stream_private_t *cio,
279               opj_event_mgr_t * p_manager )
280 {
281   OPJ_BYTE l_data_header [4];
282   int len, lenp, i;
283   
284 #if 0
285   lenp = cio_tell( cio); 
286   cio_skip( cio, 4);                         /* L [at the end]                    */
287   cio_write( cio, JPIP_MANF,4);              /* T                                 */
288 #else
289   lenp = opj_stream_tell(cio);
290   opj_stream_skip( cio, 4, p_manager);             /* L [at the end]     */
291   opj_write_bytes( l_data_header, JPIP_MANF, 4);   /* T                  */
292   opj_stream_write_data(cio,l_data_header,4,p_manager);
293 #endif
294
295   if (second){                          /* Write only during the second pass */
296     for( i=0; i<v; i++){
297 #if 0
298       cio_write( cio, box[i].length, 4);  /* Box length                     */ 
299       cio_write( cio, box[i].type, 4); /* Box type                       */
300 #else
301       opj_write_bytes( l_data_header, box[i].length, 4); /* Box length                     */
302       opj_stream_write_data(cio,l_data_header,4,p_manager);
303       opj_write_bytes( l_data_header, box[i].type, 4); /* Box type                       */
304       opj_stream_write_data(cio,l_data_header,4,p_manager);
305 #endif
306     }
307   }
308
309 #if 0
310   len = cio_tell( cio) - lenp;
311   cio_seek( cio, lenp);
312   cio_write( cio, len, 4);                   /* L                                 */
313   cio_seek( cio, lenp+len);
314 #else
315   len = opj_stream_tell(cio) - lenp;
316   opj_stream_seek(cio,lenp,p_manager);
317   opj_write_bytes(l_data_header, len, 4);/* L                                 */
318   opj_stream_write_data(cio,l_data_header,4,p_manager);
319   opj_stream_seek(cio,lenp+len,p_manager);
320 #endif
321 }
322
323 int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
324 {
325   int i;
326   int len, lenp;
327   
328   lenp = cio_tell( cio);
329   cio_skip( cio, 4);                               /* L [at the end]                    */
330   cio_write( cio, JPIP_MHIX, 4);                   /* MHIX                              */
331
332   cio_write( cio, cstr_info.main_head_end-cstr_info.main_head_start+1, 8);        /* TLEN                              */
333
334   for(i = 1; i < cstr_info.marknum; i++){    /* Marker restricted to 1 apparition, skip SOC marker */
335     cio_write( cio, cstr_info.marker[i].type, 2);
336     cio_write( cio, 0, 2);
337     cio_write( cio, cstr_info.marker[i].pos-coff, 8);
338     cio_write( cio, cstr_info.marker[i].len, 2);
339   }
340
341   len = cio_tell( cio) - lenp;
342   cio_seek( cio, lenp);
343   cio_write( cio, len, 4);        /* L           */
344   cio_seek( cio, lenp+len);
345   
346   return len;
347 }
348
349 int write_mainmhix_v2( int coff, opj_codestream_info_t cstr_info, opj_stream_private_t *cio,
350               opj_event_mgr_t * p_manager )
351 {
352   OPJ_BYTE l_data_header [8];
353   int i;
354   int len, lenp;
355   
356 #if 0
357   lenp = cio_tell( cio);
358   cio_skip( cio, 4);                               /* L [at the end]                    */
359   cio_write( cio, JPIP_MHIX, 4);                   /* MHIX                              */
360 #else
361   lenp = opj_stream_tell (cio);
362   opj_stream_skip(cio, 4, p_manager);               /* L [at the end]                    */
363   opj_write_bytes(l_data_header,JPIP_MHIX,4);       /* MHIX                              */
364   opj_stream_write_data(cio,l_data_header,4,p_manager);
365 #endif
366
367 #if 0
368   cio_write( cio, cstr_info.main_head_end-cstr_info.main_head_start+1, 8);        /* TLEN                              */
369 #else
370   opj_write_bytes(l_data_header, cstr_info.main_head_end-cstr_info.main_head_start+1, 8);        /* TLEN                              */
371   opj_stream_write_data(cio,l_data_header,8,p_manager);
372 #endif
373
374   for(i = 1; i < cstr_info.marknum; i++){    /* Marker restricted to 1 apparition, skip SOC marker */
375 #if 0
376     cio_write( cio, cstr_info.marker[i].type, 2);
377     cio_write( cio, 0, 2);
378     cio_write( cio, cstr_info.marker[i].pos-coff, 8);
379     cio_write( cio, cstr_info.marker[i].len, 2);
380 #else
381     opj_write_bytes( l_data_header, cstr_info.marker[i].type, 2);
382     opj_write_bytes( l_data_header+2, 0, 2);
383     opj_stream_write_data(cio,l_data_header,4,p_manager);
384     opj_write_bytes( l_data_header, cstr_info.marker[i].pos-coff, 8);
385     opj_stream_write_data(cio,l_data_header,8,p_manager);
386     opj_write_bytes( l_data_header, cstr_info.marker[i].len, 2);
387     opj_stream_write_data(cio,l_data_header,2,p_manager);
388 #endif
389   }
390
391 #if 0
392   len = cio_tell( cio) - lenp;
393   cio_seek( cio, lenp);
394   cio_write( cio, len, 4);        /* L           */
395   cio_seek( cio, lenp+len);
396 #else
397   len = opj_stream_tell(cio)-lenp;
398   opj_stream_seek(cio, lenp,p_manager);
399   opj_write_bytes(l_data_header,len,4);/* L  */
400   opj_stream_write_data(cio,l_data_header,4,p_manager);
401   opj_stream_seek(cio, lenp+len,p_manager);
402 #endif
403   
404   return len;
405 }
406
407 opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio)
408 {
409   opj_bool EPHused = OPJ_FALSE;
410   int i=0;
411   int org_pos;
412   unsigned int Scod;
413
414   for(i = 0; i < marknum; i++){
415     if( markers[i].type == J2K_MS_COD){
416       org_pos = cio_tell( cio);
417       cio_seek( cio, coff+markers[i].pos+2);
418       
419       Scod = cio_read( cio, 1);
420       if( ((Scod >> 2) & 1))
421   EPHused = OPJ_TRUE;
422       cio_seek( cio, org_pos);
423
424       break;
425     }
426   }    
427   return EPHused;
428 }
429
430 opj_bool check_EPHuse_v2( int coff, opj_marker_info_t *markers, int marknum, opj_stream_private_t *cio,
431               opj_event_mgr_t * p_manager )
432 {
433   OPJ_BYTE l_data_header [4];
434   opj_bool EPHused = OPJ_FALSE;
435   int i=0;
436   int org_pos;
437   unsigned int Scod;
438
439   for(i = 0; i < marknum; i++)
440     {
441     if( markers[i].type == J2K_MS_COD)
442       {
443 #if 0
444       org_pos = cio_tell( cio);
445       cio_seek( cio, coff+markers[i].pos+2);
446 #else
447       org_pos = opj_stream_tell(cio);
448       opj_stream_seek(cio, coff+markers[i].pos+2,p_manager);
449 #endif
450
451 #if 0
452       Scod = cio_read( cio, 1);
453 #else
454       opj_stream_read_data(cio,l_data_header,1,p_manager);
455       opj_read_bytes(l_data_header,&Scod,1);
456 #endif
457       if( ((Scod >> 2) & 1))
458         EPHused = OPJ_TRUE;
459 #if 0
460       cio_seek( cio, org_pos);
461 #else
462       opj_stream_seek( cio, org_pos, p_manager);
463 #endif
464
465       break;
466       }
467     }    
468   return EPHused;
469 }