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