813c1a99013c4b7828c830607ba31aef981cccfc
[openjpeg.git] / applications / jpip / libopenjpip / target_manager.c
1 /*
2  * $Id: target_manager.c 44 2011-02-15 12:32:29Z 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 <stdlib.h>
32 #include <string.h>
33 #include <stdio.h>
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <unistd.h>
37 #include <fcntl.h>
38 #include <time.h>
39 #include "target_manager.h"
40
41 #ifdef SERVER
42 #include "fcgi_stdio.h"
43 #define logstream FCGI_stdout
44 #else
45 #define FCGI_stdout stdout
46 #define FCGI_stderr stderr
47 #define logstream stderr
48 #endif //SERVER
49
50
51 targetlist_param_t * gene_targetlist()
52 {
53   targetlist_param_t *targetlist;
54
55   targetlist = (targetlist_param_t *)malloc( sizeof(targetlist_param_t));
56   
57   targetlist->first = NULL;
58   targetlist->last  = NULL;
59
60   return targetlist;
61 }
62
63
64 /**
65  * open jp2 format image file
66  *
67  * @param[in] filename file name (.jp2)
68  * @return             file descriptor
69  */
70 int open_jp2file( char filename[]);
71
72 target_param_t * gene_target( targetlist_param_t *targetlist, char *targetpath)
73 {
74   target_param_t *target;
75   int fd;
76   index_param_t *jp2idx;
77   static int last_csn = 0;
78
79   if( targetpath[0]=='\0'){
80     fprintf( FCGI_stderr, "Error: exception, no targetpath in gene_target()\n");
81     return NULL;
82   }
83
84   if((fd = open_jp2file( targetpath)) == -1){
85     fprintf( FCGI_stdout, "Status: 404\r\n"); 
86     return NULL;
87   }
88   
89   if( !(jp2idx = parse_jp2file( fd))){
90     fprintf( FCGI_stdout, "Status: 501\r\n");
91     return NULL;
92   }
93
94   target = (target_param_t *)malloc( sizeof(target_param_t));
95   snprintf( target->tid, MAX_LENOFTID, "%x-%x", (unsigned int)time(NULL), (unsigned int)rand());
96   target->filename = strdup( targetpath); 
97   target->fd = fd;
98   target->csn = last_csn++;
99   target->codeidx = jp2idx;
100   target->num_of_use = 0; 
101   target->jppstream = true;
102   target->jptstream = isJPTfeasible( *jp2idx);
103   target->next=NULL;
104
105   if( targetlist->first) // there are one or more entries
106     targetlist->last->next = target;
107   else                   // first entry
108     targetlist->first = target;
109   targetlist->last = target;
110
111 #ifndef SERVER
112   fprintf( logstream, "local log: target %s generated\n", targetpath);
113 #endif
114   
115   return target;
116 }
117
118 void refer_target( target_param_t *reftarget, target_param_t **ptr)
119 {
120   *ptr = reftarget;
121   reftarget->num_of_use++;
122 }
123
124 void unrefer_target( target_param_t *target)
125 {
126   target->num_of_use--;
127 }
128
129 void delete_target( target_param_t **target)
130 {
131   close( (*target)->fd);
132   
133   if( (*target)->codeidx)
134     delete_index ( &(*target)->codeidx);
135
136 #ifndef SERVER
137   fprintf( logstream, "local log: target: %s deleted\n", (*target)->filename);
138 #endif
139
140   free( (*target)->filename);
141
142   free(*target);
143 }
144
145 void delete_target_in_list( target_param_t **target, targetlist_param_t *targetlist)
146 {
147   target_param_t *ptr;
148
149   if( *target == targetlist->first)
150     targetlist->first = (*target)->next;
151   else{
152     ptr = targetlist->first;
153     while( ptr->next != *target){
154       ptr=ptr->next;
155     }
156     
157     ptr->next = (*target)->next;
158     
159     if( *target == targetlist->last)
160       targetlist->last = ptr;
161   }
162   delete_target( target);
163 }
164
165 void delete_targetlist(targetlist_param_t **targetlist)
166 {
167   target_param_t *targetPtr, *targetNext;
168   
169   targetPtr = (*targetlist)->first;
170   while( targetPtr != NULL){
171     targetNext=targetPtr->next;
172     delete_target( &targetPtr);
173     targetPtr=targetNext;
174   }
175   free( *targetlist);
176 }
177
178 void print_target( target_param_t *target)
179 {
180   fprintf( logstream, "target:\n");
181   fprintf( logstream, "\t tid=%s\n", target->tid);
182   fprintf( logstream, "\t csn=%d\n", target->csn);
183   fprintf( logstream, "\t target=%s\n\n", target->filename);
184 }
185
186 void print_alltarget( targetlist_param_t *targetlist)
187 {
188   target_param_t *ptr;
189
190   ptr = targetlist->first;
191   while( ptr != NULL){
192     print_target( ptr);
193     ptr=ptr->next;
194   }
195 }
196
197 target_param_t * search_target( char targetname[], targetlist_param_t *targetlist)
198 {
199   target_param_t *foundtarget;
200
201   foundtarget = targetlist->first;
202   
203   while( foundtarget != NULL){
204     
205     if( strcmp( targetname, foundtarget->filename) == 0)
206       return foundtarget;
207       
208     foundtarget = foundtarget->next;
209   }
210   return NULL;
211 }
212
213 target_param_t * search_targetBytid( char tid[], targetlist_param_t *targetlist)
214 {
215   target_param_t *foundtarget;
216   
217   foundtarget = targetlist->first;
218   
219   while( foundtarget != NULL){
220     
221     if( strcmp( tid, foundtarget->tid) == 0)
222       return foundtarget;
223       
224     foundtarget = foundtarget->next;
225   }
226
227   return NULL;
228 }
229
230 int open_jp2file( char filename[])
231 {
232   int fd;
233   char *data;
234
235   if( (fd = open( filename, O_RDONLY)) == -1){
236     fprintf( FCGI_stdout, "Reason: Target %s not found\r\n", filename);
237     return -1;
238   }
239   // Check resource is a JP family file.
240   if( lseek( fd, 0, SEEK_SET)==-1){
241     close(fd);
242     fprintf( FCGI_stdout, "Reason: Target %s broken (lseek error)\r\n", filename);
243     return -1;
244   }
245   
246   data = (char *)malloc( 12); // size of header
247   if( read( fd, data, 12) != 12){
248     free( data);
249     close(fd);
250     fprintf( FCGI_stdout, "Reason: Target %s broken (read error)\r\n", filename);
251     return -1;
252   }
253     
254   if( *data || *(data + 1) || *(data + 2) ||
255       *(data + 3) != 12 || strncmp (data + 4, "jP  \r\n\x87\n", 8)){
256     free( data);
257     close(fd);
258     fprintf( FCGI_stdout, "Reason: No JPEG 2000 Signature box in target %s\r\n", filename);
259     return -1;
260   } 
261   free( data);
262   return fd;
263 }