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