initial commit of OpenJPIP 1.0, a JPIP client-server architecture based on OpenJPEG (see README file in jpip directory for more details)

This commit is contained in:
Antonin Descampe 2011-04-14 18:37:47 +00:00
parent 27b894dd3f
commit 31dba0b4e9
105 changed files with 12467 additions and 57 deletions

View File

@ -6,6 +6,7 @@ What's New for OpenJPEG
+ : added
April 14, 2011
+ [antonin] initial commit of OpenJPIP 1.0, a JPIP client-server architecture based on OpenJPEG (see README file in jpip directory for more details)
* [antonin] fixed applications/codec/CMakeLists.txt that prevented JPWL executables to be built with JPWL functionalities.
! [antonin] changed make all behaviour : DOC target removed from ALL.

View File

@ -210,7 +210,6 @@ ADD_SUBDIRECTORY(libopenjpeg)
# Build Applications
OPTION(BUILD_CODEC "Build the CODEC executables" ON)
OPTION(BUILD_MJ2 "Build the MJ2 executables." OFF)
OPTION(BUILD_INDEXER_JPIP "Build the INDEXER_JPIP executables" OFF)
ADD_SUBDIRECTORY(applications)
#-----------------------------------------------------------------------------

View File

@ -67,7 +67,6 @@ Main available cmake flags:
* To build the CODEC executables: '-DBUILD_CODEC:bool=on' (default: 'ON')
* To build the MJ2 executables: '-DBUILD_MJ2:bool=on' (default: 'OFF')
* To build the JPWL executables and JPWL library: '-DBUILD_JPWL:bool=on' (default: 'OFF')
* [WIN32 ONLY] To build the INDEXER_JPIP executable: '-DBUILD_INDEXER_JPIP:bool=on' (default: 'OFF')
* To enable testing (and automatic result upload to http://my.cdash.org/index.php?project=OPENJPEG):
cmake . -DBUILD_TESTING:BOOL=ON -DJPEG2000_CONFORMANCE_DATA_ROOT:PATH=/path/to/your/JPEG2000/test/files
make

2
README
View File

@ -11,7 +11,7 @@ Details on folders hierarchy:
* codec: a basic codec
* mj2: motion jpeg 2000 executables
* JavaOpenJPEG: java jni to use openjpeg in a java program
* indexer_JPIP: obsolete. Will be replaced by a complete JPIP implementation soon.
* jpip: complete client-server architecture for remote browsing of jpeg 2000 images. See corresponding README for more details.
* OPJViewer: gui for displaying j2k files (based on wxWidget)
* thirdparty: thirdparty libraries used by some applications. These libraries will be build only if there are not found on the system. Note that libopenjpeg itself does not have any dependency.
* doc: doxygen documentation setup file and man pages

View File

@ -127,8 +127,4 @@ ENDIF(BUILD_CODEC)
IF(BUILD_MJ2)
ADD_SUBDIRECTORY(mj2)
ENDIF(BUILD_MJ2)
#
IF(BUILD_INDEXER_JPIP)
ADD_SUBDIRECTORY(indexer_JPIP)
ENDIF(BUILD_INDEXER_JPIP)
#

View File

@ -1,9 +0,0 @@
# index_create
ADD_EXECUTABLE(index_create
bio.c cio.c int.c pi.c t2.c tgt.c tcd.c index_create.c jpip.c jp2.c
)
INSTALL(TARGETS index_create
EXPORT OpenJPEGTargets
DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
)

View File

@ -0,0 +1,19 @@
default: t_libopenjpip t_opj_server t_opj_dec_server t_tools
t_libopenjpip:
make -C libopenjpip
t_opj_server:
make -C opj_server
t_opj_dec_server:
make -C opj_client/opj_dec_server
t_tools:
make -C tools
clean:
make clean -C libopenjpip
make clean -C opj_server
make clean -C opj_client/opj_dec_server
make clean -C tools

141
applications/jpip/README Normal file
View File

@ -0,0 +1,141 @@
========================================================================
OpenJPIP software 1.0 ReadMe
OpenJPEG:
http://www.openjpeg.org
Written by:
Kaori Hagihara
UCL/SST/ICTM/ELEN
February 18 2011
========================================================================
Contents:
1. Introduction
2. License
3. System requirements
4. Implementing instructions
5. JP2 encoding instructions
----------
1. Introduction
----------
OpenJPIP software is an implementation of JPEG 2000 Part9: Interactivity tools, APIs and protocols (JPIP).
( For more info about JPIP, check the website: http://www.jpeg.org/jpeg2000/j2kpart9.html)
The current implementation uses some results from the 2KAN project (http://www.2kan.org).
First Version 1.0 covers:
- JPT-stream (Tile based) media types
- Session, channels, cache model managements
- JPIP over HTTP
- Indexing JPEG 2000 files
- Embedding XML formatted metadata
- Region Of Interest (ROI) requests
----------
2. License
----------
This software is released under the BSD license, anybody can use or modify the library, even for commercial applications.
The only restriction is to retain the copyright in the sources or the binaries documentation.
Neither the author, nor the university accept any responsibility for any kind of error or data loss which may occur during usage.
----------
3. System requirements
----------
- OpenJPEG library (currently assumes it is installed on the system => will not use the one built higher in the directory structure)
- FastCGI development kit (C libraries) at server (http://www.fastcgi.com)
- Java application launcher at client
- Kakadu software ( http://www.kakadusoftware.com). Currently required to encode jpeg 2000 images with tile-parts. This will be implemented soon in openjpeg, making this requirement obsolete.
<Optional>
- Xerces2 java XML parser on the client for accessing embedded image metadata (http://xerces.apache.org/xerces2-j)
We tested this software with a virtual server running on the same Linux machine as the clients. Currently, it works only on linux or macosx platforms, windows version should come later.
----------
4. Building instructions
----------
A Makefile is available in the same directory as this README file. Simply type 'make' and it will build all the required C-executables.
Concerning the java-based opj_viewer, simply type 'ant' in the corresponding directory (requires 'ant' utility of course)
CMake files ar planned to be included ASAP.
The documentation can be build this way (requires doxygen utility):
cd doc
doxygen Doxyfile
----------
5. Usage
----------
Preliminary notes :
* HTML documentation is available at http://www.openjpeg.org/jpip/doc/html
* Example image is available at http://www.openjpeg.org/jpip/data/copenhague1.zip (20 Mb !)
Webserver:
You need a webserver running with the fastcgi module enabled and correctly configured.
For Apache, add the following line to your /etc/apache2/mods-available/fastcgi.conf configuration file:
FastCGIExternalServer /var/www/myFCGI -host localhost:3000
where /var/www is your DocumentRoot.
Please refer to 'http://www.openjpeg.org/jpip/doc/ApacheFastCGITutorial.pdf' for more details.
Server:
1. Store JP2 files in the same directory as opj_server
2. Launch opj_server from the server terminal:
% spawn-fcgi -f ./opj_server -p 3000 -n
Client:
1. Launch image decoding server, and keep it alive as long as image viewers are open
% ./opj_dec_server
You might prefer to implement this program from another directory since cache files are saved in the working directory.
% mkdir cache
% cd cache
% ../opj_dec_server
2. Open image viewers (as many as needed)
% java -jar opj_viewer.jar http://hostname/myFCGI JP2_filename.jp2
( The arguments
- http://hostname/myFCGI is the HTTP server URI (myFCGI refers to opj_server by the server setting)
- JP2_filename.jp2 is the name of a JP2 file available on the server.)
Image viewer GUI instructions:
Scale up request: Enlarge the window
ROI request: Select a region by mouse click and drag, then click inside the red frame of the selected region
<If Xerces2 is installed>
Annotate image with ROI information in XML metadata: Click button "Region Of Interest"
Open a new window presenting an aligned image with a locally stored image: Click button "Image Registration" (Under Construction)
3. Quit the image decoding server through the telnet, be sure all image viewers are closed
% telnet localhost 5000
quit
----------
5. JP2 encoding instructions
----------
An example to encode a TIF image "copenhague1.tif" at resolution 4780x4050, 8bit/pixel, grayscale.
1. J2K encoding using Kakadu with an option which introduces the tile-part flag at each resolution level
% ./kdu_compress -i copenhague1.tif -o copenhague1.j2k Corder=RPCL ORGtparts=R Stiles={256,256}
2. JP2 encoding with embedding indexing data
% ./index_create copenhague1.j2k copenhague1.jp2 2
<Option>
3. Embed metadata into JP2 file
% ./addXMLinJP2 copenhague1.jp2 copenhague1.xml
Input metadata file "copenhague1.xml" looks like:
<xmlbox>
<roi name="island" x="1890" y="1950" w="770" h="310"/>
<roi name="ship" x="750" y="330" w="100" h="60"/>
<roi name="airport" x="650" y="1800" w="650" h="800"/>
<roi name="harbor" x="4200" y="1650" w="130" h="130"/>
<irt refimg="name1.jp2" m1="0.50" m2="-0.50" m3="0" m4="0.80" m5="-0.80" m6="0" m7="500" m8="1000" m9="0"/>
</xmlbox>

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

View File

@ -0,0 +1,10 @@
default: local server
local:
make -f comMakefile.mk
server:
rm *.o && make jpipserver=yes -f comMakefile.mk
clean:
rm -f *.a *.o *~

View File

@ -0,0 +1,421 @@
/*
* $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 <string.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <ctype.h>
#include "box_manager.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()
{
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, Byte8_t offset, Byte8_t length)
{
boxlist_param_t *boxlist;
box_param_t *box;
int pos;
boxlist = NULL;
pos = offset;
do{
if(!(box = gene_boxbyOffset( fd, pos)))
break;
pos += box->length;
if( !boxlist)
boxlist = gene_boxlist();
insert_box_into_list( box, boxlist);
}while( pos < offset+length);
return boxlist;
}
box_param_t * gene_boxbyOffset( int fd, Byte8_t offset)
{
Byte_t *data;
Byte8_t boxlen, 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, %lld)\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])&&!isblank(boxtype[2])) ||
(!isalpha(boxtype[3])&&!isblank(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, %lld)\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, Byte8_t offset)
{
Byte8_t boxlen, 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])&&!isblank(boxtype[2])) ||
(!isalpha(boxtype[3])&&!isblank(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, Byte8_t offset, Byte8_t length, char TBox[])
{
Byte8_t pos;
Byte_t *data;
Byte8_t boxlen, headlen;
char *boxtype;
box_param_t *foundbox;
if( length==0){ // set the max length
struct stat sb;
if( fstat( fd, &sb) == -1){
fprintf( FCGI_stdout, "Reason: Target broken (fstat error)\r\n");
return NULL;
}
length = (Byte8_t)sb.st_size - offset;
}
pos = offset;
while( pos < offset+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, %lld, %lld, %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, %lld, %lld, %s)\n", fd, offset, length, TBox);
return NULL;
}
pos+= boxlen;
}
fprintf( FCGI_stderr, "Error: Box %s not found\n", TBox);
return NULL;
}
box_param_t * gene_boxbyTypeinStream( Byte_t *stream, Byte8_t offset, Byte8_t length, char TBox[])
{
Byte8_t pos;
Byte_t *data;
Byte8_t boxlen, headlen;
char *boxtype;
box_param_t *foundbox;
if( length<=0){ // set the max length
fprintf( FCGI_stderr, "func gene_boxbyTypeinStream(), max length must be more than 0\n");
return NULL;
}
pos = offset;
while( pos < offset+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;
}
pos+= boxlen;
}
fprintf( FCGI_stderr, "Error: Box %s not found\n", TBox);
return NULL;
}
box_param_t * gene_childboxbyOffset( box_param_t *superbox, Byte8_t offset)
{
return gene_boxbyOffset( superbox->fd, get_DBoxoff( superbox)+offset);
}
box_param_t * gene_childboxbyType( box_param_t *superbox, Byte8_t offset, char TBox[])
{
return gene_boxbyType( superbox->fd, get_DBoxoff( superbox)+offset, get_DBoxlen( superbox)-offset, TBox);
}
Byte8_t get_DBoxoff( box_param_t *box)
{
return box->offset+box->headlen;
}
Byte8_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, long offset, int size)
{
return fetch_bytes( box->fd, get_DBoxoff( box)+offset, size);
}
Byte_t fetch_DBox1byte( box_param_t *box, long offset)
{
return fetch_1byte( box->fd, get_DBoxoff( box)+offset);
}
Byte2_t fetch_DBox2bytebigendian( box_param_t *box, long offset)
{
return fetch_2bytebigendian( box->fd, get_DBoxoff( box)+offset);
}
Byte4_t fetch_DBox4bytebigendian( box_param_t *box, long offset)
{
return fetch_4bytebigendian( box->fd, get_DBoxoff( box)+offset);
}
Byte8_t fetch_DBox8bytebigendian( box_param_t *box, long offset)
{
return fetch_8bytebigendian( box->fd, get_DBoxoff( box)+offset);
}
box_param_t * search_box( 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: %lld %#llx\n"
"\t header length: %d\n"
"\t length: %lld %#llx\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( 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;
}

View File

@ -0,0 +1,265 @@
/*
* $Id: box_manager.h 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.
*/
#ifndef BOX_MANAGER_H_
# define BOX_MANAGER_H_
#include <stdio.h>
#include "byte_manager.h"
//! box parameters
typedef struct box_param{
int fd; //!< file descriptor
Byte8_t offset; //!< byte position of the whole Box (LBox) in the file
Byte_t headlen; //!< header length 8 or 16
Byte8_t length; //!< length of the whole Box
char type[4]; //!< type of information in the DBox
struct box_param *next; //!< pointer to the next box
} box_param_t;
//! Box list parameters
typedef struct boxlist_param{
box_param_t *first; //!< first box pointer of the list
box_param_t *last; //!< last box pointer of the list
} boxlist_param_t;
/**
* generate a box list
*
* @return pointer to the generated box list
*/
boxlist_param_t * gene_boxlist();
/**
* get box structure of JP2 file
*
* @param[in] fd file descriptor
* @param[in] offset offset of the decomposing region
* @param[in] length length of the decomposing region
* @return pointer to the generated boxlist
*/
boxlist_param_t * get_boxstructure( int fd, Byte8_t offset, Byte8_t length);
/**
* generate box from JP2 file at the given offset
*
* @param[in] fd file discriptor of the JP2 file
* @param[in] offset Box offset
* @return pointer to the structure of generate box parameters
*/
box_param_t * gene_boxbyOffset( int fd, Byte8_t offset);
/**
* generate box from code stream (JPP or JPT stream) at the given offset
*
* @param[in] stream code stream of a box
* @param[in] offset Box offset of the whole stream
* @return pointer to the structure of generate box parameters
*/
box_param_t * gene_boxbyOffinStream( Byte_t *stream, Byte8_t offset);
/**
* generate(search) box from JP2 file
*
* @param[in] fd file discriptor of the JP2 file
* @param[in] offset start Byte position of the search
* @param[in] length Byte length of the search, if 0, size to the end of file
* @param[in] TBox Box Type
* @return pointer to the structure of generate/found box parameters
*/
box_param_t * gene_boxbyType( int fd, Byte8_t offset, Byte8_t length, char TBox[]);
/**
* generate(search) box from code stream
*
* @param[in] stream code stream ( from the first byte)
* @param[in] offset start Byte position of the search
* @param[in] length Byte length of the search, if 0, size to the end of file
* @param[in] TBox Box Type
* @return pointer to the structure of generate/found box parameters
*/
box_param_t * gene_boxbyTypeinStream( Byte_t *stream, Byte8_t offset, Byte8_t length, char TBox[]);
/**
* generate child box from JP2 file at the given offset
*
* @param[in] superbox super box pointer
* @param[in] offset offset from DBox first byte of superbox
* @return pointer to the structure of generate box parameters
*/
box_param_t * gene_childboxbyOffset( box_param_t *superbox, Byte8_t offset);
/**
* generate(search) box from JP2 file
*
* @param[in] superbox super box pointer
* @param[in] offset offset from DBox first byte of superbox
* @param[in] TBox Box Type
* @return pointer to the structure of generate/found box parameters
*/
box_param_t * gene_childboxbyType( box_param_t *superbox, Byte8_t offset, char TBox[]);
/**
* get DBox offset
*
* @param[in] box box pointer
* @return DBox offset (byte position) in the file
*/
Byte8_t get_DBoxoff( box_param_t *box);
/**
* get DBox length
*
* @param[in] box box pointer
* @return DBox length ( content length)
*/
Byte8_t get_DBoxlen( box_param_t *box);
/**
* fetch header bytes in file stream
*
* @param[in] box box pointer
* @return pointer to the fetched bytes
*/
Byte_t * fetch_headbytes( box_param_t *box);
/**
* fetch DBox (Box Contents) bytes of data in file stream
*
* @param[in] box box pointer
* @param[in] offset start Byte position in DBox
* @param[in] size Byte length
* @return pointer to the fetched data
*/
Byte_t * fetch_DBoxbytes( box_param_t *box, long offset, int size);
/**
* fetch DBox (Box Contents) 1-byte Byte codes in file stream
*
* @param[in] box box pointer
* @param[in] offset start Byte position in DBox
* @return fetched code
*/
Byte_t fetch_DBox1byte( box_param_t *box, long offset);
/**
* fetch DBox (Box Contents) 2-byte big endian Byte codes in file stream
*
* @param[in] box box pointer
* @param[in] offset start Byte position in DBox
* @return fetched code
*/
Byte2_t fetch_DBox2bytebigendian( box_param_t *box, long offset);
/**
* fetch DBox (Box Contents) 4-byte big endian Byte codes in file stream
*
* @param[in] box box pointer
* @param[in] offset start Byte position in DBox
* @return fetched code
*/
Byte4_t fetch_DBox4bytebigendian( box_param_t *box, long offset);
/**
* fetch DBox (Box Contents) 8-byte big endian Byte codes in file stream
*
* @param[in] box box pointer
* @param[in] offset start Byte position in DBox
* @return fetched code
*/
Byte8_t fetch_DBox8bytebigendian( box_param_t *box, long offset);
/**
* search a box by box type
*
* @param[in] type box type
* @param[in] boxlist box list pointer
* @return found box pointer
*/
box_param_t * search_box( char type[], boxlist_param_t *boxlist);
/**
* print box parameters
*
* @param[in] box box pointer
*/
void print_box( box_param_t *box);
/**
* print all box parameters
*
* @param[in] boxlist box list pointer
*/
void print_allbox( boxlist_param_t *boxlist);
/**
* delete a box in list
*
* @param[in,out] box address of the deleting box pointer
* @param[in] boxlist box list pointer
*/
void delete_box_in_list( box_param_t **box, boxlist_param_t *boxlist);
/**
* delete a box in list by Type
*
* @param[in,out] type box type
* @param[in] boxlist box list pointer
*/
void delete_box_in_list_by_type( char type[], boxlist_param_t *boxlist);
/**
* delete box list
*
* @param[in,out] boxlist address of the box list pointer
*/
void delete_boxlist( boxlist_param_t **boxlist);
/**
* insert a box into list
*
* @param[in] box box pointer
* @param[in] boxlist box list pointer
*/
void insert_box_into_list( box_param_t *box, boxlist_param_t *boxlist);
#endif /* !BOX_MANAGER_H_ */

View File

@ -0,0 +1,81 @@
/*
* $Id: boxheader_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 <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include "boxheader_manager.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
boxheader_param_t * gene_boxheader( int fd, Byte8_t offset)
{
Byte8_t boxlen;
Byte_t headlen;
char *boxtype;
boxheader_param_t *boxheader;
boxlen = fetch_4bytebigendian( fd, offset);
boxtype = (char *)fetch_bytes( fd, offset+4, 4);
headlen = 8;
if( boxlen == 1){ // read XLBox
boxlen = fetch_8bytebigendian( fd, offset+8);
headlen = 16;
}
boxheader = (boxheader_param_t *)malloc( sizeof( boxheader_param_t));
boxheader->headlen = headlen;
boxheader->length = boxlen;
strncpy( boxheader->type, boxtype, 4);
boxheader->next = NULL;
free( boxtype);
return boxheader;
}
boxheader_param_t * gene_childboxheader( box_param_t *superbox, Byte8_t offset)
{
return gene_boxheader( superbox->fd, get_DBoxoff( superbox)+offset);
}
void print_boxheader( boxheader_param_t *boxheader)
{
fprintf( logstream, "boxheader info:\n"
"\t type: %.4s\n"
"\t length:%lld %#llx\n", boxheader->type, boxheader->length, boxheader->length);
}

View File

@ -0,0 +1,71 @@
/*
* $Id: boxheader_manager.h 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.
*/
#ifndef BOXHEADER_MANAGER_H_
# define BOXHEADER_MANAGER_H_
#include "byte_manager.h"
#include "box_manager.h"
//! box header parameters
typedef struct boxheader_param{
Byte_t headlen; //!< header length 8 or 16
Byte8_t length; //!< length of the reference Box
char type[4]; //!< type of information in the DBox
struct boxheader_param *next; //!< pointer to the next header box
} boxheader_param_t;
/**
* generate a box header at the given offset
*
* @param[in] fd file discriptor of the JP2 file
* @param[in] offset Box offset
* @return pointer to the structure of generate box header parameters
*/
boxheader_param_t * gene_boxheader( int fd, Byte8_t offset);
/**
* generate a child box header at the given offset
*
* @param[in] superbox super box pointer
* @param[in] offset offset from DBox first byte of superbox
* @return pointer to the structure of generate box header parameters
*/
boxheader_param_t * gene_childboxheader( box_param_t *superbox, Byte8_t offset);
/**
* print box header parameters
*
* @param[in] boxheader boxheader pointer
*/
void print_boxheader( boxheader_param_t *boxheader);
#endif /* !BOXHEADER_MANAGER_H_ */

View File

@ -0,0 +1,146 @@
/*
* $Id: byte_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 <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include "byte_manager.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
Byte_t * fetch_bytes( int fd, long offset, int size)
{
Byte_t *data;
if( lseek( fd, offset, SEEK_SET)==-1){
fprintf( FCGI_stdout, "Reason: Target broken (fseek error)\r\n");
fprintf( FCGI_stderr, "Error: error in fetch_bytes( %d, %ld, %d)\n", fd, offset, size);
return NULL;
}
data = (Byte_t *)malloc( size);
if( read( fd, data, size) != size){
free( data);
fprintf( FCGI_stdout, "Reason: Target broken (read error)\r\n");
fprintf( FCGI_stderr, "Error: error in fetch_bytes( %d, %ld, %d)\n", fd, offset, size);
return NULL;
}
return data;
}
Byte_t fetch_1byte( int fd, long offset)
{
Byte_t code;
if( lseek( fd, offset, SEEK_SET)==-1){
fprintf( FCGI_stdout, "Reason: Target broken (seek error)\r\n");
fprintf( FCGI_stderr, "Error: error in fetch_1byte( %d, %ld)\n", fd, offset);
return 0;
}
if( read( fd, &code, 1) != 1){
fprintf( FCGI_stdout, "Reason: Target broken (read error)\r\n");
fprintf( FCGI_stderr, "Error: error in fetch_bytes( %d, %ld)\n", fd, offset);
return 0;
}
return code;
}
Byte2_t fetch_2bytebigendian( int fd, long offset)
{
Byte_t *data;
Byte2_t code;
if(!(data = fetch_bytes( fd, offset, 2))){
fprintf( FCGI_stderr, "Error: error in fetch_2bytebigendian( %d, %ld)\n", fd, offset);
return 0;
}
code = big2(data);
free( data);
return code;
}
Byte4_t fetch_4bytebigendian( int fd, long offset)
{
Byte_t *data;
Byte4_t code;
if(!(data = fetch_bytes( fd, offset, 4))){
fprintf( FCGI_stderr, "Error: error in fetch_4bytebigendian( %d, %ld)\n", fd, offset);
return 0;
}
code = big4(data);
free( data);
return code;
}
Byte8_t fetch_8bytebigendian( int fd, long offset)
{
Byte_t *data;
Byte8_t code;
if(!(data = fetch_bytes( fd, offset, 8))){
fprintf( FCGI_stderr, "Error: error in fetch_8bytebigendian( %d, %ld)\n", fd, offset);
return 0;
}
code = big8(data);
free( data);
return code;
}
Byte2_t big2( Byte_t *buf)
{
return (((Byte2_t) buf[0]) << 8) + ((Byte2_t) buf[1]);
}
Byte4_t big4( Byte_t *buf)
{
return (((((((Byte4_t) buf[0]) << 8) + ((Byte4_t) buf[1])) << 8)
+ ((Byte4_t) buf[2])) << 8) + ((Byte4_t) buf[3]);
}
Byte8_t big8( Byte_t *buf)
{
return (((Byte8_t) big4 (buf)) << 32)
+ ((Byte8_t) big4 (buf + 4));
}

View File

@ -0,0 +1,122 @@
/*
* $Id: byte_manager.h 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.
*/
#ifndef BYTE_MANAGER_H_
# define BYTE_MANAGER_H_
#include <stdio.h>
//! 1Byte parameter type
typedef unsigned char Byte_t;
//! 2Byte parameter type
typedef unsigned short int Byte2_t;
//! 4Byte parameter type
typedef unsigned int Byte4_t;
//! 8Byte parameter type
typedef unsigned long long int Byte8_t;
/**
* fetch bytes of data in file stream
*
* @param[in] fd file discriptor
* @param[in] offset start Byte position
* @param[in] size Byte length
* @return pointer to the fetched data
*/
Byte_t * fetch_bytes( int fd, long offset, int size);
/**
* fetch a 1-byte Byte codes in file stream
*
* @param[in] fd file discriptor
* @param[in] offset start Byte position
* @return fetched codes
*/
Byte_t fetch_1byte( int fd, long offset);
/**
* fetch a 2-byte big endian Byte codes in file stream
*
* @param[in] fd file discriptor
* @param[in] offset start Byte position
* @return fetched codes
*/
Byte2_t fetch_2bytebigendian( int fd, long offset);
/**
* fetch a 4-byte big endian Byte codes in file stream
*
* @param[in] fd file discriptor
* @param[in] offset start Byte position
* @return fetched codes
*/
Byte4_t fetch_4bytebigendian( int fd, long offset);
/**
* fetch a 8-byte big endian Byte codes in file stream
*
* @param[in] fd file discriptor
* @param[in] offset start Byte position
* @return fetched codes
*/
Byte8_t fetch_8bytebigendian( int fd, long offset);
/**
* convert 2-byte big endian Byte codes to number
*
* @param[in] buf Byte codes
* @return resolved number
*/
Byte2_t big2( Byte_t *buf);
/**
* convert 4-byte big endian Byte codes to number
*
* @param[in] buf Byte codes
* @return resolved number
*/
Byte4_t big4( Byte_t *buf);
/**
* convert 8-byte big endian Byte codes to number
*
* @param[in] buf Byte codes
* @return resolved number
*/
Byte8_t big8( Byte_t *buf);
#endif /* !BYTE_MANAGER_H_ */

View File

@ -0,0 +1,80 @@
/*
* $Id: codestream_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 "codestream_manager.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
codestream_param_t set_codestream( int fd, Byte8_t offset, Byte8_t length)
{
codestream_param_t cs;
cs.fd = fd;
cs.offset = offset;
cs.length = length;
return cs;
}
Byte_t * fetch_codestreambytes( codestream_param_t *cs, long offset, int size)
{
return fetch_bytes( cs->fd, cs->offset+offset, size);
}
Byte_t fetch_codestream1byte( codestream_param_t *cs, long offset)
{
return fetch_1byte( cs->fd, cs->offset+offset);
}
Byte2_t fetch_codestream2bytebigendian( codestream_param_t *cs, long offset)
{
return fetch_2bytebigendian( cs->fd, cs->offset+offset);
}
Byte4_t fetch_codestream4bytebigendian( codestream_param_t *cs, long offset)
{
return fetch_4bytebigendian( cs->fd, cs->offset+offset);
}
void print_codestream( codestream_param_t cs)
{
fprintf( logstream, "codestream info:\n"
"\t fd: %d\n"
"\t offset: %#llx\n"
"\t length: %#llx\n", cs.fd, cs.offset, cs.length);
}

View File

@ -0,0 +1,102 @@
/*
* $Id: codestream_manager.h 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.
*/
#ifndef CODESTREAM_MANAGER_H_
# define CODESTREAM_MANAGER_H_
#include <stdio.h>
#include "byte_manager.h"
//! codestream parameters
typedef struct codestream_param{
int fd; //!< file descriptor
Byte8_t offset; //!< byte position of DBox (Box Contents) in the file
Byte8_t length; //!< content length
} codestream_param_t;
/**
* set codestream parameters from inputs
*
* @param[in] fd file descriptor
* @param[in] offset offset in the file
* @param[in] length codestream length
* @return structure of generated codestream parameters
*/
codestream_param_t set_codestream( int fd, Byte8_t offset, Byte8_t length);
/**
* fetch Codestream bytes of data in file stream
*
* @param[in] cs codestream pointer
* @param[in] offset start Byte position in codestream
* @param[in] size Byte length
* @return pointer to the fetched data
*/
Byte_t * fetch_codestreambytes( codestream_param_t *cs, long offset, int size);
/**
* fetch Codestream 1-byte Byte code in file stream
*
* @param[in] cs codestream pointer
* @param[in] offset start Byte position in codestream
* @return fetched code
*/
Byte_t fetch_codestream1byte( codestream_param_t *cs, long offset);
/**
* fetch Codestream 2-byte big endian Byte codes in file stream
*
* @param[in] cs codestream pointer
* @param[in] offset start Byte position in codestream
* @return fetched code
*/
Byte2_t fetch_codestream2bytebigendian( codestream_param_t *cs, long offset);
/**
* fetch Codestream 4-byte big endian Byte codes in file stream
*
* @param[in] cs codestream pointer
* @param[in] offset start Byte position in codestream
* @return fetched code
*/
Byte4_t fetch_codestream4bytebigendian( codestream_param_t *cs, long offset);
/**
* print codestream parameters
*
* @param[in] cs codestream
*/
void print_codestream( codestream_param_t cs);
#endif /* !CODESTREAM_MANAGER_H_ */

View File

@ -0,0 +1,17 @@
ifdef jpipserver
CFLAGS = -O3 -Wall -std=c99 -pedantic -m32 -DSERVER
LIBNAME = libopenjpip_server.a
else
CFLAGS = -O3 -Wall -std=c99 -pedantic
LIBNAME = libopenjpip_local.a
endif
all: $(LIBNAME)
$(LIBNAME): target_manager.o byte_manager.o box_manager.o boxheader_manager.o manfbox_manager.o \
mhixbox_manager.o marker_manager.o codestream_manager.o faixbox_manager.o index_manager.o \
msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o
ar r $@ $^
clean:
rm -f $(LIBNAME) *.o *~

View File

@ -0,0 +1,189 @@
/*
* $Id: faixbox_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 <stdlib.h>
#include "faixbox_manager.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
faixbox_param_t * gene_faixbox( box_param_t *box)
{
faixbox_param_t *faix;
size_t numOfelem;
long pos = 0;
faix = ( faixbox_param_t *)malloc( sizeof(faixbox_param_t));
faix->version = fetch_DBox1byte( box, (pos+=1)-1);
if( faix->version < 0 || 3< faix->version){
fprintf( FCGI_stderr, "Error: version %d in faix box is reserved for ISO use.\n", faix->version);
free(faix);
return NULL;
}
if( faix->version%2){
subfaixbox8_param_t *subfaixbox;
faix->subfaixbox.byte8_params = (subfaixbox8_param_t *)malloc( sizeof(subfaixbox8_param_t));
subfaixbox = faix->subfaixbox.byte8_params;
subfaixbox->nmax = fetch_DBox8bytebigendian( box, (pos+=8)-8);
subfaixbox->m = fetch_DBox8bytebigendian( box, (pos+=8)-8);
numOfelem = subfaixbox->nmax*subfaixbox->m;
subfaixbox->elem = ( faixelem8_param_t *)malloc( numOfelem*sizeof(faixelem8_param_t));
if( faix->version == 3)
subfaixbox->aux = ( Byte4_t *)malloc( numOfelem*sizeof(Byte4_t));
for( int i=0; i<numOfelem; i++){
subfaixbox->elem[i].off = fetch_DBox8bytebigendian( box, (pos+=8)-8);
subfaixbox->elem[i].len = fetch_DBox8bytebigendian( box, (pos+=8)-8);
if( faix->version == 3)
subfaixbox->aux[i] = fetch_DBox4bytebigendian( box, (pos+=4)-4);
}
}
else{
subfaixbox4_param_t *subfaixbox;
faix->subfaixbox.byte4_params = (subfaixbox4_param_t *)malloc( sizeof(subfaixbox4_param_t));
subfaixbox = faix->subfaixbox.byte4_params;
subfaixbox->nmax = fetch_DBox4bytebigendian( box, (pos+=4)-4);
subfaixbox->m = fetch_DBox4bytebigendian( box, (pos+=4)-4);
numOfelem = subfaixbox->nmax*subfaixbox->m;
subfaixbox->elem = ( faixelem4_param_t *)malloc( numOfelem*sizeof(faixelem4_param_t));
if( faix->version == 2)
subfaixbox->aux = ( Byte4_t *)malloc( numOfelem*sizeof(Byte4_t));
for( int i=0; i<numOfelem; i++){
subfaixbox->elem[i].off = fetch_DBox4bytebigendian( box, (pos+=4)-4);
subfaixbox->elem[i].len = fetch_DBox4bytebigendian( box, (pos+=4)-4);
if( faix->version == 2)
subfaixbox->aux[i] = fetch_DBox4bytebigendian( box, (pos+=4)-4);
}
}
return faix;
}
void print_faixbox( faixbox_param_t *faix)
{
fprintf( logstream, "faix box info\n");
fprintf( logstream, "\tversion: %d\n", faix->version);
fprintf( logstream, "\t nmax: %#llx = %lld\n", get_nmax( faix), get_nmax( faix));
fprintf( logstream, "\t m: %#llx = %lld\n", get_m( faix), get_m( faix));
for( Byte8_t i=0; i<get_m( faix); i++){
for( Byte8_t j=0; j<get_nmax( faix); j++){
fprintf( logstream, "\t off = %#llx, len = %#llx", get_elemOff( faix, j, i), get_elemLen( faix, j, i));
if( 2 <= faix->version)
fprintf( logstream, ", aux = %#x", get_elemAux( faix, j, i));
fprintf( logstream, "\n");
}
fprintf( logstream, "\n");
}
}
void delete_faixbox( faixbox_param_t **faix)
{
if((*faix)->version%2){
free((*faix)->subfaixbox.byte8_params->elem);
if( (*faix)->version == 3)
free((*faix)->subfaixbox.byte8_params->aux);
free((*faix)->subfaixbox.byte8_params);
}
else{
free((*faix)->subfaixbox.byte4_params->elem);
if( (*faix)->version == 2)
free((*faix)->subfaixbox.byte4_params->aux);
free((*faix)->subfaixbox.byte4_params);
}
free( *faix);
}
Byte8_t get_nmax( faixbox_param_t *faix)
{
if( faix->version%2)
return faix->subfaixbox.byte8_params->nmax;
else
return (Byte8_t)faix->subfaixbox.byte4_params->nmax;
}
Byte8_t get_m( faixbox_param_t *faix)
{
if( faix->version%2)
return faix->subfaixbox.byte8_params->m;
else
return (Byte8_t)faix->subfaixbox.byte4_params->m;
}
Byte8_t get_elemOff( faixbox_param_t *faix, Byte8_t elem_id, Byte8_t row_id)
{
Byte8_t nmax = get_nmax( faix);
if( faix->version%2)
return faix->subfaixbox.byte8_params->elem[ row_id*nmax+elem_id].off;
else
return (Byte8_t)faix->subfaixbox.byte4_params->elem[ row_id*nmax+elem_id].off;
}
Byte8_t get_elemLen( faixbox_param_t *faix, Byte8_t elem_id, Byte8_t row_id)
{
Byte8_t nmax = get_nmax( faix);
if( faix->version%2)
return faix->subfaixbox.byte8_params->elem[ row_id*nmax+elem_id].len;
else
return (Byte8_t)faix->subfaixbox.byte4_params->elem[ row_id*nmax+elem_id].len;
}
Byte4_t get_elemAux( faixbox_param_t *faix, Byte8_t elem_id, Byte8_t row_id)
{
if( faix->version <2)
return -1;
Byte8_t nmax = get_nmax( faix);
if( faix->version%2)
return faix->subfaixbox.byte8_params->aux[ row_id*nmax+elem_id];
else
return faix->subfaixbox.byte4_params->aux[ row_id*nmax+elem_id];
}

View File

@ -0,0 +1,146 @@
/*
* $Id: faixbox_manager.h 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.
*/
#ifndef FAIXBOX_MANAGER_H_
# define FAIXBOX_MANAGER_H_
#include "byte_manager.h"
#include "box_manager.h"
//! 4byte parameters of a faix element
typedef struct faixelem4_param{
Byte4_t off; //!< offset
Byte4_t len; //!< length
} faixelem4_param_t;
//! 8byte parameters of a faix element
typedef struct faixelem8_param{
Byte8_t off; //!< offset
Byte8_t len; //!< length
} faixelem8_param_t;
//! 4byte parameters of fragment array index box
typedef struct subfaixbox4_param{
Byte4_t nmax; //!< maximum number of valid elements in any row of the array
Byte4_t m; //!< number of raws of the array
faixelem4_param_t *elem; //!< dynamic array pointer of faix elements
Byte4_t *aux; //!< dynamic array pointer of auxiliary
//!info in each element for version 2 or 3
} subfaixbox4_param_t;
//! 8byte parameters of fragment array index box
typedef struct subfaixbox8_param{
Byte8_t nmax; //!< maximum number of valid elements in any row of the array
Byte8_t m; //!< number of raws of the array
faixelem8_param_t *elem; //!< dynamic array pointer of faix elements
Byte4_t *aux; //!< dynamic array pointer of auxiliary
//!info in each element for version 2 or 3
} subfaixbox8_param_t;
//! variable sized parameters in fragment array index box
typedef union subfaixbox_param{
subfaixbox4_param_t *byte4_params; //!< parameters with 4byte codes for version 0 or 2
subfaixbox8_param_t *byte8_params; //!< parameters with 8byte codes for version 1 or 3
} subfaixbox_param_t;
//! fragment array index box parameters
//! I.3.2.4.2 Fragment Array Index box
typedef struct faixbox_param{
Byte_t version; //!< Refer to the Table I.3 - Version values
subfaixbox_param_t subfaixbox; //!< rest information in faixbox
} faixbox_param_t;
/**
* generate faix box
*
* @param[in] box pointer to the reference faix_box
* @return generated faixbox
*/
faixbox_param_t * gene_faixbox( box_param_t *box);
/**
* print faix box parameters
*
* @param[in] faix faix box pointer
*/
void print_faixbox( faixbox_param_t *faix);
/**
* delete faix box
*
* @param[in,out] faix addressof the faixbox pointer
*/
void delete_faixbox( faixbox_param_t **faix);
/**
* get nmax parameter value from faix box
*
* @param[in] faix faix box pointer
*/
Byte8_t get_nmax( faixbox_param_t *faix);
/**
* get m parameter value from faix box
*
* @param[in] faix faix box pointer
*/
Byte8_t get_m( faixbox_param_t *faix);
/**
* get offset of a element from faix box
*
* @param[in] faix faix box pointer
* @param[in] elem_id element id in a row (0<= <nmax)
* @param[in] row_id row id (0<= <m)
*/
Byte8_t get_elemOff( faixbox_param_t *faix, Byte8_t elem_id, Byte8_t row_id);
/**
* get length of a element from faix box
*
* @param[in] faix faix box pointer
* @param[in] elem_id element id in a row (0<= <nmax)
* @param[in] row_id row id (0<= <m)
*/
Byte8_t get_elemLen( faixbox_param_t *faix, Byte8_t elem_id, Byte8_t row_id);
/**
* get aux of a element from faix box
*
* @param[in] faix faix box pointer
* @param[in] elem_id element id in a row (0<= <nmax)
* @param[in] row_id row id (0<= <m)
*/
Byte4_t get_elemAux( faixbox_param_t *faix, Byte8_t elem_id, Byte8_t row_id);
#endif /* !FAIXBOX_MANAGER_H_ */

View File

@ -0,0 +1,74 @@
/*
* $Id: ihdrbox_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 <stdlib.h>
#include "ihdrbox_manager.h"
ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptstream)
{
ihdrbox_param_t *ihdrbox;
metadata_param_t *meta;
box_param_t *jp2h, *ihdr;
jp2h = NULL;
meta = metadatalist->first;
while( meta){
if( meta->boxlist){
jp2h = search_box( "jp2h", meta->boxlist);
if( jp2h)
break;
}
meta = meta->next;
}
if( !jp2h){
fprintf( stderr, "jp2h box not found\n");
return NULL;
}
ihdr = gene_boxbyTypeinStream( jptstream, get_DBoxoff( jp2h), get_DBoxlen( jp2h), "ihdr");
if( !ihdr){
fprintf( stderr, "ihdr box not found\n");
return NULL;
}
ihdrbox = (ihdrbox_param_t *)malloc( sizeof(ihdrbox_param_t));
ihdrbox->height = big4( jptstream+get_DBoxoff(ihdr));
ihdrbox->width = big4( jptstream+get_DBoxoff(ihdr)+4);
ihdrbox->nc = big2( jptstream+get_DBoxoff(ihdr)+8);
ihdrbox->bpc = *(jptstream+get_DBoxoff(ihdr)+10)+1;
free( ihdr);
return ihdrbox;
}

View File

@ -0,0 +1,48 @@
/*
* $Id: ihdrbox_manager.h 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.
*/
#ifndef IHDRBOX_MANAGER_H_
# define IHDRBOX_MANAGER_H_
#include "byte_manager.h"
#include "box_manager.h"
#include "metadata_manager.h"
typedef struct ihdrbox_param{
Byte4_t height;
Byte4_t width;
Byte2_t nc;
Byte_t bpc;
} ihdrbox_param_t;
ihdrbox_param_t * get_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jptstream);
#endif /* !IHDRBOX_MANAGER_H_ */

View File

@ -0,0 +1,133 @@
/*
* $Id: imgreg_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 <math.h>
#include <stdlib.h>
#include "imgreg_manager.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
imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
const int rx, const int ry,
const int rw, const int rh,
const int XOsiz, const int YOsiz,
const int Xsiz, const int Ysiz,
const int numOfdecomp)
{
imgreg_param_t imgreg;
int px,py;
int xmax, ymax;
imgreg.xosiz = XOsiz;
imgreg.yosiz = YOsiz;
imgreg.fx = fx;
imgreg.fy = fy;
imgreg.level = 0;
xmax = Xsiz;
ymax = Ysiz;
find_level( numOfdecomp, &imgreg.level, &imgreg.fx, &imgreg.fy, &imgreg.xosiz, &imgreg.yosiz, &xmax, &ymax);
if( rx == -1 || ry == -1){
imgreg.ox = 0;
imgreg.oy = 0;
}
else{
imgreg.ox = rx*imgreg.fx/fx;
imgreg.oy = ry*imgreg.fy/fy;
}
if( rw == -1 || rh == -1){
imgreg.sx = imgreg.fx;
imgreg.sy = imgreg.fy;
}
else{
px = ceil((double)((rx+rw)*imgreg.fx)/(double)fx);
py = ceil((double)((ry+rh)*imgreg.fy)/(double)fy);
imgreg.sx = px - imgreg.ox;
imgreg.sy = py - imgreg.oy;
}
if( fx != imgreg.fx || fy != imgreg.fy)
fprintf( FCGI_stdout, "JPIP-fsiz: %d,%d\r\n", imgreg.fx, imgreg.fy);
if( rw != imgreg.sx || rh != imgreg.sy)
fprintf( FCGI_stdout, "JPIP-rsiz: %d,%d\r\n", imgreg.sx, imgreg.sy);
if( rx != imgreg.ox || ry != imgreg.oy)
fprintf( FCGI_stdout, "JPIP-roff: %d,%d\r\n", imgreg.ox, imgreg.oy);
return imgreg;
}
void find_level( int maxlev, int *lev, int *fx, int *fy, int *xmin, int *ymin, int *xmax, int *ymax)
{
int xwidth = *xmax - *xmin;
int ywidth = *ymax - *ymin;
/// Find smaller frame size for now (i.e. assume "round-down").
if ((*fx < 1 && xwidth != 0) || (*fy < 1 && ywidth != 0)){
fprintf( FCGI_stderr, "Frame size must be strictly positive");
exit(-1);
}
else if( *lev < maxlev-1 && ( *fx < xwidth || *fy < ywidth)) {
// Simulate the ceil function.
*xmin = ceil((double)*xmin/(double)2.0);
*ymin = ceil((double)*ymin/(double)2.0);
*xmax = ceil((double)*xmax/(double)2.0);
*ymax = ceil((double)*ymax/(double)2.0);
(*lev) ++;
find_level ( maxlev, lev, fx, fy, xmin, ymin, xmax, ymax);
} else {
*fx = xwidth;
*fy = ywidth;
}
}
void print_imgreg( imgreg_param_t imgreg)
{
#ifndef SERVER
fprintf( logstream, "codestream image region:\n");
fprintf( logstream, "\t fsiz: %d, %d\n", imgreg.fx, imgreg.fy);
fprintf( logstream, "\t roff: %d, %d\n", imgreg.ox, imgreg.oy);
fprintf( logstream, "\t rsiz: %d, %d\n", imgreg.sx, imgreg.sy);
fprintf( logstream, "\t level: %d\n", imgreg.level);
#endif
}

View File

@ -0,0 +1,89 @@
/*
* $Id: imgreg_manager.h 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.
*/
#ifndef IMGREG_MANAGER_H_
# define IMGREG_MANAGER_H_
//! image region parameters
typedef struct imgreg_param{
int xosiz, yosiz; //!< offset from the origin of the reference grid
//!at the decomposition level
int fx, fy; //!< frame size (fsiz)
int ox, oy; //!< offset (roff)
int sx, sy; //!< region size (rsiz)
int level; //!< decomposition level
} imgreg_param_t;
/**
* map view-window requests to codestream image resolutions and regions
*
* @param[in] fx,fy frame size
* @param[in] rx,ry offset of region
* @param[in] rw,rh size of region
* @param[in] XOsiz,YOsiz offset from the origin of the reference grid to the left side of the image area
* @param[in] Xsiz,Ysiz size of the reference grid
* @param[in] numOfdecomp number of decomposition levels
* @return structure of image region parameters
*/
imgreg_param_t map_viewin2imgreg( const int fx, const int fy,
const int rx, const int ry,
const int rw, const int rh,
const int XOsiz, const int YOsiz,
const int Xsiz, const int Ysiz,
const int numOfdecomp);
/**
* find deconposition level and its resolution size
* C.4.1 Mapping view-window requests to codestream image resolution
* and regions
* Note: only round-down implemented
*
* @param[in] maxlev maximum decomposition level
* @param[in/out] lev decomposition level pointer
* @param[in/out] fx horizontal frame size pointer
* @param[in/out] fy vertical frame size pointer
* @param[in/out] xmin horizontal image offset pointer
* @param[in/out] ymin vertical image offset pointer
* @param[in/out] xmax horizontal image size pointer
* @param[in/out] ymax vertical image size pointer
*/
void find_level( int maxlev, int *lev, int *fx, int *fy, int *xmin, int *ymin, int *xmax, int *ymax);
/**
* print image region parameters
*
* @param[in] imgreg image region structure of parameters
*/
void print_imgreg( imgreg_param_t imgreg);
#endif /* !IMGREG_MANAGER_H_ */

View File

@ -0,0 +1,524 @@
/*
* $Id: index_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 <stdbool.h>
#include <stdlib.h>
#include <strings.h>
#include <math.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include "index_manager.h"
#include "box_manager.h"
#include "manfbox_manager.h"
#include "mhixbox_manager.h"
#include "codestream_manager.h"
#include "marker_manager.h"
#include "faixbox_manager.h"
#include "boxheader_manager.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
/**
* chekc JP2 box indexing
*
* @param[in] toplev_boxlist top level box list
* @return if correct (true) or wrong (false)
*/
bool check_JP2boxidx( boxlist_param_t *toplev_boxlist);
/**
* set code index parameters (parse cidx box)
* Annex I
*
* @param[in] cidx_box pointer to the reference cidx_box
* @param[out] codeidx pointer to index parameters
* @return if succeeded (true) or failed (false)
*/
bool set_cidxdata( box_param_t *cidx_box, index_param_t *codeidx);
index_param_t * parse_jp2file( int fd)
{
index_param_t *jp2idx;
box_param_t *cidx;
metadatalist_param_t *metadatalist;
boxlist_param_t *toplev_boxlist;
struct stat sb;
if( fstat( fd, &sb) == -1){
fprintf( FCGI_stdout, "Reason: Target broken (fstat error)\r\n");
return NULL;
}
if( !(toplev_boxlist = get_boxstructure( fd, 0, sb.st_size))){
fprintf( FCGI_stderr, "Error: Not correctl JP2 format\n");
return NULL;
}
if( !check_JP2boxidx( toplev_boxlist)){
fprintf( FCGI_stderr, "Index format not supported\n");
delete_boxlist( &toplev_boxlist);
return NULL;
}
if( !(cidx = search_box( "cidx", toplev_boxlist))){
fprintf( FCGI_stderr, "Box cidx not found\n");
delete_boxlist( &toplev_boxlist);
return NULL;
}
jp2idx = (index_param_t *)malloc( sizeof(index_param_t));
if( !set_cidxdata( cidx, jp2idx)){
fprintf( FCGI_stderr, "Error: Not correctl format in cidx box\n");
free(jp2idx);
delete_boxlist( &toplev_boxlist);
return NULL;
}
delete_boxlist( &toplev_boxlist);
metadatalist = const_metadatalist( fd);
jp2idx->metadatalist = metadatalist;
#ifndef SERVER
fprintf( logstream, "local log: code index created\n");
#endif
return jp2idx;
}
void print_index( index_param_t index)
{
fprintf( logstream, "index info:\n");
fprintf( logstream, "\tCodestream Offset: %#llx\n", index.offset);
fprintf( logstream, "\t Length: %#llx\n", index.length);
fprintf( logstream, "\tMain header Length: %#llx\n", index.mhead_length);
fprintf( logstream, "\t Rsiz: %#x\n", index.Rsiz);
fprintf( logstream, "\t Xsiz, Ysiz: (%d,%d) = (%#x, %#x)\n", index.Xsiz, index.Ysiz, index.Xsiz, index.Ysiz);
fprintf( logstream, "\t XOsiz, YOsiz: (%d,%d) = (%#x, %#x)\n", index.XOsiz, index.YOsiz, index.XOsiz, index.YOsiz);
fprintf( logstream, "\t XTsiz, YTsiz: (%d,%d) = (%#x, %#x)\n", index.XTsiz, index.YTsiz, index.XTsiz, index.YTsiz);
fprintf( logstream, "\t XTOsiz, YTOsiz: (%d,%d) = (%#x, %#x)\n", index.XTOsiz, index.YTOsiz, index.XTOsiz, index.YTOsiz);
fprintf( logstream, "\t XTnum, YTnum: (%d,%d)\n", index.XTnum, index.YTnum);
fprintf( logstream, "\t Num of Components: %d\n", index.Csiz);
for( int i=0; i<index.Csiz; i++)
fprintf( logstream, "\t[%d] (Ssiz, XRsiz, YRsiz): (%d, %d, %d) = (%#x, %#x, %#x)\n", i, index.Ssiz[i], index.XRsiz[i], index.YRsiz[i], index.Ssiz[i], index.XRsiz[i], index.YRsiz[i]);
print_faixbox( index.tilepart);
print_allmetadata( index.metadatalist);
}
void print_cachemodel( index_param_t index)
{
Byte8_t TPnum; // num of tile parts in each tile
TPnum = get_nmax( index.tilepart);
fprintf( logstream, "\t main header model: %d\n", index.mhead_model);
fprintf( logstream, "\t tile part model:\n");
for( int i=0, n=0; i<index.YTnum; i++){
for( int j=0; j<index.XTnum; j++){
for( int k=0; k<TPnum; k++)
fprintf( logstream, "%d", index.tp_model[n++]);
fprintf( logstream, " ");
}
fprintf( logstream, "\n");
}
}
void delete_index( index_param_t **index)
{
delete_metadatalist( &((*index)->metadatalist));
delete_faixbox( &((*index)->tilepart));
free( (*index)->tp_model);
free(*index);
}
bool check_JP2boxidx( boxlist_param_t *toplev_boxlist)
{
box_param_t *iptr, *fidx, *prxy;
box_param_t *cidx, *jp2c;
iptr = search_box( "iptr", toplev_boxlist);
fidx = search_box( "fidx", toplev_boxlist);
cidx = search_box( "cidx", toplev_boxlist);
jp2c = search_box( "jp2c", toplev_boxlist);
prxy = gene_childboxbyType( fidx, 0, "prxy");
Byte8_t off = fetch_DBox8bytebigendian( iptr, 0);
if( off != fidx->offset)
fprintf( FCGI_stderr, "Reference File Index box offset in Index Finder box not correct\n");
Byte8_t len = fetch_DBox8bytebigendian( iptr, 8);
if( len != fidx->length)
fprintf( FCGI_stderr, "Reference File Index box length in Index Finder box not correct\n");
int pos = 0;
Byte8_t ooff = fetch_DBox8bytebigendian( prxy, pos);
if( ooff != jp2c->offset)
fprintf( FCGI_stderr, "Reference jp2c offset in prxy box not correct\n");
pos += 8;
boxheader_param_t *obh = gene_childboxheader( prxy, pos);
if( obh->length != jp2c->length || strncmp( obh->type, "jp2c",4)!=0)
fprintf( FCGI_stderr, "Reference jp2c header in prxy box not correct\n");
pos += obh->headlen;
free(obh);
Byte_t ni = fetch_DBox1byte( prxy, pos);
if( ni != 1){
fprintf( FCGI_stderr, "Multiple indexes not supported\n");
return false;
}
pos += 1;
Byte8_t ioff = fetch_DBox8bytebigendian( prxy, pos);
if( ioff != cidx->offset)
fprintf( FCGI_stderr, "Reference cidx offset in prxy box not correct\n");
pos += 8;
boxheader_param_t *ibh = gene_childboxheader( prxy, pos);
if( ibh->length != cidx->length || strncmp( ibh->type, "cidx",4)!=0)
fprintf( FCGI_stderr, "Reference cidx header in prxy box not correct\n");
pos += ibh->headlen;
free(ibh);
free(prxy);
return true;
}
/**
* set code index parameters from cptr box
* I.3.2.2 Codestream Finder box
*
* @param[in] cidx_box pointer to the reference cidx_box
* @param[out] jp2idx pointer to index parameters
* @return if succeeded (true) or failed (false)
*/
bool set_cptrdata( box_param_t *cidx_box, index_param_t *jp2idx);
/**
* set code index parameters from mhix box for main header
* I.3.2.4.3 Header Index Table box
*
* @param[in] cidx_box pointer to the reference cidx_box
* @param[in] codestream codestream parameters
* @param[out] jp2idx pointer to index parameters
* @return if succeeded (true) or failed (false)
*/
bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, index_param_t *jp2idx);
/**
* set code index parameters from tpix box
* I.3.2.4.4 Tile-part Index Table box
*
* @param[in] cidx_box pointer to the reference cidx_box
* @param[out] jp2idx pointer to index parameters
* @return if succeeded (true) or failed (false)
*/
bool set_tpixdata( box_param_t *cidx_box, index_param_t *jp2idx);
/**
* set code index parameters from thix box
* I.3.2.4.5 Tile Header Index Table box
*
* @param[in] cidx_box pointer to the reference cidx_box
* @param[out] jp2idx pointer to index parameters
* @return if succeeded (true) or failed (false)
*/
bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx);
bool set_cidxdata( box_param_t *cidx_box, index_param_t *jp2idx)
{
box_param_t *manf_box;
manfbox_param_t *manf;
codestream_param_t codestream;
set_cptrdata( cidx_box, jp2idx);
codestream = set_codestream( cidx_box->fd, jp2idx->offset, jp2idx->length);
manf_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "manf");
manf = gene_manfbox( manf_box);
if( !search_boxheader( "mhix", manf)){
fprintf( FCGI_stderr, "Error: mhix box not present in manfbox\n");
free(jp2idx);
return false;
}
set_mainmhixdata( cidx_box, codestream, jp2idx);
if( !search_boxheader( "tpix", manf)){
fprintf( FCGI_stderr, "Error: tpix box not present in manfbox\n");
free(jp2idx);
return false;
}
set_tpixdata( cidx_box, jp2idx);
#ifdef NO_NEED_YET
if( !search_boxheader( "thix", manf)){
fprintf( FCGI_stderr, "Error: thix box not present in manfbox\n");
return false;
}
set_thixdata( cidx_box, jp2idx);
#endif
delete_manfbox( &manf);
free( manf_box);
return true;
}
bool set_cptrdata( box_param_t *cidx_box, index_param_t *jp2idx)
{
box_param_t *box; //!< cptr box
Byte2_t dr, cont;
if( !(box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "cptr")))
return false;
// DR: Data Reference.
// If 0, the codestream or its Fragment Table box exists in the current file
if(( dr = fetch_DBox2bytebigendian( box, 0))){
fprintf( FCGI_stderr, "Error: Codestream not present in current file\n");
free( box);
return false;
}
// CONT: Container Type
// If 0, the entire codestream appears as a contiguous range of
// bytes within its file or resource.
if(( cont = fetch_DBox2bytebigendian( box, 2))){
fprintf( FCGI_stderr, "Error: Can't cope with fragmented codestreams yet\n");
free( box);
return false;
}
jp2idx->offset = fetch_DBox8bytebigendian( box, 4);
jp2idx->length = fetch_DBox8bytebigendian( box, 12);
free( box);
return true;
}
/**
* set code index parameters from SIZ marker in codestream
* A.5 Fixed information marker segment
* A.5.1 Image and tile size (SIZ)
*
* @param[in] sizmkidx pointer to SIZ marker index in mhix box
* @param[in] codestream codestream parameters
* @param[out] jp2idx pointer to index parameters
* @return if succeeded (true) or failed (false)
*/
bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, index_param_t *jp2idx);
bool set_mainmhixdata( box_param_t *cidx_box, codestream_param_t codestream, index_param_t *jp2idx)
{
box_param_t *mhix_box;
mhixbox_param_t *mhix;
markeridx_param_t *sizmkidx;
if( !(mhix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "mhix")))
return false;
jp2idx->mhead_model = 0;
jp2idx->mhead_length = fetch_DBox8bytebigendian( mhix_box, 0);
mhix = gene_mhixbox( mhix_box);
free( mhix_box);
sizmkidx = search_markeridx( 0xff51, mhix);
set_SIZmkrdata( sizmkidx, codestream, jp2idx);
delete_mhixbox( &mhix);
return true;
}
bool set_tpixdata( box_param_t *cidx_box, index_param_t *jp2idx)
{
box_param_t *tpix_box; //!< tpix box
box_param_t *faix_box; //!< faix box
faixbox_param_t *faix; //!< faix
size_t numOfelem;
if( !(tpix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "tpix")))
return false;
if( !(faix_box = gene_boxbyType( tpix_box->fd, get_DBoxoff( tpix_box), get_DBoxlen( tpix_box), "faix")))
return false;
faix = gene_faixbox( faix_box);
jp2idx->tilepart = faix;
numOfelem = get_nmax( faix)*get_m( faix);
jp2idx->tp_model = (bool *)malloc( numOfelem*sizeof(bool));
bzero( jp2idx->tp_model, numOfelem*sizeof(bool));
//delete_faixbox( &faix); // currently the jp2idx element
free( tpix_box);
free( faix_box);
return true;
}
bool set_thixdata( box_param_t *cidx_box, index_param_t *jp2idx)
{
box_param_t *thix_box, *manf_box, *mhix_box;
manfbox_param_t *manf;
boxheader_param_t *ptr;
mhixbox_param_t *mhix;
Byte8_t pos, mhixseqoff;
if( !(thix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "thix")))
return false;
if( !(manf_box = gene_boxbyType( thix_box->fd, get_DBoxoff( thix_box), get_DBoxlen( thix_box), "manf"))){
free( thix_box);
return false;
}
manf = gene_manfbox( manf_box);
ptr = manf->first;
mhixseqoff = manf_box->offset+manf_box->length;
pos = 0;
while( ptr){
mhix_box = gene_boxbyType( thix_box->fd, mhixseqoff+pos, get_DBoxlen( thix_box)-manf_box->length-pos, "mhix");
mhix = gene_mhixbox( mhix_box);
pos += mhix_box->length;
ptr = ptr->next;
free( mhix_box);
delete_mhixbox( &mhix);
}
delete_manfbox( &manf);
free( manf_box);
free( thix_box);
return true;
}
bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, index_param_t *jp2idx)
{
marker_param_t sizmkr;
sizmkr = set_marker( codestream, sizmkidx->code, sizmkidx->offset, sizmkidx->length);
if( sizmkidx->length != fetch_marker2bytebigendian( sizmkr, 0)){
fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", sizmkidx->code);
return false;
}
jp2idx->Rsiz = fetch_marker2bytebigendian( sizmkr, 2);
jp2idx->Xsiz = fetch_marker4bytebigendian( sizmkr, 4);
jp2idx->Ysiz = fetch_marker4bytebigendian( sizmkr, 8);
jp2idx->XOsiz = fetch_marker4bytebigendian( sizmkr, 12);
jp2idx->YOsiz = fetch_marker4bytebigendian( sizmkr, 16);
jp2idx->XTsiz = fetch_marker4bytebigendian( sizmkr, 20);
jp2idx->YTsiz = fetch_marker4bytebigendian( sizmkr, 24);
jp2idx->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28);
jp2idx->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32);
jp2idx->Csiz = fetch_marker2bytebigendian( sizmkr, 36);
jp2idx->XTnum = ( jp2idx->Xsiz-jp2idx->XTOsiz+jp2idx->XTsiz-1)/jp2idx->XTsiz;
jp2idx->YTnum = ( jp2idx->Ysiz-jp2idx->YTOsiz+jp2idx->YTsiz-1)/jp2idx->YTsiz;
for( int i=0; i<(int)jp2idx->Csiz; i++){
jp2idx->Ssiz[i] = fetch_marker1byte( sizmkr, 38+i*3);
jp2idx->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3);
jp2idx->YRsiz[i] = fetch_marker1byte( sizmkr, 40+i*3);
}
return true;
}
Byte4_t max( Byte4_t n1, Byte4_t n2);
Byte4_t min( Byte4_t n1, Byte4_t n2);
range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_id, int level);
range_param_t get_tile_Xrange( index_param_t index, Byte4_t tile_xid, int level)
{
return get_tile_range( index.XOsiz, index.Xsiz, index.XTOsiz, index.XTsiz, tile_xid, level);
}
range_param_t get_tile_Yrange( index_param_t index, Byte4_t tile_yid, int level)
{
return get_tile_range( index.YOsiz, index.Ysiz, index.YTOsiz, index.YTsiz, tile_yid, level);
}
range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_id, int level)
{
range_param_t range;
range.minvalue = max( Osiz, TOsiz+tile_id*Tsiz);
range.maxvalue = min( siz, TOsiz+(tile_id+1)*Tsiz);
for( int n=0; n<level; n++){
range.minvalue = ceil(range.minvalue/2.0);
range.maxvalue = ceil(range.maxvalue/2.0);
}
return range;
}
Byte4_t max( Byte4_t n1, Byte4_t n2)
{
if( n1 < n2)
return n2;
else
return n1;
}
Byte4_t min( Byte4_t n1, Byte4_t n2)
{
if( n1 < n2)
return n1;
else
return n2;
}

View File

@ -0,0 +1,139 @@
/*
* $Id: index_manager.h 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.
*/
#ifndef INDEX_MANAGER_H_
# define INDEX_MANAGER_H_
#include <stdio.h>
#include <stdbool.h>
#include "byte_manager.h"
#include "faixbox_manager.h"
#include "metadata_manager.h"
//! index parameters
typedef struct index_param{
metadatalist_param_t *metadatalist; //!< metadata-bin list
Byte8_t offset; //!< codestream offset
Byte8_t length; //!< codestream length
Byte8_t mhead_length; //!< main header length
//! A.5.1 Image and tile size (SIZ)
Byte2_t Rsiz; //!< capabilities that a decoder needs
Byte4_t Xsiz; //!< width of the reference grid
Byte4_t Ysiz; //!< height of the reference grid
Byte4_t XOsiz; //!< horizontal offset from the origin of
//!the reference grid to the left side of the image area
Byte4_t YOsiz; //!< vertical offset from the origin of
//!the reference grid to the top side of the image area
Byte4_t XTsiz; //!< width of one reference tile with
//!respect to the reference grid
Byte4_t YTsiz; //!< height of one reference tile with
//!respect to the reference grid
Byte4_t XTOsiz; //!< horizontal offset from the origin of
//!the reference grid to the left side of the first tile
Byte4_t YTOsiz; //!< vertical offset from the origin of
//!the reference grid to the top side of
//!the first tile
Byte4_t XTnum; //!< number of tiles in horizontal direction
Byte4_t YTnum; //!< number of tiles in vertical
//!direction
Byte2_t Csiz; //!< number of the components in the image
Byte_t Ssiz[3]; //!< precision (depth) in bits and sign
//!of the component samples
Byte_t XRsiz[3]; //!< horizontal separation of a sample of
//!component with respect to the reference grid
Byte_t YRsiz[3]; //!< vertical separation of a sample of
//!component with respect to the reference grid
faixbox_param_t *tilepart; //!< tile part information from tpix box
bool mhead_model; //!< main header model, if sent, 1, else 0
bool *tp_model; //!< dynamic array pointer of tile part
//!model, if sent, 1, else 0
} index_param_t;
/**
* parse JP2 file
* AnnexI: Indexing JPEG2000 files for JPIP
*
* @param[in] fd file descriptor of the JP2 file
* @return pointer to the generated structure of index parameters
*/
index_param_t * parse_jp2file( int fd);
/**
* print index parameters
*
* @param[in] index index parameters
*/
void print_index( index_param_t index);
/**
* print cache model
*
* @param[in] index index parameters
*/
void print_cachemodel( index_param_t index);
/**
* delete index
*
* @param[in,out] index addressof the index pointer
*/
void delete_index( index_param_t **index);
//! 1-dimensional range parameters
typedef struct range_param{
Byte4_t minvalue; //!< minimal value
Byte4_t maxvalue; //!< maximal value
} range_param_t;
/**
* get horizontal range of the tile in reference grid
*
* @param[in] index index parameters
* @param[in] tile_xid tile id in x-direction (0<= <XTnum)
* @param[in] level decomposition level
* @return structured range parameter
*/
range_param_t get_tile_Xrange( index_param_t index, Byte4_t tile_xid, int level);
/**
* get vertical range of the tile in reference grid
*
* @param[in] index index parameters
* @param[in] tile_yid tile id in y-direction (0<= <YTnum)
* @param[in] level decomposition level
* @return structured range parameter
*/
range_param_t get_tile_Yrange( index_param_t index, Byte4_t tile_yid, int level);
#endif /* !INDEX_MANAGER_H_ */

View File

@ -0,0 +1,115 @@
/*
* $Id: manfbox_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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "manfbox_manager.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
manfbox_param_t * gene_manfbox( box_param_t *box)
{
manfbox_param_t *manf; // manifest parameters
boxheader_param_t *bh; // current box pointer
boxheader_param_t *last; // last boxheader pointer of the list
int pos; // current position in manf_box contents;
manf = ( manfbox_param_t *)malloc( sizeof( manfbox_param_t));
pos = 0;
manf->first = last = NULL;
while( pos < get_DBoxlen( box)){
bh = gene_childboxheader( box, pos);
pos += bh->headlen;
// insert into the list
if( manf->first)
last->next = bh;
else
manf->first = bh;
last = bh;
}
return manf;
}
void delete_manfbox( manfbox_param_t **manf)
{
boxheader_param_t *bhPtr, *bhNext;
bhPtr = (*manf)->first;
while( bhPtr != NULL){
bhNext=bhPtr->next;
#ifndef SERVER
// fprintf( logstream, "local log: boxheader %.4s deleted!\n", bhPtr->type);
#endif
free(bhPtr);
bhPtr=bhNext;
}
free( *manf);
}
void print_manfbox( manfbox_param_t *manf)
{
boxheader_param_t *ptr;
ptr = manf->first;
while( ptr != NULL){
print_boxheader( ptr);
ptr=ptr->next;
}
}
boxheader_param_t * search_boxheader( char type[], manfbox_param_t *manf)
{
boxheader_param_t *found;
found = manf->first;
while( found != NULL){
if( strncmp( type, found->type, 4) == 0)
return found;
found = found->next;
}
fprintf( FCGI_stderr, "Error: Boxheader %s not found\n", type);
return NULL;
}

View File

@ -0,0 +1,81 @@
/*
* $Id: manfbox_manager.h 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.
*/
#ifndef MANFBOX_MANAGER_H_
# define MANFBOX_MANAGER_H_
#include "byte_manager.h"
#include "box_manager.h"
#include "boxheader_manager.h"
//! manifest box parameters
//! I.3.2.3 Manifest box
typedef struct manfbox_param{
boxheader_param_t *first; //!< top of the box header list
} manfbox_param_t;
/**
* generate manifest box
*
* @param[in] box pointer to the reference manf box
* @return generated manfbox
*/
manfbox_param_t * gene_manfbox( box_param_t *box);
/**
* delete manifest box
*
* @param[in,out] manf addressof the manfbox pointer
*/
void delete_manfbox( manfbox_param_t **manf);
/**
* print manf box parameters
*
* @param[in] manf manf box pointer
*/
void print_manfbox( manfbox_param_t *manf);
/**
* search a boxheader by box type from manifest box
*
* @param[in] type box type
* @param[in] manf manf box pointer
* @return found box pointer
*/
boxheader_param_t * search_boxheader( char type[], manfbox_param_t *manf);
#endif /* !MANFBOX_MANAGER_H_ */

View File

@ -0,0 +1,68 @@
/*
* $Id: marker_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 "marker_manager.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
marker_param_t set_marker( codestream_param_t cs, Byte2_t code, Byte8_t offset, Byte2_t length)
{
marker_param_t mkr;
mkr.cs = cs;
mkr.code = code;
mkr.offset = offset;
mkr.length = length;
return mkr;
}
Byte_t fetch_marker1byte( marker_param_t marker, long offset)
{
return fetch_codestream1byte( &(marker.cs), marker.offset+offset);
}
Byte2_t fetch_marker2bytebigendian( marker_param_t marker, long offset)
{
return fetch_codestream2bytebigendian( &(marker.cs), marker.offset+offset);
}
Byte4_t fetch_marker4bytebigendian( marker_param_t marker, long offset)
{
return fetch_codestream4bytebigendian( &(marker.cs), marker.offset+offset);
}

View File

@ -0,0 +1,87 @@
/*
* $Id: marker_manager.h 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.
*/
#ifndef MARKER_MANAGER_H_
# define MARKER_MANAGER_H_
#include "codestream_manager.h"
//! Marker parameters
typedef struct marker_param{
codestream_param_t cs; //!< corresponding codestream
Byte2_t code; //!< marker code
Byte8_t offset; //!< offset relative to the start of the codestream ( including the length parameter but not the marker itself)
Byte2_t length; //!< marker segment length
} marker_param_t;
/**
* set marker parameters from inputs
*
* @param[in] cs marker code
* @param[in] code marker code
* @param[in] offset offset in the codestream
* @param[in] length marker segment length
* @return structure of generated marker parameters
*/
marker_param_t set_marker( codestream_param_t cs, Byte2_t code, Byte8_t offset, Byte2_t length);
/**
* fetch marker content 1-bytes of data in file stream
*
* @param[in] marker marker structure
* @param[in] offset start Byte position in marker
* @param[in] size Byte length
* @return fetched code
*/
Byte_t fetch_marker1byte( marker_param_t marker, long offset);
/**
* fetch marker content 2-byte big endian Byte codes in file stream
*
* @param[in] marker marker structure
* @param[in] offset start Byte position in marker
* @return fetched code
*/
Byte2_t fetch_marker2bytebigendian( marker_param_t marker, long offset);
/**
* fetch marker content 4-byte big endian Byte codes in file stream
*
* @param[in] marker marker structure
* @param[in] offset start Byte position in marker
* @return fetched code
*/
Byte4_t fetch_marker4bytebigendian( marker_param_t marker, long offset);
#endif /* !MARKER_MANAGER_H_ */

View File

@ -0,0 +1,253 @@
/*
* $Id: metadata_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 <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string.h>
#include "metadata_manager.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
metadatalist_param_t * gene_metadatalist()
{
metadatalist_param_t *list;
list = (metadatalist_param_t *)malloc( sizeof(metadatalist_param_t));
list->first = NULL;
list->last = NULL;
return list;
}
metadatalist_param_t * const_metadatalist( int fd)
{
metadatalist_param_t *metadatalist;
metadata_param_t *metabin;
boxlist_param_t *toplev_boxlist;
box_param_t *box, *next;
placeholderlist_param_t *phldlist;
placeholder_param_t *phld;
int idx;
struct stat sb;
if( fstat( fd, &sb) == -1){
fprintf( FCGI_stdout, "Reason: Target broken (fstat error)\r\n");
return NULL;
}
if( !(toplev_boxlist = get_boxstructure( fd, 0, sb.st_size))){
fprintf( FCGI_stderr, "Error: Not correctl JP2 format\n");
return NULL;
}
phldlist = gene_placeholderlist();
metadatalist = gene_metadatalist();
delete_box_in_list_by_type( "iptr", toplev_boxlist);
delete_box_in_list_by_type( "cidx", toplev_boxlist);
delete_box_in_list_by_type( "fidx", toplev_boxlist);
box = toplev_boxlist->first;
idx = 0;
while( box){
next = box->next;
if( strncmp( box->type, "jP ",4)!=0 && strncmp( box->type, "ftyp",4)!=0 && strncmp( box->type, "jp2h",4)!=0){
boxlist_param_t *boxlist = NULL;
boxcontents_param_t *boxcontents = NULL;
phld = gene_placeholder( box, ++idx);
insert_placeholder_into_list( phld, phldlist);
boxlist = get_boxstructure( box->fd, get_DBoxoff( box), get_DBoxlen(box));
if( !boxlist)
boxcontents = gene_boxcontents( get_DBoxoff( box), get_DBoxlen(box));
delete_box_in_list( &box, toplev_boxlist);
metabin = gene_metadata( idx, boxlist, NULL, boxcontents);
insert_metadata_into_list( metabin, metadatalist);
}
box = next;
}
metabin = gene_metadata( 0, toplev_boxlist, phldlist, NULL);
insert_metadata_into_list( metabin, metadatalist);
return metadatalist;
}
void delete_metadatalist( metadatalist_param_t **list)
{
metadata_param_t *ptr, *next;
ptr = (*list)->first;
while( ptr != NULL){
next=ptr->next;
delete_metadata( &ptr);
ptr=next;
}
free( *list);
}
metadata_param_t * gene_metadata( int idx, boxlist_param_t *boxlist, placeholderlist_param_t *phldlist, boxcontents_param_t *boxcontents)
{
metadata_param_t *bin;
bin = (metadata_param_t *)malloc( sizeof(metadata_param_t));
bin->idx = idx;
bin->boxlist = boxlist;
bin->placeholderlist = phldlist;
bin->boxcontents = boxcontents;
bin->next = NULL;
return bin;
}
void delete_metadata( metadata_param_t **metadata)
{
delete_boxlist( &((*metadata)->boxlist));
delete_placeholderlist( &((*metadata)->placeholderlist));
if((*metadata)->boxcontents)
free((*metadata)->boxcontents);
#ifndef SERVER
// fprintf( logstream, "local log: Metadata-bin: %d deleted\n", (*metadata)->idx);
#endif
free( *metadata);
}
void insert_metadata_into_list( metadata_param_t *metabin, metadatalist_param_t *metadatalist)
{
if( metadatalist->first)
metadatalist->last->next = metabin;
else
metadatalist->first = metabin;
metadatalist->last = metabin;
}
void print_metadata( metadata_param_t *metadata)
{
fprintf( logstream, "metadata-bin %d info:\n", metadata->idx);
print_allbox( metadata->boxlist);
print_allplaceholder( metadata->placeholderlist);
boxcontents_param_t *boxcont = metadata->boxcontents;
if( boxcont)
fprintf( logstream, "box contents:\n"
"\t offset: %lld %#llx\n"
"\t length: %lld %#llx\n", boxcont->offset, boxcont->offset, boxcont->length, boxcont->length);
}
void print_allmetadata( metadatalist_param_t *list)
{
metadata_param_t *ptr;
fprintf( logstream, "all metadata info: \n");
ptr = list->first;
while( ptr != NULL){
print_metadata( ptr);
ptr=ptr->next;
}
}
boxcontents_param_t * gene_boxcontents( Byte8_t offset, Byte8_t length)
{
boxcontents_param_t *contents;
contents = (boxcontents_param_t *)malloc( sizeof(boxcontents_param_t));
contents->offset = offset;
contents->length = length;
return contents;
}
metadata_param_t * search_metadata( int idx, metadatalist_param_t *list)
{
metadata_param_t *found;
found = list->first;
while( found){
if( found->idx == idx)
return found;
found = found->next;
}
return NULL;
}
int search_metadataidx( char boxtype[4], metadatalist_param_t *list)
{
metadata_param_t *ptr;
for( int i=0; i<4; i++)
if( boxtype[i] == '_')
boxtype[i] = ' ';
ptr = list->first;
while( ptr){
if( ptr->boxlist){
box_param_t *box = ptr->boxlist->first;
while( box){
if( strncmp ( boxtype, box->type, 4) == 0)
return ptr->idx;
box = box->next;
}
}
ptr = ptr->next;
}
ptr = list->first;
while( ptr){
if( ptr->placeholderlist){
placeholder_param_t *phld = ptr->placeholderlist->first;
while( phld){
if( strncmp ( boxtype, (char *)phld->OrigBH+4, 4) == 0){
return phld->OrigID;
}
phld = phld->next;
}
}
ptr = ptr->next;
}
return -1;
}

View File

@ -0,0 +1,150 @@
/*
* $Id: metadata_manager.h 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.
*/
#ifndef METADATA_MANAGER_H_
# define METADATA_MANAGER_H_
#include "box_manager.h"
#include "placeholder_manager.h"
typedef struct boxcontents_param{
Byte8_t offset; //!< byte position of the box contents in the file
Byte8_t length; //!< length of the box contents
} boxcontents_param_t;
//! metadata-bin parameters
typedef struct metadata_param{
int idx; //!< index number
boxlist_param_t *boxlist; //!< box list
placeholderlist_param_t *placeholderlist; //!< placeholder box list
boxcontents_param_t *boxcontents; //!< box contens in case of no boxlist and placeholderlist
struct metadata_param *next; //!< pointer to the next metadata-bin
} metadata_param_t;
//! metadata-bin list parameters
typedef struct metadatalist_param{
metadata_param_t *first; //!< first metadata-bin pointer of the list
metadata_param_t *last; //!< last metadata-bin pointer of the list
} metadatalist_param_t;
/**
* generate a metadata list
*
* @return pointer to the generated metadata list
*/
metadatalist_param_t * gene_metadatalist();
/**
* construct metadata-bin list of JP2 file
*
* @param[in] fd file descriptor
* @return pointer to the generated metadata-bin list
*/
metadatalist_param_t * const_metadatalist( int fd);
/**
* delete metadata list
*
* @param[in,out] list address of the metadata list pointer
*/
void delete_metadatalist( metadatalist_param_t **list);
/**
* generate a metadata bin
*
* @param[in] idx metadata-bin index
* @param[in] boxlist box list pointer
* @param[in] phldlist placeholder list pointer
* @param[in] boxcontents boxcontents pointer
* @return pointer to the generated metadata bin
*/
metadata_param_t * gene_metadata( int idx, boxlist_param_t *boxlist, placeholderlist_param_t *phldlist, boxcontents_param_t *boxcontents);
/**
* delete a metadata bin
*
* @param[in,out] metadata address of the deleting metadata bin pointer
*/
void delete_metadata( metadata_param_t **metadata);
/**
* generate box contents
*
* @return pointer to the box contents
*/
boxcontents_param_t * gene_boxcontents( Byte8_t offset, Byte8_t length);
/**
* print metadata-bin parameters
*
* @param[in] metadata metadata-bin pointer
*/
void print_metadata( metadata_param_t *metadata);
/**
* print all metadata parameters
*
* @param[in] metadatalist metadata list pointer
*/
void print_allmetadata( metadatalist_param_t *list);
/**
* search a metadata bin by index
*
* @param[in] idx index
* @param[in] list metadata-bin list pointer
* @return found metadata-bin pointer
*/
metadata_param_t * search_metadata( int idx, metadatalist_param_t *list);
/**
* search a metadata index by box-type
*
* @param[in] boxtype box-type
* @param[in] list metadata-bin list pointer
* @return found metadata-bin index, if not found, -1
*/
int search_metadataidx( char boxtype[4], metadatalist_param_t *list);
/**
* insert a metadata-bin into list
*
* @param[in] metabin metadata-bin pointer
* @param[in] metadatalist metadata list pointer
*/
void insert_metadata_into_list( metadata_param_t *metabin, metadatalist_param_t *metadatalist);
#endif /* !METADATA_MANAGER_H_ */

View File

@ -0,0 +1,140 @@
/*
* $Id: mhixbox_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 <stdlib.h>
#include "mhixbox_manager.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
mhixbox_param_t * gene_mhixbox( box_param_t *box)
{
mhixbox_param_t *mhix;
markeridx_param_t *mkridx, *lastmkidx;
long pos = 0;
mhix = ( mhixbox_param_t *)malloc( sizeof( mhixbox_param_t));
mhix->tlen = fetch_DBox8bytebigendian( box, (pos+=8)-8);
mhix->first = lastmkidx = NULL;
while( pos < get_DBoxlen( box)){
mkridx = ( markeridx_param_t *)malloc( sizeof( markeridx_param_t));
mkridx->code = fetch_DBox2bytebigendian( box, (pos+=2)-2);
mkridx->num_remain = fetch_DBox2bytebigendian( box, (pos+=2)-2);
mkridx->offset = fetch_DBox8bytebigendian( box, (pos+=8)-8);
mkridx->length = fetch_DBox2bytebigendian( box, (pos+=2)-2);
mkridx->next = NULL;
if( mhix->first)
lastmkidx->next = mkridx;
else
mhix->first = mkridx;
lastmkidx = mkridx;
}
return mhix;
}
markeridx_param_t * search_markeridx( Byte2_t code, mhixbox_param_t *mhix)
{
markeridx_param_t *found;
found = mhix->first;
while( found != NULL){
if( code == found->code)
return found;
found = found->next;
}
fprintf( FCGI_stderr, "Error: Marker index %#x not found\n", code);
return NULL;
}
void print_mhixbox( mhixbox_param_t *mhix)
{
markeridx_param_t *ptr;
fprintf( logstream, "mhix box info:\n");
fprintf( logstream, "\t tlen: %#llx\n", mhix->tlen);
ptr = mhix->first;
while( ptr != NULL){
fprintf( logstream, "marker index info:\n"
"\t code: %#x\n"
"\t num_remain: %#x\n"
"\t offset: %#llx\n"
"\t length: %#x\n", ptr->code, ptr->num_remain, ptr->offset, ptr->length);
ptr=ptr->next;
}
}
void print_markeridx( markeridx_param_t *markeridx)
{
fprintf( logstream, "marker index info:\n"
"\t code: %#x\n"
"\t num_remain: %#x\n"
"\t offset: %#llx\n"
"\t length: %#x\n", markeridx->code, markeridx->num_remain, markeridx->offset, markeridx->length);
}
void delete_mhixbox( mhixbox_param_t **mhix)
{
markeridx_param_t *mkPtr, *mkNext;
mkPtr = (*mhix)->first;
while( mkPtr != NULL){
mkNext=mkPtr->next;
#ifndef SERVER
// fprintf( logstream, "local log: marker index %#x deleted!\n", mkPtr->code);
#endif
free(mkPtr);
mkPtr=mkNext;
}
free(*mhix);
}

View File

@ -0,0 +1,102 @@
/*
* $Id: mhixbox_manager.h 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.
*/
#ifndef MHIXBOX_MANAGER_H_
# define MHIXBOX_MANAGER_H_
#include "byte_manager.h"
#include "box_manager.h"
//! Marker index parameters
typedef struct markeridx_param{
Byte2_t code; //!< marker code
Byte2_t num_remain; //!< remining number of the same marker index segments listed immediately
Byte8_t offset; //!< offset relative to the start of the
//!codestream ( including the length
//!parameter but not the marker itself)
Byte2_t length; //!< marker segment length
struct markeridx_param *next; //!< pointer to the next markeridx
} markeridx_param_t;
//! header index table box parameters
//! I.3.2.4.3 Header Index Table box
typedef struct mhixbox_param{
Byte8_t tlen; //!< length ( total length of the main
//!header or of the first tile-part header)
markeridx_param_t *first; //!< first marker index pointer of the list
} mhixbox_param_t;
/**
* generate mhix box
*
* @param[in] box pointer to the reference mhix box
* @return generated mhixbox pointer
*/
mhixbox_param_t * gene_mhixbox( box_param_t *box);
/**
* search a marker index by marker code from mhix box
*
* @param[in] code marker code
* @param[in] mhix mhix box pointer
* @return found marker index pointer
*/
markeridx_param_t * search_markeridx( Byte2_t code, mhixbox_param_t *mhix);
/**
* print mhix box parameters
*
* @param[in] mhix mhix box pointer
*/
void print_mhixbox( mhixbox_param_t *mhix);
/**
* print marker index parameters
*
* @param[in] markeridx marker index pointer
*/
void print_markeridx( markeridx_param_t *markeridx);
/**
* delete mhix box
*
* @param[in,out] mhix address of the mhix box pointer
*/
void delete_mhixbox( mhixbox_param_t **mhix);
#endif /* !MHIXBOX_MANAGER_H_ */

View File

@ -0,0 +1,947 @@
/*
* $Id: msgqueue_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 <stdlib.h>
#include <math.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <ctype.h>
#include "msgqueue_manager.h"
#include "metadata_manager.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
#define TILE_MSG 4
#define EXT_TILE_MSG 5
#define MAINHEADER_MSG 6
#define METADATA_MSG 8
msgqueue_param_t * gene_msgqueue( bool stateless, target_param_t *target)
{
msgqueue_param_t *msgqueue;
msgqueue = (msgqueue_param_t *)malloc( sizeof(msgqueue_param_t));
msgqueue->first = NULL;
msgqueue->last = NULL;
msgqueue->stateless = stateless;
msgqueue->target = target;
return msgqueue;
}
void delete_msgqueue( msgqueue_param_t **msgqueue)
{
message_param_t *ptr, *next;
if( !(*msgqueue))
return;
ptr = (*msgqueue)->first;
while( ptr){
next = ptr->next;
free( ptr);
ptr = next;
}
if( (*msgqueue)->stateless && (*msgqueue)->target)
delete_target( &((*msgqueue)->target));
free(*msgqueue);
}
void print_msgqueue( msgqueue_param_t *msgqueue)
{
message_param_t *ptr;
if( !msgqueue)
return;
fprintf( logstream, "message queue:\n");
ptr = msgqueue->first;
while( ptr){
fprintf( logstream, "\t class_id: %lld\n", ptr->class_id );
fprintf( logstream, "\t in_class_id: %lld\n", ptr->in_class_id );
fprintf( logstream, "\t csn: %lld\n", ptr->csn );
fprintf( logstream, "\t bin_offset: %#llx\n", ptr->bin_offset );
fprintf( logstream, "\t length: %#llx\n", ptr->length );
fprintf( logstream, "\t aux: %lld\n", ptr->aux );
fprintf( logstream, "\t last_byte: %d\n", ptr->last_byte );
if( ptr->phld)
print_placeholder( ptr->phld);
else
fprintf( logstream, "\t res_offset: %#llx\n", ptr->res_offset );
fprintf( logstream, "\n");
ptr = ptr->next;
}
}
void enqueue_message( message_param_t *msg, msgqueue_param_t *msgqueue);
void enqueue_mainheader( msgqueue_param_t *msgqueue)
{
target_param_t *target;
message_param_t *msg;
target = msgqueue->target;
msg = (message_param_t *)malloc( sizeof(message_param_t));
msg->last_byte = true;
msg->in_class_id = 0;
msg->class_id = MAINHEADER_MSG;
msg->csn = target->csn;
msg->bin_offset = 0;
msg->length = target->codeidx->mhead_length;
msg->aux = 0; // non exist
msg->res_offset = target->codeidx->offset;
msg->phld = NULL;
msg->next = NULL;
enqueue_message( msg, msgqueue);
target->codeidx->mhead_model = true;
}
void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue)
{
target_param_t *target;
bool *tp_model;
Byte8_t numOftparts; // num of tile parts par tile
Byte8_t numOftiles;
index_param_t *codeidx;
faixbox_param_t *tilepart;
message_param_t *msg;
Byte8_t binOffset, binLength;
target = msgqueue->target;
codeidx = target->codeidx;
tilepart = codeidx->tilepart;
numOftparts = get_nmax( tilepart);
numOftiles = get_m( tilepart);
if( tile_id < 0 || numOftiles <= tile_id){
fprintf( FCGI_stderr, "Error, Invalid tile-id %d\n", tile_id);
return;
}
tp_model = &codeidx->tp_model[ tile_id*numOftparts];
binOffset=0;
for( int i=0; i<numOftparts-level; i++){
binLength = get_elemLen( tilepart, i, tile_id);
if( !tp_model[i]){
msg = (message_param_t *)malloc( sizeof(message_param_t));
msg->last_byte = i==numOftparts-1? true : false;
msg->in_class_id = tile_id;
#if 0
msg->class_id = TILE_MSG;
#else
msg->class_id = EXT_TILE_MSG;
#endif
msg->csn = target->csn;
msg->bin_offset = binOffset;
msg->length = binLength;
msg->aux = numOftparts-i;
msg->res_offset = codeidx->offset+get_elemOff( tilepart, i, tile_id)/*-1*/;
msg->phld = NULL;
msg->next = NULL;
enqueue_message( msg, msgqueue);
tp_model[i] = true;
}
binOffset += binLength;
}
}
void enqueue_box( int meta_id, boxlist_param_t *boxlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
void enqueue_phld( int meta_id, placeholderlist_param_t *phldlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
void enqueue_boxcontents( int meta_id, boxcontents_param_t *boxcontents, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
void enqueue_metadata( int meta_id, msgqueue_param_t *msgqueue)
{
metadatalist_param_t *metadatalist;
metadata_param_t *metadata;
Byte8_t binOffset;
metadatalist = msgqueue->target->codeidx->metadatalist;
metadata = search_metadata( meta_id, metadatalist);
if( !metadata){
fprintf( FCGI_stderr, "Error: metadata-bin %d not found\n", meta_id);
return;
}
binOffset = 0;
if( metadata->boxlist)
enqueue_box( meta_id, metadata->boxlist, msgqueue, &binOffset);
if( metadata->placeholderlist)
enqueue_phld( meta_id, metadata->placeholderlist, msgqueue, &binOffset);
if( metadata->boxcontents)
enqueue_boxcontents( meta_id, metadata->boxcontents, msgqueue, &binOffset);
msgqueue->last->last_byte = true;
}
message_param_t * gene_metamsg( int meta_id, Byte8_t binoffset, Byte8_t length, Byte8_t res_offset, placeholder_param_t *phld, Byte8_t csn);
void enqueue_box( int meta_id, boxlist_param_t *boxlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset)
{
box_param_t *box;
message_param_t *msg;
box = boxlist->first;
while( box){
msg = gene_metamsg( meta_id, *binOffset, box->length, box->offset, NULL, msgqueue->target->csn);
enqueue_message( msg, msgqueue);
*binOffset += box->length;
box = box->next;
}
}
void enqueue_phld( int meta_id, placeholderlist_param_t *phldlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset)
{
placeholder_param_t *phld;
message_param_t *msg;
phld = phldlist->first;
while( phld){
msg = gene_metamsg( meta_id, *binOffset, phld->LBox, 0, phld, msgqueue->target->csn);
enqueue_message( msg, msgqueue);
*binOffset += phld->LBox;
phld = phld->next;
}
}
void enqueue_boxcontents( int meta_id, boxcontents_param_t *boxcontents, msgqueue_param_t *msgqueue, Byte8_t *binOffset)
{
message_param_t *msg;
msg = gene_metamsg( meta_id, *binOffset, boxcontents->length, boxcontents->offset, NULL, msgqueue->target->csn);
enqueue_message( msg, msgqueue);
*binOffset += boxcontents->length;
}
message_param_t * gene_metamsg( int meta_id, Byte8_t binOffset, Byte8_t length, Byte8_t res_offset, placeholder_param_t *phld, Byte8_t csn)
{
message_param_t *msg;
msg = (message_param_t *)malloc( sizeof(message_param_t));
msg->last_byte = false;
msg->in_class_id = meta_id;
msg->class_id = METADATA_MSG;
msg->csn = csn;
msg->bin_offset = binOffset;
msg->length = length;
msg->aux = 0; // non exist
msg->res_offset = res_offset;
msg->phld = phld;
msg->next = NULL;
return msg;
}
void enqueue_message( message_param_t *msg, msgqueue_param_t *msgqueue)
{
if( msgqueue->first)
msgqueue->last->next = msg;
else
msgqueue->first = msg;
msgqueue->last = msg;
}
void emit_bin_id_vbas( Byte_t bb, Byte_t c, Byte8_t in_class_id);
void emit_vbas( Byte8_t code);
void emit_body( message_param_t *msg, int fd);
void emit_placeholder( placeholder_param_t *phld);
void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue)
{
message_param_t *msg;
Byte8_t class_id, csn;
Byte_t bb, c;
if( !(msgqueue))
return;
msg = msgqueue->first;
class_id = 0;
csn = 0;
while( msg){
if( msg->csn == csn){
if( msg->class_id == class_id)
bb = 1;
else{
bb = 2;
class_id = msg->class_id;
}
}
else{
bb = 3;
class_id = msg->class_id;
csn = msg->csn;
}
c = msg->last_byte ? 1 : 0;
emit_bin_id_vbas( bb, c, msg->in_class_id);
if( bb >= 2)
emit_vbas( class_id);
if (bb == 3)
emit_vbas( csn);
emit_vbas( msg->bin_offset);
emit_vbas (msg->length);
if( msg->class_id%2) // Aux is present only if the id is odd
emit_vbas( msg->aux);
if( msg->phld)
emit_placeholder( msg->phld);
else
emit_body( msg, msgqueue->target->fd);
msg = msg->next;
}
}
void emit_vbas_with_bytelen( Byte8_t code, int bytelength);
void print_binarycode( Byte8_t n, int segmentlen);
void emit_bin_id_vbas( Byte_t bb, Byte_t c, Byte8_t in_class_id)
{
int bytelength;
Byte8_t tmp;
// A.2.3 In-class identifiers
// 7k-3bits, where k is the number of bytes in the VBAS
bytelength = 1;
tmp = in_class_id >> 4;
while( tmp){
bytelength ++;
tmp >>= 7;
}
in_class_id |= (((bb & 3) << 5) | (c & 1) << 4) << ((bytelength-1)*7);
emit_vbas_with_bytelen( in_class_id, bytelength);
}
void emit_vbas( Byte8_t code)
{
int bytelength;
Byte8_t tmp;
bytelength = 1;
tmp = code;
while( tmp >>= 7)
bytelength ++;
emit_vbas_with_bytelen( code, bytelength);
}
void emit_vbas_with_bytelen( Byte8_t code, int bytelength)
{
int n;
Byte8_t seg;
n = bytelength - 1;
while( n >= 0) {
seg = ( code >> (n*7)) & 0x7f;
if( n)
seg |= 0x80;
fputc(( Byte4_t)seg, FCGI_stdout);
n--;
}
}
void emit_body( message_param_t *msg, int fd)
{
Byte_t *data;
if( lseek( fd, msg->res_offset, SEEK_SET)==-1){
fprintf( FCGI_stderr, "Error: fseek in emit_body()\n");
return;
}
data = (Byte_t *)malloc( msg->length);
if( read( fd, data, msg->length) != msg->length){
free( data);
fprintf( FCGI_stderr, "Error: fread in emit_body()\n");
return;
}
if( fwrite( data, msg->length, 1, FCGI_stdout) < 1){
free( data);
fprintf( FCGI_stderr, "Error: fwrite in emit_body()\n");
return;
}
free(data);
}
void emit_bigendian_bytes( Byte8_t code, int bytelength);
void emit_placeholder( placeholder_param_t *phld)
{
emit_bigendian_bytes( phld->LBox, 4);
if( fwrite( phld->TBox, 4, 1, FCGI_stdout) < 1){
fprintf( FCGI_stderr, "Error: fwrite in emit_placeholder()\n");
return;
}
emit_bigendian_bytes( phld->Flags, 4);
emit_bigendian_bytes( phld->OrigID, 8);
if( fwrite( phld->OrigBH, phld->OrigBHlen, 1, FCGI_stdout) < 1){
fprintf( FCGI_stderr, "Error: fwrite in emit_placeholder()\n");
return;
}
}
void emit_bigendian_bytes( Byte8_t code, int bytelength)
{
int n;
Byte8_t seg;
n = bytelength - 1;
while( n >= 0) {
seg = ( code >> (n*8)) & 0xff;
fputc(( Byte4_t)seg, FCGI_stdout);
n--;
}
}
void print_binarycode( Byte8_t n, int segmentlen)
{
char buf[256];
int i=0;
do{
buf[i++] = n%2 ? '1' : '0';
}while((n=n/2));
for( int j=segmentlen-1; j>=i; j--)
putchar('0');
for( int j=i-1, k=0; j>=0; j--, k++){
putchar( buf[j]);
if( !((k+1)%segmentlen))
printf(" ");
}
printf("\n");
}
Byte_t * parse_bin_id_vbas( Byte_t *streamptr, Byte_t *bb, Byte_t *c, Byte8_t *in_class_id);
Byte_t * parse_vbas( Byte_t *streamptr, Byte8_t *elem);
void parse_stream( Byte_t *stream, Byte8_t jptlen, Byte8_t offset, msgqueue_param_t *msgqueue)
{
Byte_t *ptr; // stream pointer
message_param_t *msg;
Byte_t bb, c;
Byte8_t class_id, csn;
class_id = -1; // dummy
csn = 0;
ptr = stream;
while( ptr-stream < jptlen){
msg = (message_param_t *)malloc( sizeof(message_param_t));
ptr = parse_bin_id_vbas( ptr, &bb, &c, &msg->in_class_id);
msg->last_byte = c == 1 ? true : false;
if( bb >= 2){
ptr = parse_vbas( ptr, &class_id);
// fprintf( stdout, "class_id: %lld\n", class_id);
}
msg->class_id = class_id;
if (bb == 3)
ptr = parse_vbas( ptr, &csn);
msg->csn = csn;
ptr = parse_vbas( ptr, &msg->bin_offset);
ptr = parse_vbas( ptr, &msg->length);
if( msg->class_id%2) // Aux is present only if the id is odd
ptr = parse_vbas( ptr, &msg->aux);
else
msg->aux = 0;
msg->res_offset = ptr-stream+offset;
msg->phld = NULL;
msg->next = NULL;
if(msgqueue->first)
msgqueue->last->next = msg;
else
msgqueue->first = msg;
msgqueue->last = msg;
ptr += msg->length;
}
}
void parse_metadata( metadata_param_t *metadata, message_param_t *msg, Byte_t *stream);
void parse_metamsg( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t jptlen, metadatalist_param_t *metadatalist)
{
message_param_t *msg;
if( metadatalist == NULL)
return;
msg = msgqueue->first;
while( msg){
if( msg->class_id == METADATA_MSG){
metadata_param_t *metadata = gene_metadata( msg->in_class_id, NULL, NULL, NULL);
insert_metadata_into_list( metadata, metadatalist);
parse_metadata( metadata, msg, stream+msg->res_offset);
}
msg = msg->next;
}
}
placeholder_param_t * parse_phld( Byte_t *datastream, Byte8_t metalength);
void parse_metadata( metadata_param_t *metadata, message_param_t *msg, Byte_t *datastream)
{
char *boxtype = (char *)(datastream+4);
msg->phld = NULL;
if( strncmp( boxtype, "phld", 4) == 0){
if( !metadata->placeholderlist)
metadata->placeholderlist = gene_placeholderlist();
placeholder_param_t *phld = parse_phld( datastream, msg->length);
msg->phld = phld;
insert_placeholder_into_list( phld, metadata->placeholderlist);
}
else if( isalpha(boxtype[0]) && isalpha(boxtype[1]) &&
(isalnum(boxtype[2])||isblank(boxtype[2])) &&
(isalpha(boxtype[3])||isblank(boxtype[3]))){
if( !metadata->boxlist)
metadata->boxlist = gene_boxlist();
box_param_t *box = gene_boxbyOffinStream( datastream, msg->res_offset);
insert_box_into_list( box, metadata->boxlist);
}
else
metadata->boxcontents = gene_boxcontents( msg->res_offset, msg->length);
}
placeholder_param_t * parse_phld( Byte_t *datastream, Byte8_t metalength)
{
placeholder_param_t *phld;
phld = (placeholder_param_t *)malloc( sizeof(placeholder_param_t));
phld->LBox = big4( datastream);
strcpy( phld->TBox, "phld");
phld->Flags = big4( datastream+8);
phld->OrigID = big8( datastream+12);
phld->OrigBHlen = metalength - 20;
phld->OrigBH = (Byte_t *)malloc(phld->OrigBHlen);
memcpy( phld->OrigBH, datastream+20, phld->OrigBHlen);
phld->next = NULL;
return phld;
}
Byte_t * parse_bin_id_vbas( Byte_t *streamptr, Byte_t *bb, Byte_t *c, Byte8_t *in_class_id)
{
Byte_t code;
Byte_t *ptr;
ptr = streamptr;
code = *(ptr++);
*bb = (code >> 5) & 3;
*c = (code >> 4) & 1;
*in_class_id = code & 15;
while(code >> 7){
code = *(ptr++);
*in_class_id = (*in_class_id << 7) | (code & 0x7f);
}
return ptr;
}
Byte_t * parse_vbas( Byte_t *streamptr, Byte8_t *elem)
{
Byte_t code;
Byte_t *ptr;
*elem = 0;
ptr = streamptr;
do{
code = *(ptr++);
*elem = (*elem << 7) | (code & 0x7f);
}while(code >> 7);
return ptr;
}
/**
* search a message by class_id
*
* @param[in] class_id class identifiers
* @param[in] in_class_id in-class identifiers, -1 means any
* @param[in] csn codestream number
* @param[in] msg first message pointer of the searching list
* @return found message pointer
*/
message_param_t * search_message( Byte8_t class_id, Byte8_t in_class_id, Byte8_t csn, message_param_t *msg);
/**
* delete a message in msgqueue
*
* @param[in] message address of the deleting message pointer
* @param[in] msgqueue message queue pointer
*/
void delete_message_in_msgqueue( message_param_t **message, msgqueue_param_t *msgqueue);
Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t csn, int minlev, Byte8_t *codelen);
// usable only to JPT-stream messages
Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t csn, int minlev, Byte8_t *j2klen)
{
Byte_t *j2kstream = NULL;
if( !msgqueue)
return NULL;
j2kstream = recons_codestream( msgqueue, stream, csn, minlev, j2klen);
return j2kstream;
}
Byte_t * add_emptyboxstream( placeholder_param_t *phld, Byte_t *jp2stream, Byte8_t *jp2len);
Byte_t * add_msgstream( message_param_t *message, Byte_t *origstream, Byte_t *j2kstream, Byte8_t *j2klen);
Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t csn, Byte8_t *jp2len)
{
message_param_t *ptr;
Byte_t *jp2stream = NULL;
Byte_t *codestream = NULL;
Byte8_t codelen;
Byte8_t jp2cDBoxOffset = 0, jp2cDBoxlen = 0;
*jp2len = 0;
if( !msgqueue)
return NULL;
ptr = msgqueue->first;
while(( ptr = search_message( METADATA_MSG, -1, csn, ptr))!=NULL){
if( ptr->phld){
if( strncmp( (char *)ptr->phld->OrigBH+4, "jp2c", 4) == 0){
jp2cDBoxOffset = *jp2len + ptr->phld->OrigBHlen;
jp2stream = add_emptyboxstream( ptr->phld, jp2stream, jp2len); // header only
jp2cDBoxlen = *jp2len - jp2cDBoxOffset;
}
else
jp2stream = add_emptyboxstream( ptr->phld, jp2stream, jp2len); // header only
}
jp2stream = add_msgstream( ptr, stream, jp2stream, jp2len);
ptr = ptr->next;
}
codestream = recons_codestream( msgqueue, stream, csn, 0, &codelen);
if( jp2cDBoxOffset != 0 && codelen <= jp2cDBoxlen)
memcpy( jp2stream+jp2cDBoxOffset, codestream, codelen);
free( codestream);
return jp2stream;
}
int get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn);
Byte_t * add_emptytilestream( const int tileID, Byte_t *j2kstream, Byte8_t *j2klen);
Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen);
Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t csn, int minlev, Byte8_t *codelen)
{
message_param_t *ptr;
Byte_t *codestream = NULL;
int last_tileID;
*codelen = 0;
// main header first
ptr = msgqueue->first;
while(( ptr = search_message( MAINHEADER_MSG, -1, csn, ptr))!=NULL){
codestream = add_msgstream( ptr, stream, codestream, codelen);
ptr = ptr->next;
}
last_tileID = get_last_tileID( msgqueue, csn);
for( int tileID=0; tileID <= last_tileID; tileID++){
bool found = false;
ptr = msgqueue->first;
while(( ptr = search_message( TILE_MSG, tileID, csn, ptr))!=NULL){
found = true;
codestream = add_msgstream( ptr, stream, codestream, codelen);
ptr = ptr->next;
}
ptr = msgqueue->first;
while(( ptr = search_message( EXT_TILE_MSG, tileID, csn, ptr))!=NULL){
if( ptr->aux >= minlev){
found = true;
codestream = add_msgstream( ptr, stream, codestream, codelen);
}
ptr = ptr->next;
}
if(!found)
codestream = add_emptytilestream( tileID, codestream, codelen);
}
codestream = add_EOC( codestream, codelen);
return codestream;
}
int get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn)
{
int last_tileID = 0;
message_param_t *msg;
msg = msgqueue->first;
while( msg){
if((msg->class_id == TILE_MSG || msg->class_id == EXT_TILE_MSG) && msg->csn == csn && last_tileID < msg->in_class_id)
last_tileID = msg->in_class_id;
msg = msg->next;
}
return last_tileID;
}
message_param_t * search_message( Byte8_t class_id, Byte8_t in_class_id, Byte8_t csn, message_param_t *msg)
{
while( msg != NULL){
if( in_class_id == -1){
if( msg->class_id == class_id && msg->csn == csn)
return msg;
}
else{
if( msg->class_id == class_id && msg->in_class_id == in_class_id && msg->csn == csn)
return msg;
}
msg = msg->next;
}
return NULL;
}
void delete_message_in_msgqueue( message_param_t **msg, msgqueue_param_t *msgqueue)
{
message_param_t *ptr;
if( !(*msg))
return;
if( *msg == msgqueue->first)
msgqueue->first = (*msg)->next;
else{
ptr = msgqueue->first;
while( ptr->next != *msg){
ptr=ptr->next;
}
ptr->next = (*msg)->next;
if( *msg == msgqueue->last)
msgqueue->last = ptr;
}
free( *msg);
}
Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length);
Byte_t * gene_emptytilestream( const int tileID, Byte8_t *length);
Byte_t * add_msgstream( message_param_t *message, Byte_t *origstream, Byte_t *j2kstream, Byte8_t *j2klen)
{
Byte_t *newstream;
Byte8_t newlen;
Byte_t *buf;
if( !message)
return NULL;
newstream = gene_msgstream( message, origstream, &newlen);
buf = (Byte_t *)malloc(( *j2klen)+newlen);
memcpy( buf, j2kstream, *j2klen);
memcpy( buf+(*j2klen), newstream, newlen);
*j2klen += newlen;
free( newstream);
if(j2kstream) free(j2kstream);
return buf;
}
Byte_t * add_emptyboxstream( placeholder_param_t *phld, Byte_t *jp2stream, Byte8_t *jp2len)
{
Byte_t *newstream;
Byte8_t newlen;
Byte_t *buf;
if( phld->OrigBHlen == 8)
newlen = big4(phld->OrigBH);
else
newlen = big8(phld->OrigBH+8);
newstream = (Byte_t *)malloc( newlen);
memset( newstream, 0, newlen);
memcpy( newstream, phld->OrigBH, phld->OrigBHlen);
buf = (Byte_t *)malloc(( *jp2len)+newlen);
memcpy( buf, jp2stream, *jp2len);
memcpy( buf+(*jp2len), newstream, newlen);
*jp2len += newlen;
free( newstream);
if(jp2stream) free(jp2stream);
return buf;
}
Byte_t * add_emptytilestream( const int tileID, Byte_t *j2kstream, Byte8_t *j2klen)
{
Byte_t *newstream;
Byte8_t newlen;
Byte_t *buf;
newstream = gene_emptytilestream( tileID, &newlen);
buf = (Byte_t *)malloc(( *j2klen)+newlen);
memcpy( buf, j2kstream, *j2klen);
memcpy( buf+(*j2klen), newstream, newlen);
*j2klen += newlen;
free( newstream);
if(j2kstream) free(j2kstream);
return buf;
}
Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen)
{
Byte2_t EOC = 0xd9ff;
Byte_t *buf;
buf = (Byte_t *)malloc(( *j2klen)+2);
memcpy( buf, j2kstream, *j2klen);
memcpy( buf+(*j2klen), &EOC, 2);
*j2klen += 2;
if(j2kstream) free(j2kstream);
return buf;
}
Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length)
{
Byte_t *buf;
if( !message)
return NULL;
*length = message->length;
buf = (Byte_t *)malloc( *length);
memcpy( buf, stream+message->res_offset, *length);
return buf;
}
Byte_t * gene_emptytilestream( const int tileID, Byte8_t *length)
{
Byte_t *buf;
const Byte2_t SOT = 0x90ff;
const Byte2_t Lsot = 0xa << 8;
Byte2_t Isot;
const Byte4_t Psot = 0xe << 24;
const Byte_t TPsot = 0, TNsot = 0;
const Byte2_t SOD = 0x93ff;
*length = 14;
buf = (Byte_t *)malloc(*length);
Isot = tileID << 8;
memcpy( buf, &SOT, 2);
memcpy( buf+2, &Lsot, 2);
memcpy( buf+4, &Isot, 2);
memcpy( buf+6, &Psot, 4);
memcpy( buf+10, &TPsot, 1);
memcpy( buf+11, &TNsot, 1);
memcpy( buf+12, &SOD, 2);
return buf;
}

View File

@ -0,0 +1,167 @@
/*
* $Id: msgqueue_manager.h 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.
*/
#ifndef MSGQUEUE_MANAGER_H_
# define MSGQUEUE_MANAGER_H_
#include <stdbool.h>
#include <stdio.h>
#include "byte_manager.h"
#include "target_manager.h"
#include "placeholder_manager.h"
//! message parameters
typedef struct message_param{
bool last_byte; //!< if message contains the last byte of the data-bin
Byte8_t in_class_id; //!< in-class identifier A.2.3
Byte8_t class_id; //!< class identifiers
Byte8_t csn; //!< index of the codestream
Byte8_t bin_offset; //!< offset of the data in this message from the start of the data-bin
Byte8_t length; //!< message byte length
Byte8_t aux; //!<
Byte8_t res_offset; //!< offset in the resource
placeholder_param_t *phld; //!< placeholder pointer in index
struct message_param *next; //!< pointer to the next message
} message_param_t;
//! message queue parameters
typedef struct msgqueue_param{
message_param_t *first; //!< first message pointer of the list
message_param_t *last; //!< last message pointer of the list
bool stateless; //!< if this is a stateless message queue
target_param_t *target; //!< reference target pointer
} msgqueue_param_t;
/**
* generate message queue
*
* @param[in] stateless if this is a stateless message queue
* @param[in] target reference target pointer
* @return generated message queue pointer
*/
msgqueue_param_t * gene_msgqueue( bool stateless, target_param_t *target);
/**
* delete message queue
*
* @param[in] msgqueue address of the message queue pointer
*/
void delete_msgqueue( msgqueue_param_t **msgqueue);
/**
* print message queue
*
* @param[in] msgqueue message queue pointer
*/
void print_msgqueue( msgqueue_param_t *msgqueue);
/**
* enqueue main header data-bin into message queue
*
* @param[in,out] msgqueue message queue pointer
*/
void enqueue_mainheader( msgqueue_param_t *msgqueue);
/**
* enqueue tile data-bin into message queue
*
* @param[in] tile_id tile id starting from 0
* @param[in] level decomposition level
* @param[in,out] msgqueue message queue pointer
*/
void enqueue_tile( int tile_id, int level, msgqueue_param_t *msgqueue);
/**
* enqueue Metadata-bin into message queue
*
* @param[in] meta_id metadata-bin id
* @param[in,out] msgqueue message queue pointer
*/
void enqueue_metadata( int meta_id, msgqueue_param_t *msgqueue);
/**
* emit stream from message queue
*
* @param[in] msgqueue message queue pointer
*/
void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue);
/**
* parse JPT-stream to message queue
*
* @param[in] stream JPT-stream data pointer
* @param[in] jptlen JPT-stream length
* @param[in] offset offset of the JPT-stream from the whole beginning
* @param[in,out] msgqueue adding message queue pointer
*/
void parse_stream( Byte_t *stream, Byte8_t jptlen, Byte8_t offset, msgqueue_param_t *msgqueue);
/**
* parse JPT-stream to message queue
*
* @param[in] msgqueue reference message queue pointer
* @param[in] stream JPT-stream data pointer
* @param[in] jptlen JPT-stream length
* @param[in] metadatalist adding metadata list pointer
*/
void parse_metamsg( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t jptlen, metadatalist_param_t *metadatalist);
/**
* reconstruct j2k codestream from message queue
*
* @param[in] msgqueue message queue pointer
* @param[in] stream original stream
* @param[in] csn codestream number
* @param[in] minlev minimum decomposition level
* @param[out] j2klen pointer to the j2k codestream length
* @return generated reconstructed j2k codestream
*/
Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t csn, int minlev, Byte8_t *j2klen);
/**
* reconstruct jp2 file codestream from message queue
*
* @param[in] msgqueue message queue pointer
* @param[in] stream original stream
* @param[in] csn codestream number
* @param[out] jp2len pointer to the jp2 codestream length
* @return generated reconstructed jp2 codestream
*/
Byte_t * recons_jp2( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t csn, Byte8_t *jp2len);
#endif /* !MSGQUEUE_MANAGER_H_ */

View File

@ -0,0 +1,138 @@
/*
* $Id: placeholder_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 <stdlib.h>
#include <string.h>
#include "placeholder_manager.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
placeholderlist_param_t * gene_placeholderlist()
{
placeholderlist_param_t *list;
list = (placeholderlist_param_t *)malloc( sizeof(placeholderlist_param_t));
list->first = NULL;
list->last = NULL;
return list;
}
void delete_placeholderlist( placeholderlist_param_t **list)
{
placeholder_param_t *ptr, *next;
if(!(*list))
return;
ptr = (*list)->first;
while( ptr){
next=ptr->next;
delete_placeholder( &ptr);
ptr=next;
}
free( *list);
}
placeholder_param_t * gene_placeholder( box_param_t *box, int origID)
{
placeholder_param_t *placeholder;
placeholder = (placeholder_param_t *)malloc( sizeof(placeholder_param_t));
strncpy( placeholder->TBox, "phld", 4);
placeholder->Flags = 1; // only the access to the original contents of this box, for now
placeholder->OrigID = origID;
placeholder->OrigBH = fetch_headbytes( box);
placeholder->OrigBHlen = box->headlen;
placeholder->LBox = 20+box->headlen;
placeholder->next = NULL;
return placeholder;
}
void delete_placeholder( placeholder_param_t **placeholder)
{
if( (*placeholder)->OrigBH)
free((*placeholder)->OrigBH);
free(*placeholder);
}
void insert_placeholder_into_list( placeholder_param_t *phld, placeholderlist_param_t *phldlist)
{
if( phldlist->first)
phldlist->last->next = phld;
else
phldlist->first = phld;
phldlist->last = phld;
}
void print_placeholder( placeholder_param_t *phld)
{
fprintf( logstream, "placeholder info:\n");
fprintf( logstream, "\t LBox: %d %#x\n", phld->LBox, phld->LBox);
fprintf( logstream, "\t TBox: %.4s\n", phld->TBox);
fprintf( logstream, "\t Flags: %#x %#x\n", phld->Flags, phld->Flags);
fprintf( logstream, "\t OrigID: %lld\n", phld->OrigID);
fprintf( logstream, "\t OrigBH: ");
for( int i=0; i< phld->OrigBHlen; i++)
fprintf( logstream, "%02x ", phld->OrigBH[i]);
fprintf( logstream, "\t");
for( int i=0; i< phld->OrigBHlen; i++)
fprintf( logstream, "%c", phld->OrigBH[i]);
fprintf( logstream, "\n");
}
void print_allplaceholder( placeholderlist_param_t *list)
{
placeholder_param_t *ptr;
if( !list)
return;
fprintf( logstream, "all placeholder info: \n");
ptr = list->first;
while( ptr != NULL){
print_placeholder( ptr);
ptr=ptr->next;
}
}

View File

@ -0,0 +1,115 @@
/*
* $Id: placeholder_manager.h 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.
*/
#ifndef PLACEHOLDER_MANAGER_H_
# define PLACEHOLDER_MANAGER_H_
#include "byte_manager.h"
#include "box_manager.h"
//! A.3.6.3 Placeholder box format
//! placeholder box parameters
typedef struct placeholder_param{
Byte4_t LBox;
char TBox[4];
Byte4_t Flags;
Byte8_t OrigID;
Byte_t *OrigBH; //!< dynamic memory pointer
Byte_t OrigBHlen; //!< length of OrigBH
#ifdef AAA
Byte8_t EquivID;
Byte_t *EquivBH; //!< dynamic memory pointer
Byte_t EquivBHlen; //!< length of EquivBH
Byte8_t CSID;
Byte4_t NCS;
#endif //AAA
struct placeholder_param *next; //!< pointer to the next placeholder
} placeholder_param_t;
//! placeholder box list parameters
typedef struct placeholderlist_param{
placeholder_param_t *first; //!< first placeholder pointer of the list
placeholder_param_t *last; //!< last placeholder pointer of the list
} placeholderlist_param_t;
/**
* generate a placeholder list
*
* @return pointer to the generated placeholder list
*/
placeholderlist_param_t * gene_placeholderlist();
/**
* delete placeholder list
*
* @param[in,out] list address of the placeholder list pointer
*/
void delete_placeholderlist( placeholderlist_param_t **list);
/**
* generate a placeholder of a box
*
* @param[in] box box pointer
* @param[in] origID metadata-bin ID of the bin containing the contents of the original box
* @return pointer to the generated placeholder
*/
placeholder_param_t * gene_placeholder( box_param_t *box, int origID);
/**
* delete a placeholder
*
* @param[in,out] placeholder address of the placeholder pointer
*/
void delete_placeholder( placeholder_param_t **placeholder);
void insert_placeholder_into_list( placeholder_param_t *phld, placeholderlist_param_t *phldlist);
/**
* print placeholder parameters
*
* @param[in] phld placeholder pointer
*/
void print_placeholder( placeholder_param_t *phld);
/**
* print all placeholder parameters
*
* @param[in] list placeholder list pointer
*/
void print_allplaceholder( placeholderlist_param_t *list);
#endif /* !PLACEHOLDER_MANAGER_H_ */

View File

@ -0,0 +1,210 @@
/*
* $Id: target_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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include "target_manager.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
targetlist_param_t * gene_targetlist()
{
targetlist_param_t *targetlist;
targetlist = (targetlist_param_t *)malloc( sizeof(targetlist_param_t));
targetlist->first = NULL;
targetlist->last = NULL;
return targetlist;
}
/**
* open jp2 format image file
*
* @param[in] filename file name (.jp2)
* @return file descriptor
*/
int open_jp2file( char filename[]);
target_param_t * gene_target( char *targetname)
{
target_param_t *target;
int fd;
index_param_t *jp2idx;
static int last_csn = 0;
if( targetname[0]=='\0'){
fprintf( FCGI_stderr, "Error: exception, no targetname in gene_target()\n");
return NULL;
}
if((fd = open_jp2file( targetname)) == -1){
fprintf( FCGI_stdout, "Status: 404\r\n");
return NULL;
}
if( !(jp2idx = parse_jp2file( fd))){
fprintf( FCGI_stdout, "Status: 501\r\n");
return NULL;
}
target = (target_param_t *)malloc( sizeof(target_param_t));
strcpy( target->filename, targetname);
target->fd = fd;
target->csn = last_csn++;
target->codeidx = jp2idx;
target->next=NULL;
return target;
}
void delete_target( target_param_t **target)
{
close( (*target)->fd);
delete_index ( &(*target)->codeidx);
#ifndef SERVER
fprintf( logstream, "local log: target: %s deleted\n", (*target)->filename);
#endif
free(*target);
}
void delete_target_in_list( target_param_t **target, targetlist_param_t *targetlist)
{
target_param_t *ptr;
if( *target == targetlist->first)
targetlist->first = (*target)->next;
else{
ptr = targetlist->first;
while( ptr->next != *target){
ptr=ptr->next;
}
ptr->next = (*target)->next;
if( *target == targetlist->last)
targetlist->last = ptr;
}
delete_target( target);
}
void delete_targetlist(targetlist_param_t **targetlist)
{
target_param_t *targetPtr, *targetNext;
targetPtr = (*targetlist)->first;
while( targetPtr != NULL){
targetNext=targetPtr->next;
delete_target( &targetPtr);
targetPtr=targetNext;
}
free( *targetlist);
}
void print_alltarget( targetlist_param_t *targetlist)
{
target_param_t *ptr;
ptr = targetlist->first;
while( ptr != NULL){
fprintf( logstream,"csn=%d\n", ptr->csn);
fprintf( logstream,"target=%s\n", ptr->filename);
ptr=ptr->next;
}
}
target_param_t * search_target( char targetname[], targetlist_param_t *targetlist)
{
target_param_t *foundtarget;
foundtarget = targetlist->first;
while( foundtarget != NULL){
if( strcmp( targetname, foundtarget->filename) == 0)
return foundtarget;
foundtarget = foundtarget->next;
}
return NULL;
}
int open_jp2file( char filename[])
{
int fd;
char *data;
if( (fd = open( filename, O_RDONLY)) == -1){
fprintf( FCGI_stdout, "Reason: Target %s not found\r\n", filename);
return -1;
}
// Check resource is a JP family file.
if( lseek( fd, 0, SEEK_SET)==-1){
close(fd);
fprintf( FCGI_stdout, "Reason: Target %s broken (lseek error)\r\n", filename);
return -1;
}
data = (char *)malloc( 12); // size of header
if( read( fd, data, 12) != 12){
free( data);
close(fd);
fprintf( FCGI_stdout, "Reason: Target %s broken (read error)\r\n", filename);
return -1;
}
if( *data || *(data + 1) || *(data + 2) ||
*(data + 3) != 12 || strncmp (data + 4, "jP \r\n\x87\n", 8)){
free( data);
close(fd);
fprintf( FCGI_stdout, "Reason: No JPEG 2000 Signature box in target %s\r\n", filename);
return -1;
}
free( data);
return fd;
}

View File

@ -0,0 +1,116 @@
/*
* $Id: target_manager.h 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.
*/
#ifndef TARGET_MANAGER_H_
# define TARGET_MANAGER_H_
#include "index_manager.h"
//! maximum length of target name
#define MAX_LENOFTARGET 128
//! target parameters
typedef struct target_param{
char filename[MAX_LENOFTARGET]; //!< file name
int fd; //!< file descriptor
int csn; //!< codestream number
index_param_t *codeidx; //!< index information of codestream
struct target_param *next; //!< pointer to the next target
} target_param_t;
//! Target list parameters
typedef struct targetlist_param{
target_param_t *first; //!< first target pointer of the list
target_param_t *last; //!< last target pointer of the list
} targetlist_param_t;
/**
* generate a target list
*
* @return pointer to the generated target list
*/
targetlist_param_t * gene_targetlist();
/**
* generate a target
*
* @param[in] targetname target file name
* @return pointer to the generated target
*/
target_param_t * gene_target( char *targetname);
/**
* delete a target
*
* @param[in,out] target address of the deleting target pointer
*/
void delete_target( target_param_t **target);
/**
* delete a target in list
*
* @param[in,out] target address of the deleting target pointer
* @param[in] targetlist target list pointer
*/
void delete_target_in_list( target_param_t **target, targetlist_param_t *targetlist);
/**
* delete target list
*
* @param[in,out] targetlist address of the target list pointer
*/
void delete_targetlist(targetlist_param_t **targetlist);
/**
* print all target parameters
*
* @param[in] targetlist target list pointer
*/
void print_alltarget( targetlist_param_t *targetlist);
/**
* search a target by filename
*
* @param[in] targetname target filename
* @param[in] targetlist target list pointer
* @return found target pointer
*/
target_param_t * search_target( char targetname[], targetlist_param_t *targetlist);
#endif /* !TARGET_MANAGER_H_ */

View File

@ -0,0 +1,80 @@
/*
* $Id: mainpage.h 47 2011-02-17 16:57:49Z 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.
*/
/*! \mainpage OpenJPIP v1.0 Documentation
*
* \section intro Introduction
* This manual documents the low-level OpenJPIP C API.\n
* OpenJPIP software is an implementation of JPEG 2000 Part9: Interactivity tools, APIs and protocols (JPIP).\n
* ( For more info about JPIP, check the website: http://www.jpeg.org/jpeg2000/j2kpart9.html)\n
*
* This whole documents covers the following six programs.\n
* - opj_server.c JPIP server supporting HTTP connection and JPT-stream
* - opj_dec_server.c Server to decode JPT-stream and communicate locally with JPIP client, which is coded in java
* - addXMLinJP2.c To Embed metadata into JP2 file
* - jpt_to_jp2.c To Convert JPT-stream to JP2
* - jpt_to_j2k.c To Convert JPT-stream to J2K
* - test_index.c To test index code format of a JP2 file
*
* \section license License
* This software is released under the BSD license, anybody can use or modify the library, even for commercial applications.\n
* The only restriction is to retain the copyright in the sources or the binaries documentation.\n
* Neither the author, nor the university accept any responsibility for any kind of error or data loss which may occur during usage.
*
*
* \section reqlibs Required libraries
* - OpenJPEG library
* - FastCGI development kit (C libraries) at server (http://www.fastcgi.com)
*
* We tested this software with a virtual server running on the same Linux machine as the clients.
*
*
* \section compilenotes Compiling Notes
* When you are making opj_server, set anything (e.g. yes) to the parameter jpipserver to define itself in the Makefile, which enables to make it in server mode.\n
* Otherwise do not define (or do not set to) the parameter jpipserver.\n
* Be sure that any object files and library file libopenjpip.a are not reused to compile in the two different mode (server mode and non server mode).\n
* In other words, do make clean before making new targets which are in different modes as previous make.\n
*
*
* \section sysarchtect System Architecture
* JPIP protocol is implimented between the server program opj_server and the client java program opj_viewer.\n
* The opj_server parses JPIP requests and sends corresponding JPT-stream.
* The opj_viewer is an image viewer with GUI to publish JPIP requests and receive JPT-stream.\n
* JPT-stream is unreadable for the opj_viewer by itself, and the local server program opj_dec_server handles the decoding and caching of JPT-stream.\n
* Typical requests and replies among JPIP server (opj_server), JPIP client (opj_viewer), and Image decoding Server (opj_dec_server) is presented below.\n
* The JPIP client requests the JPIP server JPT-stream, which is directly sent to the Image decoding Server, and which provides the image in PGM or PPM format to the JPIP client.\n
* JPIP client can read PGM and PPM images natively.\n
* Before connecting to the JPIP server, the JPIP client checks local cache data of the requesting image with the image decoding server.
* If its cache exists, the image decoding server provides ChannelID (CID), which identifies the image and its cache model on the JPIP server, and the whole system can continue the session using the CID.
*
* \image html jpip_protocol.png "Message Sequence Chart of OpenJPIP impementation"
*
* \author Kaori Hagihara UCL/SST/ICTM/ELEN
*/

View File

@ -0,0 +1,14 @@
LIBDIR = ../../libopenjpip
LIBFNAME = $(LIBDIR)/libopenjpip_local.a
CFLAGS = -O3 -Wall -std=c99 -pedantic -I$(LIBDIR)
LDFLAGS = -L$(LIBDIR) -lm -lopenjpeg -lopenjpip_local
ALL = opj_dec_server
all: $(ALL)
opj_dec_server: opj_dec_server.o jp2k_decoder.o imgsock_manager.o jptstream_manager.o cache_manager.o $(LIBFNAME)
$(CC) $(CFLAGS) $< jp2k_decoder.o imgsock_manager.o jptstream_manager.o cache_manager.o $(LDFLAGS) -o $@
clean:
rm -f $(ALL) *.o *~

View File

@ -0,0 +1,239 @@
/*
* $Id: cache_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 <stdlib.h>
#include <string.h>
#include "cache_manager.h"
//! maximum length of channel identifier
#define MAX_LENOFCID 30
cachelist_param_t * gene_cachelist()
{
cachelist_param_t *cachelist;
cachelist = (cachelist_param_t *)malloc( sizeof(cachelist_param_t));
cachelist->first = NULL;
cachelist->last = NULL;
return cachelist;
}
void delete_cachelist(cachelist_param_t **cachelist)
{
cache_param_t *cachePtr, *cacheNext;
cachePtr = (*cachelist)->first;
while( cachePtr != NULL){
cacheNext=cachePtr->next;
delete_cache( &cachePtr);
cachePtr=cacheNext;
}
free( *cachelist);
}
cache_param_t * gene_cache( char *targetname, int csn, char *cid)
{
cache_param_t *cache;
cache = (cache_param_t *)malloc( sizeof(cache_param_t));
strcpy( cache->filename, targetname);
cache->csn = csn;
cache->cid = (char **)malloc( sizeof(char *));
*cache->cid = (char *)malloc( MAX_LENOFCID);
strcpy( *cache->cid, cid);
cache->numOfcid = 1;
#if 1
cache->metadatalist = NULL;
#else
cache->metadatalist = gene_metadatalist();
#endif
cache->ihdrbox = NULL;
cache->next = NULL;
return cache;
}
void delete_cache( cache_param_t **cache)
{
delete_metadatalist( &(*cache)->metadatalist);
if((*cache)->ihdrbox)
free((*cache)->ihdrbox);
for( int i=0; i<(*cache)->numOfcid; i++)
free( (*cache)->cid[i]);
free( (*cache)->cid);
free( *cache);
}
void insert_cache_into_list( cache_param_t *cache, cachelist_param_t *cachelist)
{
if( cachelist->first)
cachelist->last->next = cache;
else
cachelist->first = cache;
cachelist->last = cache;
}
cache_param_t * search_cache( char targetname[], cachelist_param_t *cachelist)
{
cache_param_t *foundcache;
foundcache = cachelist->first;
while( foundcache != NULL){
if( strcmp( targetname, foundcache->filename) == 0)
return foundcache;
foundcache = foundcache->next;
}
return NULL;
}
cache_param_t * search_cacheBycsn( int csn, cachelist_param_t *cachelist)
{
cache_param_t *foundcache;
foundcache = cachelist->first;
while( foundcache != NULL){
if( csn == foundcache->csn)
return foundcache;
foundcache = foundcache->next;
}
return NULL;
}
cache_param_t * search_cacheBycid( char cid[], cachelist_param_t *cachelist)
{
cache_param_t *foundcache;
foundcache = cachelist->first;
while( foundcache != NULL){
for( int i=0; i<foundcache->numOfcid; i++)
if( strcmp( cid, foundcache->cid[i]) == 0)
return foundcache;
foundcache = foundcache->next;
}
return NULL;
}
void add_cachecid( char *cid, cache_param_t *cache)
{
char **tmp;
tmp = cache->cid;
cache->cid = (char **)malloc( (cache->numOfcid+1)*sizeof(char *));
for( int i=0; i<cache->numOfcid; i++){
cache->cid[i] = (char *)malloc( MAX_LENOFCID);
strcpy( cache->cid[i], tmp[i]);
free( tmp[i]);
}
free( tmp);
cache->cid[ cache->numOfcid] = (char *)malloc( MAX_LENOFCID);
strcpy( cache->cid[ cache->numOfcid], cid);
cache->numOfcid ++;
}
void remove_cidInCache( char *cid, cache_param_t *cache);
void remove_cachecid( char *cid, cachelist_param_t *cachelist)
{
cache_param_t *cache;
cache = search_cacheBycid( cid, cachelist);
remove_cidInCache( cid, cache);
}
void remove_cidInCache( char *cid, cache_param_t *cache)
{
int idx = -1;
char **tmp;
for( int i=0; i<cache->numOfcid; i++)
if( strcmp( cid, cache->cid[i]) == 0){
idx = i;
break;
}
if( idx == -1){
fprintf( stderr, "cid: %s not found\n", cid);
return;
}
tmp = cache->cid;
cache->cid = (char **)malloc( (cache->numOfcid-1)*sizeof(char *));
for( int i=0, j=0; i<cache->numOfcid; i++){
if( i != idx){
cache->cid[j] = (char *)malloc( MAX_LENOFCID);
strcpy( cache->cid[j], tmp[i]);
j++;
}
free( tmp[i]);
}
free( tmp);
cache->numOfcid --;
}
void print_cache( cache_param_t *cache)
{
fprintf( stdout,"cache\n");
fprintf( stdout,"\t filename: %s\n", cache->filename);
fprintf( stdout,"\t csn: %d\n", cache->csn);
fprintf( stdout,"\t cid:");
for( int i=0; i<cache->numOfcid; i++)
fprintf( stdout," %s", cache->cid[i]);
fprintf( stdout,"\n");
}
void print_allcache( cachelist_param_t *cachelist)
{
cache_param_t *ptr;
fprintf( stdout,"cache list\n");
ptr = cachelist->first;
while( ptr != NULL){
print_cache( ptr);
ptr=ptr->next;
}
}

View File

@ -0,0 +1,158 @@
/*
* $Id: cache_manager.h 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.
*/
#ifndef CACHE_MANAGER_H_
# define CACHE_MANAGER_H_
#include "metadata_manager.h"
#include "ihdrbox_manager.h"
//! maximum length of target name
#define MAX_LENOFTARGET 128
//! cache parameters
typedef struct cache_param{
char filename[MAX_LENOFTARGET]; //!< file name
int csn; //!< codestream number
char **cid; //!< dynamic array of channel identifiers
int numOfcid; //!< number of cids
metadatalist_param_t *metadatalist; //!< metadata-bin list
ihdrbox_param_t *ihdrbox; //!< ihdrbox
struct cache_param *next; //!< pointer to the next cache
} cache_param_t;
//!< cache list parameters
typedef struct cachelist_param{
cache_param_t *first; //!< first cache pointer of the list
cache_param_t *last; //!< last cache pointer of the list
} cachelist_param_t;
/**
* generate a cache list
*
* @return pointer to the generated cache list
*/
cachelist_param_t * gene_cachelist();
/**
* delete cache list
*
* @param[in,out] cachelist address of the cache list pointer
*/
void delete_cachelist(cachelist_param_t **cachelist);
/**
* generate a cache
*
* @param[in] targetname target file name
* @param[in] csn codestream number
* @param[in] cid channel identifier
* @return pointer to the generated cache
*/
cache_param_t * gene_cache( char *targetname, int csn, char *cid);
/**
* delete a cache
*
* @param[in] cache address of the cache pointer
*/
void delete_cache( cache_param_t **cache);
/**
* insert a cache into list
*
* @param[in] cache cache pointer
* @param[in] cachelist cache list pointer
*/
void insert_cache_into_list( cache_param_t *cache, cachelist_param_t *cachelist);
/**
* search a cache by target name
*
* @param[in] targetname target filename
* @param[in] cachelist cache list pointer
* @return found cache pointer
*/
cache_param_t * search_cache( char targetname[], cachelist_param_t *cachelist);
/**
* search a cache by csn
*
* @param[in] csn codestream number
* @param[in] cachelist cache list pointer
* @return found cache pointer
*/
cache_param_t * search_cacheBycsn( int csn, cachelist_param_t *cachelist);
/**
* search codestream number (csn) by cid
*
* @param[in] cid channel identifer
* @param[in] cachelist cache list pointer
* @return found cache pointer
*/
cache_param_t * search_cacheBycid( char cid[], cachelist_param_t *cachelist);
/**
* add cid into a cache
*
* @param[in] cid channel identifier
* @param[in] cache cache pointer
*/
void add_cachecid( char *cid, cache_param_t *cache);
/**
* remove cid in cache
*
* @param[in] cid channel identifier
* @param[in] cachelist cachelist pointer
*/
void remove_cachecid( char *cid, cachelist_param_t *cachelist);
/**
* print cache parameters
*
* @param[in] cache cache pointer
*/
void print_cache( cache_param_t *cache);
/**
* print all cache parameters
*
* @param[in] cachelist cache list pointer
*/
void print_allcache( cachelist_param_t *cachelist);
#endif /* !CACHE_MANAGER_H_ */

View File

@ -0,0 +1,260 @@
/*
* $Id: imgsock_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 <strings.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/uio.h>
#include <unistd.h>
#include <sys/param.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "imgsock_manager.h"
#define BUF_LEN 256
int open_listeningsocket()
{
int listening_socket;
struct sockaddr_in sin;
int sock_optval = 1;
int port = 5000;
listening_socket = socket(AF_INET, SOCK_STREAM, 0);
if ( listening_socket == -1 ){
perror("socket");
exit(1);
}
if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
&sock_optval, sizeof(sock_optval)) == -1 ){
perror("setsockopt");
exit(1);
}
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = htonl(INADDR_ANY);
if ( bind(listening_socket, (struct sockaddr *)&sin, sizeof(sin)) < 0 ){
perror("bind");
exit(1);
}
if( listen(listening_socket, SOMAXCONN) == -1){
perror("listen");
exit(1);
}
printf("port %d is listened\n", port);
return listening_socket;
}
msgtype_t identify_clientmsg( int connected_socket)
{
int read_size;
char buf[BUF_LEN];
char *magicid[] = { "JPT-stream", "PNM request", "XML request", "CID request", "CID destroy", "JP2 save", "QUIT"};
read_size = read_line( connected_socket, buf);
if( read_size == 0){
fprintf( stderr, "Error to read the header of client message\n");
return ERROR;
}
for( int i=0; i<NUM_OF_MSGTYPES; i++){
if( strncasecmp( magicid[i], buf, strlen(magicid[i])) == 0){
printf("Client message: %s\n", magicid[i]);
return i;
}
}
fprintf( stderr, "Cannot identify client message type\n");
return ERROR;
}
Byte_t * receive_JPTstream( int connected_socket, char *target, char *cid, int *streamlen)
{
Byte_t *jptstream=NULL, *ptr;
char buf[BUF_LEN], versionstring[] = "version 1.0";
int linelen, redlen, remlen;
target[0] = 0;
cid[0] = 0;
if((linelen = read_line( connected_socket, buf)) == 0)
return NULL;
if( strncmp( versionstring, buf, strlen(versionstring))!=0){
fprintf( stderr, "Wrong format\n");
return NULL;
}
if((linelen = read_line( connected_socket, buf)) == 0)
return NULL;
if( strstr( buf, "jp2")){
// register cid option
strcpy( target, buf);
if((linelen = read_line( connected_socket, buf)) == 0)
return NULL;
strcpy( cid, buf);
if((linelen = read_line( connected_socket, buf)) == 0)
return NULL;
}
*streamlen = atoi( buf);
fprintf( stderr, "Reading Data length: %d\n", *streamlen);
jptstream = (unsigned char *)malloc( (*streamlen));
ptr = jptstream;
remlen = (*streamlen);
while( remlen > 0){
redlen = read( connected_socket, ptr, remlen);
if( redlen == -1){
fprintf( stderr, "read jptstream error\n");
break;
}
remlen -= redlen;
ptr = ptr + redlen;
}
fprintf( stderr, " done\n");
return jptstream;
}
void send_stream( int connected_socket, void *stream, int length);
void send_XMLstream( int connected_socket, Byte_t *xmlstream, int length)
{
Byte_t header[5];
header[0] = 'X';
header[1] = 'M';
header[2] = 'L';
header[3] = (length >> 8) & 0xff;
header[4] = length & 0xff;
send_stream( connected_socket, header, 5);
send_stream( connected_socket, xmlstream, length);
}
void send_CIDstream( int connected_socket, char *cid, int cidlen)
{
Byte_t header[4];
header[0] = 'C';
header[1] = 'I';
header[2] = 'D';
header[3] = cidlen & 0xff;
send_stream( connected_socket, header, 4);
send_stream( connected_socket, cid, cidlen);
}
void send_PNMstream( int connected_socket, Byte_t *pnmstream, unsigned int width, unsigned int height, unsigned int numofcomp, Byte_t maxval)
{
int pnmlen = 0;
Byte_t header[7];
pnmlen = width*height*numofcomp;
header[0] = 'P';
header[1] = numofcomp==3 ? 6:5;
header[2] = (width >> 8) & 0xff;
header[3] = width & 0xff;
header[4] = (height >> 8) & 0xff;
header[5] = height & 0xff;
header[6] = maxval;
send_stream( connected_socket, header, 7);
send_stream( connected_socket, pnmstream, pnmlen);
}
void send_stream( int connected_socket, void *stream, int length)
{
void *ptr = stream;
int remlen = length;
while( remlen > 0){
int sentlen = write( connected_socket, ptr, remlen);
if( sentlen == -1){
fprintf( stderr, "sending stream error\n");
break;
}
remlen = remlen - sentlen;
ptr = ptr + sentlen;
}
}
int read_line(int socket, char *p)
{
int len = 0;
while (1){
int ret;
ret = read(socket, p, 1);
if ( ret == -1 ){
perror("read");
exit(1);
} else if ( ret == 0 ){
break;
}
if ( *p == '\n' )
break;
p++;
len++;
}
*p = '\0';
if( len == 0)
fprintf( stderr, "Header read error\n");
return len;
}
void response_signal( int connected_socket, bool succeed)
{
Byte_t code;
if( succeed)
code = 1;
else
code = 0;
if( write( connected_socket, &code, 1) != 1)
fprintf( stderr, "Response signalling error\n");
}

View File

@ -0,0 +1,159 @@
/*
* $Id: imgsock_manager.h 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.
*/
#ifndef IMGSOCK_MANAGER_H_
# define IMGSOCK_MANAGER_H_
#include <stdbool.h>
#include "byte_manager.h"
/**
* open listening socket
*
* @return file descriptor for the new socket
*/
int open_listeningsocket();
#define NUM_OF_MSGTYPES 7
typedef enum eMSGTYPE{ JPTSTREAM, PNMREQ, XMLREQ, CIDREQ, CIDDST, JP2SAVE, QUIT, ERROR} msgtype_t;
/**
* indeitify client message type
*
* @param [in] connected_socket file descriptor of the connected socket
* @return message type
*/
msgtype_t identify_clientmsg( int connected_socket);
/**
* receive JPT-stream from client
*
* @param [in] connected_socket file descriptor of the connected socket
* @param [out] target received target file name (if not received, null string)
* @param [out] cid received channel identifier (if not received, null string)
* @param [out] streamlen length of the received codestream
* @return codestream
*/
Byte_t * receive_JPTstream( int connected_socket, char *target, char *cid, int *streamlen);
/**
* send PGM/PPM image stream to the client
*
* @param [in] connected_socket file descriptor of the connected socket
* @param [in] pnmstream PGM/PPM image codestream
* @param [in] width width of the image
* @param [in] height height of the image
* @param [in] numofcomp number of components of the image
* @param [in] maxval maximum value of the image (only 255 supported)
*/
void send_PNMstream( int connected_socket, Byte_t *pnmstream, unsigned int width, unsigned int height, unsigned int numofcomp, Byte_t maxval);
/**
* send XML data stream to the client
*
* @param [in] connected_socket file descriptor of the connected socket
* @param [in] xmlstream xml data stream
* @param [in] length legnth of the xml data stream
*/
void send_XMLstream( int connected_socket, Byte_t *xmlstream, int length);
/**
* send CID data stream to the client
*
* @param [in] connected_socket file descriptor of the connected socket
* @param [in] cid cid string
* @param [in] cidlen legnth of the cid string
*/
void send_CIDstream( int connected_socket, char *cid, int cidlen);
/**
* send response signal to the client
*
* @param [in] connected_socket file descriptor of the connected socket
* @param [in] succeed whether if the requested process succeeded
*/
void response_signal( int connected_socket, bool succeed);
/**
* read a string line (ending with '\n') from client
*
* @param [in] connected_socket file descriptor of the connected socket
* @param [out] buf string to be stored
* @return red size
*/
int read_line(int connected_socket, char *buf);
#endif /* !IMGSOCK_MANAGER_H_ */
/*! \file
* PROTOCOL specification to communicate with opj_dec_server
*
*\section sec1 JPT-stream
* Cache JPT-stream in server
*
* client -> server: JPT-stream\\n version 1.0\\n (optional for cid registration: targetnamestring\\n cidstring\\n) bytelengthvalue\\n data \n
* server -> client: 1 or 0 (of 1Byte response signal)
*
*\section sec2 PNM request
* Get decoded PGM/PPM image
*
* client -> server: PNM request\\n cidstring\\n fw\\n fh\\n \n
* server -> client: P6 or P5 (2Byte) width (2Byte Big endian) height (2Byte Big endian) maxval (1Byte) data
*
*\section sec3 XML request
* Get XML data
*
* client -> server: XML request\\n \n
* server -> client: XML (3Byte) length (2Byte Big endian) data
*
*\section sec4 CID request
* Get Channel ID of identical target image
*
* client -> server: CID request\\n targetname\\n \n
* server -> client: CID (3Byte) length (1Byte) ciddata
*
*\section sec5 CID destroy
* Close Channel ID
*
* client -> server: CID destroy\\n ciddata \n
* server -> client: 1 or 0 (of 1Byte response signal)
*
*\section sec6 JP2 save
* Save in JP2 file format
*
* client -> server: JP2 save\\n ciddata \n
* server -> client: 1 or 0 (of 1Byte response signal)
*
*\section sec7 QUIT
* Quit the opj_dec_server program
*
* client -> server: quit or QUIT
*/

View File

@ -0,0 +1,202 @@
/*
* $Id: jp2k_decoder.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 <string.h>
#include <stdlib.h>
#include "jp2k_decoder.h"
#include "openjpeg.h"
void error_callback(const char *msg, void *client_data);
void warning_callback(const char *msg, void *client_data);
void info_callback(const char *msg, void *client_data);
Byte_t * imagetopnm(opj_image_t *image, ihdrbox_param_t **ihdrbox);
Byte_t * j2k_to_pnm( Byte_t *j2kstream, Byte8_t j2klen, ihdrbox_param_t **ihdrbox)
{
Byte_t *pnmstream = NULL;
opj_dparameters_t parameters; /* decompression parameters */
opj_event_mgr_t event_mgr; /* event manager */
opj_image_t *image = NULL;
opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */
opj_cio_t *cio = NULL;
/* configure the event callbacks (not required) */
memset(&event_mgr, 0, sizeof(opj_event_mgr_t));
event_mgr.error_handler = error_callback;
event_mgr.warning_handler = warning_callback;
event_mgr.info_handler = info_callback;
/* set decoding parameters to default values */
opj_set_default_decoder_parameters(&parameters);
/* decode the code-stream */
/* ---------------------- */
/* JPEG-2000 codestream */
/* get a decoder handle */
dinfo = opj_create_decompress( CODEC_J2K);
/* catch events using our callbacks and give a local context */
opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr);
/* setup the decoder decoding parameters using user parameters */
opj_setup_decoder(dinfo, &parameters);
/* open a byte stream */
cio = opj_cio_open((opj_common_ptr)dinfo, j2kstream, j2klen);
/* decode the stream and fill the image structure */
image = opj_decode(dinfo, cio);
if(!image) {
fprintf(stderr, "ERROR -> jp2_to_image: failed to decode image!\n");
opj_destroy_decompress(dinfo);
opj_cio_close(cio);
return NULL;
}
/* close the byte stream */
opj_cio_close(cio);
/* create output image */
/* ------------------- */
if( (pnmstream = imagetopnm( image, ihdrbox))==NULL)
fprintf( stderr, "PNM image not generated\n");
/* free remaining structures */
if(dinfo) {
opj_destroy_decompress(dinfo);
}
/* free image data structure */
opj_image_destroy(image);
return pnmstream;
}
/**
sample error callback expecting a FILE* client object
*/
void error_callback(const char *msg, void *client_data) {
FILE *stream = (FILE*)client_data;
fprintf(stream, "[ERROR] %s", msg);
}
/**
sample warning callback expecting a FILE* client object
*/
void warning_callback(const char *msg, void *client_data) {
FILE *stream = (FILE*)client_data;
fprintf(stream, "[WARNING] %s", msg);
}
/**
sample debug callback expecting no client object
*/
void info_callback(const char *msg, void *client_data) {
(void)client_data;
// fprintf(stdout, "[INFO] %s", msg);
}
Byte_t * imagetopnm(opj_image_t *image, ihdrbox_param_t **ihdrbox)
{
int adjustR, adjustG=0, adjustB=0;
int datasize;
Byte_t *pix=NULL, *ptr=NULL;
if(*ihdrbox){
if( (*ihdrbox)->nc != image->numcomps)
fprintf( stderr, "Exception: num of components not identical, codestream: %d, ihdrbox: %d\n", image->numcomps, (*ihdrbox)->nc);
if( (*ihdrbox)->width != image->comps[0].w)
fprintf( stderr, "Exception: width value not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].w, (*ihdrbox)->width);
if( (*ihdrbox)->height != image->comps[0].h)
fprintf( stderr, "Exception: heigth value not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].h, (*ihdrbox)->height);
if( (*ihdrbox)->bpc != image->comps[0].prec)
fprintf( stderr, "Exception: bits per component not identical, codestream: %d, ihdrbox: %d\n", image->comps[0].prec, (*ihdrbox)->bpc);
}
else{
*ihdrbox = (ihdrbox_param_t *)malloc( sizeof(ihdrbox_param_t));
(*ihdrbox)->width = image->comps[0].w;
(*ihdrbox)->height = image->comps[0].h;
(*ihdrbox)->bpc = image->comps[0].prec;
(*ihdrbox)->nc = image->numcomps;
}
datasize = (image->numcomps)*(image->comps[0].w)*(image->comps[0].h);
if (image->comps[0].prec > 8) {
adjustR = image->comps[0].prec - 8;
printf("PNM CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec);
}
else
adjustR = 0;
if( image->numcomps == 3){
if (image->comps[1].prec > 8) {
adjustG = image->comps[1].prec - 8;
printf("PNM CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec);
}
else
adjustG = 0;
if (image->comps[2].prec > 8) {
adjustB = image->comps[2].prec - 8;
printf("PNM CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec);
}
else
adjustB = 0;
}
pix = (Byte_t *)malloc( datasize);
ptr = pix;
for( int i = 0; i < image->comps[0].w * image->comps[0].h; i++){
int r, g, b;
r = image->comps[0].data[i];
r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0);
// if( adjustR > 0)
*(ptr++) = (Byte_t) ((r >> adjustR)+((r >> (adjustR-1))%2));
if( image->numcomps == 3){
g = image->comps[1].data[i];
g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0);
*(ptr++) = (Byte_t) ((g >> adjustG)+((g >> (adjustG-1))%2));
b = image->comps[2].data[i];
b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0);
*(ptr++) = (Byte_t) ((b >> adjustB)+((b >> (adjustB-1))%2));
}
}
return pix;
}

View File

@ -0,0 +1,39 @@
/*
* $Id: jp2k_decoder.h 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.
*/
#ifndef JP2K_DECODER_H_
# define JP2K_DECODER_H_
#include "byte_manager.h"
#include "ihdrbox_manager.h"
Byte_t * j2k_to_pnm( Byte_t *j2kstream, Byte8_t j2klen, ihdrbox_param_t **ihdrbox);
#endif /* !JP2K_DECODER_H_ */

View File

@ -0,0 +1,91 @@
/*
* $Id: jptstream_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 <stdlib.h>
#include <string.h>
#include <time.h>
#include "jptstream_manager.h"
#include "jp2k_decoder.h"
#include "imgreg_manager.h"
Byte_t * update_JPTstream( Byte_t *newjptstream, int newjptlen, Byte_t *cache_jptstream, int *jptlen)
{
Byte_t *jptstream = (Byte_t *)malloc( (*jptlen)+newjptlen);
if( *jptlen > 0)
memcpy( jptstream, cache_jptstream, *jptlen);
memcpy( jptstream+(*jptlen), newjptstream, newjptlen);
*jptlen += newjptlen;
if(cache_jptstream)
free( cache_jptstream);
return jptstream;
}
Byte_t * jpt_to_pnm( Byte_t *jptstream, msgqueue_param_t *msgqueue, Byte8_t csn, int fw, int fh, ihdrbox_param_t **ihdrbox)
{
Byte_t *pnmstream;
Byte_t *j2kstream; // j2k or jp2 codestream
Byte8_t j2klen;
int level = 0;
if( *ihdrbox){
// infinit value is set for maxmum level
int fx = fw, fy = fh;
int xmin = 0, ymin = 0;
int xmax = (*ihdrbox)->width, ymax = (*ihdrbox)->height;
find_level( 1000, &level, &fx, &fy, &xmin, &ymin, &xmax, &ymax);
}
j2kstream = recons_j2k( msgqueue, jptstream, csn, level+1, &j2klen);
pnmstream = j2k_to_pnm( j2kstream, j2klen, ihdrbox);
free( j2kstream);
return pnmstream;
}
void save_codestream( Byte_t *codestream, Byte8_t streamlen, char *fmt)
{
time_t timer;
struct tm *t_st;
char filename[20];
FILE *fp;
time(&timer);
t_st = localtime( &timer);
sprintf( filename, "%4d%02d%02d%02d%02d%02d.%.3s", t_st->tm_year+1900, t_st->tm_mon+1, t_st->tm_mday, t_st->tm_hour, t_st->tm_min, t_st->tm_sec, fmt);
fp = fopen( filename, "wb");
fwrite( codestream, streamlen, 1, fp);
fclose( fp);
}

View File

@ -0,0 +1,39 @@
/*
* $Id: jptstream_manager.h 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 "byte_manager.h"
#include "msgqueue_manager.h"
#include "ihdrbox_manager.h"
Byte_t * update_JPTstream( Byte_t *newjptstream, int newjptlen, Byte_t *cache_jptstream, int *jptlen);
Byte_t * jpt_to_pnm( Byte_t *jptstream, msgqueue_param_t *msgqueue, Byte8_t csn, int fw, int fh, ihdrbox_param_t **ihdrbox);
void save_codestream( Byte_t *codestream, Byte8_t streamlen, char *fmt);

View File

@ -0,0 +1,319 @@
/*
* $Id: opj_dec_server.c 46 2011-02-17 14:50:55Z 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.
*/
/*! \file
* \brief opj_dec_server is a server to decode JPT-stream and communicate locally with JPIP client, which is coded in java.
*
* \section impinst Implementing instructions
* Launch opj_dec_server from a terminal in the same machine as JPIP client image viewers. \n
* % ./opj_dec_server \n
* Keep it alive as long as image viewers are open.\n
*
* To quite the opj_dec_server, send a message "quit" through the telnet.\n
* % telnet localhost 5000\n
* quit\n
* Be sure all image viewers are closed.\n
* Cache file in JPT format is stored in the working directly before it quites.
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <unistd.h>
#include "byte_manager.h"
#include "msgqueue_manager.h"
#include "ihdrbox_manager.h"
#include "imgsock_manager.h"
#include "jptstream_manager.h"
#include "cache_manager.h"
//! maximum length of target name
#define MAX_LENOFTARGET 128
//! maximum length of channel identifier
#define MAX_LENOFCID 30
/**
* handle JPTstream message
*
* @param[in] connected_socket socket descriptor
* @param[in] cachelist cache list pointer
* @param[in,out] jptstream address of jptstream pointer
* @param[in,out] jptlen address of jptstream length
* @param[in,out] msgqueue message queue pointer
*/
void handle_JPTstreamMSG( int connected_socket, cachelist_param_t *cachelist, Byte_t **jptstream, int *jptlen, msgqueue_param_t *msgqueue);
/**
* handle PNM request message
*
* @param[in] connected_socket socket descriptor
* @param[in] jptstream jptstream pointer
* @param[in] msgqueue message queue pointer
* @param[in] cachelist cache list pointer
*/
void handle_PNMreqMSG( int connected_socket, Byte_t *jptstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist);
/**
* handle XML request message
*
* @param[in] connected_socket socket descriptor
* @param[in] jptstream address of caching jptstream pointer
* @param[in] cachelist cache list pointer
*/
void handle_XMLreqMSG( int connected_socket, Byte_t *jptstream, cachelist_param_t *cachelist);
/**
* handle ChannelID request message
*
* @param[in] connected_socket socket descriptor
* @param[in] cachelist cache list pointer
*/
void handle_CIDreqMSG( int connected_socket, cachelist_param_t *cachelist);
/**
* handle distroy ChannelID message
*
* @param[in] connected_socket socket descriptor
* @param[in,out] cachelist cache list pointer
*/
void handle_dstCIDreqMSG( int connected_socket, cachelist_param_t *cachelist);
/**
* handle saving JP2 file request message
*
* @param[in] connected_socket socket descriptor
* @param[in] cachelist cache list pointer
* @param[in] msgqueue message queue pointer
* @param[in] jptstream address of caching jptstream pointer
*/
void handle_JP2saveMSG( int connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jptstream);
int main(int argc, char *argv[]){
int connected_socket;
struct sockaddr_in peer_sin;
Byte_t *jptstream = NULL;
int jptlen = 0;
msgqueue_param_t *msgqueue = gene_msgqueue( true, NULL);
bool quit = false;
int listening_socket = open_listeningsocket();
int addrlen = sizeof(peer_sin);
cachelist_param_t *cachelist = gene_cachelist();
while(( connected_socket = accept(listening_socket, (struct sockaddr *)&peer_sin, &addrlen))!=-1 ){
msgtype_t msgtype = identify_clientmsg( connected_socket);
switch( msgtype){
case JPTSTREAM:
handle_JPTstreamMSG( connected_socket, cachelist, &jptstream, &jptlen, msgqueue);
break;
case PNMREQ:
handle_PNMreqMSG( connected_socket, jptstream, msgqueue, cachelist);
break;
case XMLREQ:
handle_XMLreqMSG( connected_socket, jptstream, cachelist);
break;
case CIDREQ:
handle_CIDreqMSG( connected_socket, cachelist);
break;
case CIDDST:
handle_dstCIDreqMSG( connected_socket, cachelist);
break;
case JP2SAVE:
handle_JP2saveMSG( connected_socket, cachelist, msgqueue, jptstream);
break;
case QUIT:
quit = true;
break;
case ERROR:
break;
}
printf("cut the connection. listening to port\n");
if( close(connected_socket) == -1 ){
perror("close");
return -1;
}
if( quit)
break;
}
if( close(listening_socket) == -1 ){
perror("close");
return -1;
}
delete_cachelist( &cachelist);
if( msgqueue)
delete_msgqueue( &msgqueue);
save_codestream( jptstream, jptlen, "jpt");
free( jptstream);
return 0;
}
void handle_JPTstreamMSG( int connected_socket, cachelist_param_t *cachelist,
Byte_t **jptstream, int *jptlen, msgqueue_param_t *msgqueue)
{
Byte_t *newjptstream;
int newjptlen = 0;
cache_param_t *cache;
char target[MAX_LENOFTARGET], cid[MAX_LENOFCID];
metadatalist_param_t *metadatalist;
newjptstream = receive_JPTstream( connected_socket, target, cid, &newjptlen);
parse_stream( newjptstream, newjptlen, *jptlen, msgqueue);
*jptstream = update_JPTstream( newjptstream, newjptlen, *jptstream, jptlen);
free( newjptstream);
metadatalist = gene_metadatalist();
parse_metamsg( msgqueue, *jptstream, *jptlen, metadatalist);
// cid registration
if( target[0] != 0 && cid[0] != 0){
if((cache = search_cache( target, cachelist)))
add_cachecid( cid, cache);
else{
cache = gene_cache( target, msgqueue->last->csn, cid);
insert_cache_into_list( cache, cachelist);
}
}
else
cache = search_cacheBycsn( msgqueue->last->csn, cachelist);
if( cache->metadatalist)
delete_metadatalist( &cache->metadatalist);
cache->metadatalist = metadatalist;
response_signal( connected_socket, true);
}
void handle_PNMreqMSG( int connected_socket, Byte_t *jptstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist)
{
Byte_t *pnmstream;
ihdrbox_param_t *ihdrbox;
char cid[MAX_LENOFCID], tmp[10];
cache_param_t *cache;
int fw, fh;
read_line( connected_socket, cid);
if(!(cache = search_cacheBycid( cid, cachelist)))
return;
read_line( connected_socket, tmp);
fw = atoi( tmp);
read_line( connected_socket, tmp);
fh = atoi( tmp);
pnmstream = jpt_to_pnm( jptstream, msgqueue, cache->csn, fw, fh, &cache->ihdrbox);
ihdrbox = cache->ihdrbox;
send_PNMstream( connected_socket, pnmstream, ihdrbox->width, ihdrbox->height, ihdrbox->nc, ihdrbox->bpc > 8 ? 255 : (1 << ihdrbox->bpc) - 1);
free( pnmstream);
}
void handle_XMLreqMSG( int connected_socket, Byte_t *jptstream, cachelist_param_t *cachelist)
{
char cid[MAX_LENOFCID];
cache_param_t *cache;
read_line( connected_socket, cid);
if(!(cache = search_cacheBycid( cid, cachelist)))
return;
boxcontents_param_t *boxcontents = cache->metadatalist->last->boxcontents;
Byte_t *xmlstream = (Byte_t *)malloc( boxcontents->length);
memcpy( xmlstream, jptstream+boxcontents->offset, boxcontents->length);
send_XMLstream( connected_socket, xmlstream, boxcontents->length);
free( xmlstream);
}
void handle_CIDreqMSG( int connected_socket, cachelist_param_t *cachelist)
{
char target[MAX_LENOFTARGET], *cid = NULL;
cache_param_t *cache;
int cidlen = 0;
read_line( connected_socket, target);
cache = search_cache( target, cachelist);
if( cache){
if( cache->numOfcid > 0){
cid = cache->cid[ cache->numOfcid-1];
cidlen = strlen(cid);
}
}
send_CIDstream( connected_socket, cid, cidlen);
}
void handle_dstCIDreqMSG( int connected_socket, cachelist_param_t *cachelist)
{
char cid[MAX_LENOFCID];
read_line( connected_socket, cid);
remove_cachecid( cid, cachelist);
response_signal( connected_socket, true);
}
void handle_JP2saveMSG( int connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jptstream)
{
char cid[MAX_LENOFCID];
cache_param_t *cache;
Byte_t *jp2stream;
Byte8_t jp2len;
read_line( connected_socket, cid);
if(!(cache = search_cacheBycid( cid, cachelist)))
return;
jp2stream = recons_jp2( msgqueue, jptstream, cache->csn, &jp2len);
if( jp2stream){
save_codestream( jp2stream, jp2len, "jp2");
free( jp2stream);
}
}

View File

@ -0,0 +1,35 @@
<project name="opj_viewer" default="dist" basedir=".">
<description>OpenJPIP client image viewer</description>
<property name="src" location="src" />
<property name="build" location="build"/>
<property name="dist" location="dist" />
<target name="init">
<tstamp/>
<mkdir dir="${build}"/>
</target>
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile">
<mkdir dir="${dist}"/>
<jar jarfile="${dist}/opj_viewer-${DSTAMP}.jar"
basedir="${build}" manifest="${dist}/manifest.txt"/>
<exec dir="${dist}" executable="ln">
<arg line="-sf opj_viewer-${DSTAMP}.jar opj_viewer.jar"/>
</exec>
</target>
<target name="clean">
<delete dir="${build}"/>
<delete dir="${dist}"/>
</target>
<target name="test" depends="dist">
<exec executable="appletviewer"><arg line="dist.html"/></exec>
</target>
<target name="build_test" depends="compile">
<exec executable="appletviewer"><arg line="compile.html"/></exec>
</target>
<target name="build_testj" depends="compile">
<exec executable="java"><arg line="-classpath build ImageWindow girl"/></exec>
</target>
</project>

View File

@ -0,0 +1,5 @@
Manifest-Version: 1.0
Ant-Version: Apache Ant 1.7.0
Created-By: Kaori Hagihara
Main-Class: ImageWindow
Class-Path: /usr/share/java/xerces-j2.jar

Binary file not shown.

View File

@ -0,0 +1 @@
opj_viewer-20110218.jar

View File

@ -0,0 +1,99 @@
/*
* $Id$
*
* 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.
*/
import java.awt.Image;
public class ImageManager extends JPIPHttpClient
{
private PnmImage pnmimage;
public ImageManager( String uri)
{
super( uri);
pnmimage = null;
}
public int getOrigWidth(){ return pnmimage.width;}
public int getOrigHeight(){ return pnmimage.height;}
public Image getImage( String j2kfilename, int reqfw, int reqfh)
{
System.err.println();
String refcid = ImgdecClient.query_cid( j2kfilename);
byte[] jptstream;
if( refcid == null)
jptstream = super.requestViewWindow( j2kfilename, reqfw, reqfh, true);
else
jptstream = super.requestViewWindow( reqfw, reqfh, refcid, true);
System.err.println( "decoding to PNM image");
pnmimage = ImgdecClient.decode_jptstream( jptstream, j2kfilename, cid, fw, fh);
System.err.println( " done");
// System.out.println( "fw: " + fw + " fh: " + fh + "pnm w: ");
return pnmimage.createROIImage( rx, ry, rw, rh);
}
public Image getImage( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
{
System.err.println();
byte[] jptstream = super.requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh);
System.err.println( "decoding to PNM image");
pnmimage = ImgdecClient.decode_jptstream( jptstream, cid, fw, fh);
System.err.println( " done");
return pnmimage.createROIImage( rx, ry, rw, rh);
}
public byte[] getXML()
{
System.err.println();
byte []xmldata = null;
byte[] jptstream = super.requestXML();
if( jptstream != null){
ImgdecClient.send_JPTstream( jptstream);
xmldata = ImgdecClient.get_XMLstream( cid);
}
return xmldata;
}
public void closeChannel()
{
ImgdecClient.destroy_cid( cid);
super.closeChannel();
}
}

View File

@ -0,0 +1,267 @@
/*
* $Id$
*
* 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.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
import java.awt.geom.*;
import java.net.URL;
import javax.swing.border.*;
import java.util.*;
import java.io.*;
public class ImageViewer extends JPanel
{
private MML myMML;
private ResizeListener myRL;
private ImageManager imgmanager;
private int vw, vh;
private int iw, ih;
private int selected = 0;
private Image img;
private String cmdline = new String();
private boolean fullRefresh = false;
private Point offset = new Point(0,0);
private Rectangle rect = new Rectangle();
private Rectangle roirect[] = null;
private String roiname[] = null;
public ImageViewer( String j2kfilename, ImageManager manager)
{
String str;
this.setSize( 200, 200);
Dimension asz = this.getSize();
vw = asz.width;
vh = asz.height;
setBackground(Color.black);
myMML = new MML(this);
myRL = new ResizeListener(this);
imgmanager = manager;
img = imgmanager.getImage( j2kfilename, vw, vh);
addMouseListener(myMML);
addMouseMotionListener(myMML);
addComponentListener(myRL);
}
public Image getImage()
{
return img;
}
public void zoomIn()
{
roirect = null;
roiname = null;
double scalex = vw/(double)rect.width;
double scaley = vh/(double)rect.height;
int fw = (int)(imgmanager.getFw()*scalex);
int fh = (int)(imgmanager.getFh()*scaley);
int rx = (int)((imgmanager.getRx()+rect.x)*scalex);
int ry = (int)((imgmanager.getRy()+rect.y)*scaley);
img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
rect.x = rect.y = rect.width = rect.height = 0;
selected = 0;
fullRefresh = true;
repaint();
}
public void enlarge()
{
roirect = null;
roiname = null;
Dimension asz = this.getSize();
vw = asz.width;
vh = asz.height;
double scalex = vw/(double)imgmanager.getRw();
double scaley = vh/(double)imgmanager.getRh();
int fw = (int)(imgmanager.getFw()*scalex);
int fh = (int)(imgmanager.getFh()*scaley);
int rx = (int)(imgmanager.getRx()*scalex);
int ry = (int)(imgmanager.getRy()*scaley);
img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
fullRefresh = true;
repaint();
}
public void setSelected(int state)
{
roirect = null;
roiname = null;
if (state != selected) {
selected = state;
repaint();
}
}
public boolean isInsideRect(int x, int y)
{
return rect.contains(x - offset.x, y - offset.y);
}
public void setRGeom(int x1, int y1, int x2, int y2)
{
rect.x = Math.min(x1,x2) - offset.x;
rect.y = Math.min(y1,y2) - offset.y;
rect.width = Math.abs(x2-x1);
rect.height = Math.abs(y2-y1);
}
public void annotate( JP2XMLparser.ROIparams roi[])
{
int numofroi = roi.length;
roirect = new Rectangle [numofroi];
roiname = new String [numofroi];
double scale_x = imgmanager.getFw()/(double)imgmanager.getOrigWidth();
double scale_y = imgmanager.getFh()/(double)imgmanager.getOrigHeight();
int rx = imgmanager.getRx();
int ry = imgmanager.getRy();
int rw = imgmanager.getRw();
int rh = imgmanager.getRh();
for( int i=0; i<numofroi ; i++){
int x = (int)(roi[i].x*scale_x) - rx;
int y = (int)(roi[i].y*scale_y) - ry;
int w = (int)(roi[i].w*scale_x);
int h = (int)(roi[i].h*scale_y);
if( 0<=x && 0<=y && x+w<=rw && y+h<=rh){ // can be optimized
roirect[i] = new Rectangle( x, y, w, h);
roiname[i] = new String( roi[i].name);
}
else{
roirect[i] = null;
roiname[i] = null;
}
}
repaint();
}
public boolean hasAnnotation()
{
if( roirect == null)
return false;
else
return true;
}
public boolean isInsideROIRect(int x, int y)
{
for( int i=0; i<roirect.length; i++)
if( roirect[i] != null)
if( roirect[i].contains(x - offset.x, y - offset.y)){
rect = roirect[i];
return true;
}
return false;
}
public void paint(Graphics g)
{
BufferedImage bi;
Graphics2D big;
Graphics2D g2 = (Graphics2D) g;
if (fullRefresh) {
g2.clearRect(0, 0, vw, vh);
fullRefresh = false;
}
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
offset.x = 0;
offset.y = 0;
iw = img.getWidth(this);
ih = img.getHeight(this);
bi = new BufferedImage( iw, ih, BufferedImage.TYPE_INT_RGB);
big = bi.createGraphics();
big.drawImage(img, 0, 0, this);
big.setPaint(Color.red);
if ((rect.width > 0) && (rect.height > 0))
big.draw(rect);
if( roirect != null){
for( int i=0; i<roirect.length; i++)
if( roirect[i] != null){
big.draw( roirect[i]);
big.drawString( roiname[i], roirect[i].x+3, roirect[i].y+roirect[i].height*2/3);
}
}
if (selected == 1)
shadeExt(big, 0, 0, 0, 64);
else if (selected == 2) {
shadeExt(big, 0, 0, 0, 255);
selected = 1;
}
g2.drawImage(bi, offset.x, offset.y, this);
}
private void shadeRect(Graphics2D g2, int r, int g, int b, int a)
{
g2.setPaint(new Color(r, g, b, a));
g2.fillRect(rect.x + 1, rect.y + 1, rect.width - 1, rect.height - 1);
}
private void shadeExt(Graphics2D g2, int r, int g, int b, int a)
{
g2.setPaint(new Color(r, g, b, a));
g2.fillRect(0, 0, iw, rect.y); /* _N_ */
g2.fillRect(rect.x + rect.width + 1, rect.y,
iw - rect.x - rect.width - 1, rect.height + 1); /* E */
g2.fillRect(0, rect.y, rect.x, rect.height + 1); /* W */
g2.fillRect(0, rect.y + rect.height + 1,
iw, ih - rect.y - rect.height - 1); /* _S_ */
}
}

View File

@ -0,0 +1,93 @@
/*
* $Id$
*
* 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.
*/
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class ImageWindow extends JFrame
{
private ImageViewer imgviewer;
private OptionPanel optpanel;
private ImageManager imgmanager;
public ImageWindow( String uri, String j2kfilename)
{
super( j2kfilename);
imgmanager = new ImageManager( uri);
imgviewer = new ImageViewer( j2kfilename, imgmanager);
imgviewer.setOpaque(true); //content panes must be opaque
optpanel = new OptionPanel( imgmanager, imgviewer);
JPanel panel = new JPanel();
panel.setLayout(new BorderLayout());
panel.add( imgviewer, BorderLayout.CENTER);
panel.add( optpanel, BorderLayout.EAST);
setContentPane( panel);
addWindowListener(new WindowMyAdapter());
}
class WindowMyAdapter extends WindowAdapter
{
public void windowClosing(WindowEvent arg)
{
imgmanager.closeChannel();
System.exit(0);
}
}
public static void main(String s[])
{
String j2kfilename, uri;
if(s.length > 0){
uri = s[0];
j2kfilename = s[1];
}
else{
System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2");
return;
}
ImageWindow frame = new ImageWindow( uri, j2kfilename);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//Display the window.
frame.pack();
frame.setSize(new Dimension(400,200));
frame.setLocation( 0, 50);
frame.setVisible(true);
}
}

View File

@ -0,0 +1,268 @@
/*
* $Id$
*
* 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.
*/
import java.io.*;
import java.net.*;
public class ImgdecClient{
public static PnmImage decode_jptstream( byte[] jptstream, String cid, int fw, int fh)
{
if( jptstream != null)
send_JPTstream( jptstream);
return get_PNMstream( cid, fw, fh);
}
public static PnmImage decode_jptstream( byte[] jptstream, String j2kfilename, String cid, int fw, int fh)
{
send_JPTstream( jptstream, j2kfilename, cid);
return get_PNMstream( cid, fw, fh);
}
public static void send_JPTstream( byte[] jptstream)
{
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
System.err.println("Sending " + jptstream.length + "Data Bytes to decodingServer");
os.writeBytes("JPT-stream\n");
os.writeBytes("version 1.0\n");
os.writeBytes( jptstream.length + "\n");
os.write( jptstream, 0, jptstream.length);
byte signal = is.readByte();
if( signal == 0)
System.err.println(" failed");
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
public static void send_JPTstream( byte[] jptstream, String j2kfilename, String cid)
{
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
int length = 0;
if( jptstream != null)
length = jptstream.length;
System.err.println("Sending " + length + "Data Bytes to decodingServer");
os.writeBytes("JPT-stream\n");
os.writeBytes("version 1.0\n");
os.writeBytes( j2kfilename + "\n");
os.writeBytes( cid + "\n");
os.writeBytes( length + "\n");
os.write( jptstream, 0, length);
byte signal = is.readByte();
if( signal == 0)
System.err.println(" failed");
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
public static PnmImage get_PNMstream( String cid, int fw, int fh)
{
PnmImage pnmstream = new PnmImage();
try {
Socket imgdecSocket = new Socket( "localhost", 5000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
byte []header = new byte[7];
os.writeBytes("PNM request\n");
os.writeBytes( cid + "\n");
os.writeBytes( fw + "\n");
os.writeBytes( fh + "\n");
read_stream( is, header, 7);
if( header[0] == 80){
// P5: gray, P6: color
byte magicknum = header[1];
if( magicknum == 5 || magicknum == 6){
int length;
boolean iscolor = magicknum==6 ? true:false;
if( iscolor)
pnmstream.channel = 3;
else
pnmstream.channel = 1;
pnmstream.width = (header[2]&0xff)<<8 | (header[3]&0xff);
pnmstream.height = (header[4]&0xff)<<8 | (header[5]&0xff);
int maxval = header[6]&0xff;
if( maxval == 255){
length = pnmstream.width*pnmstream.height*pnmstream.channel;
pnmstream.data = new byte [ length];
read_stream( is, pnmstream.data, length);
}
else
System.err.println("Error in get_PNMstream(), only 255 is accepted");
}
else
System.err.println("Error in get_PNMstream(), wrong magick number" + header[1]);
}
else
System.err.println("Error in get_PNMstream(), Not starting with P");
os.close();
is.close();
imgdecSocket.close();
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
return pnmstream;
}
public static byte [] get_XMLstream( String cid)
{
byte []xmldata = null;
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
byte []header = new byte[5];
os.writeBytes("XML request\n");
os.writeBytes( cid + "\n");
read_stream( is, header, 5);
if( header[0] == 88 && header[1] == 77 && header[2] == 76){
int length = (header[3]&0xff)<<8 | (header[4]&0xff);
xmldata = new byte[ length];
read_stream( is, xmldata, length);
}
else
System.err.println("Error in get_XMLstream(), not starting with XML");
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
return xmldata;
}
public static String query_cid( String j2kfilename)
{
String cid = null;
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
byte []header = new byte[4];
os.writeBytes("CID request\n");
os.writeBytes( j2kfilename + "\n");
read_stream( is, header, 4);
if( header[0] == 67 && header[1] == 73 && header[2] == 68){
int length = header[3]&0xff;
if( length > 0){
byte []ciddata = new byte[ length];
read_stream( is, ciddata, length);
cid = new String( ciddata);
}
}
else
System.err.println("Error in query_cid(), not starting with CID");
}
catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
return cid;
}
public static void read_stream( DataInputStream is, byte []stream, int length)
{
int remlen = length;
int off = 0;
try{
while( remlen > 0){
int redlen = is.read( stream, off, remlen);
if( redlen == -1){
System.err.println(" failed to read_stream()");
break;
}
off += redlen;
remlen -= redlen;
}
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
public static void destroy_cid( String cid)
{
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
os.writeBytes("CID destroy\n");
os.writeBytes( cid + "\n");
byte signal = is.readByte();
if( signal == 0)
System.err.println(" failed");
} catch (UnknownHostException e) {
System.err.println("Trying to connect to unknown host: " + e);
} catch (IOException e) {
System.err.println("IOException: " + e);
}
}
}

View File

@ -0,0 +1,122 @@
/*
* $Id$
*
* 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.
*/
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXParseException;
import org.xml.sax.ErrorHandler;
import org.apache.xerces.parsers.DOMParser;
import org.xml.sax.InputSource;
import java.io.*;
import java.lang.Integer;
public class JP2XMLparser
{
Document document;
public static class ROIparams{
public String name = null;
public int x = 0;
public int y = 0;
public int w = 0;
public int h = 0;
}
public static class IRTparams{
public String refimg = null;
public double []mat = { 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
}
public JP2XMLparser( byte[] buf)
{
try{
InputSource source = new InputSource( new ByteArrayInputStream( buf));
DOMParser parser = new DOMParser();
parser.setErrorHandler(new MyHandler());
parser.parse( source);
document = parser.getDocument();
}
catch (Exception e) {
e.printStackTrace();
}
}
public ROIparams [] getROIparams()
{
ROIparams roi[];
NodeList elements = document.getElementsByTagName("roi");
int elementCount = elements.getLength();
roi = new ROIparams [elementCount];
for( int i = 0; i < elementCount; i++) {
Element element = (Element)elements.item(i);
roi[i] = new ROIparams();
roi[i].name = element.getAttribute( "name");
roi[i].x = Integer.parseInt( element.getAttribute( "x")) ;
roi[i].y = Integer.parseInt( element.getAttribute( "y")) ;
roi[i].w = Integer.parseInt( element.getAttribute( "w")) ;
roi[i].h = Integer.parseInt( element.getAttribute( "h")) ;
}
return roi;
}
public IRTparams getIRTparams()
{
IRTparams irt = new IRTparams();
NodeList elements = document.getElementsByTagName("irt");
int elementCount = elements.getLength();
Element element = (Element)elements.item(0);
irt.refimg = element.getAttribute( "refimg");
for( int i=1; i<=9; i++)
irt.mat[i-1] = Double.parseDouble( element.getAttribute("m" + i));
return irt;
}
}
class MyHandler implements ErrorHandler {
public void warning(SAXParseException e) {
System.out.println("Warning: line" + e.getLineNumber());
System.out.println(e.getMessage());
}
public void error(SAXParseException e) {
System.out.println("Error: line" + e.getLineNumber());
System.out.println(e.getMessage());
}
public void fatalError(SAXParseException e) {
System.out.println("Critical error: line" + e.getLineNumber());
System.out.println(e.getMessage());
}
}

View File

@ -0,0 +1,301 @@
/*
* $Id$
*
* 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.
*/
import java.net.*;
import java.io.*;
import java.util.*;
public class JPIPHttpClient
{
private String comURL;
protected int fw, fh;
protected int rx, ry;
protected int rw, rh;
protected String cid;
public JPIPHttpClient( String URI)
{
comURL = URI + "?";
fw = fh = -1;
rx = ry = -1;
rw = rh = -1;
cid = null;
}
public int getFw(){ return fw;}
public int getFh(){ return fh;}
public int getRx(){ return rx;}
public int getRy(){ return ry;}
public int getRw(){ return rw;}
public int getRh(){ return rh;}
public byte[] requestViewWindow( int reqfw, int reqfh)
{
if( cid != null)
return requestViewWindow( reqfw, reqfh, cid);
else
return null;
}
public byte[] requestViewWindow( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
{
if( cid != null)
return requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh, cid);
else
return null;
}
public byte[] requestViewWindow( int reqfw, int reqfh, String reqcid)
{
return requestViewWindow( null, reqfw, reqfh, -1, -1, -1, -1, reqcid, false);
}
public byte[] requestViewWindow( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh, String reqcid)
{
return requestViewWindow( null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, false);
}
public byte[] requestViewWindow( String target, int reqfw, int reqfh)
{
return requestViewWindow( target, reqfw, reqfh, -1, -1, -1, -1, null, false);
}
public byte[] requestViewWindow( String target, int reqfw, int reqfh, boolean reqcnew)
{
if( cid == null) // 1 channel allocation only
return requestViewWindow( target, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew);
else
return null;
}
public byte[] requestViewWindow( String target, int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
{
return requestViewWindow( target, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false);
}
public byte[] requestViewWindow( int reqfw, int reqfh, String reqcid, boolean reqcnew)
{
return requestViewWindow( null, reqfw, reqfh, -1, -1, -1, -1, reqcid, reqcnew);
}
public byte[] requestViewWindow( String target,
int reqfw, int reqfh,
int reqrx, int reqry,
int reqrw, int reqrh,
String reqcid, boolean reqcnew)
{
String urlstring = const_urlstring( target, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, reqcnew);
return GETrequest( urlstring);
}
public byte[] requestXML()
{
String urlstring = comURL;
if( cid == null)
return null;
urlstring = urlstring.concat( "cid=" + cid);
urlstring = urlstring.concat( "&metareq=[xml_]");
return GETrequest( urlstring);
}
private byte[] GETrequest( String urlstring)
{
int buflen = 0;
URL url = null;
HttpURLConnection urlconn = null;
byte[] jptstream = null;
try{
url = new URL( urlstring);
System.err.println("Requesting: " + url);
urlconn = (HttpURLConnection)url.openConnection();
urlconn.setRequestMethod("GET");
urlconn.setInstanceFollowRedirects(false);
urlconn.connect();
Map<String,java.util.List<String>> headers = urlconn.getHeaderFields();
java.util.List<String> hvaluelist;
if(( hvaluelist = headers.get("JPIP-fsiz")) != null){
String hvalueline = hvaluelist.get(0);
fw = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
fh = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
System.err.println("fw,fh: " + fw + "," + fh);
}
if(( hvaluelist = headers.get("JPIP-roff")) != null){
String hvalueline = hvaluelist.get(0);
rx = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
ry = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
System.err.println("rx,ry: " + rx + "," + ry);
}
if(( hvaluelist = headers.get("JPIP-rsiz")) != null){
String hvalueline = hvaluelist.get(0);
rw = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
rh = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
System.err.println("rw,rh: " + rw + "," + rh);
}
if(( hvaluelist = headers.get("JPIP-cnew")) != null){
String hvalueline = hvaluelist.get(0);
cid = hvalueline.substring( hvalueline.indexOf('=')+1, hvalueline.indexOf(','));
System.err.println("cid: " + cid);
}
InputStream input = urlconn.getInputStream();
buflen = input.available();
if( buflen > 0){
ByteArrayOutputStream tmpstream = new ByteArrayOutputStream();
byte[] buf = new byte[ 1024];
System.err.println("reading jptstream...");
int redlen;
do{
redlen = input.read( buf);
if( redlen == -1)
break;
tmpstream.write( buf, 0, redlen);
}while( redlen > 0);
buflen = tmpstream.size();
jptstream = tmpstream.toByteArray();
tmpstream = null;
System.err.println("jptlen: " + buflen);
System.err.println(" succeeded");
}
else{
System.err.println("No new jptstream");
}
input.close();
}
catch ( MalformedURLException e){
e.printStackTrace();
}
catch ( ProtocolException e){
e.printStackTrace();
}
catch( ClassCastException e){
e.printStackTrace();
}
catch( NullPointerException e){
e.printStackTrace();
}
catch( UnknownServiceException e){
e.printStackTrace();
}
catch ( IOException e){
e.printStackTrace();
}
urlconn.disconnect();
return jptstream;
}
private String const_urlstring( String target,
int reqfw, int reqfh,
int reqrx, int reqry,
int reqrw, int reqrh,
String reqcid, boolean reqcnew)
{
String urlstring = comURL;
if( target != null){
if( !urlstring.endsWith("?"))
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "target=" + target);
}
if( reqfw != -1 && reqfh != -1){
if( !urlstring.endsWith("?"))
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "fsiz=" + reqfw + "," + reqfh);
}
if( reqrx != -1 && reqry != -1){
if( !urlstring.endsWith("?"))
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "roff=" + reqrx + "," + reqry);
}
if( reqrw != -1 && reqrh != -1){
if( !urlstring.endsWith("?"))
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "rsiz=" + reqrw + "," + reqrh);
}
if( reqcid != null){
if( !urlstring.endsWith("?"))
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "cid=" + reqcid);
}
if( reqcnew){
if( !urlstring.endsWith("?"))
urlstring = urlstring.concat( "&");
urlstring = urlstring.concat( "cnew=http");
}
return urlstring;
}
public void closeChannel()
{
if( cid == null)
return;
try{
URL url = new URL( comURL + "cclose=" + cid);
System.err.println( "closing cid: " + cid);
HttpURLConnection urlconn = (HttpURLConnection)url.openConnection();
urlconn.setRequestMethod("GET");
urlconn.setInstanceFollowRedirects(false);
urlconn.connect();
Map headers = urlconn.getHeaderFields();
urlconn.disconnect();
} catch ( MalformedURLException e){
e.printStackTrace();
} catch ( IOException e){
e.printStackTrace();
}
}
}

View File

@ -0,0 +1,116 @@
/*
* $Id$
*
* 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.
*/
import java.awt.event.*;
class MML implements MouseMotionListener, MouseListener
{
public void mouseExited(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
private ImageViewer iv;
private int x1, y1, x2, y2, zf, btn;
private boolean zoomrq;
public MML(ImageViewer imageviewer)
{
x1 = y1 = -1;
iv = imageviewer;
zoomrq = false;
zf = 0;
}
private boolean isInside(int x, int y)
{
x -= iv.getX();
y -= iv.getY();
return (x >= 0) && (x < iv.getWidth())
&& (y >= 0) && (y < iv.getHeight());
}
public void mousePressed(MouseEvent e)
{
btn = e.getButton();
if( iv.hasAnnotation()){
if( iv.isInsideROIRect(e.getX(), e.getY())){
iv.zoomIn();
System.out.println("annotation click");
return;
}
}
if (iv.isInsideRect(e.getX(), e.getY())) {
iv.setSelected(2);
iv.repaint();
zoomrq = true;
} else {
iv.setRGeom(0, 0, 0, 0);
iv.setSelected(0);
iv.repaint();
x1 = y1 = -1;
}
}
public void mouseReleased(MouseEvent e)
{
if(e.getButton() == 1) {
if (zoomrq) {
iv.zoomIn();
zoomrq = false;
}
}
}
public void mouseMoved(MouseEvent e)
{
}
public void mouseDragged(MouseEvent e)
{
if (btn == 1) {
x2 = e.getX();
y2 = e.getY();
iv.setSelected(0);
zoomrq = false;
if (isInside(x2, y2)) {
if (x1 == -1) {
x1 = x2;
y1 = y2;
} else {
iv.setRGeom(x1, y1, x2, y2);
iv.repaint();
}
}
}
}
}

View File

@ -0,0 +1,98 @@
/*
* $Id$
*
* 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.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class OptionPanel extends JPanel implements ActionListener
{
private JButton roibutton;
private JButton imregbutton;
private ImageManager imgmanager;
private ImageViewer iv;
private JP2XMLparser xmlparser;
private JFrame regimwindow;
private RegimViewer regimgviewer;
public OptionPanel( ImageManager manager, ImageViewer imgviewer)
{
this.setLayout(new BoxLayout( this, BoxLayout.Y_AXIS));
roibutton = new JButton("Region Of Interest");
imregbutton = new JButton("Image Registration");
roibutton.setAlignmentX( Component.CENTER_ALIGNMENT);
imregbutton.setAlignmentX( Component.CENTER_ALIGNMENT);
add( roibutton);
add( imregbutton);
roibutton.addActionListener(this);
imregbutton.addActionListener(this);
imgmanager = manager;
iv = imgviewer;
xmlparser = null;
}
public void actionPerformed(ActionEvent e)
{
if( xmlparser == null){
byte []xmldata = imgmanager.getXML();
if( xmldata != null)
xmlparser = new JP2XMLparser( xmldata);
}
if( e.getSource() == roibutton){
if( xmlparser != null){
JP2XMLparser.ROIparams roi[] = xmlparser.getROIparams();
iv.annotate( roi);
}
}
if( e.getSource() == imregbutton){
if( xmlparser != null){
if( regimwindow == null){
JP2XMLparser.IRTparams irt = xmlparser.getIRTparams();
regimgviewer = new RegimViewer( irt.refimg, irt.mat);
regimgviewer.setOpaque(false);
regimwindow = new JFrame("Registered Image");
regimwindow.getContentPane().add("Center", regimgviewer);
regimwindow.pack();
regimwindow.setLocation( 500, 50);
regimwindow.setVisible(true);
}
regimgviewer.projection( iv.getImage(), (double)imgmanager.getRw()/(double)imgmanager.getOrigWidth());
regimwindow.setSize( regimgviewer.get_imsize());
regimwindow.show();
}
}
}
}

View File

@ -0,0 +1,141 @@
/*
* $Id$
*
* 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.
*/
import java.awt.*;
import java.awt.image.*;
import java.io.*;
import java.util.regex.*;
public class PnmImage extends Component
{
public byte[] data = null;
public int width = 0;
public int height = 0;
public int channel = 0;
public Image createROIImage( int rx, int ry, int rw, int rh)
{
int []pix = new int[ rw*rh];
for( int i=0; i<rh; i++)
for( int j=0; j<rw; j++){
pix[i*rw+j] = 0xFF << 24; // transparency
if( channel == 1){
Byte lum = data[(ry+i)*width+rx+j];
short slum;
if( lum < 0)
slum = (short)(2*128+lum);
else
slum = (short)lum;
for( int c=0; c<3; c++){
pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
}
}
else
for( int c=0; c<3; c++){
Byte lum = data[ ((ry+i)*width+rx+j)*channel+(2-c)];
short slum;
if( lum < 0)
slum = (short)(2*128+lum);
else
slum = (short)lum;
pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
}
}
return createImage(new MemoryImageSource( rw, rh, pix, 0, rw));
}
public Image createScaleImage( double scale)
{
Image src = createROIImage( 0, 0, width, height);
ImageFilter replicate = new ReplicateScaleFilter( (int)(width*scale), (int)(height*scale));
ImageProducer prod = new FilteredImageSource( src.getSource(), replicate);
return createImage(prod);
}
public void openimage( String filename)
{
String str;
Pattern pat;
Matcher mat;
int bytes;
int r, offset = 0;
try {
FileInputStream fis = new FileInputStream( new File(filename));
DataInputStream is = new DataInputStream( fis);
pat = Pattern.compile("^P([56])$");
mat = pat.matcher(str = is.readLine());
if( !mat.matches()){
System.out.println("PNM header format error");
return;
}
if( (mat.group(1)).compareTo("5") == 0)
channel = 1;
else
channel = 3;
pat = Pattern.compile("^(\\d+) (\\d+)$");
mat = pat.matcher(str = is.readLine());
if( !mat.matches()){
System.out.println("PNM header format error");
return;
}
width = Integer.parseInt( mat.group(1));
height = Integer.parseInt( mat.group(2));
str = is.readLine(); // 255
bytes = width*height*channel;
data = new byte[bytes];
while( bytes > 0){
try {
r = is.read(data, offset, bytes);
if( r == -1){
System.err.println(" failed to read()");
break;
}
offset += r;
bytes -= r;
}
catch (IOException e) { e.printStackTrace(); }
}
fis.close();
} catch (IOException e) { e.printStackTrace(); }
}
}

View File

@ -0,0 +1,115 @@
/*
* $Id$
*
* 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.
*/
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.geom.AffineTransform;
public class RegimViewer extends JPanel
{
private PnmImage refpnm;
private int vw, vh;
private Image refimg;
private Image jpipImg;
private double[] affine_matrix;
private AffineTransform affine;
public RegimViewer( String refname, double[] mat)
{
refpnm = new PnmImage();
refpnm.openimage(refname.replaceFirst("jp2", "pgm")); // decoding not realized
affine_matrix = new double[6];
affine_matrix[0] = mat[0];
affine_matrix[1] = mat[3];
affine_matrix[2] = mat[1];
affine_matrix[3] = mat[4];
affine_matrix[4] = mat[2];
affine_matrix[5] = mat[5];
affine = new AffineTransform();
for( int i=0; i<3; i++){
for( int j=0; j<3; j++)
System.out.print( mat[i*3+j] + " ");
System.out.println();
}
}
public void projection( Image jpipimg, double scale)
{
jpipImg = jpipimg;
refimg = refpnm.createScaleImage( scale);
vw = refimg.getWidth(this);
vh = refimg.getHeight(this);
this.setSize( vw, vh);
affine.setTransform( affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]);
repaint();
}
public void paint(Graphics g)
{
int iw, ih;
BufferedImage bi, bi2;
Graphics2D big, big2;
Graphics2D g2 = (Graphics2D) g;
g2.clearRect(0, 0, vw, vh);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
iw = refimg.getWidth(this);
ih = refimg.getHeight(this);
bi = new BufferedImage( iw, ih, BufferedImage.TYPE_INT_RGB);
big = bi.createGraphics();
big.drawImage(refimg, 0, 0, this);
g2.drawImage(bi, 0, 0, this);
bi2 = new BufferedImage( jpipImg.getWidth(this), jpipImg.getHeight(this), BufferedImage.TYPE_INT_RGB);
big2 = bi2.createGraphics();
big2.drawImage( jpipImg, 0, 0, this);
g2.setTransform(affine);
g2.drawImage(bi2, 0, 0, this);
}
public Dimension get_imsize()
{
return (new Dimension( vw, vh));
}
}

View File

@ -0,0 +1,59 @@
/*
* $Id$
*
* 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.
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
class ResizeListener implements ComponentListener
{
private ImageViewer iv;
private Dimension largest;
public ResizeListener( ImageViewer _iv)
{
iv = _iv;
largest = iv.getSize();
}
public void componentHidden(ComponentEvent e) {}
public void componentMoved(ComponentEvent e) {}
public void componentResized(ComponentEvent e) {
Dimension cursize = iv.getSize();
if( largest.getWidth() < cursize.getWidth() || largest.getHeight() < cursize.getHeight()){
largest = cursize;
iv.enlarge();
}
}
public void componentShown(ComponentEvent e) {}
}

View File

@ -0,0 +1,14 @@
LIBDIR = ../libopenjpip
LIBFNAME = $(LIBDIR)/libopenjpip_server.a
CFLAGS = -O3 -Wall -std=c99 -pedantic -m32 -DSERVER -I$(LIBDIR)
LDFLAGS = -L$(LIBDIR) -lm -lfcgi -lopenjpip_server
ALL = opj_server
all: $(ALL)
opj_server: opj_server.o query_parser.o channel_manager.o session_manager.o $(LIBFNAME)
$(CC) $(CFLAGS) $< query_parser.o channel_manager.o session_manager.o $(LDFLAGS) -o $@
clean:
rm -f $(ALL) *.o *~

View File

@ -0,0 +1,166 @@
/*
* $Id: channel_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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "channel_manager.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
channellist_param_t * gene_channellist()
{
channellist_param_t *channellist;
channellist = (channellist_param_t *)malloc( sizeof(channellist_param_t));
channellist->first = NULL;
channellist->last = NULL;
return channellist;
}
channel_param_t * gene_channel( query_param_t query_param, target_param_t *target, channellist_param_t *channellist)
{
channel_param_t *channel;
// set the target
if( !target){
fprintf( FCGI_stdout, "Status: 404\r\n");
fprintf( FCGI_stdout, "Reason: cnew cancelled\r\n");
return NULL;
}
channel = (channel_param_t *)malloc( sizeof(channel_param_t));
channel->target = target;
// set channel ID and get present time
snprintf( channel->cid, MAX_LENOFCID, "%x%x", (unsigned int)time( &channel->start_tm), (unsigned int)rand());;
channel->next=NULL;
set_channel_variable_param( query_param, channel);
if( channellist->first != NULL)
channellist->last->next = channel;
else
channellist->first = channel;
channellist->last = channel;
fprintf( FCGI_stdout, "JPIP-cnew: cid=%s", channel->cid);
// only http implemented for now
fprintf( FCGI_stdout, ",transport=http\r\n");
return channel;
}
void set_channel_variable_param( query_param_t query_param, channel_param_t *channel)
{
// set roi information
}
void delete_channel( channel_param_t **channel, channellist_param_t *channellist)
{
channel_param_t *ptr;
if( *channel == channellist->first)
channellist->first = (*channel)->next;
else{
ptr = channellist->first;
while( ptr->next != *channel){
ptr=ptr->next;
}
ptr->next = (*channel)->next;
if( *channel == channellist->last)
channellist->last = ptr;
}
#ifndef SERVER
fprintf( logstream, "local log: channel: %s deleted\n", (*channel)->cid);
#endif
free(*channel);
}
void delete_channellist( channellist_param_t **channellist)
{
channel_param_t *channelPtr, *channelNext;
channelPtr = (*channellist)->first;
while( channelPtr != NULL){
channelNext=channelPtr->next;
#ifndef SERVER
fprintf( logstream, "local log: channel %s deleted!\n", channelPtr->cid);
#endif
free(channelPtr);
channelPtr=channelNext;
}
free( *channellist);
}
void print_allchannel( channellist_param_t *channellist)
{
channel_param_t *ptr;
ptr = channellist->first;
while( ptr != NULL){
fprintf( logstream,"channel-ID=%s \t target=%s\n", ptr->cid, ptr->target->filename);
ptr=ptr->next;
}
}
channel_param_t * search_channel( char cid[], channellist_param_t *channellist)
{
channel_param_t *foundchannel;
foundchannel = channellist->first;
while( foundchannel != NULL){
if( strcmp( cid, foundchannel->cid) == 0)
return foundchannel;
foundchannel = foundchannel->next;
}
fprintf( FCGI_stdout, "Status: 503\r\n");
fprintf( FCGI_stdout, "Reason: Channel %s not found in this session\r\n", cid);
return NULL;
}

View File

@ -0,0 +1,115 @@
/*
* $Id: channel_manager.h 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.
*/
#ifndef CHANNEL_MANAGER_H_
# define CHANNEL_MANAGER_H_
#include <time.h>
#include "query_parser.h"
#include "target_manager.h"
//! Channel parameters
typedef struct channel_param{
target_param_t *target; //!< reference pointer to the target
char cid[MAX_LENOFCID]; //!< channel identifier
// - a record of the client's capabilities and preferences
// - to the extent that the server queues requests
time_t start_tm; //!< starting time
struct channel_param *next; //!< pointer to the next channel
} channel_param_t;
//! Channel list parameters
typedef struct channellist_param{
channel_param_t *first; //!< first channel pointer of the list
channel_param_t *last; //!< last channel pointer of the list
} channellist_param_t;
/**
* generate a channel list
*
* @return pointer to the generated channel list
*/
channellist_param_t * gene_channellist();
/**
* generate a channel under the channel list
*
* @param[in] query_param query parameters
* @param[in] target reference target
* @param[in] channellist channel list pointer
* @return pointer to the generated channel
*/
channel_param_t * gene_channel( query_param_t query_param, target_param_t *target, channellist_param_t *channellist);
/**
* set channel variable parameters
*
* @param[in] query_param query parameters
* @param[in,out] channel pointer to the modifying channel
*/
void set_channel_variable_param( query_param_t query_param, channel_param_t *channel);
/**
* delete a channel
*
* @param[in] channel address of the deleting channel pointer
* @param[in,out] channellist channel list pointer
*/
void delete_channel( channel_param_t **channel, channellist_param_t *channellist);
/**
* delete channel list
*
* @param[in,out] channellist address of the channel list pointer
*/
void delete_channellist( channellist_param_t **channellist);
/**
* print all channel parameters
*
* @param[in] channellist channel list pointer
*/
void print_allchannel( channellist_param_t *channellist);
/**
* search a channel by channel ID
*
* @param[in] cid channel identifier
* @param[in] channellist channel list pointer
* @return found channel pointer
*/
channel_param_t * search_channel( char cid[], channellist_param_t *channellist);
#endif /* !CHANNEL_MANAGER_H_ */

View File

@ -0,0 +1,430 @@
/*
* $Id: opj_server.c 46 2011-02-17 14:50:55Z 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.
*/
/*! \file
* \brief opj_server is a JPIP server program, which supports HTTP connection, JPT-stream, session, channels, and cache model managements.
*
* \section req Requirements
* FastCGI development kit (http://www.fastcgi.com).
*
* \section impinst Implementing instructions
* Launch opj_server from the server terminal:\n
* % spawn-fcgi -f ./opj_server -p 3000 -n
*
* Note: JP2 files are stored in the working directory of opj_server\n
* Check README for the JP2 Encoding\n
*
* We tested this software with a virtual server running on the same Linux machine as the clients.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "query_parser.h"
#include "channel_manager.h"
#include "session_manager.h"
#include "target_manager.h"
#include "imgreg_manager.h"
#include "msgqueue_manager.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
/**
* parse JPIP request
*
* @param[in] query_param structured query
* @param[in] sessionlist session list pointer
* @param[in,out] msgqueue address of the message queue pointer
* @return if succeeded (true) or failed (false)
*/
bool parse_JPIPrequest( query_param_t query_param,
sessionlist_param_t *sessionlist,
msgqueue_param_t **msgqueue);
/**
* REQUEST: channel association
* this must be processed before any process
*
* @param[in] query_param structured query
* @param[in] sessionlist session list pointer
* @param[out] cursession address of the associated session pointer
* @param[out] curchannel address of the associated channel pointer
* @return if succeeded (true) or failed (false)
*/
bool associate_channel( query_param_t query_param,
sessionlist_param_t *sessionlist,
session_param_t **cursession,
channel_param_t **curchannel);
/**
* REQUEST: new channel (cnew) assignment
*
* @param[in] query_param structured query
* @param[in] sessionlist session list pointer
* @param[in,out] cursession address of the associated/opened session pointer
* @param[in,out] curchannel address of the associated/opened channel pointer
* @return if succeeded (true) or failed (false)
*/
bool open_channel( query_param_t query_param,
sessionlist_param_t *sessionlist,
session_param_t **cursession,
channel_param_t **curchannel);
/**
* REQUEST: channel close (cclose)
*
* @param[in] query_param structured query
* @param[in] sessionlist session list pointer
* @param[in,out] cursession address of the session pointer of deleting channel
* @param[in,out] curchannel address of the deleting channel pointer
* @return if succeeded (true) or failed (false)
*/
bool close_channel( query_param_t query_param,
sessionlist_param_t *sessionlist,
session_param_t **cursession,
channel_param_t **curchannel);
/**
* REQUEST: view-window (fsiz)
*
* @param[in] query_param structured query
* @param[in,out] cursession associated session pointer
* @param[in,out] curchannel associated channel pointer
* @param[in,out] msgqueue address of the message queue pointer
* @return if succeeded (true) or failed (false)
*/
bool gene_JPTstream( query_param_t query_param,
session_param_t *cursession,
channel_param_t *curchannel,
msgqueue_param_t **msgqueue);
int main(void)
{
sessionlist_param_t *sessionlist;
bool parse_status;
sessionlist = gene_sessionlist();
#ifdef SERVER
char *query_string;
while(FCGI_Accept() >= 0)
#else
char query_string[128];
while((fgets( query_string, 128, stdin))[0] != '\n' )
#endif
{
#ifdef SERVER
query_string = getenv("QUERY_STRING");
#endif //SERVER
fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
query_param_t query_param;
msgqueue_param_t *msgqueue;
parse_query( query_string, &query_param);
#ifndef SERVER
print_queryparam( query_param);
#endif
msgqueue = NULL;
parse_status = parse_JPIPrequest( query_param, sessionlist, &msgqueue);
fprintf( FCGI_stdout, "\r\n");
#ifndef SERVER
// if( parse_status)
// print_allsession( sessionlist);
print_msgqueue( msgqueue);
#endif
emit_stream_from_msgqueue( msgqueue);
delete_msgqueue( &msgqueue);
}
delete_sessionlist( &sessionlist);
return 0;
}
bool parse_JPIPrequest( query_param_t query_param,
sessionlist_param_t *sessionlist,
msgqueue_param_t **msgqueue)
{
session_param_t *cursession = NULL;
channel_param_t *curchannel = NULL;
if( query_param.cid[0] != '\0')
if( !associate_channel( query_param, sessionlist, &cursession, &curchannel))
return false;
if( query_param.cnew){
if( !open_channel( query_param, sessionlist, &cursession, &curchannel))
return false;
}
if( query_param.cclose[0][0] != '\0')
if( !close_channel( query_param, sessionlist, &cursession, &curchannel))
return false;
if( (query_param.fx > 0 && query_param.fx > 0) || query_param.box_type[0][0] != 0)
if( !gene_JPTstream( query_param, cursession, curchannel, msgqueue))
return false;
return true;
}
bool associate_channel( query_param_t query_param,
sessionlist_param_t *sessionlist,
session_param_t **cursession,
channel_param_t **curchannel)
{
if( search_session_and_channel( query_param.cid, sessionlist, cursession, curchannel)){
if( !query_param.cnew)
set_channel_variable_param( query_param, *curchannel);
}
else{
fprintf( FCGI_stderr, "Error: process canceled\n");
return false;
}
return true;
}
bool open_channel( query_param_t query_param,
sessionlist_param_t *sessionlist,
session_param_t **cursession,
channel_param_t **curchannel)
{
target_param_t *target=NULL;
if( query_param.target[0] !='\0'){ // target query specified
if( *cursession){
if( !( target = search_target( query_param.target, (*cursession)->targetlist))){
if((target = gene_target( query_param.target)))
insert_target_into_session( *cursession, target);
else
return false;
}
}
else{
if((target = gene_target( query_param.target))){
// new session
*cursession = gene_session( sessionlist);
insert_target_into_session( *cursession, target);
}
else
return false;
}
}
else{
if( *cursession)
target = (*curchannel)->target;
}
*curchannel = gene_channel( query_param, target, (*cursession)->channellist);
if( *curchannel == NULL)
return false;
return true;
}
bool close_channel( query_param_t query_param,
sessionlist_param_t *sessionlist,
session_param_t **cursession,
channel_param_t **curchannel)
{
if( query_param.cclose[0][0] =='*'){
#ifndef SERVER
fprintf( logstream, "local log: close all\n");
#endif
// all channels associatd with the session will be closed
if( !delete_session( cursession, sessionlist))
return false;
}
else{
// check if all entry belonging to the same session
int i=0;
while( query_param.cclose[i][0] !='\0'){
// In case of the first entry of close cid
if( *cursession == NULL){
if( !search_session_and_channel( query_param.cclose[i], sessionlist, cursession, curchannel))
return false;
}
else // second or more entry of close cid
if( !(*curchannel=search_channel( query_param.cclose[i], (*cursession)->channellist))){
fprintf( FCGI_stdout, "Reason: Cclose id %s is from another session\r\n", query_param.cclose[i]);
return false;
}
i++;
}
// delete channels
i=0;
while( query_param.cclose[i][0] !='\0'){
*curchannel = search_channel( query_param.cclose[i], (*cursession)->channellist);
delete_channel( curchannel, (*cursession)->channellist);
i++;
}
if( (*cursession)->channellist->first == NULL || (*cursession)->channellist->last == NULL)
// In case of empty session
delete_session( cursession, sessionlist);
}
return true;
}
/**
* enqueue tiles into the message queue
*
* @param[in] query_param structured query
* @param[in] codeidx pointer to index parameters
* @param[in,out] msgqueue message queue pointer
*/
void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_param_t *msgqueue);
/**
* enqueue metadata bins into the message queue
*
* @param[in] query_param structured query
* @param[in] metadatalist pointer to metadata bin list
* @param[in,out] msgqueue message queue pointer
*/
void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue);
bool gene_JPTstream( query_param_t query_param,
session_param_t *cursession,
channel_param_t *curchannel,
msgqueue_param_t **msgqueue)
{
target_param_t *target;
index_param_t *codeidx;
if( !cursession || !curchannel){ // stateless
if((target = gene_target( query_param.target)))
*msgqueue = gene_msgqueue( true, target);
else
return false;
}
else{ // session
target = curchannel->target;
*msgqueue = gene_msgqueue( false, target);
}
codeidx = target->codeidx;
//meta
if( query_param.box_type[0][0] != 0)
enqueue_metabins( query_param, codeidx->metadatalist, *msgqueue);
// image code
if( query_param.fx > 0 && query_param.fx > 0){
if( !codeidx->mhead_model)
enqueue_mainheader( *msgqueue);
enqueue_tiles( query_param, codeidx, *msgqueue);
}
return true;
}
void enqueue_tiles( query_param_t query_param, index_param_t *codeidx, msgqueue_param_t *msgqueue)
{
imgreg_param_t imgreg;
range_param_t tile_Xrange, tile_Yrange;
imgreg = map_viewin2imgreg( query_param.fx, query_param.fy,
query_param.rx, query_param.ry, query_param.rw, query_param.rh,
codeidx->XOsiz, codeidx->YOsiz, codeidx->Xsiz, codeidx->Ysiz,
get_nmax( codeidx->tilepart));
for( int u=0, tile_id=0; u<codeidx->YTnum; u++){
tile_Yrange = get_tile_Yrange( *codeidx, u, imgreg.level);
for( int v=0; v<codeidx->XTnum; v++, tile_id++){
tile_Xrange = get_tile_Xrange( *codeidx, v, imgreg.level);
if( tile_Xrange.minvalue < tile_Xrange.maxvalue && tile_Yrange.minvalue < tile_Yrange.maxvalue){
if( tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox ||
tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox + imgreg.sx ||
tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy ||
tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy + imgreg.sy) {
//printf("Tile completely excluded from view-window %d\n", tile_id);
// Tile completely excluded from view-window
}
else if( tile_Xrange.minvalue >= imgreg.xosiz + imgreg.ox &&
tile_Xrange.maxvalue <= imgreg.xosiz + imgreg.ox + imgreg.sx &&
tile_Yrange.minvalue >= imgreg.yosiz + imgreg.oy &&
tile_Yrange.maxvalue <= imgreg.yosiz + imgreg.oy + imgreg.sy) {
// Tile completely contained within view-window
// high priority
//printf("Tile completely contained within view-window %d\n", tile_id);
enqueue_tile( tile_id, imgreg.level, msgqueue);
}
else{
// Tile partially overlaps view-window
// low priority
//printf("Tile partially overlaps view-window %d\n", tile_id);
enqueue_tile( tile_id, imgreg.level, msgqueue);
}
}
}
}
}
void enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue)
{
for( int i=0; query_param.box_type[i][0]!=0 && i<MAX_NUMOFBOX; i++){
if( query_param.box_type[i][0] == '*'){
// not implemented
}
else{
int idx = search_metadataidx( query_param.box_type[i], metadatalist);
if( idx != -1)
enqueue_metadata( idx, msgqueue);
}
}
}

View File

@ -0,0 +1,250 @@
/*
* $Id: query_parser.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 <strings.h>
#include <stdio.h>
#include <string.h>
#include "query_parser.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
/**
* initialize query parameters
*
* @param[in,out] query_param query parameters
*/
void init_queryparam( query_param_t *query_param);
/**
* parse string to string array
*
* @param[in] src src string
* @param[out] cclose parsed string array
*/
void str2cclose( char *src, char cclose[][MAX_LENOFCID]);
void parse_metareq( char *field, query_param_t *query_param);
void parse_query( char *query_string, query_param_t *query_param)
{
char *pquery, *field, *fieldname;
init_queryparam( query_param);
pquery = query_string;
while( pquery!=NULL) {
field = strsep(&pquery, "&\n");
//field = strtok_r( query, "&", pquery);
fieldname = strsep(&field, "=");
//fieldname = strtok( field, "=");
if( field != NULL){
if( strcasecmp( fieldname, "target") == 0)
strcpy( query_param->target,field);
else if( strcasecmp( fieldname, "fsiz") == 0)
sscanf( field, "%d,%d", &query_param->fx, &query_param->fy);
else if( strcasecmp( fieldname, "roff") == 0)
sscanf( field, "%d,%d", &query_param->rx, &query_param->ry);
else if( strcasecmp( fieldname, "rsiz") == 0)
sscanf( field, "%d,%d", &query_param->rw, &query_param->rh);
else if( strcasecmp( fieldname, "cid") == 0)
strcpy( query_param->cid, field);
else if( strcasecmp( fieldname, "cnew") == 0)
query_param->cnew = true;
else if( strcasecmp( fieldname, "cclose") == 0)
str2cclose( field, query_param->cclose);
else if( strcasecmp( fieldname, "metareq") == 0)
parse_metareq( field, query_param);
}
}
}
void init_queryparam( query_param_t *query_param)
{
query_param->target[0]='\0';
query_param->fx=-1;
query_param->fy=-1;
query_param->rx=-1;
query_param->ry=-1;
query_param->rw=-1;
query_param->rh=-1;
query_param->cid[0]='\0';
query_param->cnew=false;
memset( query_param->cclose, 0, MAX_NUMOFCCLOSE*MAX_LENOFCID);
memset( query_param->box_type, 0, MAX_NUMOFBOX*4);
memset( query_param->limit, 0, MAX_NUMOFBOX*sizeof(int));
for( int i=0; i<MAX_NUMOFBOX; i++){
query_param->w[i] = false;
query_param->s[i] = false;
query_param->g[i] = false;
query_param->a[i] = false;
query_param->priority[i] = false;
}
query_param->root_bin = 0;
query_param->max_depth = -1;
query_param->metadata_only = false;
}
void print_queryparam( query_param_t query_param)
{
fprintf( logstream, "query parameters:\n");
fprintf( logstream, "\t target: %s\n", query_param.target);
fprintf( logstream, "\t fx,fy: %d, %d\n", query_param.fx, query_param.fy);
fprintf( logstream, "\t rx,ry: %d, %d \t rw,rh: %d, %d\n", query_param.rx, query_param.ry, query_param.rw, query_param.rh);
fprintf( logstream, "\t cnew: %d\n", query_param.cnew);
fprintf( logstream, "\t cid: %s\n", query_param.cid);
fprintf( logstream, "\t cclose: ");
for( int i=0; query_param.cclose[i][0]!=0 && i<MAX_NUMOFCCLOSE; i++)
fprintf( logstream, "%s ", query_param.cclose[i]);
fprintf(logstream, "\n");
fprintf( logstream, "\t req-box-prop\n");
for( int i=0; query_param.box_type[i][0]!=0 && i<MAX_NUMOFBOX; i++){
fprintf( logstream, "\t\t box_type: %.4s limit: %d w:%d s:%d g:%d a:%d priority:%d\n", query_param.box_type[i], query_param.limit[i], query_param.w[i], query_param.s[i], query_param.g[i], query_param.a[i], query_param.priority[i]);
}
fprintf( logstream, "\t root-bin: %d\n", query_param.root_bin);
fprintf( logstream, "\t max-depth: %d\n", query_param.max_depth);
fprintf( logstream, "\t metadata-only: %d\n", query_param.metadata_only);
}
void str2cclose( char *src, char cclose[][MAX_LENOFCID])
{
size_t len = strlen( src);
for( int i=0, u=0, v=0; i<len; i++){
if( src[i]==','){
u++;
v=0;
}
else
cclose[u][v++] = src[i];
}
}
void parse_req_box_prop( char *req_box_prop, int idx, query_param_t *query_param);
void parse_metareq( char *field, query_param_t *query_param)
{
char req_box_prop[20];
char *ptr, *src;
int numofboxreq = 0;
bzero( req_box_prop, 20);
// req-box-prop
ptr = strchr( field, '[');
ptr++;
src = ptr;
while( *ptr != ']'){
if( *ptr == ';'){
strncpy( req_box_prop, src, ptr-src);
parse_req_box_prop( req_box_prop, numofboxreq++, query_param);
ptr++;
src = ptr;
bzero( req_box_prop, 20);
}
ptr++;
}
strncpy( req_box_prop, src, ptr-src);
parse_req_box_prop( req_box_prop, numofboxreq++, query_param);
if(( ptr = strchr( field, 'R')))
sscanf( ptr+1, "%d", &(query_param->root_bin));
if(( ptr = strchr( field, 'D')))
sscanf( ptr+1, "%d", &(query_param->max_depth));
if(( ptr = strstr( field, "!!")))
query_param->metadata_only = true;
}
void parse_req_box_prop( char *req_box_prop, int idx, query_param_t *query_param)
{
char *ptr;
if( *req_box_prop == '*')
query_param->box_type[idx][0]='*';
else
strncpy( query_param->box_type[idx], req_box_prop, 4);
if(( ptr = strchr( req_box_prop, ':'))){
if( *(ptr+1)=='r')
query_param->limit[idx] = -1;
else
sscanf( ptr+1, "%d", &(query_param->limit[idx]));
}
if(( ptr = strchr( req_box_prop, '/'))){
ptr++;
while( *ptr=='w' || *ptr=='s' || *ptr=='g' || *ptr=='a'){
switch( *ptr){
case 'w': query_param->w[idx] = true; break;
case 's': query_param->s[idx] = true; break;
case 'g': query_param->g[idx] = true; break;
case 'a': query_param->a[idx] = true; break;
}
ptr++;
}
}
else{
query_param->g[idx] = true;
query_param->s[idx] = true;
query_param->w[idx] = true;
}
if((ptr = strchr( req_box_prop, '!')))
query_param->priority[idx] = true;
idx++;
}

View File

@ -0,0 +1,84 @@
/*
* $Id: query_parser.h 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.
*/
#ifndef QUERY_PARSER_H_
# define QUERY_PARSER_H_
#include <stdbool.h>
//! maximum length of target name
#define MAX_LENOFTARGET 128
//! maximum length of channel identifier
#define MAX_LENOFCID 30
//! maximum number of closing channel
#define MAX_NUMOFCCLOSE 10
//! maximum number of meta request box
#define MAX_NUMOFBOX 10
//! Query parameters
typedef struct query_param{
char target[MAX_LENOFTARGET]; //!< target name
int fx, fy; //!< frame size (fx,fy)
int rx, ry, rw, rh; //!< roi region
char cid[MAX_LENOFCID]; //!< channel identifier
bool cnew; //!< if there is new channel request(true) or not (false)
char cclose[MAX_NUMOFCCLOSE][MAX_LENOFCID]; //!< closing channel identifiers
char box_type[MAX_NUMOFBOX][4]; //!< interested box-types
int limit[MAX_NUMOFBOX]; //!< limit value, -1: skeleton request "r", 0: entire contents
bool w[MAX_NUMOFBOX]; //!< Metadata request qualifier flags
bool s[MAX_NUMOFBOX];
bool g[MAX_NUMOFBOX];
bool a[MAX_NUMOFBOX];
bool priority[MAX_NUMOFBOX]; //!< priority flag
int root_bin; //!< root-bin
int max_depth; //!< max-depth
bool metadata_only; //!< metadata-only request
} query_param_t;
/**
* parse query
*
* @param[in] query_string request query string
* @param[out] query_param query parameters
*/
void parse_query( char *query_string, query_param_t *query_param);
/**
* print query parameters
*
* @param[in] query_param query parameters
*/
void print_queryparam( query_param_t query_param);
#endif /* !QUERY_PARSER_H_ */

View File

@ -0,0 +1,190 @@
/*
* $Id: session_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 <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "session_manager.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
sessionlist_param_t * gene_sessionlist()
{
sessionlist_param_t *sessionlist;
sessionlist = (sessionlist_param_t *)malloc( sizeof(sessionlist_param_t));
sessionlist->first = NULL;
sessionlist->last = NULL;
return sessionlist;
}
session_param_t * gene_session( sessionlist_param_t *sessionlist)
{
session_param_t *session;
session = (session_param_t *)malloc( sizeof(session_param_t));
session->channellist = gene_channellist();
session->targetlist = gene_targetlist();
session->next = NULL;
if( sessionlist->first) // there are one or more entries
sessionlist->last->next = session;
else // first entry
sessionlist->first = session;
sessionlist->last = session;
return session;
}
bool search_session_and_channel( char cid[],
sessionlist_param_t *sessionlist,
session_param_t **foundsession,
channel_param_t **foundchannel)
{
*foundsession = sessionlist->first;
while( *foundsession != NULL){
*foundchannel = (*foundsession)->channellist->first;
while( *foundchannel != NULL){
if( strcmp( cid, (*foundchannel)->cid) == 0)
return true;
*foundchannel = (*foundchannel)->next;
}
*foundsession = (*foundsession)->next;
}
fprintf( FCGI_stdout, "Status: 503\r\n");
fprintf( FCGI_stdout, "Reason: Channel %s not found\r\n", cid);
return false;
}
void insert_target_into_session( session_param_t *session, target_param_t *target)
{
if(!target)
return;
#ifndef SERVER
fprintf( logstream, "local log: insert target into session %p\n", (void *)session);
#endif
if( session->targetlist->first != NULL)
session->targetlist->last->next = target;
else
session->targetlist->first = target;
session->targetlist->last = target;
}
bool delete_session( session_param_t **session, sessionlist_param_t *sessionlist)
{
session_param_t *ptr;
if( *session == NULL)
return false;
if( *session == sessionlist->first)
sessionlist->first = (*session)->next;
else{
ptr = sessionlist->first;
while( ptr->next != *session)
ptr = ptr->next;
ptr->next = (*session)->next;
if( *session == sessionlist->last)
sessionlist->last = ptr;
}
delete_channellist( &((*session)->channellist));
delete_targetlist ( &((*session)->targetlist));
#ifndef SERVER
fprintf( logstream, "local log: session: %p deleted!\n", (void *)(*session));
#endif
free( *session);
return true;
}
void delete_sessionlist( sessionlist_param_t **sessionlist)
{
session_param_t *sessionPtr, *sessionNext;
sessionPtr = (*sessionlist)->first;
while( sessionPtr != NULL){
sessionNext=sessionPtr->next;
delete_channellist( &(sessionPtr->channellist));
delete_targetlist ( &(sessionPtr->targetlist));
#ifndef SERVER
fprintf( logstream, "local log: session: %p deleted!\n", (void *)sessionPtr);
#endif
free( sessionPtr);
sessionPtr=sessionNext;
}
(*sessionlist)->first = NULL;
(*sessionlist)->last = NULL;
free(*sessionlist);
}
void print_allsession( sessionlist_param_t *sessionlist)
{
session_param_t *ptr;
int i=0;
fprintf( logstream, "SESSIONS info:\n");
ptr = sessionlist->first;
while( ptr != NULL){
fprintf( logstream, "session No.%d\n", i++);
print_allchannel( ptr->channellist);
print_alltarget( ptr->targetlist);
ptr=ptr->next;
}
}

View File

@ -0,0 +1,116 @@
/*
* $Id: session_manager.h 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.
*/
#ifndef SESSION_MANAGER_H_
# define SESSION_MANAGER_H_
#include <stdbool.h>
#include "channel_manager.h"
#include "target_manager.h"
//! Session parameters
typedef struct session_param{
channellist_param_t *channellist; //!< channel list pointer
targetlist_param_t *targetlist; //!< target list pointer
struct session_param *next; //!< pointer to the next session
} session_param_t;
//! Session list parameters
typedef struct sessionlist_param{
session_param_t *first; //!< first session pointer of the list
session_param_t *last; //!< last session pointer of the list
} sessionlist_param_t;
/**
* generate a session list
*
* @return pointer to the generated session list
*/
sessionlist_param_t * gene_sessionlist();
/**
* generate a session under the sesion list
*
* @param[in] sessionlist session list to insert the new session
* @return pointer to the generated session
*/
session_param_t * gene_session( sessionlist_param_t *sessionlist);
/**
* search a channel and its belonging session by channel ID
*
* @param[in] cid channel identifier
* @param[in] sessionlist session list pointer
* @param[in,out] foundsession address of the found session pointer
* @param[in,out] foundchannel address of the found channel pointer
* @return if the channel is found (true) or not (false)
*/
bool search_session_and_channel( char cid[],
sessionlist_param_t *sessionlist,
session_param_t **foundsession,
channel_param_t **foundchannel);
/**
* insert a target into a session
*
* @param[in] session session pointer
* @param[in] target target pointer
*/
void insert_target_into_session( session_param_t *session, target_param_t *target);
/**
* delete a session
*
* @param[in] session address of the session pointer
* @param[in] sessionlist session list pointer
* @return if succeeded (true) or failed (false)
*/
bool delete_session( session_param_t **session, sessionlist_param_t *sessionlist);
/**
* delete session list
*
* @param[in,out] sessionlist address of the session list pointer
*/
void delete_sessionlist( sessionlist_param_t **sessionlist);
/**
* print all sessions
*
* @param[in] sessionlist session list pointer
*/
void print_allsession( sessionlist_param_t *sessionlist);
#endif /* !SESSION_MANAGER_H_ */

View File

@ -0,0 +1,24 @@
LIBDIR = ../libopenjpip
LIBFNAME = $(LIBDIR)/libopenjpip_local.a
CFLAGS = -O3 -Wall -std=c99 -pedantic -I$(LIBDIR)
LDFLAGS = -L$(LIBDIR) -lm -lopenjpip_local
ALL = jpt_to_jp2 jpt_to_j2k test_index addXMLinJP2
all: t_indexer $(ALL)
t_indexer:
make -C indexer
jpt_to_jp2: jpt_to_jp2.o $(LIBFNAME)
$(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
jpt_to_j2k: jpt_to_j2k.o $(LIBFNAME)
$(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
test_index: test_index.o $(LIBFNAME)
$(CC) $(CFLAGS) $< $(LDFLAGS) -o $@
clean:
rm -f $(ALL) *.o *~
make clean -C indexer

View File

@ -0,0 +1,181 @@
/*
* $Id: addXMLinJP2.c 46 2011-02-17 14:50:55Z 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.
*/
/*! \file
* \brief addXMLinJP2 is a program to embed metadata into JP2 file
*
* \section impinst Implementing instructions
* This program takes two arguments. \n
* -# Input/output image file in JP2 format, this JP2 file is being modified
* -# Input XML file with metadata contents\n
* % ./addXMLinJP2 image.jp2 metadata.xml\n
*
* Currently, this program does not parse XML file, and the XML file contents is directly embedded as a XML Box.\n
* The following is an example of XML file contents specifying Region Of Interests with target names.\n
* <xmlbox>\n
* <roi name="island" x="1890" y="1950" w="770" h="310"/>\n
* <roi name="ship" x="750" y="330" w="100" h="60"/>\n
* <roi name="airport" x="650" y="1800" w="650" h="800"/>\n
* <roi name="harbor" x="4200" y="1650" w="130" h="130"/>\n
* </xmlbox>
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/**
* Open JP2 file with the check of JP2 header
*
* @param[in] filename file name string
* @return file descriptor
*/
FILE * open_jp2file( char filename[]);
/**
* read xml file without any format check for the moment
*
* @param[in] filename file name string
* @param[out] fsize file byte size
* @return pointer to the xml file content buffer
*/
char * read_xmlfile( char filename[], long *fsize);
int main(int argc, char *argv[])
{
if( argc<3){
fprintf( stderr, "USAGE: ./addXMLinJP2 modifing.jp2 adding.xml\n");
return -1;
}
FILE *fp;
char *xmldata, type[]="xml ";
long fsize, boxsize;
fp = open_jp2file( argv[1]);
if( !fp)
return -1;
xmldata = read_xmlfile( argv[2], &fsize);
boxsize = fsize + 8;
fputc( (boxsize>>24)&0xff, fp);
fputc( (boxsize>>16)&0xff, fp);
fputc( (boxsize>>8)&0xff, fp);
fputc( boxsize&0xff, fp);
fwrite( type, 4, 1, fp);
fwrite( xmldata, fsize, 1, fp);
free( xmldata);
fclose(fp);
return 0;
}
FILE * open_jp2file( char filename[])
{
FILE *fp;
char *data;
if( !(fp = fopen( filename, "a+b"))){
fprintf( stderr, "Original JP2 %s not found\n", filename);
return NULL;
}
// Check resource is a JP family file.
if( fseek( fp, 0, SEEK_SET)==-1){
fclose(fp);
fprintf( stderr, "Original JP2 %s broken (fseek error)\n", filename);
return NULL;
}
data = (char *)malloc( 12); // size of header
if( fread( data, 12, 1, fp) != 1){
free( data);
fclose(fp);
fprintf( stderr, "Original JP2 %s broken (read error)\n", filename);
return NULL;
}
if( *data || *(data + 1) || *(data + 2) ||
*(data + 3) != 12 || strncmp (data + 4, "jP \r\n\x87\n", 8)){
free( data);
fclose(fp);
fprintf( stderr, "No JPEG 2000 Signature box in target %s\n", filename);
return NULL;
}
free( data);
return fp;
}
char * read_xmlfile( char filename[], long *fsize)
{
FILE *fp;
char *data;
// fprintf( stderr, "open %s\n", filename);
if(!(fp = fopen( filename, "r"))){
fprintf( stderr, "XML file %s not found\n", filename);
return NULL;
}
if( fseek( fp, 0, SEEK_END) == -1){
fprintf( stderr, "XML file %s broken (seek error)\n", filename);
fclose( fp);
return NULL;
}
if( (*fsize = ftell( fp)) == -1){
fprintf( stderr, "XML file %s broken (seek error)\n", filename);
fclose( fp);
return NULL;
}
if( fseek( fp, 0, SEEK_SET) == -1){
fprintf( stderr, "XML file %s broken (seek error)\n", filename);
fclose( fp);
return NULL;
}
data = (char *)malloc( *fsize);
if( fread( data, *fsize, 1, fp) != 1){
fprintf( stderr, "XML file %s broken (read error)\n", filename);
free( data);
fclose(fp);
return NULL;
}
fclose( fp);
return data;
}

View File

@ -20,4 +20,4 @@ jp2.o : jp2.c j2k.h cio.h tcd.h int.h
index_create : bio.o cio.o int.o pi.o t2.o tgt.o tcd.o index_create.o jpip.o jp2.o
clean:
rm -rf *.o *.*~ *~ core.*
rm -rf index_create *.o *.*~ *~ core.*

View File

@ -28,13 +28,11 @@
#include "fix.h"
#ifdef _WIN32
#include <windows.h>
#ifdef WIN32
#define int64 __int64
#else
#define int64 long long
#endif /* _WIN32 */
#endif
/// <summary>
/// Multiply two fixed-precision rational numbers.

View File

@ -32,6 +32,7 @@
#include <string.h>
#include <setjmp.h>
#include <math.h>
#include <unistd.h>
#include "j2k.h"
#include "cio.h"
@ -68,7 +69,7 @@
#define J2K_STATE_TPH 0x0010
#define J2K_STATE_MT 0x0020
#define START_NB 5
#define START_NB 10
#define INCREMENT 5
jmp_buf j2k_error;
@ -322,7 +323,7 @@ void j2k_read_cod() {
/* <INDEX> [MHIX BOX] */
if (j2k_state == J2K_STATE_MH)
{
img.marker[img.num_marker].type = J2K_MS_SIZ;
img.marker[img.num_marker].type = J2K_MS_COD;
img.marker[img.num_marker].start_pos = cio_tell()-2;
img.marker[img.num_marker].len = len;
img.num_marker++;
@ -330,7 +331,7 @@ void j2k_read_cod() {
else
{
tile = &img.tile[j2k_curtileno];
tile->marker[tile->num_marker].type = J2K_MS_SIZ;
tile->marker[tile->num_marker].type = J2K_MS_COD;
tile->marker[tile->num_marker].start_pos = cio_tell()-2;
tile->marker[tile->num_marker].len = len;
tile->num_marker++;
@ -848,7 +849,7 @@ void j2k_read_sot() {
/* <INDEX> */
if (tileno == 0 && partno == 0 )
img.Main_head_end = cio_tell() - 7; /* Correction End = First byte of first SOT */
img.Main_head_end = cio_tell() - 12; /* Correction End = First byte of first SOT */
img.tile[tileno].num_tile = tileno;
/* </INDEX> */
@ -864,7 +865,7 @@ void j2k_read_sot() {
if (partno >= tile->Cztile_parts)
{
tilepart_tmp = (info_tile_part_t*)malloc((INCREMENT + tile->Cztile_parts) * sizeof(info_tile_part_t));
memcpy(tilepart_tmp, tile->tile_parts, tile->Cztile_parts);
memcpy(tilepart_tmp, tile->tile_parts, tile->Cztile_parts); /*add tilepart_ a tmp*/
tile->Cztile_parts += INCREMENT;
free(tile->tile_parts);
tile->tile_parts = tilepart_tmp;
@ -873,14 +874,12 @@ void j2k_read_sot() {
tile->tile_parts[partno].start_pos = cio_tell() - 12; /* INDEX : start_pos of the tile_part */
tile->tile_parts[partno].length = totlen; /* INDEX : length of the tile_part */
tile->tile_parts[partno].end_pos = totlen + cio_tell() - 12; /* INDEX : end position of the tile_part */
//tile->tile_parts[partno].num_reso_AUX = j2k_default_tcp.tccps[0].numresolutions;
j2k_curtileno = tileno;
j2k_eot = cio_getbp() - 12 + totlen;
j2k_state = J2K_STATE_TPH;
tcp = &j2k_cp->tcps[j2k_curtileno];
tile->tile_parts[numparts].num_reso_AUX = tcp->tccps[0].numresolutions; /* INDEX : AUX value for TPIX */
if (partno == 0)
// if (tcp->first == 1)
@ -897,6 +896,7 @@ void j2k_read_sot() {
}
//j2k_cp->tcps[j2k_curtileno].first=0;
}
// tile->tile_parts[numparts].num_reso_AUX = tcp->tccps[0].numresolutions; /* INDEX : AUX value for TPIX */
}
@ -958,11 +958,10 @@ void j2k_read_rgn() {
void j2k_read_sod() {
int len;
int len, i;
unsigned char *data;
info_tile_t *tile;
info_tile_part_t *tile_part;
// fprintf(stderr,"SOD\n");
/* <INDEX> [MHIX BOX] */
tile = &img.tile[j2k_curtileno];
tile->marker[tile->num_marker].type = J2K_MS_SOD;
@ -976,17 +975,27 @@ void j2k_read_sod() {
tile_part->end_header = cio_tell() - 1; /* INDEX : end header position of the tile-part header */
len = int_min(j2k_eot - cio_getbp(), cio_numbytesleft());
data = (unsigned char*)malloc((j2k_tile_len[j2k_curtileno] + len) * sizeof(unsigned char));
for (i=0; i<j2k_tile_len[j2k_curtileno]; i++)
data[i] = j2k_tile_data[j2k_curtileno][i];
for (i=0 ; i<len ; i++)
data[i+j2k_tile_len[j2k_curtileno]] = cio_read(1);
j2k_tile_len[j2k_curtileno] += len;
data = (unsigned char*)realloc(j2k_tile_data[j2k_curtileno], j2k_tile_len[j2k_curtileno]);
memcpy(data, cio_getbp(), len);
j2k_tile_data[j2k_curtileno] = data;
cio_skip(len);
/*
free(j2k_tile_data[j2k_curtileno]);
*/
j2k_tile_data[j2k_curtileno] = data;
data = NULL;
j2k_state = J2K_STATE_TPHSOT;
}
void j2k_read_eoc() {
int tileno;
tcd_init(j2k_img, j2k_cp, &img);
for (tileno = 0; tileno<j2k_cp->tw * j2k_cp->th; tileno++) {
tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno, &img);
@ -1008,7 +1017,7 @@ void j2k_read_unk() {
int j2k_index_JPIP(char *Idx_file, char *J2K_file, int len, int version){
FILE *dest;
unsigned char *index;
char *index;
int pos_iptr, end_pos;
int len_cidx, pos_cidx;
int len_jp2c, pos_jp2c;
@ -1021,7 +1030,7 @@ int j2k_index_JPIP(char *Idx_file, char *J2K_file, int len, int version){
}
/* INDEX MODE JPIP */
index = (unsigned char*)malloc(len);
index = (char*)malloc(len);
cio_init(index, len);
jp2_write_jp();
jp2_write_ftyp();
@ -1087,13 +1096,13 @@ j2k_dec_mstabent_t j2k_dec_mstab[]={
};
j2k_dec_mstabent_t *j2k_dec_mstab_lookup(int id) {
j2k_dec_mstabent_t *e;
for (e = j2k_dec_mstab; e->id != 0; e++) {
if (e->id == id) {
break;
j2k_dec_mstabent_t *e;
for (e = j2k_dec_mstab; e->id != 0; e++) {
if (e->id == id) {
break;
}
}
}
return e;
return e;
}
int j2k_decode(unsigned char *src, int len, j2k_image_t **image, j2k_cp_t **cp) {
@ -1130,7 +1139,7 @@ int j2k_decode(unsigned char *src, int len, j2k_image_t **image, j2k_cp_t **cp)
}
#ifdef _WIN32
#ifdef WIN32
#include <windows.h>
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) {
@ -1143,20 +1152,20 @@ BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserve
}
return TRUE;
}
#endif /* _WIN32 */
#endif
int main(int argc, char **argv)
{
FILE *src;
int totlen;
unsigned char *j2kfile;
char *j2kfile;
j2k_image_t *imgg;
j2k_cp_t *cp;
int version;
if (argc != 4)
{
fprintf(stderr,"\nUSAGE : ./index_create J2K-file JP2-file version\n\nVersion : 0, 1, 2 or 3\n 0 : [faix] 4-byte and no AUX fields\n 1 : [faix] 8-byte and no AUX fields\n 2 : [faix] 4-byte and AUX fields\n 3 : [faix] 8-byte and AUX fields\n\nReference Document : annex I from JPIP-FCD-version 2 (SC 29 N5727)\n\n");
fprintf(stderr,"\nERROR in entry : index_create J2K-file JP2-file version\n\nVersion : 0, 1, 2 or 3\n0 : [faix] 4-byte and no AUX fields\n1 : [faix] 8-byte and no AUX fields\n2 : [faix] 4-byte and AUX fields\n3 : [faix] 8-byte and AUX fields\n");
return 1;
}
@ -1171,7 +1180,7 @@ int main(int argc, char **argv)
totlen = ftell(src);
fseek(src, 0, SEEK_SET);
j2kfile = (unsigned char*)malloc(totlen);
j2kfile = (char*)malloc(totlen);
fread(j2kfile, 1, totlen, src);
fclose(src);
@ -1197,7 +1206,6 @@ int main(int argc, char **argv)
if (!j2k_decode(j2kfile, totlen, &imgg, &cp)) {
fprintf(stderr, "Index_creator: failed to decode image!\n");
free(j2kfile);
return 1;
}
free(j2kfile);

View File

@ -28,7 +28,7 @@
#define VERSION "0.0.8"
#ifdef _WIN32
#ifdef WIN32
#ifdef LIBJ2K_EXPORTS
#define LIBJ2K_API __declspec(dllexport)
#else
@ -105,6 +105,7 @@ typedef struct {
} j2k_poc_t;
typedef struct {
//int first;
int csty; /* coding style */
int prg; /* progression order */
int numlayers; /* number of layers */
@ -204,7 +205,6 @@ typedef struct{
int length_header; /* Length of the header */
int end_pos; /* End position of the tile part */
int end_header; /* End position of the tile part header */
int num_reso_AUX; /* Number of resolution level completed */
} info_tile_part_t;

View File

@ -50,8 +50,7 @@
void jp2_write_url(char *Idx_file)
{
int len, lenp;
unsigned int i;
int len, lenp, i;
char str[256];
sprintf(str, "%s", Idx_file);

View File

@ -30,6 +30,7 @@
#include <string.h>
#include <setjmp.h>
#include <math.h>
#include <unistd.h>
#include "j2k.h"
#include "cio.h"
@ -157,7 +158,7 @@ int jpip_write_mhix(info_image_t img, int status, int tileno)
cio_skip(4); /* L [at the end] */
cio_write(JPIP_MHIX, 4); /* MHIX */
if (status) /* MAIN HEADER */
if (status==0) /* MAIN HEADER */
{
cio_write(img.Main_head_end,8); /* TLEN */
@ -327,7 +328,7 @@ void jpip_read_mhix(int len)
int jpip_write_faix(int v, int compno, info_image_t img, j2k_cp_t *j2k_cp, int version)
{
int len, lenp, i, j;
/*int version = 0;*/
int Aux;
int tileno, resno, precno, layno, num_packet=0;
lenp=cio_tell();
@ -347,8 +348,17 @@ int jpip_write_faix(int v, int compno, info_image_t img, j2k_cp_t *j2k_cp, int v
cio_write(img.tile[i].tile_parts[j].start_pos,(version & 0x01)?8:4); /* start position */
cio_write(img.tile[i].tile_parts[j].length,(version & 0x01)?8:4); /* length */
if (version & 0x02)
cio_write(img.tile[i].tile_parts[j].num_reso_AUX,4); /* Aux_i,j : Auxiliary value */
//cio_write(0,4);
{
if (img.tile[i].numparts == 1 && img.Decomposition > 1)
Aux = img.Decomposition + 1;
else
Aux = j + 1;
cio_write(Aux,4);
//cio_write(img.tile[i].tile_parts[j].num_reso_AUX,4); /* Aux_i,j : Auxiliary value */
// fprintf(stderr,"AUX value %d\n",Aux);
}
//cio_write(0,4);
}
/* PADDING */
while (j < img.num_max_tile_parts)

View File

@ -0,0 +1,140 @@
/*
* Copyright (c) 2004, Yannick Verschueren
* Copyright (c) 2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium
* 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 <stdlib.h>
#include "cio.h"
/*
* Read the information contains in VBAS [JPP/JPT stream message header]
* Store information (7 bits) in value
*
*/
unsigned int jpt_read_VBAS_info(unsigned int value)
{
char elmt;
elmt = cio_read(1);
while ((elmt >> 7) == 1)
{
value = value << 7;
value |= (elmt & 0x7f);
elmt = cio_read(1);
}
value = value << 7;
value |= (elmt & 0x7f);
return value;
}
/*
* Read the message header for a JPP/JPT - stream
*
*/
void jpt_read_Msg_Header()
{
char elmt, Class, CSn, last_byte, Aux;
unsigned int ID=0, Class_ID=0, CSn_ID=0, Msg_offset=0, Msg_length=0, Layer_nb;
/* ------------- */
/* VBAS : Bin-ID */
/* ------------- */
elmt = cio_read(1);
/* See for Class and CSn */
switch((elmt>>5) & 0x03)
{
case 0:
fprintf(stderr,"Forbidden value encounter in message header !!\n");
break;
case 1:
Class = 0;
CSn = 0;
break;
case 2:
Class = 1;
CSn = 0;
break;
case 3:
Class = 1;
CSn = 1;
break;
default :
break;
}
/* see information on bits 'c' [p 10 : A.2.1 general, ISO/IEC FCD 15444-9] */
if (((elmt>>3) & 0x01) == 1)
last = 1;
/* In-class identifier */
ID |= (elmt & 0x0f);
if ((elmt>>7)==1)
ID = jpt_read_VBAS_info(ID);
/* ------------ */
/* VBAS : Class */
/* ------------ */
if (Class==1)
{
Class_ID = jpt_read_VBAS_info(Class_ID);
} else
{
/* 0 si pas de precedent message */
/* inchange sinon */
}
/* ---------- */
/* VBAS : CSn */
/* ---------- */
if (CSn==1)
{
CSn_ID = jpt_read_VBAS_info(CSn_ID);
} else
{
/* 0 si pas de precedent message */
/* inchange sinon */
}
/* ----------------- */
/* VBAS : Msg_offset */
/* ----------------- */
Msg_offset = jpt_read_VBAS_info(Msg_offset);
/* ----------------- */
/* VBAS : Msg_length */
/* ----------------- */
Msg_length = jpt_read_VBAS_info(Msg_length);
/* ---------- */
/* VBAS : Aux */
/* ---------- */
if (CSn_ID == 1)
Layer_nb = jpt_read_VBAS_info(Layer_nb);
}

Some files were not shown because too many files have changed in this diff Show More