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
45 /*
46 * Write main header index table (box)
47 *
48 * @param[in] coff offset of j2k codestream
49 * @param[in] cstr_info codestream information
50 * @param[in] cio file output handle
51 * @return length of mainmhix box
52 */
53 int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio);
54
55
56 /*
57 * Check if EPH option is used
58 *
59 * @param[in] coff offset of j2k codestream
60 * @param[in] markers marker information
61 * @param[in] marknum number of markers
62 * @param[in] cio file output handle
63 * @return true if EPH is used
64 */
65 opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio);
66
67
write_cidx(int offset,opj_cio_t * cio,opj_image_t * image,opj_codestream_info_t cstr_info,int j2klen)68 int write_cidx( int offset, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t cstr_info, int j2klen)
69 {
70 int len, i, lenp;
71 opj_jp2_box_t *box;
72 int num_box = 0;
73 opj_bool EPHused;
74 (void)image; /* unused ? */
75
76 lenp = -1;
77 box = (opj_jp2_box_t *)opj_calloc( 32, sizeof(opj_jp2_box_t));
78
79 for (i=0;i<2;i++){
80
81 if(i)
82 cio_seek( cio, lenp);
83
84 lenp = cio_tell( cio);
85
86 cio_skip( cio, 4); /* L [at the end] */
87 cio_write( cio, JPIP_CIDX, 4); /* CIDX */
88 write_cptr( offset, cstr_info.codestream_size, cio);
89
90 write_manf( i, num_box, box, cio);
91
92 num_box = 0;
93 box[num_box].length = write_mainmhix( offset, cstr_info, cio);
94 box[num_box].type = JPIP_MHIX;
95 num_box++;
96
97 box[num_box].length = write_tpix( offset, cstr_info, j2klen, cio);
98 box[num_box].type = JPIP_TPIX;
99 num_box++;
100
101 box[num_box].length = write_thix( offset, cstr_info, cio);
102 box[num_box].type = JPIP_THIX;
103 num_box++;
104
105 EPHused = check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio);
106
107 box[num_box].length = write_ppix( offset, cstr_info, EPHused, j2klen, cio);
108 box[num_box].type = JPIP_PPIX;
109 num_box++;
110
111 box[num_box].length = write_phix( offset, cstr_info, EPHused, j2klen, cio);
112 box[num_box].type = JPIP_PHIX;
113 num_box++;
114
115 len = cio_tell( cio)-lenp;
116 cio_seek( cio, lenp);
117 cio_write( cio, len, 4); /* L */
118 cio_seek( cio, lenp+len);
119 }
120
121 opj_free( box);
122
123 return len;
124 }
125
write_cptr(int coff,int clen,opj_cio_t * cio)126 void write_cptr(int coff, int clen, opj_cio_t *cio)
127 {
128 int len, lenp;
129
130 lenp = cio_tell( cio);
131 cio_skip( cio, 4); /* L [at the end] */
132 cio_write( cio, JPIP_CPTR, 4); /* T */
133 cio_write( cio, 0, 2); /* DR A PRECISER !! */
134 cio_write( cio, 0, 2); /* CONT */
135 cio_write( cio, coff, 8); /* COFF A PRECISER !! */
136 cio_write( cio, clen, 8); /* CLEN */
137 len = cio_tell( cio) - lenp;
138 cio_seek( cio, lenp);
139 cio_write( cio, len, 4); /* L */
140 cio_seek( cio, lenp+len);
141 }
142
write_manf(int second,int v,opj_jp2_box_t * box,opj_cio_t * cio)143 void write_manf(int second, int v, opj_jp2_box_t *box, opj_cio_t *cio)
144 {
145 int len, lenp, i;
146
147 lenp = cio_tell( cio);
148 cio_skip( cio, 4); /* L [at the end] */
149 cio_write( cio, JPIP_MANF,4); /* T */
150
151 if (second){ /* Write only during the second pass */
152 for( i=0; i<v; i++){
153 cio_write( cio, box[i].length, 4); /* Box length */
154 cio_write( cio, box[i].type, 4); /* Box type */
155 }
156 }
157
158 len = cio_tell( cio) - lenp;
159 cio_seek( cio, lenp);
160 cio_write( cio, len, 4); /* L */
161 cio_seek( cio, lenp+len);
162 }
163
write_mainmhix(int coff,opj_codestream_info_t cstr_info,opj_cio_t * cio)164 int write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_cio_t *cio)
165 {
166 int i;
167 int len, lenp;
168
169 lenp = cio_tell( cio);
170 cio_skip( cio, 4); /* L [at the end] */
171 cio_write( cio, JPIP_MHIX, 4); /* MHIX */
172
173 cio_write( cio, cstr_info.main_head_end-cstr_info.main_head_start+1, 8); /* TLEN */
174
175 for(i = 1; i < cstr_info.marknum; i++){ /* Marker restricted to 1 apparition, skip SOC marker */
176 cio_write( cio, cstr_info.marker[i].type, 2);
177 cio_write( cio, 0, 2);
178 cio_write( cio, cstr_info.marker[i].pos-coff, 8);
179 cio_write( cio, cstr_info.marker[i].len, 2);
180 }
181
182 len = cio_tell( cio) - lenp;
183 cio_seek( cio, lenp);
184 cio_write( cio, len, 4); /* L */
185 cio_seek( cio, lenp+len);
186
187 return len;
188 }
189
check_EPHuse(int coff,opj_marker_info_t * markers,int marknum,opj_cio_t * cio)190 opj_bool check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_cio_t *cio)
191 {
192 opj_bool EPHused = OPJ_FALSE;
193 int i=0;
194 int org_pos;
195 unsigned int Scod;
196
197 for(i = 0; i < marknum; i++){
198 if( markers[i].type == J2K_MS_COD){
199 org_pos = cio_tell( cio);
200 cio_seek( cio, coff+markers[i].pos+2);
201
202 Scod = cio_read( cio, 1);
203 if( ((Scod >> 2) & 1))
204 EPHused = OPJ_TRUE;
205 cio_seek( cio, org_pos);
206
207 break;
208 }
209 }
210 return EPHused;
211 }
212