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);
217 if (strncmp(boxtype, TBox, 4) == 0) {
218 foundbox = (box_param_t *)malloc(sizeof(box_param_t));
220 foundbox->offset = pos;
221 foundbox->headlen = headlen;
222 foundbox->length = boxlen;
223 strncpy(foundbox->type, TBox, 4);
224 foundbox->next = NULL;
230 fprintf(FCGI_stderr, "Error: error in gene_boxbyType( %d, %" PRId64 ", %" PRId64
231 ", %s)\n", fd, offset, length, TBox);
234 assert(((Byte8_t)pos + boxlen) >= (Byte8_t)pos);
235 pos += (OPJ_OFF_T)boxlen;
237 fprintf(FCGI_stderr, "Error: Box %s not found\n", TBox);
242 box_param_t * gene_boxbyTypeinStream(Byte_t *stream, OPJ_OFF_T offset,
243 OPJ_SIZE_T length, const char TBox[])
250 box_param_t *foundbox;
254 assert((OPJ_OFF_T)length >= 0);
255 while (pos < offset + (OPJ_OFF_T)(length) - 7) { /* LBox+TBox-1=7*/
257 /* read LBox and TBox*/
260 boxlen = (Byte8_t)big4(data);
261 boxtype = (char *)(data + 4);
266 boxlen = big8(data + 8);
269 if (strncmp(boxtype, TBox, 4) == 0) {
270 foundbox = (box_param_t *)malloc(sizeof(box_param_t));
272 foundbox->offset = pos;
273 foundbox->headlen = headlen;
274 foundbox->length = boxlen;
275 strncpy(foundbox->type, TBox, 4);
276 foundbox->next = NULL;
279 assert(((Byte8_t)pos + boxlen) >= (Byte8_t)pos);
280 pos += (OPJ_OFF_T)boxlen;
282 fprintf(FCGI_stderr, "Error: Box %s not found\n", TBox);
287 box_param_t * gene_childboxbyOffset(box_param_t *superbox, OPJ_OFF_T offset)
289 return gene_boxbyOffset(superbox->fd, get_DBoxoff(superbox) + offset);
292 box_param_t * gene_childboxbyType(box_param_t *superbox, OPJ_OFF_T offset,
295 OPJ_SIZE_T DBOXlen = get_DBoxlen(superbox);
297 if (DBOXlen < (OPJ_SIZE_T)offset) {
298 fprintf(FCGI_stderr, "Error: Impossible happen %lu < %ld\n", DBOXlen, offset);
301 return gene_boxbyType(superbox->fd, get_DBoxoff(superbox) + offset,
302 DBOXlen - (OPJ_SIZE_T)offset, TBox);
305 OPJ_OFF_T get_DBoxoff(box_param_t *box)
307 return box->offset + box->headlen;
310 OPJ_SIZE_T get_DBoxlen(box_param_t *box)
312 return box->length - box->headlen;
315 Byte_t * fetch_headbytes(box_param_t *box)
317 return fetch_bytes(box->fd, box->offset, box->headlen);
320 Byte_t * fetch_DBoxbytes(box_param_t *box, OPJ_OFF_T offset, OPJ_SIZE_T size)
322 return fetch_bytes(box->fd, get_DBoxoff(box) + offset, size);
325 Byte_t fetch_DBox1byte(box_param_t *box, OPJ_OFF_T offset)
327 return fetch_1byte(box->fd, get_DBoxoff(box) + offset);
330 Byte2_t fetch_DBox2bytebigendian(box_param_t *box, OPJ_OFF_T offset)
332 return fetch_2bytebigendian(box->fd, get_DBoxoff(box) + offset);
335 Byte4_t fetch_DBox4bytebigendian(box_param_t *box, OPJ_OFF_T offset)
337 return fetch_4bytebigendian(box->fd, get_DBoxoff(box) + offset);
340 Byte8_t fetch_DBox8bytebigendian(box_param_t *box, OPJ_OFF_T offset)
342 return fetch_8bytebigendian(box->fd, get_DBoxoff(box) + offset);
345 box_param_t * search_box(const char type[], boxlist_param_t *boxlist)
347 box_param_t *foundbox;
349 foundbox = boxlist->first;
351 while (foundbox != NULL) {
353 if (strncmp(type, foundbox->type, 4) == 0) {
357 foundbox = foundbox->next;
359 fprintf(FCGI_stderr, "Error: Box %s not found\n", type);
364 void print_box(box_param_t *box)
366 fprintf(logstream, "box info:\n"
368 "\t offset: %" PRId64 " %#" PRIx64 "\n"
369 "\t header length: %d\n"
370 "\t length: %" PRId64 " %#" PRIx64 "\n", box->type, box->offset,
371 box->offset, box->headlen, box->length, box->length);
374 void print_allbox(boxlist_param_t *boxlist)
382 ptr = boxlist->first;
384 fprintf(logstream, "no box\n");
387 fprintf(logstream, "all box info: \n");
388 while (ptr != NULL) {
394 void delete_box_in_list(box_param_t **box, boxlist_param_t *boxlist)
398 if (*box == boxlist->first) {
399 boxlist->first = (*box)->next;
401 ptr = boxlist->first;
402 while (ptr->next != *box) {
405 ptr->next = (*box)->next;
407 if (*box == boxlist->last) {
414 void delete_box_in_list_by_type(const char type[], boxlist_param_t *boxlist)
418 box = search_box(type, boxlist);
419 delete_box_in_list(&box, boxlist);
422 void delete_boxlist(boxlist_param_t **boxlist)
424 box_param_t *boxPtr, *boxNext;
430 boxPtr = (*boxlist)->first;
431 while (boxPtr != NULL) {
432 boxNext = boxPtr->next;
439 void insert_box_into_list(box_param_t *box, boxlist_param_t *boxlist)
441 if (boxlist->first) {
442 boxlist->last->next = box;
444 boxlist->first = box;