[1.5] enabled JPP stream in JPIP (result of GSoC program)
[openjpeg.git] / applications / jpip / tools / indexer / idxjp2_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) 2001-2003, David Janssens
7  * Copyright (c) 2002-2003, Yannick Verschueren
8  * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe
9  * Copyright (c) 2005, Herve Drolon, FreeImage Team
10
11  * Copyright (c) 2010-2011, Kaori Hagihara
12  * All rights reserved.
13  *
14  * Redistribution and use in source and binary forms, with or without
15  * modification, are permitted provided that the following conditions
16  * are met:
17  * 1. Redistributions of source code must retain the above copyright
18  *    notice, this list of conditions and the following disclaimer.
19  * 2. Redistributions in binary form must reproduce the above copyright
20  *    notice, this list of conditions and the following disclaimer in the
21  *    documentation and/or other materials provided with the distribution.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
24  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 /*! \file
37  *  \brief Copy of some jp2.c functions, and modification of jpip.h from 2KAN indexer
38  */
39
40 #include <stdio.h>
41 #include <string.h>
42 #include <stdlib.h>
43 #include "event_mgr_handler.h"
44 #include "cio.h"
45 #include "cio_ext.h"
46 #include "j2k_to_idxjp2.h"
47 #include "cidx_manager.h"
48 #include "indexbox_manager.h"
49
50 /* 
51  * Encode JP2 stream with index box
52  *
53  * @param[in] jp2       jp2 handle
54  * @param[in] cio       file output handle
55  * @param[in] j2kstream j2k codestream
56  * @param[in] j2klen    length of j2k codestream
57  * @param[in] cstr_info codestream information
58  * @param[in] image     image data
59  * @return              true if succeed
60  */
61 opj_bool idxjp2_encode( opj_jp2_t *jp2, opj_cio_t *cio, unsigned char *j2kstream, int j2klen, opj_codestream_info_t cstr_info, opj_image_t *image);
62
63
64 void fwrite_idxjp2( char filename[], unsigned char *j2kstream, int j2klen, opj_image_t *image, opj_codestream_info_t cstr_info)
65 {
66   int codestream_length;
67   opj_cio_t *cio = NULL;
68   FILE *fp = NULL;
69   opj_cinfo_t *cinfo;
70   opj_cparameters_t parameters; /* compression parameters */
71   opj_event_mgr_t event_mgr;
72   opj_bool encSuccess;
73
74   /* set encoding parameters to default values */
75   opj_set_default_encoder_parameters(&parameters);
76   
77   /* get a JP2 compressor handle */
78   cinfo = opj_create_compress(CODEC_JP2);
79
80   event_mgr = set_default_event_mgr();
81
82   /* catch events using our callbacks and give a local context */
83   opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr);
84
85   /* setup the encoder parameters using the current image and using user parameters */
86   opj_setup_encoder(cinfo, &parameters, image);
87
88   /* open a byte stream for writing */
89   /* allocate memory for all tiles */
90   cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0);
91
92   encSuccess = idxjp2_encode( (opj_jp2_t*)cinfo->jp2_handle, cio, j2kstream, j2klen, cstr_info, image);
93
94   if (!encSuccess){
95     opj_cio_close(cio);
96     fprintf(stderr, "failed to encode image\n");
97     return;
98   }
99   codestream_length = cio_tell(cio);
100
101   /* write the buffer to disk */
102   fp = fopen( filename, "wb");
103   if (!fp) {
104     fprintf(stderr, "failed to open %s for writing\n", filename);
105     return;
106   }
107
108   fwrite(cio->buffer, 1, codestream_length, fp);
109   fclose(fp);
110   fprintf(stderr,"Generated outfile %s\n", filename);
111   /* close and free the byte stream */
112   opj_cio_close(cio);
113
114   /* free remaining compression structures */
115   opj_destroy_compress(cinfo);
116
117   opj_destroy_cstr_info(&cstr_info);
118 }
119
120 /* 
121  * Write JP box
122  *    copy from jp2.c
123  *
124  * @param[in] cio file output handler
125  */
126 void jp2_write_jp(opj_cio_t *cio);
127
128 /* 
129  * Write FTYP box - File type box
130  *    copy from jp2.c
131  *
132  * @param[in] jp2 JP2 handle
133  * @param[in] cio file output handle
134  */
135 void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio);
136
137 /* 
138  * Write file Index (superbox)
139  *
140  * @param[in] offset_jp2c offset of jp2c box
141  * @param[in] length_jp2c length of jp2c box
142  * @param[in] offset_idx  offset of cidx box
143  * @param[in] length_idx  length of cidx box
144  * @param[in] cio         file output handle
145  * @return                length of fidx box
146  */
147 int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio);
148
149 /* 
150  * Write index Finder box
151  *
152  * @param[in] offset offset of fidx box
153  * @param[in] length length of fidx box
154  * @param[in] cio         file output handle
155  */
156 void write_iptr( int offset, int length, opj_cio_t *cio);
157
158 opj_bool idxjp2_encode( opj_jp2_t *jp2, opj_cio_t *cio, unsigned char *j2kstream, int j2klen, opj_codestream_info_t cstr_info, opj_image_t *image)
159 {  
160   int pos_iptr, pos_cidx, pos_jp2c, end_pos, pos_fidx, len_fidx;
161   int i;
162   
163   /* JP2 encoding */
164  
165   /* JPEG 2000 Signature box */
166   jp2_write_jp(cio);
167   /* File Type box */
168   jp2_write_ftyp(jp2, cio);
169   /* JP2 Header box */
170   jp2_write_jp2h(jp2, cio);
171   
172   pos_iptr = cio_tell( cio);
173   cio_skip( cio, 24); /* IPTR further ! */
174   
175   pos_jp2c = cio_tell( cio);
176
177   cio_write( cio, j2klen+8, 4); // L NOTICE: modify for the extended box
178   cio_write( cio, JP2_JP2C, 4);  // JP2C
179
180   for( i=0; i<j2klen; i++)
181     cio_write( cio, j2kstream[i], 1);
182
183   pos_cidx = cio_tell( cio);
184
185   write_cidx( pos_jp2c+8, cio, image, cstr_info, j2klen);
186
187   pos_fidx = cio_tell( cio);
188   len_fidx = write_fidx( pos_jp2c, pos_cidx-pos_jp2c, pos_cidx, cio_tell(cio), cio);
189
190   end_pos = cio_tell( cio);
191
192   cio_seek( cio, pos_iptr);
193   write_iptr( pos_fidx, len_fidx, cio);
194   
195   cio_seek( cio, end_pos);
196
197   return OPJ_TRUE;
198 }
199
200 void jp2_write_jp( opj_cio_t *cio)
201 {
202   opj_jp2_box_t box;
203
204   box.init_pos = cio_tell(cio);
205   cio_skip(cio, 4);
206   cio_write(cio, JP2_JP, 4);            /* JP2 signature */
207   cio_write(cio, 0x0d0a870a, 4);
208
209   box.length = cio_tell(cio) - box.init_pos;
210   cio_seek(cio, box.init_pos);
211   cio_write(cio, box.length, 4);        /* L */
212   cio_seek(cio, box.init_pos + box.length);
213 }
214
215 void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio)
216 {
217   unsigned int i;
218   opj_jp2_box_t box;
219
220   box.init_pos = cio_tell(cio);
221   cio_skip(cio, 4);
222   cio_write(cio, JP2_FTYP, 4);          /* FTYP */
223
224   cio_write(cio, jp2->brand, 4);                /* BR */
225   cio_write(cio, jp2->minversion, 4);   /* MinV */
226
227   for (i = 0; i < jp2->numcl; i++) {
228     cio_write(cio, jp2->cl[i], 4);      /* CL */
229   }
230
231   box.length = cio_tell(cio) - box.init_pos;
232   cio_seek(cio, box.init_pos);
233   cio_write(cio, box.length, 4);        /* L */
234   cio_seek(cio, box.init_pos + box.length);
235 }
236
237
238 /* 
239  * Write proxy box
240  *
241  * @param[in] offset_jp2c offset of jp2c box
242  * @param[in] length_jp2c length of jp2c box
243  * @param[in] offset_idx  offset of cidx box
244  * @param[in] length_idx  length of cidx box
245  * @param[in] cio         file output handle
246  */
247 void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio);
248
249 int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio)
250 {  
251   int len, lenp;
252   
253   lenp = cio_tell( cio);
254   cio_skip( cio, 4);              /* L [at the end] */
255   cio_write( cio, JPIP_FIDX, 4);  /* IPTR           */
256   
257   write_prxy( offset_jp2c, length_jp2c, offset_idx, offset_jp2c, cio);
258
259   len = cio_tell( cio)-lenp;
260   cio_seek( cio, lenp);
261   cio_write( cio, len, 4);        /* L              */
262   cio_seek( cio, lenp+len);  
263
264   return len;
265 }
266
267 void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_cio_t *cio)
268 {
269   int len, lenp;
270
271   lenp = cio_tell( cio);
272   cio_skip( cio, 4);              /* L [at the end] */
273   cio_write( cio, JPIP_PRXY, 4);  /* IPTR           */
274   
275   cio_ext_write( cio, offset_jp2c, 8); /* OOFF           */
276   cio_write( cio, length_jp2c, 4); /* OBH part 1     */
277   cio_write( cio, JP2_JP2C, 4);        /* OBH part 2     */
278   
279   cio_write( cio, 1,1);           /* NI             */
280
281   cio_ext_write( cio, offset_idx, 8);  /* IOFF           */
282   cio_write( cio, length_idx, 4);  /* IBH part 1     */
283   cio_write( cio, JPIP_CIDX, 4);   /* IBH part 2     */
284
285   len = cio_tell( cio)-lenp;
286   cio_seek( cio, lenp);
287   cio_write( cio, len, 4);        /* L              */
288   cio_seek( cio, lenp+len);
289 }
290
291 void write_iptr( int offset, int length, opj_cio_t *cio)
292 {
293   int len, lenp;
294   
295   lenp = cio_tell( cio);
296   cio_skip( cio, 4);              /* L [at the end] */
297   cio_write( cio, JPIP_IPTR, 4);  /* IPTR           */
298   
299   cio_ext_write( cio, offset, 8);
300   cio_ext_write( cio, length, 8);
301
302   len = cio_tell( cio)-lenp;
303   cio_seek( cio, lenp);
304   cio_write( cio, len, 4);        /* L             */
305   cio_seek( cio, lenp+len);
306 }