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