1 /*
2 * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
3 * Copyright (c) 2002-2007, Professor Benoit Macq
4 * Copyright (c) 2003-2007, Francois-Olivier Devaux
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
17 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
20 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29 #include <stdio.h>
30 #include <math.h>
31 #include <string.h>
32 #include "openjpeg.h"
33 #include "index.h"
34
35 /* ------------------------------------------------------------------------------------ */
36
37 /**
38 Write a structured index to a file
39 @param cstr_info Codestream information
40 @param index Index filename
41 @return Returns 0 if successful, returns 1 otherwise
42 */
write_index_file(opj_codestream_info_t * cstr_info,char * index)43 int write_index_file(opj_codestream_info_t *cstr_info, char *index) {
44 int tileno, compno, layno, resno, precno, pack_nb, x, y;
45 FILE *stream = NULL;
46 double total_disto = 0;
47 /* UniPG>> */
48 int tilepartno;
49 char disto_on, numpix_on;
50
51 #ifdef USE_JPWL
52 if (!strcmp(index, JPWL_PRIVATEINDEX_NAME))
53 return 0;
54 #endif /* USE_JPWL */
55 /* <<UniPG */
56
57 if (!cstr_info)
58 return 1;
59
60 stream = fopen(index, "w");
61 if (!stream) {
62 fprintf(stderr, "failed to open index file [%s] for writing\n", index);
63 return 1;
64 }
65
66 if (cstr_info->tile[0].distotile)
67 disto_on = 1;
68 else
69 disto_on = 0;
70
71 if (cstr_info->tile[0].numpix)
72 numpix_on = 1;
73 else
74 numpix_on = 0;
75
76 fprintf(stream, "%d %d\n", cstr_info->image_w, cstr_info->image_h);
77 fprintf(stream, "%d\n", cstr_info->prog);
78 fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y);
79 fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th);
80 fprintf(stream, "%d\n", cstr_info->numcomps);
81 fprintf(stream, "%d\n", cstr_info->numlayers);
82 fprintf(stream, "%d\n", cstr_info->numdecompos[0]); /* based on component 0 */
83
84 for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {
85 fprintf(stream, "[%d,%d] ",
86 (1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno])); /* based on tile 0 and component 0 */
87 }
88
89 fprintf(stream, "\n");
90 /* UniPG>> */
91 fprintf(stream, "%d\n", cstr_info->main_head_start);
92 /* <<UniPG */
93 fprintf(stream, "%d\n", cstr_info->main_head_end);
94 fprintf(stream, "%d\n", cstr_info->codestream_size);
95
96 fprintf(stream, "\nINFO ON TILES\n");
97 fprintf(stream, "tileno start_pos end_hd end_tile nbparts");
98 if (disto_on)
99 fprintf(stream," disto");
100 if (numpix_on)
101 fprintf(stream," nbpix");
102 if (disto_on && numpix_on)
103 fprintf(stream," disto/nbpix");
104 fprintf(stream, "\n");
105
106 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
107 fprintf(stream, "%4d %9d %9d %9d %9d",
108 cstr_info->tile[tileno].tileno,
109 cstr_info->tile[tileno].start_pos,
110 cstr_info->tile[tileno].end_header,
111 cstr_info->tile[tileno].end_pos,
112 cstr_info->tile[tileno].num_tps);
113 if (disto_on)
114 fprintf(stream," %9e", cstr_info->tile[tileno].distotile);
115 if (numpix_on)
116 fprintf(stream," %9d", cstr_info->tile[tileno].numpix);
117 if (disto_on && numpix_on)
118 fprintf(stream," %9e", cstr_info->tile[tileno].distotile / cstr_info->tile[tileno].numpix);
119 fprintf(stream, "\n");
120 }
121
122 for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {
123 int start_pos, end_ph_pos, end_pos;
124 double disto = 0;
125 int max_numdecompos = 0;
126 pack_nb = 0;
127
128 for (compno = 0; compno < cstr_info->numcomps; compno++) {
129 if (max_numdecompos < cstr_info->numdecompos[compno])
130 max_numdecompos = cstr_info->numdecompos[compno];
131 }
132
133 fprintf(stream, "\nTILE %d DETAILS\n", tileno);
134 fprintf(stream, "part_nb tileno start_pack num_packs start_pos end_tph_pos end_pos\n");
135 for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++)
136 fprintf(stream, "%4d %9d %9d %9d %9d %11d %9d\n",
137 tilepartno, tileno,
138 cstr_info->tile[tileno].tp[tilepartno].tp_start_pack,
139 cstr_info->tile[tileno].tp[tilepartno].tp_numpacks,
140 cstr_info->tile[tileno].tp[tilepartno].tp_start_pos,
141 cstr_info->tile[tileno].tp[tilepartno].tp_end_header,
142 cstr_info->tile[tileno].tp[tilepartno].tp_end_pos
143 );
144
145 if (cstr_info->prog == LRCP) { /* LRCP */
146 fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos");
147 if (disto_on)
148 fprintf(stream, " disto");
149 fprintf(stream,"\n");
150
151 for (layno = 0; layno < cstr_info->numlayers; layno++) {
152 for (resno = 0; resno < max_numdecompos + 1; resno++) {
153 for (compno = 0; compno < cstr_info->numcomps; compno++) {
154 int prec_max;
155 if (resno > cstr_info->numdecompos[compno])
156 break;
157 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
158 for (precno = 0; precno < prec_max; precno++) {
159 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
160 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
161 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
162 disto = cstr_info->tile[tileno].packet[pack_nb].disto;
163 fprintf(stream, "%4d %6d %7d %5d %6d %6d %6d %6d %7d",
164 pack_nb, tileno, layno, resno, compno, precno, start_pos, end_ph_pos, end_pos);
165 if (disto_on)
166 fprintf(stream, " %8e", disto);
167 fprintf(stream, "\n");
168 total_disto += disto;
169 pack_nb++;
170 }
171 }
172 }
173 }
174 } /* LRCP */
175
176 else if (cstr_info->prog == RLCP) { /* RLCP */
177 fprintf(stream, "RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos\n");
178 if (disto_on)
179 fprintf(stream, " disto");
180 fprintf(stream,"\n");
181
182 for (resno = 0; resno < max_numdecompos + 1; resno++) {
183 for (layno = 0; layno < cstr_info->numlayers; layno++) {
184 for (compno = 0; compno < cstr_info->numcomps; compno++) {
185 int prec_max;
186 if (resno > cstr_info->numdecompos[compno])
187 break;
188 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
189 for (precno = 0; precno < prec_max; precno++) {
190 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
191 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
192 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
193 disto = cstr_info->tile[tileno].packet[pack_nb].disto;
194 fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %7d",
195 pack_nb, tileno, resno, layno, compno, precno, start_pos, end_ph_pos, end_pos);
196 if (disto_on)
197 fprintf(stream, " %8e", disto);
198 fprintf(stream, "\n");
199 total_disto += disto;
200 pack_nb++;
201 }
202 }
203 }
204 }
205 } /* RLCP */
206
207 else if (cstr_info->prog == RPCL) { /* RPCL */
208
209 fprintf(stream, "RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos");
210 if (disto_on)
211 fprintf(stream, " disto");
212 fprintf(stream,"\n");
213
214 for (resno = 0; resno < max_numdecompos + 1; resno++) {
215 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
216 for (precno = 0; precno < numprec; precno++) {
217 /* I suppose components have same XRsiz, YRsiz */
218 int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
219 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
220 int x1 = x0 + cstr_info->tile_x;
221 int y1 = y0 + cstr_info->tile_y;
222 for (compno = 0; compno < cstr_info->numcomps; compno++) {
223 int pcnx = cstr_info->tile[tileno].pw[resno];
224 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
225 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
226 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
227 int precno_y = (int) floor( (float)precno/(float)pcnx );
228 if (resno > cstr_info->numdecompos[compno])
229 break;
230 for(y = y0; y < y1; y++) {
231 if (precno_y*pcy == y ) {
232 for (x = x0; x < x1; x++) {
233 if (precno_x*pcx == x ) {
234 for (layno = 0; layno < cstr_info->numlayers; layno++) {
235 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
236 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
237 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
238 disto = cstr_info->tile[tileno].packet[pack_nb].disto;
239 fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %7d",
240 pack_nb, tileno, resno, precno, compno, layno, start_pos, end_ph_pos, end_pos);
241 if (disto_on)
242 fprintf(stream, " %8e", disto);
243 fprintf(stream, "\n");
244 total_disto += disto;
245 pack_nb++;
246 }
247 }
248 }/* x = x0..x1 */
249 }
250 } /* y = y0..y1 */
251 } /* precno */
252 } /* compno */
253 } /* resno */
254 } /* RPCL */
255
256 else if (cstr_info->prog == PCRL) { /* PCRL */
257 /* I suppose components have same XRsiz, YRsiz */
258 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
259 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
260 int x1 = x0 + cstr_info->tile_x;
261 int y1 = y0 + cstr_info->tile_y;
262
263 // Count the maximum number of precincts
264 int max_numprec = 0;
265 for (resno = 0; resno < max_numdecompos + 1; resno++) {
266 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
267 if (numprec > max_numprec)
268 max_numprec = numprec;
269 }
270
271 fprintf(stream, "PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos");
272 if (disto_on)
273 fprintf(stream, " disto");
274 fprintf(stream,"\n");
275
276 for (precno = 0; precno < max_numprec; precno++) {
277 for (compno = 0; compno < cstr_info->numcomps; compno++) {
278 for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
279 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
280 int pcnx = cstr_info->tile[tileno].pw[resno];
281 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
282 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
283 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
284 int precno_y = (int) floor( (float)precno/(float)pcnx );
285 if (precno >= numprec)
286 continue;
287 for(y = y0; y < y1; y++) {
288 if (precno_y*pcy == y ) {
289 for (x = x0; x < x1; x++) {
290 if (precno_x*pcx == x ) {
291 for (layno = 0; layno < cstr_info->numlayers; layno++) {
292 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
293 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
294 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
295 disto = cstr_info->tile[tileno].packet[pack_nb].disto;
296 fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %7d",
297 pack_nb, tileno, precno, compno, resno, layno, start_pos, end_ph_pos, end_pos);
298 if (disto_on)
299 fprintf(stream, " %8e", disto);
300 fprintf(stream, "\n");
301 total_disto += disto;
302 pack_nb++;
303 }
304 }
305 }/* x = x0..x1 */
306 }
307 } /* y = y0..y1 */
308 } /* resno */
309 } /* compno */
310 } /* precno */
311 } /* PCRL */
312
313 else { /* CPRL */
314 // Count the maximum number of precincts
315 int max_numprec = 0;
316 for (resno = 0; resno < max_numdecompos + 1; resno++) {
317 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
318 if (numprec > max_numprec)
319 max_numprec = numprec;
320 }
321
322 fprintf(stream, "CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos");
323 if (disto_on)
324 fprintf(stream, " disto");
325 fprintf(stream,"\n");
326
327 for (compno = 0; compno < cstr_info->numcomps; compno++) {
328 /* I suppose components have same XRsiz, YRsiz */
329 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;
330 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;
331 int x1 = x0 + cstr_info->tile_x;
332 int y1 = y0 + cstr_info->tile_y;
333
334 for (precno = 0; precno < max_numprec; precno++) {
335 for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {
336 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];
337 int pcnx = cstr_info->tile[tileno].pw[resno];
338 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );
339 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );
340 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;
341 int precno_y = (int) floor( (float)precno/(float)pcnx );
342 if (precno >= numprec)
343 continue;
344
345 for(y = y0; y < y1; y++) {
346 if (precno_y*pcy == y ) {
347 for (x = x0; x < x1; x++) {
348 if (precno_x*pcx == x ) {
349 for (layno = 0; layno < cstr_info->numlayers; layno++) {
350 start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;
351 end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;
352 end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;
353 disto = cstr_info->tile[tileno].packet[pack_nb].disto;
354 fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %7d",
355 pack_nb, tileno, compno, precno, resno, layno, start_pos, end_ph_pos, end_pos);
356 if (disto_on)
357 fprintf(stream, " %8e", disto);
358 fprintf(stream, "\n");
359 total_disto += disto;
360 pack_nb++;
361 }
362 }
363 }/* x = x0..x1 */
364 }
365 } /* y = y0..y1 */
366 } /* resno */
367 } /* precno */
368 } /* compno */
369 } /* CPRL */
370 } /* tileno */
371
372 if (disto_on) {
373 fprintf(stream, "%8e\n", cstr_info->D_max); /* SE max */
374 fprintf(stream, "%.8e\n", total_disto); /* SE totale */
375 }
376 /* UniPG>> */
377 /* print the markers' list */
378 if (cstr_info->marknum) {
379 fprintf(stream, "\nMARKER LIST\n");
380 fprintf(stream, "%d\n", cstr_info->marknum);
381 fprintf(stream, "type\tstart_pos length\n");
382 for (x = 0; x < cstr_info->marknum; x++)
383 fprintf(stream, "%X\t%9d %9d\n", cstr_info->marker[x].type, cstr_info->marker[x].pos, cstr_info->marker[x].len);
384 }
385 /* <<UniPG */
386 fclose(stream);
387
388 fprintf(stderr,"Generated index file %s\n", index);
389
390 return 0;
391 }
392