Require `stdint.h` & `inttypes.h`
[openjpeg.git] / src / lib / openjpip / metadata_manager.c
1 /*
2  * $Id$
3  *
4  * Copyright (c) 2002-2014, Universite catholique de Louvain (UCL), Belgium
5  * Copyright (c) 2002-2014, Professor Benoit Macq
6  * Copyright (c) 2010-2011, Kaori Hagihara
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
19  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28  * POSSIBILITY OF SUCH DAMAGE.
29  */
30
31 #include "metadata_manager.h"
32 #include <inttypes.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <limits.h>
37 #include <assert.h>
38
39 #ifdef SERVER
40 #include "fcgi_stdio.h"
41 #define logstream FCGI_stdout
42 #else
43 #define FCGI_stdout stdout
44 #define FCGI_stderr stderr
45 #define logstream stderr
46 #endif /*SERVER*/
47
48
49 metadatalist_param_t * gene_metadatalist(void)
50 {
51     metadatalist_param_t *list;
52
53     list = (metadatalist_param_t *)malloc(sizeof(metadatalist_param_t));
54
55     list->first = NULL;
56     list->last  = NULL;
57
58     return list;
59 }
60
61 metadatalist_param_t * const_metadatalist(int fd)
62 {
63     metadatalist_param_t *metadatalist;
64     metadata_param_t *metabin;
65     boxlist_param_t *toplev_boxlist;
66     box_param_t *box, *next;
67     placeholderlist_param_t *phldlist;
68     placeholder_param_t *phld;
69     Byte8_t idx;
70     Byte8_t filesize;
71
72     if (!(filesize = (Byte8_t)get_filesize(fd))) {
73         return NULL;
74     }
75
76     if (!(toplev_boxlist = get_boxstructure(fd, 0, filesize))) {
77         fprintf(FCGI_stderr, "Error: Not correctl JP2 format\n");
78         return NULL;
79     }
80
81     phldlist = gene_placeholderlist();
82     metadatalist = gene_metadatalist();
83
84     box = toplev_boxlist->first;
85     idx = 0;
86     while (box) {
87         next = box->next;
88         if (strncmp(box->type, "jP  ", 4) != 0 && strncmp(box->type, "ftyp", 4) != 0 &&
89                 strncmp(box->type, "jp2h", 4) != 0) {
90             boxlist_param_t *boxlist = NULL;
91             boxcontents_param_t *boxcontents = NULL;
92
93             phld = gene_placeholder(box, ++idx);
94             insert_placeholder_into_list(phld, phldlist);
95
96             boxlist = get_boxstructure(box->fd, get_DBoxoff(box), get_DBoxlen(box));
97             if (!boxlist) {
98                 boxcontents = gene_boxcontents(get_DBoxoff(box), get_DBoxlen(box));
99             }
100
101             delete_box_in_list(&box, toplev_boxlist);
102             metabin = gene_metadata(idx, boxlist, NULL, boxcontents);
103             insert_metadata_into_list(metabin, metadatalist);
104         }
105         box = next;
106     }
107
108     metabin = gene_metadata(0, toplev_boxlist, phldlist, NULL);
109     insert_metadata_into_list(metabin, metadatalist);
110
111     return metadatalist;
112 }
113
114 void delete_metadatalist(metadatalist_param_t **list)
115 {
116     metadata_param_t *ptr, *next;
117
118     ptr = (*list)->first;
119
120     while (ptr != NULL) {
121         next = ptr->next;
122         delete_metadata(&ptr);
123         ptr = next;
124     }
125     free(*list);
126 }
127
128 metadata_param_t * gene_metadata(Byte8_t idx, boxlist_param_t *boxlist,
129                                  placeholderlist_param_t *phldlist, boxcontents_param_t *boxcontents)
130 {
131     metadata_param_t *bin;
132
133     bin = (metadata_param_t *)malloc(sizeof(metadata_param_t));
134     bin->idx = idx;
135     bin->boxlist = boxlist;
136     bin->placeholderlist = phldlist;
137     bin->boxcontents = boxcontents;
138     bin->next = NULL;
139
140     return bin;
141 }
142
143 void delete_metadata(metadata_param_t **metadata)
144 {
145     delete_boxlist(&((*metadata)->boxlist));
146     delete_placeholderlist(&((*metadata)->placeholderlist));
147     if ((*metadata)->boxcontents) {
148         free((*metadata)->boxcontents);
149     }
150 #ifndef SERVER
151     /*  fprintf( logstream, "local log: Metadata-bin: %d deleted\n", (*metadata)->idx);*/
152 #endif
153     free(*metadata);
154 }
155
156 void insert_metadata_into_list(metadata_param_t *metabin,
157                                metadatalist_param_t *metadatalist)
158 {
159     if (metadatalist->first) {
160         metadatalist->last->next = metabin;
161     } else {
162         metadatalist->first = metabin;
163     }
164     metadatalist->last = metabin;
165 }
166
167 void print_metadata(metadata_param_t *metadata)
168 {
169     boxcontents_param_t *boxcont;
170     fprintf(logstream, "metadata-bin %" PRIu64 " info:\n", metadata->idx);
171     print_allbox(metadata->boxlist);
172     print_allplaceholder(metadata->placeholderlist);
173
174     boxcont = metadata->boxcontents;
175     if (boxcont)
176         fprintf(logstream, "box contents:\n"
177                 "\t offset: %" PRId64 " %#" PRIx64 "\n"
178                 "\t length: %" PRId64 " %#" PRIx64 "\n", boxcont->offset,
179                 boxcont->offset, boxcont->length, boxcont->length);
180 }
181
182 void print_allmetadata(metadatalist_param_t *list)
183 {
184     metadata_param_t *ptr;
185
186     fprintf(logstream, "all metadata info: \n");
187     ptr = list->first;
188     while (ptr != NULL) {
189         print_metadata(ptr);
190         ptr = ptr->next;
191     }
192 }
193
194 boxcontents_param_t * gene_boxcontents(OPJ_OFF_T offset, OPJ_SIZE_T length)
195 {
196     boxcontents_param_t *contents;
197
198     contents = (boxcontents_param_t *)malloc(sizeof(boxcontents_param_t));
199
200     contents->offset = offset;
201     contents->length = length;
202
203     return contents;
204 }
205
206 metadata_param_t * search_metadata(Byte8_t idx, metadatalist_param_t *list)
207 {
208     metadata_param_t *found;
209
210     found = list->first;
211
212     while (found) {
213
214         if (found->idx == idx) {
215             return found;
216         }
217
218         found = found->next;
219     }
220     return NULL;
221 }
222
223 Byte8_t search_metadataidx(char boxtype[4], metadatalist_param_t *list)
224 {
225     /* MM FIXME: what is the return type of this function ?
226      Byte8_t or int ? */
227     metadata_param_t *ptr;
228     int i;
229
230     for (i = 0; i < 4; i++)
231         if (boxtype[i] == '_') {
232             boxtype[i] = ' ';
233         }
234
235     ptr = list->first;
236     while (ptr) {
237         if (ptr->boxlist) {
238             box_param_t *box = ptr->boxlist->first;
239             while (box) {
240                 if (strncmp(boxtype, box->type, 4) == 0) {
241                     return ptr->idx;
242                 }
243                 box = box->next;
244             }
245         }
246         ptr = ptr->next;
247     }
248
249     ptr = list->first;
250     while (ptr) {
251         if (ptr->placeholderlist) {
252             placeholder_param_t *phld = ptr->placeholderlist->first;
253             while (phld) {
254                 if (strncmp(boxtype, (char *)phld->OrigBH + 4, 4) == 0) {
255                     return phld->OrigID;
256                 }
257                 phld = phld->next;
258             }
259         }
260         ptr = ptr->next;
261     }
262     return (Byte8_t) - 1;
263 }