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
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
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.
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.
36 #include "box_manager.h"
37 #include "opj_inttypes.h"
40 #include "fcgi_stdio.h"
41 #define logstream FCGI_stdout
43 #define FCGI_stdout stdout
44 #define FCGI_stderr stderr
45 #define logstream stderr
48 boxlist_param_t * gene_boxlist(void)
50 boxlist_param_t *boxlist;
52 boxlist = (boxlist_param_t *)malloc(sizeof(boxlist_param_t));
54 boxlist->first = NULL;
60 boxlist_param_t * get_boxstructure(int fd, OPJ_OFF_T offset, OPJ_SIZE_T length)
62 boxlist_param_t *boxlist;
68 assert((OPJ_OFF_T)length >= 0);
70 if (!(box = gene_boxbyOffset(fd, pos))) {
74 assert((OPJ_OFF_T)box->length >= 0);
75 pos += (OPJ_OFF_T)box->length;
78 boxlist = gene_boxlist();
80 insert_box_into_list(box, boxlist);
81 } while (pos < offset + (OPJ_OFF_T)length);
86 box_param_t * gene_boxbyOffset(int fd, OPJ_OFF_T offset)
94 /* read LBox and TBox*/
95 if (!(data = fetch_bytes(fd, offset, 8))) {
96 fprintf(FCGI_stderr, "Error: error in gene_boxbyOffset( %d, %" PRId64 ")\n", fd,
102 boxlen = (Byte8_t)big4(data);
103 boxtype = (char *)(data + 4);
105 /* box type constraint*/
106 if (!isalpha(boxtype[0]) || !isalpha(boxtype[1]) ||
107 (!isalnum(boxtype[2]) && !isspace(boxtype[2])) ||
108 (!isalpha(boxtype[3]) && !isspace(boxtype[3]))) {
117 if ((data2 = fetch_bytes(fd, offset + 8, 8))) {
118 boxlen = big8(data2);
121 fprintf(FCGI_stderr, "Error: error in gene_boxbyOffset( %d, %" PRId64 ")\n", fd,
127 box = (box_param_t *)malloc(sizeof(box_param_t));
129 box->offset = offset;
130 box->headlen = headlen;
131 box->length = boxlen;
132 strncpy(box->type, boxtype, 4);
138 box_param_t * gene_boxbyOffinStream(Byte_t *stream, OPJ_OFF_T offset)
145 /* read LBox and TBox*/
147 boxlen = (Byte8_t)big4(stream);
148 boxtype = (char *)(stream + 4);
150 /* box type constraint*/
151 if (!isalpha(boxtype[0]) || !isalpha(boxtype[1]) ||
152 (!isalnum(boxtype[2]) && !isspace(boxtype[2])) ||
153 (!isalpha(boxtype[3]) && !isspace(boxtype[3]))) {
159 boxlen = big8(stream + 8); /* read XLBox*/
161 box = (box_param_t *)malloc(sizeof(box_param_t));
163 box->offset = offset;
164 box->headlen = headlen;
165 box->length = boxlen;
166 strncpy(box->type, boxtype, 4);
173 box_param_t * gene_boxbyType(int fd, OPJ_OFF_T offset, OPJ_SIZE_T length,
181 box_param_t *foundbox;
184 if (length == 0) { /* set the max length*/
185 if (get_filesize(fd) <= offset) {
188 assert(get_filesize(fd) > offset);
190 length = (OPJ_SIZE_T)(get_filesize(fd) - offset);
195 assert((OPJ_OFF_T)length >= 0);
196 while (pos < offset + (OPJ_OFF_T)length - 7) { /* LBox+TBox-1=7*/
198 /* read LBox and TBox*/
199 if ((data = fetch_bytes(fd, pos, 8))) {
201 boxlen = (Byte8_t)big4(data);
202 boxtype = (char *)(data + 4);
208 if ((data2 = fetch_bytes(fd, pos + 8, 8))) {
209 boxlen = big8(data2);
212 fprintf(FCGI_stderr, "Error: error in gene_boxbyType( %d, %" PRId64 ", %" PRId64
213 ", %s)\n", fd, offset, length, TBox);
218 if (strncmp(boxtype, TBox, 4) == 0) {
219 foundbox = (box_param_t *)malloc(sizeof(box_param_t));
221 foundbox->offset = pos;
222 foundbox->headlen = headlen;
223 foundbox->length = boxlen;
224 strncpy(foundbox->type, TBox, 4);
225 foundbox->next = NULL;
231 fprintf(FCGI_stderr, "Error: error in gene_boxbyType( %d, %" PRId64 ", %" PRId64
232 ", %s)\n", fd, offset, length, TBox);
235 assert(((Byte8_t)pos + boxlen) >= (Byte8_t)pos);
236 pos += (OPJ_OFF_T)boxlen;
238 fprintf(FCGI_stderr, "Error: Box %s not found\n", TBox);
243 box_param_t * gene_boxbyTypeinStream(Byte_t *stream, OPJ_OFF_T offset,
244 OPJ_SIZE_T length, const char TBox[])
251 box_param_t *foundbox;
255 assert((OPJ_OFF_T)length >= 0);
256 while (pos < offset + (OPJ_OFF_T)(length) - 7) { /* LBox+TBox-1=7*/
258 /* read LBox and TBox*/
261 boxlen = (Byte8_t)big4(data);
262 boxtype = (char *)(data + 4);
267 boxlen = big8(data + 8);
270 if (strncmp(boxtype, TBox, 4) == 0) {
271 foundbox = (box_param_t *)malloc(sizeof(box_param_t));
273 foundbox->offset = pos;
274 foundbox->headlen = headlen;
275 foundbox->length = boxlen;
276 strncpy(foundbox->type, TBox, 4);
277 foundbox->next = NULL;
280 assert(((Byte8_t)pos + boxlen) >= (Byte8_t)pos);
281 pos += (OPJ_OFF_T)boxlen;
283 fprintf(FCGI_stderr, "Error: Box %s not found\n", TBox);
288 box_param_t * gene_childboxbyOffset(box_param_t *superbox, OPJ_OFF_T offset)
290 return gene_boxbyOffset(superbox->fd, get_DBoxoff(superbox) + offset);
293 box_param_t * gene_childboxbyType(box_param_t *superbox, OPJ_OFF_T offset,
296 OPJ_SIZE_T DBOXlen = get_DBoxlen(superbox);
298 if (DBOXlen < (OPJ_SIZE_T)offset) {
299 fprintf(FCGI_stderr, "Error: Impossible happen %lu < %ld\n", DBOXlen, offset);
302 return gene_boxbyType(superbox->fd, get_DBoxoff(superbox) + offset,
303 DBOXlen - (OPJ_SIZE_T)offset, TBox);
306 OPJ_OFF_T get_DBoxoff(box_param_t *box)
308 return box->offset + box->headlen;
311 OPJ_SIZE_T get_DBoxlen(box_param_t *box)
313 return box->length - box->headlen;
316 Byte_t * fetch_headbytes(box_param_t *box)
318 return fetch_bytes(box->fd, box->offset, box->headlen);
321 Byte_t * fetch_DBoxbytes(box_param_t *box, OPJ_OFF_T offset, OPJ_SIZE_T size)
323 return fetch_bytes(box->fd, get_DBoxoff(box) + offset, size);
326 Byte_t fetch_DBox1byte(box_param_t *box, OPJ_OFF_T offset)
328 return fetch_1byte(box->fd, get_DBoxoff(box) + offset);
331 Byte2_t fetch_DBox2bytebigendian(box_param_t *box, OPJ_OFF_T offset)
333 return fetch_2bytebigendian(box->fd, get_DBoxoff(box) + offset);
336 Byte4_t fetch_DBox4bytebigendian(box_param_t *box, OPJ_OFF_T offset)
338 return fetch_4bytebigendian(box->fd, get_DBoxoff(box) + offset);
341 Byte8_t fetch_DBox8bytebigendian(box_param_t *box, OPJ_OFF_T offset)
343 return fetch_8bytebigendian(box->fd, get_DBoxoff(box) + offset);
346 box_param_t * search_box(const char type[], boxlist_param_t *boxlist)
348 box_param_t *foundbox;
350 foundbox = boxlist->first;
352 while (foundbox != NULL) {
354 if (strncmp(type, foundbox->type, 4) == 0) {
358 foundbox = foundbox->next;
360 fprintf(FCGI_stderr, "Error: Box %s not found\n", type);
365 void print_box(box_param_t *box)
367 fprintf(logstream, "box info:\n"
369 "\t offset: %" PRId64 " %#" PRIx64 "\n"
370 "\t header length: %d\n"
371 "\t length: %" PRId64 " %#" PRIx64 "\n", box->type, box->offset,
372 box->offset, box->headlen, box->length, box->length);
375 void print_allbox(boxlist_param_t *boxlist)
383 ptr = boxlist->first;
385 fprintf(logstream, "no box\n");
388 fprintf(logstream, "all box info: \n");
389 while (ptr != NULL) {
395 void delete_box_in_list(box_param_t **box, boxlist_param_t *boxlist)
399 if (*box == boxlist->first) {
400 boxlist->first = (*box)->next;
402 ptr = boxlist->first;
403 while (ptr->next != *box) {
406 ptr->next = (*box)->next;
408 if (*box == boxlist->last) {
415 void delete_box_in_list_by_type(const char type[], boxlist_param_t *boxlist)
419 box = search_box(type, boxlist);
420 delete_box_in_list(&box, boxlist);
423 void delete_boxlist(boxlist_param_t **boxlist)
425 box_param_t *boxPtr, *boxNext;
431 boxPtr = (*boxlist)->first;
432 while (boxPtr != NULL) {
433 boxNext = boxPtr->next;
440 void insert_box_into_list(box_param_t *box, boxlist_param_t *boxlist)
442 if (boxlist->first) {
443 boxlist->last->next = box;
445 boxlist->first = box;