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