c60f437afff31cfdcb524c7655a8aa2497acd4de
[openjpeg.git] / applications / jpip / libopenjpip / metadata_manager.c
1 /*
2  * $Id: metadata_manager.c 53 2011-05-09 16:55:39Z kaori $
3  *
4  * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
5  * Copyright (c) 2002-2011, 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 <stdio.h>
32 #include <stdlib.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <unistd.h>
36 #include <string.h>
37 #include "metadata_manager.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()
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   int idx;
70   struct stat sb;
71   
72   if( fstat( fd, &sb) == -1){
73     fprintf( FCGI_stdout, "Reason: Target broken (fstat error)\r\n");
74     return NULL;
75   }
76
77   if( !(toplev_boxlist = get_boxstructure( fd, 0, sb.st_size))){
78     fprintf( FCGI_stderr, "Error: Not correctl JP2 format\n");
79     return NULL;
80   }
81   
82   phldlist = gene_placeholderlist();
83   metadatalist = gene_metadatalist();
84
85   delete_box_in_list_by_type( "iptr", toplev_boxlist);
86   delete_box_in_list_by_type( "cidx", toplev_boxlist);
87   delete_box_in_list_by_type( "fidx", toplev_boxlist);
88   
89   box = toplev_boxlist->first;
90   idx = 0;
91   while( box){
92     next = box->next;
93     if( strncmp( box->type, "jP  ",4)!=0 && strncmp( box->type, "ftyp",4)!=0 && strncmp( box->type, "jp2h",4)!=0){
94       boxlist_param_t *boxlist = NULL;
95       boxcontents_param_t *boxcontents = NULL;
96
97       phld = gene_placeholder( box, ++idx);
98       insert_placeholder_into_list( phld, phldlist);
99
100       boxlist = get_boxstructure( box->fd, get_DBoxoff( box), get_DBoxlen(box));
101       if( !boxlist)
102         boxcontents = gene_boxcontents( get_DBoxoff( box), get_DBoxlen(box));
103       
104       delete_box_in_list( &box, toplev_boxlist);
105       metabin = gene_metadata( idx, boxlist, NULL, boxcontents);
106       insert_metadata_into_list( metabin, metadatalist);
107     }
108     box = next;
109   }
110
111   metabin = gene_metadata( 0, toplev_boxlist, phldlist, NULL);
112   insert_metadata_into_list( metabin, metadatalist);
113
114   return metadatalist;
115 }
116
117 void delete_metadatalist( metadatalist_param_t **list)
118 {
119   metadata_param_t *ptr, *next;
120
121   ptr = (*list)->first;
122
123   while( ptr != NULL){
124     next=ptr->next;
125     delete_metadata( &ptr);
126     ptr=next;
127   }
128   free( *list);
129 }
130
131 metadata_param_t * gene_metadata( int idx, boxlist_param_t *boxlist, placeholderlist_param_t *phldlist, boxcontents_param_t *boxcontents)
132 {
133   metadata_param_t *bin;
134   
135   bin = (metadata_param_t *)malloc( sizeof(metadata_param_t));
136   bin->idx = idx;
137   bin->boxlist = boxlist;
138   bin->placeholderlist = phldlist;
139   bin->boxcontents = boxcontents;
140   bin->next = NULL;
141
142   return bin;
143 }
144
145 void delete_metadata( metadata_param_t **metadata)
146 {
147   delete_boxlist( &((*metadata)->boxlist));
148   delete_placeholderlist( &((*metadata)->placeholderlist));
149   if((*metadata)->boxcontents)
150     free((*metadata)->boxcontents);
151 #ifndef SERVER
152   //  fprintf( logstream, "local log: Metadata-bin: %d deleted\n", (*metadata)->idx);
153 #endif
154   free( *metadata);
155 }
156
157 void insert_metadata_into_list( metadata_param_t *metabin, metadatalist_param_t *metadatalist)
158 {
159   if( metadatalist->first)
160     metadatalist->last->next = metabin;
161   else
162     metadatalist->first = metabin;
163   metadatalist->last = metabin;
164 }
165
166 void print_metadata( metadata_param_t *metadata)
167 {
168   fprintf( logstream, "metadata-bin %d info:\n", metadata->idx);
169   print_allbox( metadata->boxlist);
170   print_allplaceholder( metadata->placeholderlist);
171  
172   boxcontents_param_t *boxcont = metadata->boxcontents;
173   if( boxcont)
174       fprintf( logstream, "box contents:\n"
175                "\t offset: %lld %#llx\n" 
176                "\t length: %lld %#llx\n", boxcont->offset, boxcont->offset, boxcont->length, boxcont->length);
177 }
178
179 void print_allmetadata( metadatalist_param_t *list)
180 {
181   metadata_param_t *ptr;
182   
183   fprintf( logstream, "all metadata info: \n");
184   ptr = list->first;
185   while( ptr != NULL){
186     print_metadata( ptr);
187     ptr=ptr->next;
188   }
189 }
190
191 boxcontents_param_t * gene_boxcontents( Byte8_t offset, Byte8_t length)
192 {
193   boxcontents_param_t *contents;
194
195   contents = (boxcontents_param_t *)malloc( sizeof(boxcontents_param_t));
196
197   contents->offset = offset;
198   contents->length = length;
199
200   return contents;
201 }
202
203 metadata_param_t * search_metadata( int idx, metadatalist_param_t *list)
204
205   metadata_param_t *found;
206
207   found = list->first;
208   
209   while( found){
210     
211     if( found->idx == idx)
212       return found;
213       
214     found = found->next;
215   }
216   return NULL;
217 }
218
219 int search_metadataidx( char boxtype[4], metadatalist_param_t *list)
220 {
221   metadata_param_t *ptr;
222   int i;
223
224   for( i=0; i<4; i++)
225     if( boxtype[i] == '_')
226       boxtype[i] = ' ';
227   
228   ptr = list->first;
229   while( ptr){
230     if( ptr->boxlist){
231       box_param_t *box = ptr->boxlist->first;
232       while( box){
233         if( strncmp ( boxtype, box->type, 4) == 0)
234           return ptr->idx;
235         box = box->next;
236       }
237     }
238     ptr = ptr->next;
239   }
240
241   ptr = list->first;
242   while( ptr){
243     if( ptr->placeholderlist){
244       placeholder_param_t *phld = ptr->placeholderlist->first;
245       while( phld){
246         if( strncmp ( boxtype, (char *)phld->OrigBH+4, 4) == 0){
247           return phld->OrigID;
248         }
249         phld = phld->next;
250       }
251     }
252     ptr = ptr->next;
253   }
254   return -1;
255 }