diff options
| author | Mathieu Malaterre <mathieu.malaterre@gmail.com> | 2012-09-28 08:11:41 +0000 |
|---|---|---|
| committer | Mathieu Malaterre <mathieu.malaterre@gmail.com> | 2012-09-28 08:11:41 +0000 |
| commit | d518970039a19a2a9b6d2bdd592cc88a43897bbb (patch) | |
| tree | 57bac2cf7e63e9352228231062763baac627563c /src/lib/openjpip/box_manager.c | |
| parent | 8363a6ab1e031bb4b2e40a92e56efd40fdab1aa1 (diff) | |
[trunk] Start FolderReorgProposal task
Update issue 177
Diffstat (limited to 'src/lib/openjpip/box_manager.c')
| -rw-r--r-- | src/lib/openjpip/box_manager.c | 434 |
1 files changed, 434 insertions, 0 deletions
diff --git a/src/lib/openjpip/box_manager.c b/src/lib/openjpip/box_manager.c new file mode 100644 index 00000000..87bb7756 --- /dev/null +++ b/src/lib/openjpip/box_manager.c @@ -0,0 +1,434 @@ +/* + * $Id: box_manager.c 44 2011-02-15 12:32:29Z kaori $ + * + * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2011, Professor Benoit Macq + * Copyright (c) 2010-2011, Kaori Hagihara + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <ctype.h> +#include <assert.h> +#include "box_manager.h" +#include "opj_inttypes.h" + +#ifdef SERVER +#include "fcgi_stdio.h" +#define logstream FCGI_stdout +#else +#define FCGI_stdout stdout +#define FCGI_stderr stderr +#define logstream stderr +#endif /*SERVER*/ + +boxlist_param_t * gene_boxlist(void) +{ + boxlist_param_t *boxlist; + + boxlist = (boxlist_param_t *)malloc( sizeof(boxlist_param_t)); + + boxlist->first = NULL; + boxlist->last = NULL; + + return boxlist; +} + +boxlist_param_t * get_boxstructure( int fd, OPJ_OFF_T offset, OPJ_SIZE_T length) +{ + boxlist_param_t *boxlist; + box_param_t *box; + OPJ_OFF_T pos; + + boxlist = NULL; + pos = offset; + assert( (OPJ_OFF_T)length>=0); + do{ + if(!(box = gene_boxbyOffset( fd, pos))) + break; + + assert( (OPJ_OFF_T)box->length >= 0); + pos += (OPJ_OFF_T)box->length; + + if( !boxlist) + boxlist = gene_boxlist(); + insert_box_into_list( box, boxlist); + }while( pos < offset+(OPJ_OFF_T)length); + + return boxlist; +} + +box_param_t * gene_boxbyOffset( int fd, OPJ_OFF_T offset) +{ + Byte_t *data; + Byte8_t boxlen; + Byte_t headlen; + char *boxtype; + box_param_t *box; + + /* read LBox and TBox*/ + if(!(data = fetch_bytes( fd, offset, 8))){ + fprintf( FCGI_stderr, "Error: error in gene_boxbyOffset( %d, %" PRId64 ")\n", fd, offset); + return NULL; + } + + headlen = 8; + boxlen = (Byte8_t)big4(data); + boxtype = (char *)(data+4); + + /* box type constraint*/ + if( !isalpha(boxtype[0]) || !isalpha(boxtype[1]) || + (!isalnum(boxtype[2])&&!isspace(boxtype[2])) || + (!isalpha(boxtype[3])&&!isspace(boxtype[3]))){ + free( data); + return NULL; + } + + if( boxlen == 1){ + Byte_t *data2; + headlen = 16; + /* read XLBox*/ + if((data2 = fetch_bytes( fd, offset+8, 8))){ + boxlen = big8(data2); + free(data2); + } + else{ + fprintf( FCGI_stderr, "Error: error in gene_boxbyOffset( %d, %" PRId64 ")\n", fd, offset); + free( data); + return NULL; + } + } + box = (box_param_t *)malloc( sizeof( box_param_t)); + box->fd = fd; + box->offset = offset; + box->headlen = headlen; + box->length = boxlen; + strncpy( box->type, boxtype, 4); + box->next = NULL; + free( data); + return box; +} + +box_param_t * gene_boxbyOffinStream( Byte_t *stream, OPJ_OFF_T offset) +{ + Byte8_t boxlen; + Byte_t headlen; + char *boxtype; + box_param_t *box; + + /* read LBox and TBox*/ + headlen = 8; + boxlen = (Byte8_t)big4( stream); + boxtype = (char *)( stream+4); + + /* box type constraint*/ + if( !isalpha(boxtype[0]) || !isalpha(boxtype[1]) || + (!isalnum(boxtype[2])&&!isspace(boxtype[2])) || + (!isalpha(boxtype[3])&&!isspace(boxtype[3]))){ + return NULL; + } + + if( boxlen == 1){ + headlen = 16; + boxlen = big8( stream+8); /* read XLBox*/ + } + box = (box_param_t *)malloc( sizeof( box_param_t)); + box->fd = -1; + box->offset = offset; + box->headlen = headlen; + box->length = boxlen; + strncpy( box->type, boxtype, 4); + box->next = NULL; + + return box; +} + + +box_param_t * gene_boxbyType( int fd, OPJ_OFF_T offset, OPJ_SIZE_T length, const char TBox[]) +{ + OPJ_OFF_T pos; + Byte_t *data; + Byte8_t boxlen; + Byte_t headlen; + char *boxtype; + box_param_t *foundbox; + + + if( length==0){ /* set the max length*/ + if( get_filesize( fd) <= offset ) + return NULL; + assert( get_filesize( fd) > offset ); + assert( offset >= 0 ); + length = (OPJ_SIZE_T)(get_filesize( fd) - offset); + } + + pos = offset; + assert( pos >= 0 ); + assert( (OPJ_OFF_T)length >= 0 ); + while( pos < offset+(OPJ_OFF_T)length-7){ /* LBox+TBox-1=7*/ + + /* read LBox and TBox*/ + if((data = fetch_bytes( fd, pos, 8))){ + headlen = 8; + boxlen = (Byte8_t)big4(data); + boxtype = (char *)(data+4); + + if( boxlen == 1){ + Byte_t *data2; + headlen = 16; + /* read XLBox*/ + if((data2 = fetch_bytes( fd, pos+8, 8))){ + boxlen = big8(data2); + free(data2); + } + else{ + fprintf( FCGI_stderr, "Error: error in gene_boxbyType( %d, %" PRId64 ", %" PRId64 ", %s)\n", fd, offset, length, TBox); + return NULL; + } + } + if( strncmp ( boxtype, TBox, 4) == 0){ + foundbox = (box_param_t *)malloc( sizeof( box_param_t)); + foundbox->fd = fd; + foundbox->offset = pos; + foundbox->headlen = headlen; + foundbox->length = boxlen; + strncpy( foundbox->type, TBox, 4); + foundbox->next = NULL; + free( data); + return foundbox; + } + free( data); + } + else{ + fprintf( FCGI_stderr, "Error: error in gene_boxbyType( %d, %" PRId64 ", %" PRId64 ", %s)\n", fd, offset, length, TBox); + return NULL; + } + assert( ((Byte8_t)pos+boxlen)>=(Byte8_t)pos); + pos+= (OPJ_OFF_T)boxlen; + } + fprintf( FCGI_stderr, "Error: Box %s not found\n", TBox); + + return NULL; +} + +box_param_t * gene_boxbyTypeinStream( Byte_t *stream, OPJ_OFF_T offset, OPJ_SIZE_T length, const char TBox[]) +{ + OPJ_OFF_T pos; + Byte_t *data; + Byte8_t boxlen; + Byte_t headlen; + char *boxtype; + box_param_t *foundbox; + + pos = offset; + assert( pos >= 0 ); + assert( (OPJ_OFF_T)length >= 0 ); + while( pos < offset+(OPJ_OFF_T)(length)-7){ /* LBox+TBox-1=7*/ + + /* read LBox and TBox*/ + data = stream + pos; + headlen = 8; + boxlen = (Byte8_t)big4(data); + boxtype = (char *)(data+4); + + if( boxlen == 1){ + /* read XLBox*/ + headlen = 16; + boxlen = big8( data+8); + } + + if( strncmp ( boxtype, TBox, 4) == 0){ + foundbox = (box_param_t *)malloc( sizeof( box_param_t)); + foundbox->fd = -1; + foundbox->offset = pos; + foundbox->headlen = headlen; + foundbox->length = boxlen; + strncpy( foundbox->type, TBox, 4); + foundbox->next = NULL; + return foundbox; + } + assert( ((Byte8_t)pos+boxlen)>=(Byte8_t)pos); + pos+= (OPJ_OFF_T)boxlen; + } + fprintf( FCGI_stderr, "Error: Box %s not found\n", TBox); + + return NULL; +} + +box_param_t * gene_childboxbyOffset( box_param_t *superbox, OPJ_OFF_T offset) +{ + return gene_boxbyOffset( superbox->fd, get_DBoxoff( superbox)+offset); +} + +box_param_t * gene_childboxbyType( box_param_t *superbox, OPJ_OFF_T offset, const char TBox[]) +{ + OPJ_SIZE_T DBOXlen = get_DBoxlen(superbox); + assert( offset >= 0 ); + if( DBOXlen < (OPJ_SIZE_T)offset ) + { + fprintf( FCGI_stderr, "Error: Impossible happen %lu < %ld\n", DBOXlen, offset); + return NULL; + } + return gene_boxbyType( superbox->fd, get_DBoxoff( superbox)+offset, DBOXlen-(OPJ_SIZE_T)offset, TBox); +} + +OPJ_OFF_T get_DBoxoff( box_param_t *box) +{ + return box->offset+box->headlen; +} + +OPJ_SIZE_T get_DBoxlen( box_param_t *box) +{ + return box->length - box->headlen; +} + +Byte_t * fetch_headbytes( box_param_t *box) +{ + return fetch_bytes( box->fd, box->offset, box->headlen); +} + +Byte_t * fetch_DBoxbytes( box_param_t *box, OPJ_OFF_T offset, OPJ_SIZE_T size) +{ + return fetch_bytes( box->fd, get_DBoxoff( box)+offset, size); +} + +Byte_t fetch_DBox1byte( box_param_t *box, OPJ_OFF_T offset) +{ + return fetch_1byte( box->fd, get_DBoxoff( box)+offset); +} + +Byte2_t fetch_DBox2bytebigendian( box_param_t *box, OPJ_OFF_T offset) +{ + return fetch_2bytebigendian( box->fd, get_DBoxoff( box)+offset); +} + +Byte4_t fetch_DBox4bytebigendian( box_param_t *box, OPJ_OFF_T offset) +{ + return fetch_4bytebigendian( box->fd, get_DBoxoff( box)+offset); +} + +Byte8_t fetch_DBox8bytebigendian( box_param_t *box, OPJ_OFF_T offset) +{ + return fetch_8bytebigendian( box->fd, get_DBoxoff( box)+offset); +} + +box_param_t * search_box( const char type[], boxlist_param_t *boxlist) +{ + box_param_t *foundbox; + + foundbox = boxlist->first; + + while( foundbox != NULL){ + + if( strncmp( type, foundbox->type, 4) == 0) + return foundbox; + + foundbox = foundbox->next; + } + fprintf( FCGI_stderr, "Error: Box %s not found\n", type); + + return NULL; +} + +void print_box( box_param_t *box) +{ + fprintf( logstream, "box info:\n" + "\t type: %.4s\n" + "\t offset: %" PRId64 " %#" PRIx64 "\n" + "\t header length: %d\n" + "\t length: %" PRId64 " %#" PRIx64 "\n", box->type, box->offset, + box->offset, box->headlen, box->length, box->length); +} + +void print_allbox( boxlist_param_t *boxlist) +{ + box_param_t *ptr; + + if( !boxlist) + return; + + ptr = boxlist->first; + if( !ptr) + fprintf( logstream, "no box\n"); + + fprintf( logstream, "all box info: \n"); + while( ptr != NULL){ + print_box( ptr); + ptr=ptr->next; + } +} + +void delete_box_in_list( box_param_t **box, boxlist_param_t *boxlist) +{ + box_param_t *ptr; + + if( *box == boxlist->first) + boxlist->first = (*box)->next; + else{ + ptr = boxlist->first; + while( ptr->next != *box){ + ptr=ptr->next; + } + ptr->next = (*box)->next; + + if( *box == boxlist->last) + boxlist->last = ptr; + } + free( *box); +} + +void delete_box_in_list_by_type( const char type[], boxlist_param_t *boxlist) +{ + box_param_t *box; + + box = search_box( type, boxlist); + delete_box_in_list( &box, boxlist); +} + +void delete_boxlist( boxlist_param_t **boxlist) +{ + box_param_t *boxPtr, *boxNext; + + if(!(*boxlist)) + return; + + boxPtr = (*boxlist)->first; + while( boxPtr != NULL){ + boxNext=boxPtr->next; + free( boxPtr); + boxPtr=boxNext; + } + free( *boxlist); +} + +void insert_box_into_list( box_param_t *box, boxlist_param_t *boxlist) +{ + if( boxlist->first) + boxlist->last->next = box; + else + boxlist->first = box; + boxlist->last = box; +} |
