27a40740a285b13f27e69590087a1ddc6b53b2bb
[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 \r
29 #include <stdio.h>\r
30 #include <math.h>\r
31 #include <string.h>\r
32 #include <stdlib.h>\r
33 \r
34 #include "openjpeg.h"\r
35 #include "index.h"\r
36 \r
37 /* ------------------------------------------------------------------------------------ */\r
38 \r
39 /**\r
40 Write a structured index to a file\r
41 @param cstr_info Codestream information \r
42 @param index Index filename\r
43 @return Returns 0 if successful, returns 1 otherwise\r
44 */\r
45 int write_index_file(opj_codestream_info_t *cstr_info, char *index) {\r
46         int tileno, compno, layno, resno, precno, pack_nb, x, y;\r
47         FILE *stream = NULL;\r
48         double total_disto = 0;\r
49 /* UniPG>> */\r
50         int tilepartno;\r
51         char disto_on, numpix_on;\r
52 \r
53 #ifdef USE_JPWL\r
54         if (!strcmp(index, JPWL_PRIVATEINDEX_NAME))\r
55                 return 0;\r
56 #endif /* USE_JPWL */\r
57 /* <<UniPG */\r
58 \r
59         if (!cstr_info)         \r
60                 return 1;\r
61 \r
62         stream = fopen(index, "w");\r
63         if (!stream) {\r
64                 fprintf(stderr, "failed to open index file [%s] for writing\n", index);\r
65                 return 1;\r
66         }\r
67         \r
68         if (cstr_info->tile[0].distotile)\r
69                 disto_on = 1;\r
70         else \r
71                 disto_on = 0;\r
72 \r
73         if (cstr_info->tile[0].numpix)\r
74                 numpix_on = 1;\r
75         else \r
76                 numpix_on = 0;\r
77 \r
78         fprintf(stream, "%d %d\n", cstr_info->image_w, cstr_info->image_h);\r
79         fprintf(stream, "%d\n", cstr_info->prog);\r
80         fprintf(stream, "%d %d\n", cstr_info->tile_x, cstr_info->tile_y);\r
81         fprintf(stream, "%d %d\n", cstr_info->tw, cstr_info->th);\r
82         fprintf(stream, "%d\n", cstr_info->numcomps);\r
83         fprintf(stream, "%d\n", cstr_info->numlayers);\r
84         fprintf(stream, "%d\n", cstr_info->numdecompos[0]); /* based on component 0 */\r
85 \r
86         for (resno = cstr_info->numdecompos[0]; resno >= 0; resno--) {\r
87                 fprintf(stream, "[%d,%d] ", \r
88                         (1 << cstr_info->tile[0].pdx[resno]), (1 << cstr_info->tile[0].pdx[resno]));    /* based on tile 0 and component 0 */\r
89         }\r
90 \r
91         fprintf(stream, "\n");\r
92 /* UniPG>> */\r
93         fprintf(stream, "%d\n", cstr_info->main_head_start);\r
94 /* <<UniPG */\r
95         fprintf(stream, "%d\n", cstr_info->main_head_end);\r
96         fprintf(stream, "%d\n", cstr_info->codestream_size);\r
97         \r
98         fprintf(stream, "\nINFO ON TILES\n");\r
99         fprintf(stream, "tileno start_pos  end_hd  end_tile   nbparts");\r
100         if (disto_on)\r
101                 fprintf(stream,"         disto");\r
102         if (numpix_on)\r
103                 fprintf(stream,"     nbpix");\r
104         if (disto_on && numpix_on)\r
105                 fprintf(stream,"  disto/nbpix");\r
106         fprintf(stream, "\n");\r
107 \r
108         for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {\r
109                 fprintf(stream, "%4d %9d %9d %9d %9d", \r
110                         cstr_info->tile[tileno].tileno,\r
111                         cstr_info->tile[tileno].start_pos,\r
112                         cstr_info->tile[tileno].end_header,\r
113                         cstr_info->tile[tileno].end_pos,\r
114                         cstr_info->tile[tileno].num_tps);\r
115                 if (disto_on)\r
116                         fprintf(stream," %9e", cstr_info->tile[tileno].distotile);\r
117                 if (numpix_on)\r
118                         fprintf(stream," %9d", cstr_info->tile[tileno].numpix);\r
119                 if (disto_on && numpix_on)\r
120                         fprintf(stream," %9e", cstr_info->tile[tileno].distotile / cstr_info->tile[tileno].numpix);\r
121                 fprintf(stream, "\n");\r
122         }\r
123                 \r
124         for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) {\r
125                 int start_pos, end_ph_pos, end_pos;\r
126                 double disto = 0;\r
127                 int max_numdecompos = 0;\r
128                 pack_nb = 0;\r
129 \r
130                 for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
131                         if (max_numdecompos < cstr_info->numdecompos[compno])\r
132                                 max_numdecompos = cstr_info->numdecompos[compno];\r
133                 }       \r
134 \r
135                 fprintf(stream, "\nTILE %d DETAILS\n", tileno); \r
136                 fprintf(stream, "part_nb tileno  start_pack num_packs  start_pos end_tph_pos   end_pos\n");\r
137                 for (tilepartno = 0; tilepartno < cstr_info->tile[tileno].num_tps; tilepartno++)\r
138                         fprintf(stream, "%4d %9d   %9d %9d  %9d %11d %9d\n",\r
139                                 tilepartno, tileno,\r
140                                 cstr_info->tile[tileno].tp[tilepartno].tp_start_pack,\r
141                                 cstr_info->tile[tileno].tp[tilepartno].tp_numpacks,\r
142                                 cstr_info->tile[tileno].tp[tilepartno].tp_start_pos,\r
143                                 cstr_info->tile[tileno].tp[tilepartno].tp_end_header,\r
144                                 cstr_info->tile[tileno].tp[tilepartno].tp_end_pos\r
145                                 );\r
146 \r
147                 if (cstr_info->prog == LRCP) {  /* LRCP */\r
148                         fprintf(stream, "LRCP\npack_nb tileno layno resno compno precno start_pos end_ph_pos end_pos");\r
149                         if (disto_on)\r
150                                 fprintf(stream, " disto");\r
151                         fprintf(stream,"\n");\r
152 \r
153                         for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
154                                 for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
155                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
156                                                 int prec_max;\r
157                                                 if (resno > cstr_info->numdecompos[compno])\r
158                                                         break;\r
159                                                 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
160                                                 for (precno = 0; precno < prec_max; precno++) {\r
161                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
162                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;\r
163                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
164                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;\r
165                                                         fprintf(stream, "%4d %6d %7d %5d %6d  %6d    %6d     %6d %7d",\r
166                                                                 pack_nb, tileno, layno, resno, compno, precno, start_pos, end_ph_pos, end_pos);\r
167                                                         if (disto_on)\r
168                                                                 fprintf(stream, " %8e", disto);\r
169                                                         fprintf(stream, "\n");\r
170                                                         total_disto += disto;\r
171                                                         pack_nb++;\r
172                                                 }\r
173                                         }\r
174                                 }\r
175                         }\r
176                 } /* LRCP */\r
177 \r
178                 else if (cstr_info->prog == RLCP) {     /* RLCP */                      \r
179                         fprintf(stream, "RLCP\npack_nb tileno resno layno compno precno start_pos end_ph_pos end_pos\n");\r
180                         if (disto_on)\r
181                                 fprintf(stream, " disto");\r
182                         fprintf(stream,"\n");\r
183 \r
184                         for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
185                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
186                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
187                                                 int prec_max; \r
188                                                 if (resno > cstr_info->numdecompos[compno])\r
189                                                         break;\r
190                                                 prec_max = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
191                                                 for (precno = 0; precno < prec_max; precno++) {\r
192                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
193                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;\r
194                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
195                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;\r
196                                                         fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d   %9d %7d",\r
197                                                                 pack_nb, tileno, resno, layno, compno, precno, start_pos, end_ph_pos, end_pos);\r
198                                                         if (disto_on)\r
199                                                                 fprintf(stream, " %8e", disto);\r
200                                                         fprintf(stream, "\n");\r
201                                                         total_disto += disto;\r
202                                                         pack_nb++;\r
203                                                 }\r
204                                         }\r
205                                 }\r
206                         }\r
207                 } /* RLCP */\r
208 \r
209                 else if (cstr_info->prog == RPCL) {     /* RPCL */\r
210 \r
211                         fprintf(stream, "RPCL\npack_nb tileno resno precno compno layno start_pos end_ph_pos end_pos"); \r
212                         if (disto_on)\r
213                                 fprintf(stream, " disto");\r
214                         fprintf(stream,"\n");\r
215 \r
216                         for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
217                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
218                                 for (precno = 0; precno < numprec; precno++) {                                                          \r
219                                         /* I suppose components have same XRsiz, YRsiz */\r
220                                         int x0 = cstr_info->tile_Ox + tileno - (int)floor((float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
221                                         int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
222                                         int x1 = x0 + cstr_info->tile_x;\r
223                                         int y1 = y0 + cstr_info->tile_y;\r
224                                         for (compno = 0; compno < cstr_info->numcomps; compno++) {                                      \r
225                                                 int pcnx = cstr_info->tile[tileno].pw[resno];\r
226                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
227                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
228                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
229                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );\r
230                                                 if (resno > cstr_info->numdecompos[compno])\r
231                                                         break;\r
232                                                 for(y = y0; y < y1; y++) {                                                      \r
233                                                         if (precno_y*pcy == y ) {\r
234                                                                 for (x = x0; x < x1; x++) {                                                                     \r
235                                                                         if (precno_x*pcx == x ) {\r
236                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
237                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
238                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;\r
239                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
240                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;\r
241                                                                                         fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d   %9d %7d",\r
242                                                                                                 pack_nb, tileno, resno, precno, compno, layno, start_pos, end_ph_pos, end_pos); \r
243                                                                                         if (disto_on)\r
244                                                                                                 fprintf(stream, " %8e", disto);\r
245                                                                                         fprintf(stream, "\n");\r
246                                                                                         total_disto += disto;\r
247                                                                                         pack_nb++; \r
248                                                                                 }\r
249                                                                         }\r
250                                                                 }/* x = x0..x1 */\r
251                                                         } \r
252                                                 }  /* y = y0..y1 */\r
253                                         } /* precno */\r
254                                 } /* compno */\r
255                         } /* resno */\r
256                 } /* RPCL */\r
257 \r
258                 else if (cstr_info->prog == PCRL) {     /* PCRL */\r
259                         /* I suppose components have same XRsiz, YRsiz */\r
260                         int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
261                         int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
262                         int x1 = x0 + cstr_info->tile_x;\r
263                         int y1 = y0 + cstr_info->tile_y;\r
264 \r
265                         // Count the maximum number of precincts \r
266                         int max_numprec = 0;\r
267                         for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
268                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
269                                 if (numprec > max_numprec)\r
270                                         max_numprec = numprec;\r
271                         }\r
272 \r
273                         fprintf(stream, "PCRL\npack_nb tileno precno compno resno layno start_pos end_ph_pos end_pos"); \r
274                         if (disto_on)\r
275                                 fprintf(stream, " disto");\r
276                         fprintf(stream,"\n");\r
277 \r
278                         for (precno = 0; precno < max_numprec; precno++) {\r
279                                 for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
280                                         for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {\r
281                                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
282                                                 int pcnx = cstr_info->tile[tileno].pw[resno];\r
283                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
284                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
285                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
286                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );\r
287                                                 if (precno >= numprec)\r
288                                                         continue;\r
289                                                 for(y = y0; y < y1; y++) {                                                      \r
290                                                         if (precno_y*pcy == y ) {\r
291                                                                 for (x = x0; x < x1; x++) {                                                                     \r
292                                                                         if (precno_x*pcx == x ) {\r
293                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
294                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
295                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;\r
296                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
297                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;\r
298                                                                                         fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d   %9d %7d",\r
299                                                                                                 pack_nb, tileno, precno, compno, resno, layno, start_pos, end_ph_pos, end_pos); \r
300                                                                                         if (disto_on)\r
301                                                                                                 fprintf(stream, " %8e", disto);\r
302                                                                                         fprintf(stream, "\n");\r
303                                                                                         total_disto += disto;\r
304                                                                                         pack_nb++; \r
305                                                                                 }\r
306                                                                         }\r
307                                                                 }/* x = x0..x1 */\r
308                                                         } \r
309                                                 }  /* y = y0..y1 */\r
310                                         } /* resno */\r
311                                 } /* compno */\r
312                         } /* precno */\r
313                 } /* PCRL */\r
314 \r
315                 else {  /* CPRL */\r
316                         // Count the maximum number of precincts \r
317                         int max_numprec = 0;\r
318                         for (resno = 0; resno < max_numdecompos + 1; resno++) {\r
319                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
320                                 if (numprec > max_numprec)\r
321                                         max_numprec = numprec;\r
322                         }\r
323 \r
324                         fprintf(stream, "CPRL\npack_nb tileno compno precno resno layno start_pos end_ph_pos end_pos"); \r
325                         if (disto_on)\r
326                                 fprintf(stream, " disto");\r
327                         fprintf(stream,"\n");\r
328 \r
329                         for (compno = 0; compno < cstr_info->numcomps; compno++) {\r
330                                 /* I suppose components have same XRsiz, YRsiz */\r
331                                 int x0 = cstr_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tw * cstr_info->tile_x;\r
332                                 int y0 = cstr_info->tile_Ox + (int)floor( (float)tileno/(float)cstr_info->tw ) * cstr_info->tile_y;\r
333                                 int x1 = x0 + cstr_info->tile_x;\r
334                                 int y1 = y0 + cstr_info->tile_y;\r
335 \r
336                                 for (precno = 0; precno < max_numprec; precno++) {\r
337                                         for (resno = 0; resno < cstr_info->numdecompos[compno] + 1; resno++) {\r
338                                                 int numprec = cstr_info->tile[tileno].pw[resno] * cstr_info->tile[tileno].ph[resno];\r
339                                                 int pcnx = cstr_info->tile[tileno].pw[resno];\r
340                                                 int pcx = (int) pow( 2, cstr_info->tile[tileno].pdx[resno] + cstr_info->numdecompos[compno] - resno );\r
341                                                 int pcy = (int) pow( 2, cstr_info->tile[tileno].pdy[resno] + cstr_info->numdecompos[compno] - resno );\r
342                                                 int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx;\r
343                                                 int precno_y = (int) floor( (float)precno/(float)pcnx );\r
344                                                 if (precno >= numprec)\r
345                                                         continue;\r
346 \r
347                                                 for(y = y0; y < y1; y++) {\r
348                                                         if (precno_y*pcy == y ) {\r
349                                                                 for (x = x0; x < x1; x++) {\r
350                                                                         if (precno_x*pcx == x ) {\r
351                                                                                 for (layno = 0; layno < cstr_info->numlayers; layno++) {\r
352                                                                                         start_pos = cstr_info->tile[tileno].packet[pack_nb].start_pos;\r
353                                                                                         end_ph_pos = cstr_info->tile[tileno].packet[pack_nb].end_ph_pos;\r
354                                                                                         end_pos = cstr_info->tile[tileno].packet[pack_nb].end_pos;\r
355                                                                                         disto = cstr_info->tile[tileno].packet[pack_nb].disto;\r
356                                                                                         fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d   %9d %7d",\r
357                                                                                                 pack_nb, tileno, compno, precno, resno, layno, start_pos, end_ph_pos, end_pos); \r
358                                                                                         if (disto_on)\r
359                                                                                                 fprintf(stream, " %8e", disto);\r
360                                                                                         fprintf(stream, "\n");\r
361                                                                                         total_disto += disto;\r
362                                                                                         pack_nb++; \r
363                                                                                 }\r
364                                                                         }\r
365                                                                 }/* x = x0..x1 */\r
366                                                         }\r
367                                                 } /* y = y0..y1 */\r
368                                         } /* resno */\r
369                                 } /* precno */\r
370                         } /* compno */\r
371                 } /* CPRL */   \r
372         } /* tileno */\r
373         \r
374         if (disto_on) {\r
375                 fprintf(stream, "%8e\n", cstr_info->D_max); /* SE max */        \r
376                 fprintf(stream, "%.8e\n", total_disto); /* SE totale */\r
377         }\r
378 /* UniPG>> */\r
379         /* print the markers' list */\r
380         if (cstr_info->marknum) {\r
381                 fprintf(stream, "\nMARKER LIST\n");\r
382                 fprintf(stream, "%d\n", cstr_info->marknum);\r
383                 fprintf(stream, "type\tstart_pos    length\n");\r
384                 for (x = 0; x < cstr_info->marknum; x++)\r
385                         fprintf(stream, "%X\t%9d %9d\n", cstr_info->marker[x].type, cstr_info->marker[x].pos, cstr_info->marker[x].len);\r
386         }\r
387 /* <<UniPG */\r
388         fclose(stream);\r
389 \r
390         fprintf(stderr,"Generated index file %s\n", index);\r
391 \r
392         return 0;\r
393 }\r
394 \r
395 \r