summaryrefslogtreecommitdiff
path: root/src/lib/openjpip
diff options
context:
space:
mode:
authorMathieu Malaterre <mathieu.malaterre@gmail.com>2012-09-28 08:11:41 +0000
committerMathieu Malaterre <mathieu.malaterre@gmail.com>2012-09-28 08:11:41 +0000
commitd518970039a19a2a9b6d2bdd592cc88a43897bbb (patch)
tree57bac2cf7e63e9352228231062763baac627563c /src/lib/openjpip
parent8363a6ab1e031bb4b2e40a92e56efd40fdab1aa1 (diff)
[trunk] Start FolderReorgProposal task
Update issue 177
Diffstat (limited to 'src/lib/openjpip')
-rw-r--r--src/lib/openjpip/CMakeLists.txt72
-rw-r--r--src/lib/openjpip/Makefile.am153
-rw-r--r--src/lib/openjpip/auxtrans_manager.c267
-rw-r--r--src/lib/openjpip/auxtrans_manager.h72
-rw-r--r--src/lib/openjpip/bool.h52
-rw-r--r--src/lib/openjpip/box_manager.c434
-rw-r--r--src/lib/openjpip/box_manager.h264
-rw-r--r--src/lib/openjpip/boxheader_manager.c84
-rw-r--r--src/lib/openjpip/boxheader_manager.h71
-rw-r--r--src/lib/openjpip/byte_manager.c172
-rw-r--r--src/lib/openjpip/byte_manager.h129
-rw-r--r--src/lib/openjpip/cache_manager.c275
-rw-r--r--src/lib/openjpip/cache_manager.h177
-rw-r--r--src/lib/openjpip/cachemodel_manager.c236
-rw-r--r--src/lib/openjpip/cachemodel_manager.h115
-rw-r--r--src/lib/openjpip/channel_manager.c180
-rw-r--r--src/lib/openjpip/channel_manager.h120
-rw-r--r--src/lib/openjpip/codestream_manager.c81
-rw-r--r--src/lib/openjpip/codestream_manager.h101
-rw-r--r--src/lib/openjpip/dec_clientmsg_handler.c253
-rw-r--r--src/lib/openjpip/dec_clientmsg_handler.h113
-rw-r--r--src/lib/openjpip/faixbox_manager.c195
-rw-r--r--src/lib/openjpip/faixbox_manager.h146
-rw-r--r--src/lib/openjpip/ihdrbox_manager.c78
-rw-r--r--src/lib/openjpip/ihdrbox_manager.h56
-rw-r--r--src/lib/openjpip/imgreg_manager.c157
-rw-r--r--src/lib/openjpip/imgreg_manager.h101
-rw-r--r--src/lib/openjpip/imgsock_manager.c209
-rw-r--r--src/lib/openjpip/imgsock_manager.h174
-rw-r--r--src/lib/openjpip/index_manager.c732
-rw-r--r--src/lib/openjpip/index_manager.h187
-rw-r--r--src/lib/openjpip/j2kheader_manager.c295
-rw-r--r--src/lib/openjpip/j2kheader_manager.h73
-rw-r--r--src/lib/openjpip/jp2k_decoder.c236
-rw-r--r--src/lib/openjpip/jp2k_decoder.h39
-rw-r--r--src/lib/openjpip/jp2k_encoder.c804
-rw-r--r--src/lib/openjpip/jp2k_encoder.h74
-rw-r--r--src/lib/openjpip/jpip_parser.c460
-rw-r--r--src/lib/openjpip/jpip_parser.h114
-rw-r--r--src/lib/openjpip/jpipstream_manager.c120
-rw-r--r--src/lib/openjpip/jpipstream_manager.h41
-rw-r--r--src/lib/openjpip/manfbox_manager.c115
-rw-r--r--src/lib/openjpip/manfbox_manager.h81
-rw-r--r--src/lib/openjpip/marker_manager.c68
-rw-r--r--src/lib/openjpip/marker_manager.h87
-rw-r--r--src/lib/openjpip/metadata_manager.c253
-rw-r--r--src/lib/openjpip/metadata_manager.h151
-rw-r--r--src/lib/openjpip/mhixbox_manager.c141
-rw-r--r--src/lib/openjpip/mhixbox_manager.h102
-rw-r--r--src/lib/openjpip/msgqueue_manager.c762
-rw-r--r--src/lib/openjpip/msgqueue_manager.h188
-rw-r--r--src/lib/openjpip/openjpip.c450
-rw-r--r--src/lib/openjpip/openjpip.h308
-rw-r--r--src/lib/openjpip/placeholder_manager.c143
-rw-r--r--src/lib/openjpip/placeholder_manager.h115
-rw-r--r--src/lib/openjpip/query_parser.c429
-rw-r--r--src/lib/openjpip/query_parser.h97
-rw-r--r--src/lib/openjpip/session_manager.c196
-rw-r--r--src/lib/openjpip/session_manager.h116
-rw-r--r--src/lib/openjpip/sock_manager.c181
-rw-r--r--src/lib/openjpip/sock_manager.h106
-rw-r--r--src/lib/openjpip/target_manager.c345
-rw-r--r--src/lib/openjpip/target_manager.h159
63 files changed, 12305 insertions, 0 deletions
diff --git a/src/lib/openjpip/CMakeLists.txt b/src/lib/openjpip/CMakeLists.txt
new file mode 100644
index 00000000..e42e95fc
--- /dev/null
+++ b/src/lib/openjpip/CMakeLists.txt
@@ -0,0 +1,72 @@
+include_regular_expression("^.*$")
+
+include_directories(
+ ${OPENJPEG_SOURCE_DIR}/src/lib/openjp2
+ ${FCGI_INCLUDE_DIRS}
+ ${CURL_INCLUDE_DIRS}
+)
+
+# Defines the source code for the library
+set(OPENJPIP_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/boxheader_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/codestream_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/imgreg_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/marker_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/msgqueue_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/box_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/faixbox_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/index_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/metadata_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/placeholder_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/byte_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/ihdrbox_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/manfbox_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/mhixbox_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/target_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/cachemodel_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/j2kheader_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/jp2k_encoder.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/openjpip.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/query_parser.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/channel_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/session_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/jpip_parser.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/sock_manager.c
+ )
+
+set(SERVER_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/auxtrans_manager.c
+ )
+
+set(LOCAL_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/jp2k_decoder.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/imgsock_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/jpipstream_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/cache_manager.c
+ ${CMAKE_CURRENT_SOURCE_DIR}/dec_clientmsg_handler.c
+ )
+
+# Build the library
+add_library(openjpip_local STATIC ${OPENJPIP_SRCS} ${LOCAL_SRCS})
+target_link_libraries(openjpip_local ${OPENJPEG_LIBRARY_NAME})
+if(WIN32)
+ # add Winsock on windows+mingw
+ target_link_libraries(openjpip_local ws2_32)
+endif()
+
+# Install library
+install(TARGETS openjpip_local
+ EXPORT OpenJPEGTargets
+ DESTINATION ${OPENJPEG_INSTALL_LIB_DIR} COMPONENT Libraries
+ )
+
+if(BUILD_JPIP_SERVER)
+ add_library(openjpip_server STATIC ${OPENJPIP_SRCS} ${SERVER_SRCS})
+ target_link_libraries(openjpip_server ${FCGI_LIBRARIES} ${CURL_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT})
+ set_target_properties(openjpip_server
+ PROPERTIES COMPILE_FLAGS "-DSERVER")
+ install(TARGETS openjpip_server
+ EXPORT OpenJPEGTargets
+ DESTINATION ${OPENJPEG_INSTALL_LIB_DIR} COMPONENT Libraries
+ )
+endif()
diff --git a/src/lib/openjpip/Makefile.am b/src/lib/openjpip/Makefile.am
new file mode 100644
index 00000000..6def5d6f
--- /dev/null
+++ b/src/lib/openjpip/Makefile.am
@@ -0,0 +1,153 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+includesdir = $(includedir)/openjpeg-$(MAJOR_NR).$(MINOR_NR)
+includes_HEADERS =
+
+lib_LTLIBRARIES =
+
+if WANT_JPIP
+lib_LTLIBRARIES += libopenjpip_local.la
+endif
+
+if WANT_JPIP_SERVER
+lib_LTLIBRARIES += libopenjpip_server.la
+endif
+
+JPIP_SRC = \
+openjpip.c \
+query_parser.c \
+channel_manager.c \
+session_manager.c \
+jpip_parser.c \
+boxheader_manager.c \
+codestream_manager.c \
+imgreg_manager.c \
+marker_manager.c \
+msgqueue_manager.c \
+box_manager.c \
+faixbox_manager.c \
+index_manager.c \
+metadata_manager.c \
+placeholder_manager.c \
+byte_manager.c \
+ihdrbox_manager.c \
+manfbox_manager.c \
+mhixbox_manager.c \
+target_manager.c \
+cachemodel_manager.c \
+j2kheader_manager.c \
+jp2k_encoder.c \
+sock_manager.c \
+openjpip.h \
+bool.h \
+boxheader_manager.h \
+box_manager.h \
+byte_manager.h \
+codestream_manager.h \
+faixbox_manager.h \
+ihdrbox_manager.h \
+imgreg_manager.h \
+index_manager.h \
+manfbox_manager.h \
+marker_manager.h \
+metadata_manager.h \
+mhixbox_manager.h \
+msgqueue_manager.h \
+placeholder_manager.h \
+target_manager.h \
+cachemodel_manager.h \
+j2kheader_manager.h \
+jp2k_encoder.h \
+query_parser.h \
+channel_manager.h \
+session_manager.h \
+jpip_parser.h \
+jp2k_decoder.h \
+sock_manager.h
+
+SERVER_SRC = auxtrans_manager.c \
+auxtrans_manager.h
+
+LOCAL_SRC = jp2k_decoder.c \
+imgsock_manager.c \
+jpipstream_manager.c \
+cache_manager.c \
+dec_clientmsg_handler.c \
+imgsock_manager.h \
+jpipstream_manager.h \
+cache_manager.h \
+dec_clientmsg_handler.h
+
+libopenjpip_server_la_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/libopenjpeg \
+-I$(top_builddir)/libopenjpeg \
+-I$(top_srcdir)/applications/jpip/libopenjpip \
+-I$(top_builddir)/applications/jpip/libopenjpip \
+@FCGI_CFLAGS@ \
+@LIBCURL_CFLAGS@ \
+-DSERVER
+libopenjpip_server_la_CFLAGS = @THREAD_CFLAGS@
+libopenjpip_server_la_LIBADD = @FCGI_LIBS@ @LIBCURL_LIBS@ @THREAD_LIBS@ -lm
+libopenjpip_server_la_LDFLAGS = -no-undefined -version-info @lt_version@
+libopenjpip_server_la_SOURCES = $(JPIP_SRC) $(SERVER_SRC)
+
+libopenjpip_local_la_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/libopenjpeg \
+-I$(top_builddir)/libopenjpeg \
+-I$(top_srcdir)/applications/jpip/libopenjpip \
+-I$(top_builddir)/applications/jpip/libopenjpip \
+@LIBCURL_CFLAGS@
+libopenjpip_local_la_CFLAGS =
+libopenjpip_local_la_LIBADD = $(top_builddir)/libopenjpeg/libopenjpeg.la -lm
+libopenjpip_local_la_LDFLAGS = -no-undefined -version-info @lt_version@
+libopenjpip_local_la_SOURCES = $(JPIP_SRC) $(LOCAL_SRC)
+
+install-data-hook:
+if WANT_JPIP_SERVER
+ @echo -e " (LA)\t$(libdir)/libopenjpip_server.la" >> $(top_builddir)/report.txt
+if BUILD_SHARED
+ @( $(call solist_s) ) >> $(top_builddir)/report.txt
+endif
+if BUILD_STATIC
+ @echo -e " (A)\t$(base_s)/$(a_s)" >> $(top_builddir)/report.txt
+endif
+endif
+if WANT_JPIP
+ @echo -e " (LA)\t$(libdir)/libopenjpip_local.la" >> $(top_builddir)/report.txt
+if BUILD_SHARED
+ @( $(call solist_c) ) >> $(top_builddir)/report.txt
+endif
+if BUILD_STATIC
+ @echo -e " (A)\t$(base_c)/$(a_c)" >> $(top_builddir)/report.txt
+endif
+endif
+
+solist_s = $(foreach f, $(dll_s) $(so_s), echo -e ' $(SO_PREFIX)\t$(base_s)/$(f)' ;)
+get_tok_s = $(shell grep -E "^$(1)=" libopenjpip_server.la | cut -d "'" -f 2)
+base_s = $(call get_tok_s,libdir)
+so_s = $(call get_tok_s,library_names)
+a_s = $(call get_tok_s,old_library)
+
+solist_c = $(foreach f, $(dll_c) $(so_c), echo -e ' $(SO_PREFIX)\t$(base_c)/$(f)' ;)
+get_tok_c = $(shell grep -E "^$(1)=" libopenjpip_local.la | cut -d "'" -f 2)
+base_c = $(call get_tok_c,libdir)
+so_c = $(call get_tok_c,library_names)
+a_c = $(call get_tok_c,old_library)
+
+if HAVE_WIN32
+SO_PREFIX = (DLL)
+dll_s = $(call get_tok_s,dlname)
+dll_c = $(call get_tok_c,dlname)
+else
+if HAVE_DARWIN
+SO_PREFIX = (DY)
+dll_s =
+dll_c =
+else
+SO_PREFIX = (SO)
+dll_s =
+dll_c =
+endif
+endif
diff --git a/src/lib/openjpip/auxtrans_manager.c b/src/lib/openjpip/auxtrans_manager.c
new file mode 100644
index 00000000..91c06ac4
--- /dev/null
+++ b/src/lib/openjpip/auxtrans_manager.c
@@ -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.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "auxtrans_manager.h"
+
+#ifdef _WIN32
+#include <process.h>
+#else
+#include <pthread.h>
+#endif
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER */
+
+auxtrans_param_t init_aux_transport( int tcp_auxport, int udp_auxport)
+{
+ auxtrans_param_t auxtrans;
+
+ auxtrans.tcpauxport = tcp_auxport;
+ auxtrans.udpauxport = udp_auxport;
+
+ if( 49152 <= tcp_auxport && tcp_auxport <= 65535)
+ auxtrans.tcplistensock = open_listeningsocket( (uint16_t)tcp_auxport);
+ else
+ auxtrans.tcplistensock = -1;
+
+ auxtrans.udplistensock = -1;
+ /* open listening socket for udp later */
+
+ return auxtrans;
+}
+
+void close_aux_transport( auxtrans_param_t auxtrans)
+{
+ if( auxtrans.tcplistensock != -1)
+ if( close_socket( auxtrans.tcplistensock) != 0)
+ perror("close");
+
+ if( auxtrans.udplistensock != -1)
+ if( close_socket( auxtrans.udplistensock) != 0)
+ perror("close");
+}
+
+
+/*!< auxiliary response parameters */
+typedef struct aux_response_param{
+ char *cid; /*!< channel ID */
+ unsigned char *data; /*!< sending data */
+ OPJ_SIZE_T datalen; /*!< length of data */
+ OPJ_SIZE_T maxlenPerFrame; /*!< maximum data length to send per frame */
+ SOCKET listensock; /*!< listeing socket */
+#ifdef _WIN32
+ HANDLE hTh; /*!< thread handle */
+#endif
+} aux_response_param_t;
+
+aux_response_param_t * gene_auxresponse( bool istcp, auxtrans_param_t auxtrans, const char cid[], void *data, OPJ_SIZE_T datalen, OPJ_SIZE_T maxlenPerFrame);
+
+void delete_auxresponse( aux_response_param_t **auxresponse);
+
+
+#ifdef _WIN32
+unsigned __stdcall aux_streaming( void *arg);
+#else
+void * aux_streaming( void *arg);
+#endif
+
+void send_responsedata_on_aux( bool istcp, auxtrans_param_t auxtrans, const char cid[], void *data, OPJ_SIZE_T datalen, OPJ_SIZE_T maxlenPerFrame)
+{
+ aux_response_param_t *auxresponse;
+#ifdef _WIN32
+ unsigned int threadId;
+#else
+ pthread_t thread;
+ int status;
+#endif
+
+ if( istcp){
+ if( auxtrans.tcplistensock == -1){
+ fprintf( FCGI_stderr, "Error: error in send_responsedata_on_aux(), tcp listening socket no open\n");
+ return;
+ }
+
+ auxresponse = gene_auxresponse( istcp, auxtrans, cid, data, datalen, maxlenPerFrame);
+
+#ifdef _WIN32
+ auxresponse->hTh = (HANDLE)_beginthreadex( NULL, 0, &aux_streaming, auxresponse, 0, &threadId);
+ if( auxresponse->hTh == 0)
+ fprintf( FCGI_stderr,"ERRO: pthread_create() %s", strerror( (int)auxresponse->hTh));
+#else
+ status = pthread_create( &thread, NULL, &aux_streaming, auxresponse);
+ if( status != 0)
+ fprintf( FCGI_stderr,"ERROR: pthread_create() %s",strerror(status));
+#endif
+ }
+ else
+ fprintf( FCGI_stderr, "Error: error in send_responsedata_on_aux(), udp not implemented\n");
+}
+
+aux_response_param_t * gene_auxresponse( bool istcp, auxtrans_param_t auxtrans, const char cid[], void *data, OPJ_SIZE_T datalen, OPJ_SIZE_T maxlenPerFrame)
+{
+ aux_response_param_t *auxresponse;
+
+ auxresponse = (aux_response_param_t *)malloc( sizeof(aux_response_param_t));
+
+ auxresponse->cid = strdup( cid);
+ auxresponse->data = data;
+ auxresponse->datalen = datalen;
+ auxresponse->maxlenPerFrame = maxlenPerFrame;
+ auxresponse->listensock = istcp ? auxtrans.tcplistensock : auxtrans.udplistensock;
+
+ return auxresponse;
+}
+
+void delete_auxresponse( aux_response_param_t **auxresponse)
+{
+ free( (*auxresponse)->cid);
+ free( (*auxresponse)->data);
+ free( *auxresponse);
+}
+
+/**
+ * Identify cid sent from client
+ *
+ * @param [in] connected_socket file descriptor of the connected socket
+ * @param [in] refcid refenrece channel ID
+ * @param [in] fp file pointer for log of aux stream
+ * @return true if identified, false otherwise
+ */
+bool identify_cid( SOCKET connected_socket, char refcid[], FILE *fp);
+
+bool recv_ack( SOCKET connected_socket, void *data);
+
+#ifdef _WIN32
+unsigned __stdcall aux_streaming( void *arg)
+#else
+void * aux_streaming( void *arg)
+#endif
+{
+ SOCKET connected_socket;
+ unsigned char *chunk, *ptr;
+ OPJ_SIZE_T maxLenOfBody, remlen, chunklen;
+ const OPJ_SIZE_T headlen = 8;
+
+ aux_response_param_t *auxresponse = (aux_response_param_t *)arg;
+
+#ifdef _WIN32
+ CloseHandle( auxresponse->hTh);
+#else
+ pthread_detach( pthread_self());
+#endif
+
+ chunk = (unsigned char *)malloc( auxresponse->maxlenPerFrame);
+ maxLenOfBody = auxresponse->maxlenPerFrame - headlen;
+ remlen = auxresponse->datalen;
+
+ while((connected_socket = accept_socket( auxresponse->listensock)) != -1){
+ if( identify_cid( connected_socket, auxresponse->cid, FCGI_stderr)){
+ ptr = auxresponse->data;
+ while( 0 < remlen){
+ memset( chunk, 0, auxresponse->maxlenPerFrame);
+
+ chunklen = remlen<maxLenOfBody?remlen:maxLenOfBody;
+ chunklen += headlen;
+
+ chunk[0] = (chunklen >> 8) & 0xff;
+ chunk[1] = chunklen & 0xff;
+
+ memcpy( chunk+headlen, ptr, chunklen-headlen);
+
+ do{
+ send_stream( connected_socket, chunk, chunklen);
+ }while( !recv_ack( connected_socket, chunk));
+
+ remlen -= maxLenOfBody;
+ ptr += maxLenOfBody;
+ }
+ if( close_socket( connected_socket) != 0)
+ perror("close");
+ break;
+ }
+ }
+ free( chunk);
+
+ delete_auxresponse( &auxresponse);
+
+#ifdef _WIN32
+ _endthreadex(0);
+#else
+ pthread_exit(0);
+#endif
+
+ return 0;
+}
+
+
+bool identify_cid( SOCKET connected_socket, char refcid[], FILE *fp)
+{
+ char *cid;
+ bool succeed;
+
+ if(!(cid = receive_string( connected_socket))){
+ fprintf( fp, "Error: error in identify_cid(), while receiving cid from client\n");
+ return false;
+ }
+
+ succeed = false;
+ if( strncmp( refcid, cid, strlen( refcid)) == 0)
+ succeed = true;
+
+ free( cid);
+
+ return succeed;
+}
+
+bool recv_ack( SOCKET connected_socket, void *data)
+{
+ char *header;
+ bool succeed;
+
+ header = receive_stream( connected_socket, 8);
+
+ if( memcmp( header, data, 8) != 0)
+ succeed = false;
+ else
+ succeed = true;
+
+ free( header);
+
+ return succeed;
+}
diff --git a/src/lib/openjpip/auxtrans_manager.h b/src/lib/openjpip/auxtrans_manager.h
new file mode 100644
index 00000000..c80988a9
--- /dev/null
+++ b/src/lib/openjpip/auxtrans_manager.h
@@ -0,0 +1,72 @@
+/*
+ * $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.
+ */
+
+#ifndef AUXTRANS_MANAGER_H_
+# define AUXTRANS_MANAGER_H_
+
+#include "sock_manager.h"
+
+/** auxiliary transport setting parameters*/
+typedef struct auxtrans_param{
+ int tcpauxport; /**< tcp port*/
+ int udpauxport; /**< udp port*/
+ SOCKET tcplistensock; /**< listenning socket for aux tcp (-1 if not open)*/
+ SOCKET udplistensock; /**< listenning socket for aux udp (-1 if not open)*/
+} auxtrans_param_t;
+
+/**
+ * Initialize auxiliary transport server of JPIP server
+ *
+ * @param[in] tcp_auxport opening tcp auxiliary port ( 0 not to open, valid No. 49152-65535)
+ * @param[in] udp_auxport opening udp auxiliary port ( 0 not to open, valid No. 49152-65535)
+ * @return intialized transport parameters
+ */
+auxtrans_param_t init_aux_transport( int tcp_auxport, int udp_auxport);
+
+/**
+ * Close auxiliary transport server of JPIP server
+ *
+ * @param[in] auxtrans closing transport server
+ */
+void close_aux_transport( auxtrans_param_t auxtrans);
+
+/**
+ * Send response data on aux transport
+ *
+ * @param[in] istcp true if tcp, false if udp
+ * @param[in] auxtrans available transport parameters
+ * @param[in] cid channel ID
+ * @param[in] data sending data
+ * @param[in] length length of data
+ * @param[in] maxlenPerFrame maximum data length to send per frame
+ */
+void send_responsedata_on_aux( bool istcp, auxtrans_param_t auxtrans, const char cid[], void *data, OPJ_SIZE_T length, OPJ_SIZE_T maxlenPerFrame);
+
+#endif /* !AUXTRANS_MANAGER_H_ */
diff --git a/src/lib/openjpip/bool.h b/src/lib/openjpip/bool.h
new file mode 100644
index 00000000..c3adf580
--- /dev/null
+++ b/src/lib/openjpip/bool.h
@@ -0,0 +1,52 @@
+/*
+ * $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.
+ */
+
+#ifndef BOOL_H_
+# define BOOL_H_
+
+#ifndef false
+#define false 0
+#endif
+
+#ifndef FALSE
+#define FALSE 0
+#endif
+
+#ifndef true
+#define true (!false)
+#endif
+
+#ifndef TRUE
+#define TRUE (!FALSE)
+#endif
+
+typedef char bool;
+
+#endif /* !BOOL_H_ */
diff --git a/src/lib/openjpip/box_manager.c b/src/lib/openjpip/box_manager.c
new file mode 100644
index 00000000..87bb7756
--- /dev/null
+++ b/src/lib/openjpip/box_manager.c
@@ -0,0 +1,434 @@
+/*
+ * $Id: box_manager.c 44 2011-02-15 12:32:29Z kaori $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <assert.h>
+#include "box_manager.h"
+#include "opj_inttypes.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER*/
+
+boxlist_param_t * gene_boxlist(void)
+{
+ boxlist_param_t *boxlist;
+
+ boxlist = (boxlist_param_t *)malloc( sizeof(boxlist_param_t));
+
+ boxlist->first = NULL;
+ boxlist->last = NULL;
+
+ return boxlist;
+}
+
+boxlist_param_t * get_boxstructure( int fd, OPJ_OFF_T offset, OPJ_SIZE_T length)
+{
+ boxlist_param_t *boxlist;
+ box_param_t *box;
+ OPJ_OFF_T pos;
+
+ boxlist = NULL;
+ pos = offset;
+ assert( (OPJ_OFF_T)length>=0);
+ do{
+ if(!(box = gene_boxbyOffset( fd, pos)))
+ break;
+
+ assert( (OPJ_OFF_T)box->length >= 0);
+ pos += (OPJ_OFF_T)box->length;
+
+ if( !boxlist)
+ boxlist = gene_boxlist();
+ insert_box_into_list( box, boxlist);
+ }while( pos < offset+(OPJ_OFF_T)length);
+
+ return boxlist;
+}
+
+box_param_t * gene_boxbyOffset( int fd, OPJ_OFF_T offset)
+{
+ Byte_t *data;
+ Byte8_t boxlen;
+ Byte_t headlen;
+ char *boxtype;
+ box_param_t *box;
+
+ /* read LBox and TBox*/
+ if(!(data = fetch_bytes( fd, offset, 8))){
+ fprintf( FCGI_stderr, "Error: error in gene_boxbyOffset( %d, %" PRId64 ")\n", fd, offset);
+ return NULL;
+ }
+
+ headlen = 8;
+ boxlen = (Byte8_t)big4(data);
+ boxtype = (char *)(data+4);
+
+ /* box type constraint*/
+ if( !isalpha(boxtype[0]) || !isalpha(boxtype[1]) ||
+ (!isalnum(boxtype[2])&&!isspace(boxtype[2])) ||
+ (!isalpha(boxtype[3])&&!isspace(boxtype[3]))){
+ free( data);
+ return NULL;
+ }
+
+ if( boxlen == 1){
+ Byte_t *data2;
+ headlen = 16;
+ /* read XLBox*/
+ if((data2 = fetch_bytes( fd, offset+8, 8))){
+ boxlen = big8(data2);
+ free(data2);
+ }
+ else{
+ fprintf( FCGI_stderr, "Error: error in gene_boxbyOffset( %d, %" PRId64 ")\n", fd, offset);
+ free( data);
+ return NULL;
+ }
+ }
+ box = (box_param_t *)malloc( sizeof( box_param_t));
+ box->fd = fd;
+ box->offset = offset;
+ box->headlen = headlen;
+ box->length = boxlen;
+ strncpy( box->type, boxtype, 4);
+ box->next = NULL;
+ free( data);
+ return box;
+}
+
+box_param_t * gene_boxbyOffinStream( Byte_t *stream, OPJ_OFF_T offset)
+{
+ Byte8_t boxlen;
+ Byte_t headlen;
+ char *boxtype;
+ box_param_t *box;
+
+ /* read LBox and TBox*/
+ headlen = 8;
+ boxlen = (Byte8_t)big4( stream);
+ boxtype = (char *)( stream+4);
+
+ /* box type constraint*/
+ if( !isalpha(boxtype[0]) || !isalpha(boxtype[1]) ||
+ (!isalnum(boxtype[2])&&!isspace(boxtype[2])) ||
+ (!isalpha(boxtype[3])&&!isspace(boxtype[3]))){
+ return NULL;
+ }
+
+ if( boxlen == 1){
+ headlen = 16;
+ boxlen = big8( stream+8); /* read XLBox*/
+ }
+ box = (box_param_t *)malloc( sizeof( box_param_t));
+ box->fd = -1;
+ box->offset = offset;
+ box->headlen = headlen;
+ box->length = boxlen;
+ strncpy( box->type, boxtype, 4);
+ box->next = NULL;
+
+ return box;
+}
+
+
+box_param_t * gene_boxbyType( int fd, OPJ_OFF_T offset, OPJ_SIZE_T length, const char TBox[])
+{
+ OPJ_OFF_T pos;
+ Byte_t *data;
+ Byte8_t boxlen;
+ Byte_t headlen;
+ char *boxtype;
+ box_param_t *foundbox;
+
+
+ if( length==0){ /* set the max length*/
+ if( get_filesize( fd) <= offset )
+ return NULL;
+ assert( get_filesize( fd) > offset );
+ assert( offset >= 0 );
+ length = (OPJ_SIZE_T)(get_filesize( fd) - offset);
+ }
+
+ pos = offset;
+ assert( pos >= 0 );
+ assert( (OPJ_OFF_T)length >= 0 );
+ while( pos < offset+(OPJ_OFF_T)length-7){ /* LBox+TBox-1=7*/
+
+ /* read LBox and TBox*/
+ if((data = fetch_bytes( fd, pos, 8))){
+ headlen = 8;
+ boxlen = (Byte8_t)big4(data);
+ boxtype = (char *)(data+4);
+
+ if( boxlen == 1){
+ Byte_t *data2;
+ headlen = 16;
+ /* read XLBox*/
+ if((data2 = fetch_bytes( fd, pos+8, 8))){
+ boxlen = big8(data2);
+ free(data2);
+ }
+ else{
+ fprintf( FCGI_stderr, "Error: error in gene_boxbyType( %d, %" PRId64 ", %" PRId64 ", %s)\n", fd, offset, length, TBox);
+ return NULL;
+ }
+ }
+ if( strncmp ( boxtype, TBox, 4) == 0){
+ foundbox = (box_param_t *)malloc( sizeof( box_param_t));
+ foundbox->fd = fd;
+ foundbox->offset = pos;
+ foundbox->headlen = headlen;
+ foundbox->length = boxlen;
+ strncpy( foundbox->type, TBox, 4);
+ foundbox->next = NULL;
+ free( data);
+ return foundbox;
+ }
+ free( data);
+ }
+ else{
+ fprintf( FCGI_stderr, "Error: error in gene_boxbyType( %d, %" PRId64 ", %" PRId64 ", %s)\n", fd, offset, length, TBox);
+ return NULL;
+ }
+ assert( ((Byte8_t)pos+boxlen)>=(Byte8_t)pos);
+ pos+= (OPJ_OFF_T)boxlen;
+ }
+ fprintf( FCGI_stderr, "Error: Box %s not found\n", TBox);
+
+ return NULL;
+}
+
+box_param_t * gene_boxbyTypeinStream( Byte_t *stream, OPJ_OFF_T offset, OPJ_SIZE_T length, const char TBox[])
+{
+ OPJ_OFF_T pos;
+ Byte_t *data;
+ Byte8_t boxlen;
+ Byte_t headlen;
+ char *boxtype;
+ box_param_t *foundbox;
+
+ pos = offset;
+ assert( pos >= 0 );
+ assert( (OPJ_OFF_T)length >= 0 );
+ while( pos < offset+(OPJ_OFF_T)(length)-7){ /* LBox+TBox-1=7*/
+
+ /* read LBox and TBox*/
+ data = stream + pos;
+ headlen = 8;
+ boxlen = (Byte8_t)big4(data);
+ boxtype = (char *)(data+4);
+
+ if( boxlen == 1){
+ /* read XLBox*/
+ headlen = 16;
+ boxlen = big8( data+8);
+ }
+
+ if( strncmp ( boxtype, TBox, 4) == 0){
+ foundbox = (box_param_t *)malloc( sizeof( box_param_t));
+ foundbox->fd = -1;
+ foundbox->offset = pos;
+ foundbox->headlen = headlen;
+ foundbox->length = boxlen;
+ strncpy( foundbox->type, TBox, 4);
+ foundbox->next = NULL;
+ return foundbox;
+ }
+ assert( ((Byte8_t)pos+boxlen)>=(Byte8_t)pos);
+ pos+= (OPJ_OFF_T)boxlen;
+ }
+ fprintf( FCGI_stderr, "Error: Box %s not found\n", TBox);
+
+ return NULL;
+}
+
+box_param_t * gene_childboxbyOffset( box_param_t *superbox, OPJ_OFF_T offset)
+{
+ return gene_boxbyOffset( superbox->fd, get_DBoxoff( superbox)+offset);
+}
+
+box_param_t * gene_childboxbyType( box_param_t *superbox, OPJ_OFF_T offset, const char TBox[])
+{
+ OPJ_SIZE_T DBOXlen = get_DBoxlen(superbox);
+ assert( offset >= 0 );
+ if( DBOXlen < (OPJ_SIZE_T)offset )
+ {
+ fprintf( FCGI_stderr, "Error: Impossible happen %lu < %ld\n", DBOXlen, offset);
+ return NULL;
+ }
+ return gene_boxbyType( superbox->fd, get_DBoxoff( superbox)+offset, DBOXlen-(OPJ_SIZE_T)offset, TBox);
+}
+
+OPJ_OFF_T get_DBoxoff( box_param_t *box)
+{
+ return box->offset+box->headlen;
+}
+
+OPJ_SIZE_T get_DBoxlen( box_param_t *box)
+{
+ return box->length - box->headlen;
+}
+
+Byte_t * fetch_headbytes( box_param_t *box)
+{
+ return fetch_bytes( box->fd, box->offset, box->headlen);
+}
+
+Byte_t * fetch_DBoxbytes( box_param_t *box, OPJ_OFF_T offset, OPJ_SIZE_T size)
+{
+ return fetch_bytes( box->fd, get_DBoxoff( box)+offset, size);
+}
+
+Byte_t fetch_DBox1byte( box_param_t *box, OPJ_OFF_T offset)
+{
+ return fetch_1byte( box->fd, get_DBoxoff( box)+offset);
+}
+
+Byte2_t fetch_DBox2bytebigendian( box_param_t *box, OPJ_OFF_T offset)
+{
+ return fetch_2bytebigendian( box->fd, get_DBoxoff( box)+offset);
+}
+
+Byte4_t fetch_DBox4bytebigendian( box_param_t *box, OPJ_OFF_T offset)
+{
+ return fetch_4bytebigendian( box->fd, get_DBoxoff( box)+offset);
+}
+
+Byte8_t fetch_DBox8bytebigendian( box_param_t *box, OPJ_OFF_T offset)
+{
+ return fetch_8bytebigendian( box->fd, get_DBoxoff( box)+offset);
+}
+
+box_param_t * search_box( const char type[], boxlist_param_t *boxlist)
+{
+ box_param_t *foundbox;
+
+ foundbox = boxlist->first;
+
+ while( foundbox != NULL){
+
+ if( strncmp( type, foundbox->type, 4) == 0)
+ return foundbox;
+
+ foundbox = foundbox->next;
+ }
+ fprintf( FCGI_stderr, "Error: Box %s not found\n", type);
+
+ return NULL;
+}
+
+void print_box( box_param_t *box)
+{
+ fprintf( logstream, "box info:\n"
+ "\t type: %.4s\n"
+ "\t offset: %" PRId64 " %#" PRIx64 "\n"
+ "\t header length: %d\n"
+ "\t length: %" PRId64 " %#" PRIx64 "\n", box->type, box->offset,
+ box->offset, box->headlen, box->length, box->length);
+}
+
+void print_allbox( boxlist_param_t *boxlist)
+{
+ box_param_t *ptr;
+
+ if( !boxlist)
+ return;
+
+ ptr = boxlist->first;
+ if( !ptr)
+ fprintf( logstream, "no box\n");
+
+ fprintf( logstream, "all box info: \n");
+ while( ptr != NULL){
+ print_box( ptr);
+ ptr=ptr->next;
+ }
+}
+
+void delete_box_in_list( box_param_t **box, boxlist_param_t *boxlist)
+{
+ box_param_t *ptr;
+
+ if( *box == boxlist->first)
+ boxlist->first = (*box)->next;
+ else{
+ ptr = boxlist->first;
+ while( ptr->next != *box){
+ ptr=ptr->next;
+ }
+ ptr->next = (*box)->next;
+
+ if( *box == boxlist->last)
+ boxlist->last = ptr;
+ }
+ free( *box);
+}
+
+void delete_box_in_list_by_type( const char type[], boxlist_param_t *boxlist)
+{
+ box_param_t *box;
+
+ box = search_box( type, boxlist);
+ delete_box_in_list( &box, boxlist);
+}
+
+void delete_boxlist( boxlist_param_t **boxlist)
+{
+ box_param_t *boxPtr, *boxNext;
+
+ if(!(*boxlist))
+ return;
+
+ boxPtr = (*boxlist)->first;
+ while( boxPtr != NULL){
+ boxNext=boxPtr->next;
+ free( boxPtr);
+ boxPtr=boxNext;
+ }
+ free( *boxlist);
+}
+
+void insert_box_into_list( box_param_t *box, boxlist_param_t *boxlist)
+{
+ if( boxlist->first)
+ boxlist->last->next = box;
+ else
+ boxlist->first = box;
+ boxlist->last = box;
+}
diff --git a/src/lib/openjpip/box_manager.h b/src/lib/openjpip/box_manager.h
new file mode 100644
index 00000000..88cd5336
--- /dev/null
+++ b/src/lib/openjpip/box_manager.h
@@ -0,0 +1,264 @@
+/*
+ * $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 "byte_manager.h"
+
+/** box parameters*/
+typedef struct box_param{
+ int fd; /**< file descriptor*/
+ OPJ_OFF_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(void);
+
+/**
+ * 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, OPJ_OFF_T offset, OPJ_SIZE_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, OPJ_OFF_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, OPJ_OFF_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, OPJ_OFF_T offset, OPJ_SIZE_T length, const 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, OPJ_OFF_T offset, OPJ_SIZE_T length, const 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, OPJ_OFF_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, OPJ_OFF_T offset, const char TBox[]);
+
+/**
+ * get DBox offset
+ *
+ * @param[in] box box pointer
+ * @return DBox offset (byte position) in the file
+ */
+OPJ_OFF_T get_DBoxoff( box_param_t *box);
+
+
+/**
+ * get DBox length
+ *
+ * @param[in] box box pointer
+ * @return DBox length ( content length)
+ */
+OPJ_SIZE_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, OPJ_OFF_T offset, OPJ_SIZE_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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( const 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( const 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_ */
diff --git a/src/lib/openjpip/boxheader_manager.c b/src/lib/openjpip/boxheader_manager.c
new file mode 100644
index 00000000..b345a96d
--- /dev/null
+++ b/src/lib/openjpip/boxheader_manager.c
@@ -0,0 +1,84 @@
+/*
+ * $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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdlib.h>
+#include "boxheader_manager.h"
+#include "opj_inttypes.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER*/
+
+
+boxheader_param_t * gene_boxheader( int fd, OPJ_OFF_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, OPJ_OFF_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:%" PRId64 " %#" PRIx64 "\n", boxheader->type, boxheader->length, boxheader->length);
+}
diff --git a/src/lib/openjpip/boxheader_manager.h b/src/lib/openjpip/boxheader_manager.h
new file mode 100644
index 00000000..f8e48f39
--- /dev/null
+++ b/src/lib/openjpip/boxheader_manager.h
@@ -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, OPJ_OFF_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, OPJ_OFF_T offset);
+
+/**
+ * print box header parameters
+ *
+ * @param[in] boxheader boxheader pointer
+ */
+void print_boxheader( boxheader_param_t *boxheader);
+
+#endif /* !BOXHEADER_MANAGER_H_ */
diff --git a/src/lib/openjpip/byte_manager.c b/src/lib/openjpip/byte_manager.c
new file mode 100644
index 00000000..502c26bd
--- /dev/null
+++ b/src/lib/openjpip/byte_manager.c
@@ -0,0 +1,172 @@
+/*
+ * $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 <stdio.h>
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+#include <stdlib.h>
+#include <sys/stat.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, OPJ_OFF_T offset, OPJ_SIZE_T 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, %lu)\n", fd, offset, size);
+ return NULL;
+ }
+
+ data = (Byte_t *)malloc( size);
+
+ if( (OPJ_SIZE_T)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, %lu)\n", fd, offset, size);
+ return NULL;
+ }
+ return data;
+}
+
+Byte_t fetch_1byte( int fd, OPJ_OFF_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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)((((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));
+}
+
+void modify_4Bytecode( Byte4_t code, Byte_t *stream)
+{
+ *stream = (Byte_t) ((Byte4_t)(code & 0xff000000) >> 24);
+ *(stream+1) = (Byte_t) ((Byte4_t)(code & 0x00ff0000) >> 16);
+ *(stream+2) = (Byte_t) ((Byte4_t)(code & 0x0000ff00) >> 8);
+ *(stream+3) = (Byte_t) (code & 0x000000ff);
+}
+
+OPJ_OFF_T get_filesize( int fd)
+{
+ struct stat sb;
+
+ if( fstat( fd, &sb) == -1){
+ fprintf( FCGI_stdout, "Reason: Target broken (fstat error)\r\n");
+ fprintf( FCGI_stderr, "Error: error in get_filesize( %d)\n", fd);
+ return 0;
+ }
+ return sb.st_size;
+}
diff --git a/src/lib/openjpip/byte_manager.h b/src/lib/openjpip/byte_manager.h
new file mode 100644
index 00000000..0a29503e
--- /dev/null
+++ b/src/lib/openjpip/byte_manager.h
@@ -0,0 +1,129 @@
+/*
+ * $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 <stddef.h>
+#include "opj_stdint.h"
+typedef uint8_t Byte_t;
+typedef uint16_t Byte2_t;
+typedef uint32_t Byte4_t;
+typedef uint64_t 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, OPJ_OFF_T offset, OPJ_SIZE_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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);
+
+/**
+ * modify 4Byte code in a codestream
+ *
+ * @param[in] code code value
+ * @param[out] stream modifying codestream
+ */
+void modify_4Bytecode( Byte4_t code, Byte_t *stream);
+
+/**
+ * Get file size
+ *
+ * @param[in] fd file discriptor
+ * @return file size
+ */
+OPJ_OFF_T get_filesize( int fd);
+
+#endif /* !BYTE_MANAGER_H_ */
diff --git a/src/lib/openjpip/cache_manager.c b/src/lib/openjpip/cache_manager.c
new file mode 100644
index 00000000..76f7b7b3
--- /dev/null
+++ b/src/lib/openjpip/cache_manager.c
@@ -0,0 +1,275 @@
+/*
+ * $Id: cache_manager.c 53 2011-05-09 16:55:39Z 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"
+
+cachelist_param_t * gene_cachelist(void)
+{
+ 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( const char *targetname, int csn, char *tid, char *cid)
+{
+ cache_param_t *cache;
+
+ cache = (cache_param_t *)malloc( sizeof(cache_param_t));
+ cache->filename = strdup( targetname);
+ cache->tid = strdup( tid);
+ cache->csn = csn;
+ cache->cid = (char **)malloc( sizeof(char *));
+ *cache->cid = strdup( 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)
+{
+ int i;
+
+ free( (*cache)->filename);
+ free( (*cache)->tid);
+
+ delete_metadatalist( &(*cache)->metadatalist);
+
+ if((*cache)->ihdrbox)
+ free((*cache)->ihdrbox);
+ for( 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( const char targetname[], cachelist_param_t *cachelist)
+{
+ cache_param_t *foundcache;
+
+ if( !targetname)
+ return NULL;
+
+ 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( const char cid[], cachelist_param_t *cachelist)
+{
+ cache_param_t *foundcache;
+ int i;
+
+ if( !cid)
+ return NULL;
+
+ foundcache = cachelist->first;
+
+ while( foundcache != NULL){
+ for( i=0; i<foundcache->numOfcid; i++)
+ if( strcmp( cid, foundcache->cid[i]) == 0)
+ return foundcache;
+ foundcache = foundcache->next;
+ }
+ return NULL;
+}
+
+cache_param_t * search_cacheBytid( const char tid[], cachelist_param_t *cachelist)
+{
+ cache_param_t *foundcache;
+
+ if( !tid)
+ return NULL;
+
+ foundcache = cachelist->first;
+
+ while( foundcache != NULL){
+ if( strcmp( tid, foundcache->tid) == 0)
+ return foundcache;
+ foundcache = foundcache->next;
+ }
+ return NULL;
+}
+
+void add_cachecid( const char *cid, cache_param_t *cache)
+{
+ if( !cid)
+ return;
+
+ if( (cache->cid = realloc( cache->cid, (OPJ_SIZE_T)(cache->numOfcid+1)*sizeof(char *))) == NULL){
+ fprintf( stderr, "failed to add new cid to cache table in add_cachecid()\n");
+ return;
+ }
+
+ cache->cid[ cache->numOfcid] = strdup( cid);
+
+ cache->numOfcid ++;
+}
+
+void update_cachetid( const char *tid, cache_param_t *cache)
+{
+ if( !tid)
+ return;
+
+ if( tid[0] != '0' && strcmp( tid, cache->tid) !=0){
+ fprintf( stderr, "tid is updated to %s for %s\n", tid, cache->filename);
+ free( cache->tid);
+ cache->tid = strdup( tid);
+ }
+}
+
+void remove_cidInCache( const char *cid, cache_param_t *cache);
+
+void remove_cachecid( const char *cid, cachelist_param_t *cachelist)
+{
+ cache_param_t *cache;
+
+ cache = search_cacheBycid( cid, cachelist);
+ remove_cidInCache( cid, cache);
+}
+
+void remove_cidInCache( const char *cid, cache_param_t *cache)
+{
+ int idx = -1;
+ char **tmp;
+ int i, j;
+
+ for( 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( (OPJ_SIZE_T)(cache->numOfcid-1)*sizeof(char *));
+
+ for( i=0, j=0; i<cache->numOfcid; i++){
+ if( i != idx){
+ cache->cid[j] = strdup( tmp[i]);
+ j++;
+ }
+ free( tmp[i]);
+ }
+ free( tmp);
+
+ cache->numOfcid --;
+}
+
+void print_cache( cache_param_t *cache)
+{
+ int i;
+
+ fprintf( stdout,"cache\n");
+ fprintf( stdout,"\t filename: %s\n", cache->filename);
+ fprintf( stdout,"\t tid: %s\n", cache->tid);
+ fprintf( stdout,"\t csn: %d\n", cache->csn);
+ fprintf( stdout,"\t cid:");
+
+ for( 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;
+ }
+}
diff --git a/src/lib/openjpip/cache_manager.h b/src/lib/openjpip/cache_manager.h
new file mode 100644
index 00000000..0c9afb0b
--- /dev/null
+++ b/src/lib/openjpip/cache_manager.h
@@ -0,0 +1,177 @@
+/*
+ * $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"
+
+/** cache parameters*/
+typedef struct cache_param{
+ char *filename; /**< file name*/
+ char *tid; /**< taregt identifier*/
+ 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(void);
+
+/**
+ * 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] tid target identifier
+ * @param[in] cid channel identifier
+ * @return pointer to the generated cache
+ */
+cache_param_t * gene_cache( const char *targetname, int csn, char *tid, 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( const 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 a cache by cid
+ *
+ * @param[in] cid channel identifer
+ * @param[in] cachelist cache list pointer
+ * @return found cache pointer
+ */
+cache_param_t * search_cacheBycid( const char cid[], cachelist_param_t *cachelist);
+
+
+/**
+ * search a cache by tid
+ *
+ * @param[in] tid target identifer
+ * @param[in] cachelist cache list pointer
+ * @return found cache pointer
+ */
+cache_param_t * search_cacheBytid( const char tid[], cachelist_param_t *cachelist);
+
+/**
+ * add cid into a cache
+ *
+ * @param[in] cid channel identifier
+ * @param[in] cache cache pointer
+ */
+void add_cachecid( const char *cid, cache_param_t *cache);
+
+
+/**
+ * update tid of a cache
+ *
+ * @param[in] tid target identifier
+ * @param[in] cache cache pointer
+ */
+void update_cachetid( const char *tid, cache_param_t *cache);
+
+
+/**
+ * remove cid in cache
+ *
+ * @param[in] cid channel identifier
+ * @param[in] cachelist cachelist pointer
+ */
+void remove_cachecid( const 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_ */
diff --git a/src/lib/openjpip/cachemodel_manager.c b/src/lib/openjpip/cachemodel_manager.c
new file mode 100644
index 00000000..1a84a6b8
--- /dev/null
+++ b/src/lib/openjpip/cachemodel_manager.c
@@ -0,0 +1,236 @@
+/*
+ * $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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "cachemodel_manager.h"
+#include "faixbox_manager.h"
+#include "opj_inttypes.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER*/
+
+
+cachemodellist_param_t * gene_cachemodellist(void)
+{
+ cachemodellist_param_t *cachemodellist;
+
+ cachemodellist = (cachemodellist_param_t *)malloc( sizeof(cachemodellist_param_t));
+
+ cachemodellist->first = NULL;
+ cachemodellist->last = NULL;
+
+ return cachemodellist;
+}
+
+cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, target_param_t *target, bool reqJPP)
+{
+ cachemodel_param_t *cachemodel;
+ faixbox_param_t *tilepart;
+ faixbox_param_t *precpacket;
+ size_t numOfelem;
+ Byte8_t numOftiles;
+ int i;
+
+ cachemodel = (cachemodel_param_t *)malloc( sizeof(cachemodel_param_t));
+
+ refer_target( target, &cachemodel->target);
+
+ if( reqJPP){
+ if( target->jppstream)
+ cachemodel->jppstream = true;
+ else
+ cachemodel->jppstream = false;
+ } else{ /* reqJPT */
+ if( target->jptstream)
+ cachemodel->jppstream = false;
+ else
+ cachemodel->jppstream = true;
+ }
+
+ cachemodel->mhead_model = false;
+
+ tilepart = target->codeidx->tilepart;
+ numOftiles = get_m( tilepart);
+ numOfelem = get_nmax( tilepart)*numOftiles;
+ cachemodel->tp_model = (bool *)calloc( 1, numOfelem*sizeof(bool));
+ cachemodel->th_model = (bool *)calloc( 1, numOftiles*sizeof(bool));
+ cachemodel->pp_model = (bool **)malloc( target->codeidx->SIZ.Csiz*sizeof(bool *));
+ for( i=0; i<target->codeidx->SIZ.Csiz; i++){
+ precpacket = target->codeidx->precpacket[i];
+ cachemodel->pp_model[i] = (bool *)calloc( 1, get_nmax(precpacket)*get_m(precpacket)*sizeof(bool));
+ }
+ cachemodel->next = NULL;
+
+ if( cachemodellist){
+ if( cachemodellist->first) /* there are one or more entries */
+ cachemodellist->last->next = cachemodel;
+ else /* first entry */
+ cachemodellist->first = cachemodel;
+ cachemodellist->last = cachemodel;
+ }
+
+#ifndef SERVER
+ fprintf( logstream, "local log: cachemodel generated\n");
+#endif
+
+ return cachemodel;
+}
+
+void print_cachemodel( cachemodel_param_t cachemodel)
+{
+ target_param_t *target;
+ Byte8_t TPnum; /* num of tile parts in each tile */
+ Byte8_t Pmax; /* max num of packets per tile */
+ Byte8_t i, j, k;
+ int n; /* FIXME: Is this large enough ? */
+
+ target = cachemodel.target;
+
+ fprintf( logstream, "target: %s\n", target->targetname);
+ fprintf( logstream, "\t main header model: %d\n", cachemodel.mhead_model);
+
+ fprintf( logstream, "\t tile part model:\n");
+ TPnum = get_nmax( target->codeidx->tilepart);
+
+ for( i=0, n=0; i<target->codeidx->SIZ.YTnum; i++){
+ for( j=0; j<target->codeidx->SIZ.XTnum; j++){
+ for( k=0; k<TPnum; k++)
+ fprintf( logstream, "%d", cachemodel.tp_model[n++]);
+ fprintf( logstream, " ");
+ }
+ fprintf( logstream, "\n");
+ }
+
+ fprintf( logstream, "\t tile header and precinct packet model:\n");
+ for( i=0; i<target->codeidx->SIZ.XTnum*target->codeidx->SIZ.YTnum; i++){
+ fprintf( logstream, "\t tile.%" PRIu64 " %d\n", i, cachemodel.th_model[i]);
+ for( j=0; j<target->codeidx->SIZ.Csiz; j++){
+ fprintf( logstream, "\t compo.%" PRIu64 ": ", j);
+ Pmax = get_nmax( target->codeidx->precpacket[j]);
+ for( k=0; k<Pmax; k++)
+ fprintf( logstream, "%d", cachemodel.pp_model[j][i*Pmax+k]);
+ fprintf( logstream, "\n");
+ }
+ }
+}
+
+cachemodel_param_t * search_cachemodel( target_param_t *target, cachemodellist_param_t *cachemodellist)
+{
+ cachemodel_param_t *foundcachemodel;
+
+ foundcachemodel = cachemodellist->first;
+
+ while( foundcachemodel != NULL){
+
+ if( foundcachemodel->target == target)
+ return foundcachemodel;
+
+ foundcachemodel = foundcachemodel->next;
+ }
+ return NULL;
+}
+
+void delete_cachemodellist( cachemodellist_param_t **cachemodellist)
+{
+ cachemodel_param_t *cachemodelPtr, *cachemodelNext;
+
+ cachemodelPtr = (*cachemodellist)->first;
+ while( cachemodelPtr != NULL){
+ cachemodelNext=cachemodelPtr->next;
+ delete_cachemodel( &cachemodelPtr);
+ cachemodelPtr=cachemodelNext;
+ }
+ free(*cachemodellist);
+}
+
+void delete_cachemodel( cachemodel_param_t **cachemodel)
+{
+ int i;
+
+ unrefer_target( (*cachemodel)->target);
+
+ free( (*cachemodel)->tp_model);
+ free( (*cachemodel)->th_model);
+
+ for( i=0; i<(*cachemodel)->target->codeidx->SIZ.Csiz; i++)
+ free( (*cachemodel)->pp_model[i]);
+ free( (*cachemodel)->pp_model);
+
+#ifndef SERVER
+ fprintf( logstream, "local log: cachemodel deleted\n");
+#endif
+ free( *cachemodel);
+}
+
+bool is_allsent( cachemodel_param_t cachemodel)
+{
+ target_param_t *target;
+ Byte8_t TPnum; /* num of tile parts in each tile */
+ Byte8_t Pmax; /* max num of packets per tile */
+ Byte8_t i, j, k;
+ int n; /* FIXME: is this large enough ? */
+
+ target = cachemodel.target;
+
+ if( !cachemodel.mhead_model)
+ return false;
+
+ TPnum = get_nmax( target->codeidx->tilepart);
+
+ if( cachemodel.jppstream){
+ for( i=0; i<target->codeidx->SIZ.XTnum*target->codeidx->SIZ.YTnum; i++){
+ if( !cachemodel.th_model[i])
+ return false;
+
+ for( j=0; j<target->codeidx->SIZ.Csiz; j++){
+ Pmax = get_nmax( target->codeidx->precpacket[j]);
+ for( k=0; k<Pmax; k++)
+ if( !cachemodel.pp_model[j][i*Pmax+k])
+ return false;
+ }
+ }
+ return true;
+ }
+ else{
+ for( i=0, n=0; i<target->codeidx->SIZ.YTnum; i++)
+ for( j=0; j<target->codeidx->SIZ.XTnum; j++)
+ for( k=0; k<TPnum; k++)
+ if( !cachemodel.tp_model[n++])
+ return false;
+ return true;
+ }
+}
diff --git a/src/lib/openjpip/cachemodel_manager.h b/src/lib/openjpip/cachemodel_manager.h
new file mode 100644
index 00000000..2c9dc540
--- /dev/null
+++ b/src/lib/openjpip/cachemodel_manager.h
@@ -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.
+ */
+
+#ifndef CACHEMODEL_MANAGER_H_
+# define CACHEMODEL_MANAGER_H_
+
+#include "bool.h"
+#include "target_manager.h"
+
+/** Cache model parameters*/
+typedef struct cachemodel_param{
+ target_param_t *target; /**< reference pointer to the target*/
+ bool jppstream; /**< return type, true: JPP-stream, false: JPT-stream*/
+ 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*/
+ bool *th_model; /**< dynamic array pointer of tile header model*/
+ bool **pp_model; /**< dynamic array pointer of precint packet model*/
+ struct cachemodel_param *next; /**< pointer to the next cache model*/
+} cachemodel_param_t;
+
+/** Cache model list parameters*/
+typedef struct cachemodellist_param{
+ cachemodel_param_t *first; /**< first cache model pointer of the list*/
+ cachemodel_param_t *last; /**< last cache model pointer of the list*/
+} cachemodellist_param_t;
+
+
+/**
+ * generate a cache model list
+ *
+ * @return pointer to the generated cache model list
+ */
+cachemodellist_param_t * gene_cachemodellist(void);
+
+/**
+ * generate a cache model under a list
+ *
+ * @param[in] cachemodellist cachemodel list to insert the generated cache model, NULL for stateless
+ * @param[in] target pointer the reference target
+ * @param[in] reqJPP if JPP-stream is desired true, JPT-stream false
+ * @return pointer to the generated cache model
+ */
+cachemodel_param_t * gene_cachemodel( cachemodellist_param_t *cachemodellist, target_param_t *target, bool reqJPP);
+
+
+/**
+ * print cache model
+ *
+ * @param[in] cachemodel cache model
+ */
+void print_cachemodel( cachemodel_param_t cachemodel);
+
+
+/**
+ * search a cache model of a target
+ *
+ * @param[in] target refering target
+ * @param[in] cachemodellist cache model list
+ * @return found cache model pointer
+ */
+cachemodel_param_t * search_cachemodel( target_param_t *target, cachemodellist_param_t *cachemodellist);
+
+
+/**
+ * check if all data has been sent
+ *
+ * @param[in] cachemodel cache model
+ * @return true if sent all, false otherwise
+ */
+bool is_allsent( cachemodel_param_t cachemodel);
+
+
+/**
+ * delete a cache model
+ *
+ * @param[in] cachemodel address of the cachemodel pointer
+ */
+void delete_cachemodel( cachemodel_param_t **cachemodel);
+
+/**
+ * delete cachemodel list
+ *
+ * @param[in,out] cachemodellist address of the cachemodel list pointer
+ */
+void delete_cachemodellist( cachemodellist_param_t **cachemodellist);
+
+
+#endif /* !CACHEMODEL_MANAGER_H_ */
diff --git a/src/lib/openjpip/channel_manager.c b/src/lib/openjpip/channel_manager.c
new file mode 100644
index 00000000..313f8ced
--- /dev/null
+++ b/src/lib/openjpip/channel_manager.c
@@ -0,0 +1,180 @@
+/*
+ * $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 _WIN32
+#define snprintf _snprintf /* Visual Studio */
+#endif
+
+#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(void)
+{
+ 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, auxtrans_param_t auxtrans, cachemodel_param_t *cachemodel, channellist_param_t *channellist)
+{
+ channel_param_t *channel;
+ const char transport[4][10] = { "non", "http", "http-tcp", "http-udp"};
+
+ if( !cachemodel){
+ 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->cachemodel = cachemodel;
+
+ /* set channel ID and get present time */
+ snprintf( channel->cid, MAX_LENOFCID, "%x%x", (unsigned int)time( &channel->start_tm), (unsigned int)rand());
+
+ channel->aux = query_param.cnew;
+
+ /* only tcp implemented for now */
+ if( channel->aux == udp)
+ channel->aux = tcp;
+
+ 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);
+ fprintf( FCGI_stdout, ",transport=%s", transport[channel->aux]);
+
+ if( channel->aux == tcp || channel->aux == udp)
+ fprintf( FCGI_stdout, ",auxport=%d", channel->aux==tcp ? auxtrans.tcpauxport : auxtrans.udpauxport);
+
+ fprintf( FCGI_stdout, "\r\n");
+
+ return channel;
+}
+
+
+void set_channel_variable_param( query_param_t query_param, channel_param_t *channel)
+{
+ /* set roi information */
+ (void)query_param;
+ (void)channel;
+}
+
+
+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->cachemodel->target->targetname);
+ ptr=ptr->next;
+ }
+}
+
+channel_param_t * search_channel( const 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;
+}
diff --git a/src/lib/openjpip/channel_manager.h b/src/lib/openjpip/channel_manager.h
new file mode 100644
index 00000000..79cc0160
--- /dev/null
+++ b/src/lib/openjpip/channel_manager.h
@@ -0,0 +1,120 @@
+/*
+ * $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 "cachemodel_manager.h"
+#include "auxtrans_manager.h"
+
+/** maximum length of channel identifier*/
+#define MAX_LENOFCID 30
+
+/** Channel parameters*/
+typedef struct channel_param{
+ cachemodel_param_t *cachemodel; /**< reference pointer to the cache model*/
+ char cid[MAX_LENOFCID]; /**< channel identifier*/
+ cnew_transport_t aux; /**< auxiliary transport*/
+ /* - 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(void);
+
+
+/**
+ * generate a channel under the channel list
+ *
+ * @param[in] query_param query parameters
+ * @param[in] auxtrans auxiliary transport
+ * @param[in] cachemodel reference cachemodel
+ * @param[in] channellist channel list pointer
+ * @return pointer to the generated channel
+ */
+channel_param_t * gene_channel( query_param_t query_param, auxtrans_param_t auxtrans, cachemodel_param_t *cachemodel, 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( const char cid[], channellist_param_t *channellist);
+#endif /* !CHANNEL_MANAGER_H_ */
diff --git a/src/lib/openjpip/codestream_manager.c b/src/lib/openjpip/codestream_manager.c
new file mode 100644
index 00000000..d7797c13
--- /dev/null
+++ b/src/lib/openjpip/codestream_manager.c
@@ -0,0 +1,81 @@
+/*
+ * $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"
+#include "opj_inttypes.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER */
+
+codestream_param_t set_codestream( int fd, OPJ_OFF_T offset, OPJ_SIZE_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, OPJ_OFF_T offset, OPJ_SIZE_T size)
+{
+ return fetch_bytes( cs->fd, cs->offset+offset, size);
+}
+
+Byte_t fetch_codestream1byte( codestream_param_t *cs, OPJ_OFF_T offset)
+{
+ return fetch_1byte( cs->fd, cs->offset+offset);
+}
+
+Byte2_t fetch_codestream2bytebigendian( codestream_param_t *cs, OPJ_OFF_T offset)
+{
+ return fetch_2bytebigendian( cs->fd, cs->offset+offset);
+}
+
+Byte4_t fetch_codestream4bytebigendian( codestream_param_t *cs, OPJ_OFF_T 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: %#" PRIx64 "\n"
+ "\t length: %#" PRIx64 "\n", cs.fd, cs.offset, cs.length);
+}
diff --git a/src/lib/openjpip/codestream_manager.h b/src/lib/openjpip/codestream_manager.h
new file mode 100644
index 00000000..b600d8e5
--- /dev/null
+++ b/src/lib/openjpip/codestream_manager.h
@@ -0,0 +1,101 @@
+/*
+ * $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 "byte_manager.h"
+
+/** codestream parameters*/
+typedef struct codestream_param{
+ int fd; /**< file descriptor*/
+ OPJ_OFF_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, OPJ_OFF_T offset, OPJ_SIZE_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, OPJ_OFF_T offset, OPJ_SIZE_T 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, OPJ_OFF_T 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, OPJ_OFF_T 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, OPJ_OFF_T offset);
+
+
+/**
+ * print codestream parameters
+ *
+ * @param[in] cs codestream
+ */
+void print_codestream( codestream_param_t cs);
+
+
+#endif /* !CODESTREAM_MANAGER_H_ */
diff --git a/src/lib/openjpip/dec_clientmsg_handler.c b/src/lib/openjpip/dec_clientmsg_handler.c
new file mode 100644
index 00000000..20bd4f2b
--- /dev/null
+++ b/src/lib/openjpip/dec_clientmsg_handler.c
@@ -0,0 +1,253 @@
+/*
+ * $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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <limits.h>
+#include "dec_clientmsg_handler.h"
+#include "ihdrbox_manager.h"
+#include "jpipstream_manager.h"
+#include "jp2k_encoder.h"
+#include "opj_inttypes.h"
+
+void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist,
+ Byte_t **jpipstream, OPJ_SIZE_T *streamlen, msgqueue_param_t *msgqueue)
+{
+ Byte_t *newjpipstream;
+ OPJ_SIZE_T newstreamlen = 0;
+ cache_param_t *cache;
+ char *target, *tid, *cid;
+ metadatalist_param_t *metadatalist;
+
+ newjpipstream = receive_JPIPstream( connected_socket, &target, &tid, &cid, &newstreamlen);
+
+ fprintf( stderr, "newjpipstream length: %" PRIu64 "\n", newstreamlen);
+
+ parse_JPIPstream( newjpipstream, newstreamlen, (OPJ_OFF_T)*streamlen, msgqueue);
+
+ *jpipstream = update_JPIPstream( newjpipstream, newstreamlen, *jpipstream, streamlen);
+ free( newjpipstream);
+
+ metadatalist = gene_metadatalist();
+ parse_metamsg( msgqueue, *jpipstream, *streamlen, metadatalist);
+
+ assert( msgqueue->last );
+ assert( msgqueue->last->csn < INT_MAX );
+ /* cid registration*/
+ if( target != NULL){
+ if((cache = search_cache( target, cachelist))){
+ if( tid != NULL)
+ update_cachetid( tid, cache);
+ if( cid != NULL)
+ add_cachecid( cid, cache);
+ }
+ else{
+ cache = gene_cache( target, (int)msgqueue->last->csn, tid, cid);
+ insert_cache_into_list( cache, cachelist);
+ }
+ }
+ else
+ cache = search_cacheBycsn( (int)msgqueue->last->csn, cachelist);
+
+ if( cache->metadatalist)
+ delete_metadatalist( &cache->metadatalist);
+ cache->metadatalist = metadatalist;
+
+ if( target) free( target);
+ if( tid) free( tid);
+ if( cid) free( cid);
+
+ response_signal( connected_socket, true);
+}
+
+void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist)
+{
+ Byte_t *pnmstream;
+ ihdrbox_param_t *ihdrbox;
+ char *CIDorTID, tmp[10];
+ cache_param_t *cache;
+ int fw, fh;
+ int maxval;
+
+ CIDorTID = receive_string( connected_socket);
+
+ if(!(cache = search_cacheBycid( CIDorTID, cachelist)))
+ if(!(cache = search_cacheBytid( CIDorTID, cachelist))){
+ free( CIDorTID);
+ return;
+ }
+
+ free( CIDorTID);
+
+ receive_line( connected_socket, tmp);
+ fw = atoi( tmp);
+
+ receive_line( connected_socket, tmp);
+ fh = atoi( tmp);
+
+ ihdrbox = NULL;
+ assert( cache->csn >= 0 );
+ pnmstream = jpipstream_to_pnm( jpipstream, msgqueue, (Byte8_t)cache->csn, fw, fh, &ihdrbox);
+
+ maxval = ihdrbox->bpc > 8 ? 255 : (1 << ihdrbox->bpc) - 1;
+ send_PNMstream( connected_socket, pnmstream, ihdrbox->width, ihdrbox->height, ihdrbox->nc, (Byte_t)maxval );
+
+ free( ihdrbox);
+ free( pnmstream);
+}
+
+void handle_XMLreqMSG( SOCKET connected_socket, Byte_t *jpipstream, cachelist_param_t *cachelist)
+{
+ char *cid;
+ cache_param_t *cache;
+ boxcontents_param_t *boxcontents;
+ Byte_t *xmlstream;
+
+ cid = receive_string( connected_socket);
+
+ if(!(cache = search_cacheBycid( cid, cachelist))){
+ free( cid);
+ return;
+ }
+
+ free( cid);
+
+ boxcontents = cache->metadatalist->last->boxcontents;
+ xmlstream = (Byte_t *)malloc( boxcontents->length);
+ memcpy( xmlstream, jpipstream+boxcontents->offset, boxcontents->length);
+ send_XMLstream( connected_socket, xmlstream, boxcontents->length);
+ free( xmlstream);
+}
+
+void handle_TIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
+{
+ char *target, *tid = NULL;
+ cache_param_t *cache;
+ OPJ_SIZE_T tidlen = 0;
+
+ target = receive_string( connected_socket);
+ cache = search_cache( target, cachelist);
+
+ free( target);
+
+ if( cache){
+ tid = cache->tid;
+ tidlen = strlen(tid);
+ }
+ send_TIDstream( connected_socket, tid, tidlen);
+}
+
+void handle_CIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
+{
+ char *target, *cid = NULL;
+ cache_param_t *cache;
+ OPJ_SIZE_T cidlen = 0;
+
+ target = receive_string( connected_socket);
+ cache = search_cache( target, cachelist);
+
+ free( target);
+
+ if( cache){
+ if( cache->numOfcid > 0){
+ cid = cache->cid[ cache->numOfcid-1];
+ cidlen = strlen(cid);
+ }
+ }
+ send_CIDstream( connected_socket, cid, cidlen);
+}
+
+void handle_dstCIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist)
+{
+ char *cid;
+
+ cid = receive_string( connected_socket);
+ remove_cachecid( cid, cachelist);
+ response_signal( connected_socket, true);
+
+ free( cid);
+}
+
+void handle_SIZreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist)
+{
+ char *tid, *cid;
+ cache_param_t *cache;
+ Byte4_t width, height;
+
+ tid = receive_string( connected_socket);
+ cid = receive_string( connected_socket);
+
+ cache = NULL;
+
+ if( tid[0] != '0')
+ cache = search_cacheBytid( tid, cachelist);
+
+ if( !cache && cid[0] != '0')
+ cache = search_cacheBycid( cid, cachelist);
+
+ free( tid);
+ free( cid);
+
+ width = height = 0;
+ if( cache){
+ assert( cache->csn >= 0);
+ if( !cache->ihdrbox)
+ cache->ihdrbox = get_SIZ_from_jpipstream( jpipstream, msgqueue, (Byte8_t)cache->csn);
+ width = cache->ihdrbox->width;
+ height = cache->ihdrbox->height;
+ }
+ send_SIZstream( connected_socket, width, height);
+}
+
+void handle_JP2saveMSG( SOCKET connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jpipstream)
+{
+ char *cid;
+ cache_param_t *cache;
+ Byte_t *jp2stream;
+ Byte8_t jp2len;
+
+ cid = receive_string( connected_socket);
+ if(!(cache = search_cacheBycid( cid, cachelist))){
+ free( cid);
+ return;
+ }
+
+ free( cid);
+
+ assert( cache->csn >= 0);
+ jp2stream = recons_jp2( msgqueue, jpipstream, (Byte8_t)cache->csn, &jp2len);
+
+ if( jp2stream){
+ save_codestream( jp2stream, jp2len, "jp2");
+ free( jp2stream);
+ }
+}
diff --git a/src/lib/openjpip/dec_clientmsg_handler.h b/src/lib/openjpip/dec_clientmsg_handler.h
new file mode 100644
index 00000000..7929207a
--- /dev/null
+++ b/src/lib/openjpip/dec_clientmsg_handler.h
@@ -0,0 +1,113 @@
+/*
+ * $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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 DEC_CLIENTMSG_HANDLER_H_
+# define DEC_CLIENTMSG_HANDLER_H_
+
+#include "imgsock_manager.h"
+#include "cache_manager.h"
+#include "byte_manager.h"
+#include "msgqueue_manager.h"
+
+/**
+ * handle JPT- JPP- stream message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] cachelist cache list pointer
+ * @param[in,out] jpipstream address of JPT- JPP- stream pointer
+ * @param[in,out] streamlen address of stream length
+ * @param[in,out] msgqueue message queue pointer
+ */
+void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist, Byte_t **jpipstream, OPJ_SIZE_T *streamlen, msgqueue_param_t *msgqueue);
+
+/**
+ * handle PNM request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] jpipstream jpipstream pointer
+ * @param[in] msgqueue message queue pointer
+ * @param[in] cachelist cache list pointer
+ */
+void handle_PNMreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, cachelist_param_t *cachelist);
+
+/**
+ * handle XML request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] jpipstream address of caching jpipstream pointer
+ * @param[in] cachelist cache list pointer
+ */
+void handle_XMLreqMSG( SOCKET connected_socket, Byte_t *jpipstream, cachelist_param_t *cachelist);
+
+/**
+ * handle TargetID request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] cachelist cache list pointer
+ */
+void handle_TIDreqMSG( SOCKET connected_socket, cachelist_param_t *cachelist);
+
+/**
+ * handle ChannelID request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in] cachelist cache list pointer
+ */
+void handle_CIDreqMSG( SOCKET 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( SOCKET connected_socket, cachelist_param_t *cachelist);
+
+/**
+ * handle SIZ request message
+ *
+ * @param[in] connected_socket socket descriptor
+ * @param[in,out] cachelist cache list pointer
+ */
+void handle_SIZreqMSG( SOCKET connected_socket, Byte_t *jpipstream, msgqueue_param_t *msgqueue, 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] jpipstream address of caching jpipstream pointer
+ */
+void handle_JP2saveMSG( SOCKET connected_socket, cachelist_param_t *cachelist, msgqueue_param_t *msgqueue, Byte_t *jpipstream);
+
+
+#endif /* !DEC_CLIENTMSG_HANDLER_H_ */
diff --git a/src/lib/openjpip/faixbox_manager.c b/src/lib/openjpip/faixbox_manager.c
new file mode 100644
index 00000000..3c443832
--- /dev/null
+++ b/src/lib/openjpip/faixbox_manager.c
@@ -0,0 +1,195 @@
+/*
+ * $Id: faixbox_manager.c 53 2011-05-09 16:55:39Z 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"
+#include "opj_inttypes.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER*/
+
+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( 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;
+ size_t i;
+
+ 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( 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;
+ size_t i;
+
+ 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( 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)
+{
+ Byte8_t i, j;
+
+ fprintf( logstream, "faix box info\n");
+ fprintf( logstream, "\tversion: %d\n", faix->version);
+
+ fprintf( logstream, "\t nmax: %#" PRIx64 " = %" PRId64 "\n", get_nmax( faix), get_nmax( faix));
+ fprintf( logstream, "\t m: %#" PRIx64 " = %" PRId64 "\n", get_m( faix), get_m( faix));
+
+ for( i=0; i<get_m( faix); i++){
+ for( j=0; j<get_nmax( faix); j++){
+ fprintf( logstream, "\t off = %#" PRIx64 ", len = %#" PRIx64 "", 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)
+{
+ Byte8_t nmax;
+ if( faix->version <2)
+ return (Byte4_t)-1;
+
+ 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];
+}
diff --git a/src/lib/openjpip/faixbox_manager.h b/src/lib/openjpip/faixbox_manager.h
new file mode 100644
index 00000000..45ea8c3e
--- /dev/null
+++ b/src/lib/openjpip/faixbox_manager.h
@@ -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_ */
diff --git a/src/lib/openjpip/ihdrbox_manager.c b/src/lib/openjpip/ihdrbox_manager.c
new file mode 100644
index 00000000..d501b612
--- /dev/null
+++ b/src/lib/openjpip/ihdrbox_manager.c
@@ -0,0 +1,78 @@
+/*
+ * $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 <assert.h>
+#include "ihdrbox_manager.h"
+
+ihdrbox_param_t * gene_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jpipstream)
+{
+ ihdrbox_param_t *ihdrbox;
+ metadata_param_t *meta;
+ box_param_t *jp2h, *ihdr;
+ int bpc_val;
+
+ 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( jpipstream, 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( jpipstream+get_DBoxoff(ihdr));
+ ihdrbox->width = big4( jpipstream+get_DBoxoff(ihdr)+4);
+ ihdrbox->nc = big2( jpipstream+get_DBoxoff(ihdr)+8);
+ bpc_val = *(jpipstream+get_DBoxoff(ihdr)+10)+1;
+ assert( bpc_val >= 0 && bpc_val <= 255 );
+ ihdrbox->bpc = (Byte_t)bpc_val;
+
+ free( ihdr);
+
+ return ihdrbox;
+}
+
diff --git a/src/lib/openjpip/ihdrbox_manager.h b/src/lib/openjpip/ihdrbox_manager.h
new file mode 100644
index 00000000..9fa9a830
--- /dev/null
+++ b/src/lib/openjpip/ihdrbox_manager.h
@@ -0,0 +1,56 @@
+/*
+ * $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"
+
+/** I.5.3.1 Image Header box*/
+typedef struct ihdrbox_param{
+ Byte4_t height;
+ Byte4_t width;
+ Byte2_t nc; /**< number of components*/
+ Byte_t bpc; /**< bits per component*/
+} ihdrbox_param_t;
+
+/**
+ * generate ihdr box
+ *
+ * @param[in] metadatalist metadata list pointer
+ * @param[in] jpipstream JPT/JPP stream
+ * @return pointer to generated ihdr box
+ */
+ihdrbox_param_t * gene_ihdrbox( metadatalist_param_t *metadatalist, Byte_t *jpipstream);
+
+
+#endif /* !IHDRBOX_MANAGER_H_ */
diff --git a/src/lib/openjpip/imgreg_manager.c b/src/lib/openjpip/imgreg_manager.c
new file mode 100644
index 00000000..3a713c32
--- /dev/null
+++ b/src/lib/openjpip/imgreg_manager.c
@@ -0,0 +1,157 @@
+/*
+ * $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 <assert.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 numOfreslev)
+{
+ 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( numOfreslev, &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 = (int)ceil((double)((rx+rw)*imgreg.fx)/(double)fx);
+ py = (int)ceil((double)((ry+rh)*imgreg.fy)/(double)fy);
+
+ if( imgreg.fx < px)
+ px = imgreg.fx;
+ if( imgreg.fy < py)
+ py = imgreg.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 = (int)ceil((double)*xmin/(double)2.0);
+ *ymin = (int)ceil((double)*ymin/(double)2.0);
+ *xmax = (int)ceil((double)*xmax/(double)2.0);
+ *ymax = (int)ceil((double)*ymax/(double)2.0);
+
+ (*lev) ++;
+ find_level ( maxlev, lev, fx, fy, xmin, ymin, xmax, ymax);
+ } else {
+ *fx = xwidth;
+ *fy = ywidth;
+ }
+}
+
+int comp_decomplev( int fw, int fh, int Xsiz, int Ysiz)
+{
+ int level;
+ int xmin, xmax, ymin, ymax;
+
+ level = 0;
+ xmin = ymin = 0;
+ xmax = Xsiz;
+ ymax = Ysiz;
+
+ find_level( 1000, &level, &fw, &fh, &xmin, &ymin, &xmax, &ymax);
+
+ assert( level >= 0 );
+ return level;
+}
+
+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);
+#else
+ (void)imgreg;
+#endif
+}
diff --git a/src/lib/openjpip/imgreg_manager.h b/src/lib/openjpip/imgreg_manager.h
new file mode 100644
index 00000000..7967120b
--- /dev/null
+++ b/src/lib/openjpip/imgreg_manager.h
@@ -0,0 +1,101 @@
+/*
+ * $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] numOfreslev number of resolution 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 numOfreslev);
+
+
+/**
+ * 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);
+
+/**
+ * compute decomposition level (only to get the level
+ * use find_level for all parameters
+ *
+ * @param[in] fx horizontal frame size
+ * @param[in] fy vertical frame size
+ * @param[in] Xsiz image width
+ * @param[in] Ysiz image height
+ * @return decomposition level
+ */
+int comp_decomplev( int fw, int fh, int Xsiz, int Ysiz);
+
+/**
+ * print image region parameters
+ *
+ * @param[in] imgreg image region structure of parameters
+ */
+void print_imgreg( imgreg_param_t imgreg);
+
+
+#endif /* !IMGREG_MANAGER_H_ */
diff --git a/src/lib/openjpip/imgsock_manager.c b/src/lib/openjpip/imgsock_manager.c
new file mode 100644
index 00000000..612cb378
--- /dev/null
+++ b/src/lib/openjpip/imgsock_manager.c
@@ -0,0 +1,209 @@
+/*
+ * $Id: imgsock_manager.c 54 2011-05-10 13:22:47Z kaori $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "imgsock_manager.h"
+#if _WIN32
+#define strncasecmp _strnicmp
+#endif
+
+msgtype_t identify_clientmsg( SOCKET connected_socket)
+{
+ OPJ_SIZE_T receive_size;
+ char buf[BUF_LEN];
+ static const char *magicid[] = { "JPIP-stream", "PNM request", "XML request",
+ "TID request", "CID request", "CID destroy", "SIZ request", "JP2 save",
+ "QUIT"};
+ int i;
+
+ receive_size = receive_line( connected_socket, buf);
+
+ if( receive_size == 0){
+ fprintf( stderr, "Error to receive the header of client message\n");
+ return MSGERROR;
+ }
+
+ for( i=0; i<NUM_OF_MSGTYPES; i++){
+ if( strncasecmp( magicid[i], buf, strlen(magicid[i])) == 0){
+ fprintf( stderr, "%s\n", magicid[i]);
+ return i;
+ }
+ }
+
+ fprintf( stderr, "Cannot identify client message type %s\n", buf);
+ return MSGERROR;
+}
+
+Byte_t * receive_JPIPstream( SOCKET connected_socket, char **target, char **tid, char **cid, OPJ_SIZE_T *streamlen)
+{
+ char buf[BUF_LEN];
+ const char versionstring[] = "version 1.2";
+ int idatalen;
+ OPJ_SIZE_T linelen, datalen;
+ Byte_t *jpipstream;
+
+ *target = *cid = *tid = NULL;
+
+ if((linelen = receive_line( connected_socket, buf)) == 0)
+ return NULL;
+ if( strncmp( versionstring, buf, strlen(versionstring))!=0){
+ fprintf( stderr, "Wrong format\n");
+ return NULL;
+ }
+
+ if((linelen = receive_line( connected_socket, buf)) == 0)
+ return NULL;
+
+ if( strstr( buf, "jp2")){
+ /* register cid option*/
+ *target = strdup( buf);
+
+ if((linelen = receive_line( connected_socket, buf)) == 0)
+ return NULL;
+ if( strcmp( buf, "0") != 0)
+ *tid = strdup( buf);
+
+ if((linelen = receive_line( connected_socket, buf)) == 0)
+ return NULL;
+ if( strcmp( buf, "0") != 0)
+ *cid = strdup( buf);
+
+ if((linelen = receive_line( connected_socket, buf)) == 0)
+ return NULL;
+ }
+
+ idatalen = atoi( buf);
+ if( idatalen < 0 )
+ {
+ fprintf( stderr, "Receive Data: %d Bytes\n", idatalen);
+ return NULL;
+ }
+ datalen = (OPJ_SIZE_T)idatalen;
+ fprintf( stdout, "Receive Data: %lu Bytes\n", datalen);
+
+ jpipstream = receive_stream( connected_socket, datalen);
+
+ /* check EOR*/
+ if( jpipstream[datalen-3] == 0x00 && ( jpipstream[datalen-2] == 0x01 || jpipstream[datalen-2] == 0x02))
+ *streamlen = datalen -3;
+ else
+ *streamlen = datalen;
+
+ return jpipstream;
+}
+
+void send_XMLstream( SOCKET connected_socket, Byte_t *xmlstream, OPJ_SIZE_T length)
+{
+ Byte_t header[5];
+
+ header[0] = 'X';
+ header[1] = 'M';
+ header[2] = 'L';
+ header[3] = (Byte_t)((length >> 8) & 0xff);
+ header[4] = (Byte_t)(length & 0xff);
+
+ send_stream( connected_socket, header, 5);
+ send_stream( connected_socket, xmlstream, length);
+}
+
+void send_IDstream( SOCKET connected_socket, const char *id, OPJ_SIZE_T idlen, const char *label);
+
+void send_CIDstream( SOCKET connected_socket, const char *cid, OPJ_SIZE_T cidlen)
+{
+ send_IDstream( connected_socket, cid, cidlen, "CID");
+}
+
+void send_TIDstream( SOCKET connected_socket, const char *tid, OPJ_SIZE_T tidlen)
+{
+ send_IDstream( connected_socket, tid, tidlen, "TID");
+}
+
+void send_IDstream( SOCKET connected_socket, const char *id, OPJ_SIZE_T idlen, const char *label)
+{
+ char header[4];
+
+ header[0] = label[0];
+ header[1] = label[1];
+ header[2] = label[2];
+ header[3] = (char)(idlen & 0xff);
+
+ send_stream( connected_socket, header, 4);
+ send_stream( connected_socket, id, idlen);
+}
+
+void send_PNMstream( SOCKET connected_socket, Byte_t *pnmstream, unsigned int width, unsigned int height, unsigned int numofcomp, Byte_t maxval)
+{
+ OPJ_SIZE_T 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_SIZstream( SOCKET connected_socket, unsigned int width, unsigned int height)
+{
+ Byte_t responce[9];
+
+ responce[0] = 'S';
+ responce[1] = 'I';
+ responce[2] = 'Z';
+ responce[3] = (width >> 16) & 0xff;
+ responce[4] = (width >> 8) & 0xff;
+ responce[5] = width & 0xff;
+ responce[6] = (height >> 16) & 0xff;
+ responce[7] = (height >> 8) & 0xff;
+ responce[8] = height & 0xff;
+
+ send_stream( connected_socket, responce, 9);
+}
+
+void response_signal( SOCKET connected_socket, bool succeed)
+{
+ Byte_t code;
+
+ if( succeed)
+ code = 1;
+ else
+ code = 0;
+
+ send_stream( connected_socket, &code, 1);
+}
diff --git a/src/lib/openjpip/imgsock_manager.h b/src/lib/openjpip/imgsock_manager.h
new file mode 100644
index 00000000..044bdc53
--- /dev/null
+++ b/src/lib/openjpip/imgsock_manager.h
@@ -0,0 +1,174 @@
+/*
+ * $Id: imgsock_manager.h 54 2011-05-10 13:22:47Z 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 "bool.h"
+#include "byte_manager.h"
+#include "sock_manager.h"
+
+#define NUM_OF_MSGTYPES 9
+typedef enum eMSGTYPE{ JPIPSTREAM, PNMREQ, XMLREQ, TIDREQ, CIDREQ, CIDDST, SIZREQ, JP2SAVE, QUIT, MSGERROR} msgtype_t;
+
+/**
+ * indeitify client message type
+ *
+ * @param [in] connected_socket file descriptor of the connected socket
+ * @return message type
+ */
+msgtype_t identify_clientmsg( SOCKET connected_socket);
+
+/**
+ * receive a JPT- JPP- stream from client
+ *
+ * @param [in] connected_socket file descriptor of the connected socket
+ * @param [out] target address of received target file name string pointer ( malloced, if not received, NULL)
+ * @param [out] tid address of received target identifier string pointer ( malloced, if not received, null string)
+ * @param [out] cid address of received channel identifier string pointer ( malloced, if not received, null string)
+ * @param [out] streamlen length of the received codestream
+ * @return JPT- JPP- codestream
+ */
+Byte_t * receive_JPIPstream( SOCKET connected_socket, char **target, char **tid, char **cid, OPJ_SIZE_T *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 PGM/PPM image (different from the original image)
+ * @param [in] height height of the PGM/PPM image
+ * @param [in] numofcomp number of components of the image
+ * @param [in] maxval maximum value of the image (only 255 supported)
+ */
+void send_PNMstream( SOCKET 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( SOCKET connected_socket, Byte_t *xmlstream, OPJ_SIZE_T length);
+
+/**
+ * send TID data stream to the client
+ *
+ * @param [in] connected_socket file descriptor of the connected socket
+ * @param [in] tid tid string
+ * @param [in] tidlen legnth of the tid string
+ */
+void send_TIDstream( SOCKET connected_socket, const char *tid, OPJ_SIZE_T tidlen);
+
+/**
+ * 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( SOCKET connected_socket, const char *cid, OPJ_SIZE_T cidlen);
+
+/**
+ * send SIZ data stream to the client
+ *
+ * @param [in] connected_socket file descriptor of the connected socket
+ * @param [in] width original width of the image
+ * @param [in] height original height of the image
+ */
+void send_SIZstream( SOCKET connected_socket, unsigned int width, unsigned int height);
+
+/**
+ * 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( SOCKET connected_socket, bool succeed);
+
+#endif /* !IMGSOCK_MANAGER_H_ */
+
+/*! \file
+ * PROTOCOL specification to communicate with opj_dec_server
+ *
+ *\section sec1 JPIP-stream
+ * Cache JPT- JPP- stream in server
+ *
+ * client -> server: JPIP-stream\\n version 1.1\\n (optional for cid registration: targetnamestring\\n tidstring\\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 [cid/tid]string\\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 TID request
+ * Get target ID of target image
+ *
+ * client -> server: TID request\\n targetname\\n \n
+ * server -> client: TID (3Byte) length (1Byte) tiddata
+ *
+ *\section sec5 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 sec6 CID destroy
+ * Close Channel ID
+ *
+ * client -> server: CID destroy\\n ciddata \n
+ * server -> client: 1 or 0 (of 1Byte response signal)
+ *
+ *\section sec7 SIZ request
+ * Get original size of image
+ *
+ * client -> server: SIZ request\\n tidstring\\n cidstring\\n \n
+ * server -> client: SIZ (3Byte) width (3Byte Big endian) height (3Byte Big endian)
+ *
+ *\section sec8 JP2 save
+ * Save in JP2 file format
+ *
+ * client -> server: JP2 save\\n ciddata \n
+ * server -> client: 1 or 0 (of 1Byte response signal)
+ *
+ *\section sec9 QUIT
+ * Quit the opj_dec_server program
+ *
+ * client -> server: quit or QUIT
+ */
diff --git a/src/lib/openjpip/index_manager.c b/src/lib/openjpip/index_manager.c
new file mode 100644
index 00000000..6f8357e9
--- /dev/null
+++ b/src/lib/openjpip/index_manager.c
@@ -0,0 +1,732 @@
+/*
+ * $Id: index_manager.c 53 2011-05-09 16:55:39Z 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 <math.h>
+#include <string.h>
+
+#include "bool.h"
+#include "opj_inttypes.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;
+ Byte8_t filesize;
+
+ if( !(filesize = (Byte8_t)get_filesize( fd)))
+ return NULL;
+
+ if( !(toplev_boxlist = get_boxstructure( fd, 0, filesize))){
+ 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)
+{
+ int i;
+
+ fprintf( logstream, "index info:\n");
+ fprintf( logstream, "\tCodestream Offset: %#" PRIx64 "\n", index.offset);
+ fprintf( logstream, "\t Length: %#" PRIx64 "\n", index.length);
+ fprintf( logstream, "\tMain header Length: %#" PRIx64 "\n", index.mhead_length);
+
+ print_SIZ( index.SIZ);
+ print_COD( index.COD);
+
+ fprintf( logstream, "Tile part information: \n");
+ print_faixbox( index.tilepart);
+
+ fprintf( logstream, "Tile header information: \n");
+ for( i=0; i<(int)(index.SIZ.XTnum*index.SIZ.YTnum);i++)
+ print_mhixbox( index.tileheader[i]);
+
+ fprintf( logstream, "Precinct packet information: \n");
+ for( i=0; i<index.SIZ.Csiz; i++){
+ fprintf( logstream, "Component %d\n", i);
+ print_faixbox( index.precpacket[i]);
+ }
+
+ print_allmetadata( index.metadatalist);
+}
+
+void print_SIZ( SIZmarker_param_t SIZ)
+{
+ int i;
+
+ fprintf( logstream, "\tImage and Tile SIZ parameters\n");
+ fprintf( logstream, "\t Rsiz: %#x\n", SIZ.Rsiz);
+ fprintf( logstream, "\t Xsiz, Ysiz: (%d,%d) = (%#x, %#x)\n", SIZ.Xsiz, SIZ.Ysiz, SIZ.Xsiz, SIZ.Ysiz);
+ fprintf( logstream, "\t XOsiz, YOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XOsiz, SIZ.YOsiz, SIZ.XOsiz, SIZ.YOsiz);
+ fprintf( logstream, "\t XTsiz, YTsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTsiz, SIZ.YTsiz, SIZ.XTsiz, SIZ.YTsiz);
+ fprintf( logstream, "\t XTOsiz, YTOsiz: (%d,%d) = (%#x, %#x)\n", SIZ.XTOsiz, SIZ.YTOsiz, SIZ.XTOsiz, SIZ.YTOsiz);
+ fprintf( logstream, "\t XTnum, YTnum: (%d,%d)\n", SIZ.XTnum, SIZ.YTnum);
+ fprintf( logstream, "\t Num of Components: %d\n", SIZ.Csiz);
+
+ for( i=0; i<SIZ.Csiz; i++)
+ fprintf( logstream, "\t[%d] (Ssiz, XRsiz, YRsiz): (%d, %d, %d) = (%#x, %#x, %#x)\n", i, SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i], SIZ.Ssiz[i], SIZ.XRsiz[i], SIZ.YRsiz[i]);
+}
+
+void print_COD( CODmarker_param_t COD)
+{
+ int i;
+
+ fprintf( logstream, "\tCoding style default COD parameters\n");
+ fprintf( logstream, "\t Progression order: %d [ LRCP=0, RLCP=1, RPCL=2, PCRL=3, CPRL=4]\n", COD.prog_order);
+ fprintf( logstream, "\t Num of layers: %d\n", COD.numOflayers);
+ fprintf( logstream, "\t Decomposition lvl: %d\n", COD.numOfdecomp);
+
+ for( i=0; i<=((COD.Scod & 0x01) ? COD.numOfdecomp:0); i++){
+ fprintf( logstream, "\t [%d] XPsiz, YPsiz: (%d,%d) = (%#x, %#x)\n",i, COD.XPsiz[i], COD.YPsiz[i], COD.XPsiz[i], COD.YPsiz[i]);
+ }
+}
+
+void delete_index( index_param_t **index)
+{
+ int i;
+
+ delete_metadatalist( &((*index)->metadatalist));
+
+ delete_COD( (*index)->COD);
+
+ delete_faixbox( &((*index)->tilepart));
+
+ for( i=0; i< (int)((*index)->SIZ.XTnum*(*index)->SIZ.YTnum);i++)
+ delete_mhixbox( &((*index)->tileheader[i]));
+ free( (*index)->tileheader);
+
+ for( i=0; i<(*index)->SIZ.Csiz; i++)
+ delete_faixbox( &((*index)->precpacket[i]));
+ free( (*index)->precpacket);
+
+ free(*index);
+}
+
+void delete_COD( CODmarker_param_t COD)
+{
+ if( COD.XPsiz) free( COD.XPsiz);
+ if( COD.YPsiz) free( COD.YPsiz);
+}
+
+bool check_JP2boxidx( boxlist_param_t *toplev_boxlist)
+{
+ box_param_t *iptr, *fidx, *prxy;
+ box_param_t *cidx, *jp2c;
+ Byte8_t off;
+ Byte8_t len;
+ int pos;
+ Byte8_t ooff;
+ boxheader_param_t *obh;
+ Byte_t ni;
+ Byte8_t ioff;
+ boxheader_param_t *ibh;
+
+ 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");
+
+ off = fetch_DBox8bytebigendian( iptr, 0);
+ if( off != (Byte8_t)fidx->offset)
+ fprintf( FCGI_stderr, "Reference File Index box offset in Index Finder box not correct\n");
+
+ len = fetch_DBox8bytebigendian( iptr, 8);
+ if( len != fidx->length)
+ fprintf( FCGI_stderr, "Reference File Index box length in Index Finder box not correct\n");
+
+ pos = 0;
+ ooff = fetch_DBox8bytebigendian( prxy, pos);
+ if( ooff != (Byte8_t)jp2c->offset)
+ fprintf( FCGI_stderr, "Reference jp2c offset in prxy box not correct\n");
+ pos += 8;
+
+ 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);
+
+ ni = fetch_DBox1byte( prxy, pos);
+ if( ni != 1){
+ fprintf( FCGI_stderr, "Multiple indexes not supported\n");
+ return false;
+ }
+ pos += 1;
+
+ ioff = fetch_DBox8bytebigendian( prxy, pos);
+ if( ioff != (Byte8_t)cidx->offset)
+ fprintf( FCGI_stderr, "Reference cidx offset in prxy box not correct\n");
+ pos += 8;
+
+ 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);
+
+/**
+ * set code index parameters from ppix box
+ * I.3.2.4.6 Precinct Packet 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_ppixdata( 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);
+
+ if( !search_boxheader( "thix", manf)){
+ fprintf( FCGI_stderr, "Error: thix box not present in manfbox\n");
+ free(jp2idx);
+ return false;
+ }
+ set_thixdata( cidx_box, jp2idx);
+
+ if( !search_boxheader( "ppix", manf)){
+ fprintf( FCGI_stderr, "Error: ppix box not present in manfbox\n");
+ free(jp2idx);
+ return false;
+ }
+ set_ppixdata( cidx_box, jp2idx);
+
+ 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 = (OPJ_OFF_T)fetch_DBox8bytebigendian( box, 4);
+ jp2idx->length = fetch_DBox8bytebigendian( box, 12);
+
+ free( box);
+
+ return true;
+}
+
+
+/**
+ * set SIZ marker information
+ * 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] SIZ SIZ marker parameters pointer
+ * @return if succeeded (true) or failed (false)
+ */
+bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, SIZmarker_param_t *SIZ);
+
+/**
+ * set code index parameters from COD marker in codestream
+ * A.6 Functional marker segments
+ * A.6.1 Coding style default (COD)
+ *
+ * @param[in] codmkidx pointer to COD marker index in mhix box
+ * @param[in] codestream codestream parameters
+ * @param[out] COD COD marker parameters pointer
+ * @return if succeeded (true) or failed (false)
+ */
+bool set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestream, CODmarker_param_t *COD);
+
+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;
+ markeridx_param_t *codmkidx;
+
+ if( !(mhix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "mhix")))
+ return false;
+
+ 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->SIZ));
+
+ codmkidx = search_markeridx( 0xff52, mhix);
+ set_CODmkrdata( codmkidx, codestream, &(jp2idx->COD));
+
+ 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*/
+
+ if( !(tpix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "tpix"))){
+ fprintf( FCGI_stderr, "Error: tpix box not present in cidx box\n");
+ return false;
+ }
+
+ if( !(faix_box = gene_boxbyType( tpix_box->fd, get_DBoxoff( tpix_box), get_DBoxlen( tpix_box), "faix"))){
+ fprintf( FCGI_stderr, "Error: faix box not present in tpix box\n");
+ return false;
+ }
+
+ jp2idx->tilepart = gene_faixbox( faix_box);
+
+ 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;
+ OPJ_OFF_T mhixseqoff;
+ Byte2_t tile_no;
+
+ if( !(thix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "thix"))){
+ fprintf( FCGI_stderr, "Error: thix box not present in cidx box\n");
+ return false;
+ }
+
+ if( !(manf_box = gene_boxbyType( thix_box->fd, get_DBoxoff( thix_box), get_DBoxlen( thix_box), "manf"))){
+ fprintf( FCGI_stderr, "Error: manf box not present in thix box\n");
+ free( thix_box);
+ return false;
+ }
+
+ manf = gene_manfbox( manf_box);
+ ptr = manf->first;
+ mhixseqoff = manf_box->offset+(OPJ_OFF_T)manf_box->length;
+ pos = 0;
+ tile_no = 0;
+ jp2idx->tileheader = (mhixbox_param_t **)malloc( jp2idx->SIZ.XTnum*jp2idx->SIZ.YTnum*sizeof(mhixbox_param_t *));
+
+ while( ptr){
+ if( !(mhix_box = gene_boxbyType( thix_box->fd, mhixseqoff+(OPJ_OFF_T)pos, get_DBoxlen( thix_box)-manf_box->length-pos, "mhix"))){
+ fprintf( FCGI_stderr, "Error: mhix box not present in thix box\n");
+ delete_manfbox( &manf);
+ free( manf_box);
+ free( thix_box);
+ return false;
+ }
+ mhix = gene_mhixbox( mhix_box);
+
+ pos += mhix_box->length;
+ ptr = ptr->next;
+
+ free( mhix_box);
+ jp2idx->tileheader[tile_no++] = mhix;
+ }
+
+ delete_manfbox( &manf);
+ free( manf_box);
+ free( thix_box);
+
+ return true;
+}
+
+bool set_ppixdata( box_param_t *cidx_box, index_param_t *jp2idx)
+{
+ box_param_t *ppix_box, *faix_box, *manf_box;
+ manfbox_param_t *manf; /**< manf*/
+ boxheader_param_t *bh; /**< box headers*/
+ faixbox_param_t *faix; /**< faix*/
+ OPJ_OFF_T inbox_offset;
+ int comp_idx;
+
+ if( !(ppix_box = gene_boxbyType( cidx_box->fd, get_DBoxoff( cidx_box), get_DBoxlen( cidx_box), "ppix"))){
+ fprintf( FCGI_stderr, "Error: ppix box not present in cidx box\n");
+ return false;
+ }
+
+ inbox_offset = get_DBoxoff( ppix_box);
+ if( !(manf_box = gene_boxbyType( ppix_box->fd, inbox_offset, get_DBoxlen( ppix_box), "manf"))){
+ fprintf( FCGI_stderr, "Error: manf box not present in ppix box\n");
+ free( ppix_box);
+ return false;
+ }
+
+ free( ppix_box);
+
+ manf = gene_manfbox( manf_box);
+ bh = search_boxheader( "faix", manf);
+ inbox_offset = manf_box->offset + (OPJ_OFF_T)manf_box->length;
+
+ free( manf_box);
+
+ jp2idx->precpacket = (faixbox_param_t **)malloc( jp2idx->SIZ.Csiz*sizeof(faixbox_param_t *));
+
+ for( comp_idx=0; bh!=NULL; bh=bh->next, comp_idx++){
+ if( jp2idx->SIZ.Csiz <= comp_idx ){
+ fprintf( FCGI_stderr, "Error: num of faix boxes is not identical to num of components in ppix box\n");
+ return false;
+ }
+
+ if( !(faix_box = gene_boxbyOffset( cidx_box->fd, inbox_offset))){
+ fprintf( FCGI_stderr, "Error: faix box not present in ppix box\n");
+ return false;
+ }
+
+ faix = gene_faixbox( faix_box);
+ jp2idx->precpacket[comp_idx] = faix;
+
+ inbox_offset = faix_box->offset + (OPJ_OFF_T)faix_box->length;
+ free( faix_box);
+ }
+
+ delete_manfbox( &manf);
+
+ return true;
+}
+
+bool set_SIZmkrdata( markeridx_param_t *sizmkidx, codestream_param_t codestream, SIZmarker_param_t *SIZ)
+{
+ marker_param_t sizmkr;
+ int i;
+
+ sizmkr = set_marker( codestream, sizmkidx->code, sizmkidx->offset, sizmkidx->length);
+
+ SIZ->Lsiz = fetch_marker2bytebigendian( sizmkr, 0);
+
+ if( sizmkidx->length != SIZ->Lsiz){
+ fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", sizmkidx->code);
+ return false;
+ }
+
+ SIZ->Rsiz = fetch_marker2bytebigendian( sizmkr, 2);
+ SIZ->Xsiz = fetch_marker4bytebigendian( sizmkr, 4);
+ SIZ->Ysiz = fetch_marker4bytebigendian( sizmkr, 8);
+ SIZ->XOsiz = fetch_marker4bytebigendian( sizmkr, 12);
+ SIZ->YOsiz = fetch_marker4bytebigendian( sizmkr, 16);
+ SIZ->XTsiz = fetch_marker4bytebigendian( sizmkr, 20);
+ SIZ->YTsiz = fetch_marker4bytebigendian( sizmkr, 24);
+ SIZ->XTOsiz = fetch_marker4bytebigendian( sizmkr, 28);
+ SIZ->YTOsiz = fetch_marker4bytebigendian( sizmkr, 32);
+ SIZ->Csiz = fetch_marker2bytebigendian( sizmkr, 36);
+
+ SIZ->XTnum = ( SIZ->Xsiz-SIZ->XTOsiz+SIZ->XTsiz-1)/SIZ->XTsiz;
+ SIZ->YTnum = ( SIZ->Ysiz-SIZ->YTOsiz+SIZ->YTsiz-1)/SIZ->YTsiz;
+
+ for( i=0; i<(int)SIZ->Csiz; i++){
+ SIZ->Ssiz[i] = fetch_marker1byte( sizmkr, 38+i*3);
+ SIZ->XRsiz[i] = fetch_marker1byte( sizmkr, 39+i*3);
+ SIZ->YRsiz[i] = fetch_marker1byte( sizmkr, 40+i*3);
+ }
+ return true;
+}
+
+bool set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestream, CODmarker_param_t *COD)
+{
+ marker_param_t codmkr;
+ int i;
+
+ codmkr = set_marker( codestream, codmkidx->code, codmkidx->offset, codmkidx->length);
+
+ COD->Lcod = fetch_marker2bytebigendian( codmkr, 0);
+
+ if( codmkidx->length != COD->Lcod){
+ fprintf( FCGI_stderr, "Error: marker %#x index is not correct\n", codmkidx->code);
+ return false;
+ }
+
+ COD->Scod = fetch_marker1byte( codmkr, 2);
+ COD->prog_order = fetch_marker1byte( codmkr, 3);
+ COD->numOflayers = fetch_marker2bytebigendian( codmkr, 4);
+ COD->numOfdecomp = fetch_marker1byte( codmkr, 7);
+
+ if(COD->Scod & 0x01){
+ COD->XPsiz = (Byte4_t *)malloc( (OPJ_SIZE_T)(COD->numOfdecomp+1)*sizeof(Byte4_t));
+ COD->YPsiz = (Byte4_t *)malloc( (OPJ_SIZE_T)(COD->numOfdecomp+1)*sizeof(Byte4_t));
+
+ for( i=0; i<=COD->numOfdecomp; i++){
+ /*precinct size*/
+ COD->XPsiz[i] = (Byte2_t)pow( 2, fetch_marker1byte( codmkr, 12+i) & 0x0F);
+ COD->YPsiz[i] = (Byte2_t)pow( 2,(fetch_marker1byte( codmkr, 12+i) & 0xF0) >> 4);
+ }
+ }
+ else{
+ COD->XPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
+ COD->YPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
+
+ COD->XPsiz[0] = COD->YPsiz[0] = pow(2,15);
+ }
+ return true;
+}
+
+
+/* very very generic name see NOMINMAX */
+#ifdef min
+#undef min
+#endif
+#ifdef max
+#undef max
+#endif
+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_XYid, int level);
+
+range_param_t get_tile_Xrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
+{
+ return get_tile_range( SIZ.XOsiz, SIZ.Xsiz, SIZ.XTOsiz, SIZ.XTsiz, tile_id%SIZ.XTnum, level);
+}
+
+range_param_t get_tile_Yrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
+{
+ return get_tile_range( SIZ.YOsiz, SIZ.Ysiz, SIZ.YTOsiz, SIZ.YTsiz, tile_id/SIZ.XTnum, level);
+}
+
+range_param_t get_tile_range( Byte4_t Osiz, Byte4_t siz, Byte4_t TOsiz, Byte4_t Tsiz, Byte4_t tile_XYid, int level)
+{
+ range_param_t range;
+ int n;
+
+ range.minvalue = max( Osiz, TOsiz+tile_XYid*Tsiz);
+ range.maxvalue = min( siz, TOsiz+(tile_XYid+1)*Tsiz);
+
+ for( n=0; n<level; n++){
+ range.minvalue = (Byte4_t)ceil(range.minvalue/2.0);
+ range.maxvalue = (Byte4_t)ceil(range.maxvalue/2.0);
+ }
+ return range;
+}
+
+Byte4_t get_tile_XSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
+{
+ range_param_t tile_Xrange;
+
+ tile_Xrange = get_tile_Xrange( SIZ, tile_id, level);
+ return tile_Xrange.maxvalue - tile_Xrange.minvalue;
+}
+
+Byte4_t get_tile_YSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level)
+{
+ range_param_t tile_Yrange;
+
+ tile_Yrange = get_tile_Yrange( SIZ, tile_id, level);
+ return tile_Yrange.maxvalue - tile_Yrange.minvalue;
+}
+
+/* TODO: what is this code doing ? will all compiler be able to optimize the following ? */
+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;
+}
+
+bool isJPTfeasible( index_param_t index)
+{
+ if( 1 < get_nmax( index.tilepart))
+ return true;
+ else
+ return false;
+}
diff --git a/src/lib/openjpip/index_manager.h b/src/lib/openjpip/index_manager.h
new file mode 100644
index 00000000..c1969fac
--- /dev/null
+++ b/src/lib/openjpip/index_manager.h
@@ -0,0 +1,187 @@
+/*
+ * $Id: index_manager.h 53 2011-05-09 16:55:39Z 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 "byte_manager.h"
+#include "faixbox_manager.h"
+#include "metadata_manager.h"
+#include "mhixbox_manager.h"
+#include "bool.h"
+
+/** progression order */
+typedef enum porder {
+ PROG_UNKNOWN = -1, /**< place-holder */
+ LRCP = 0, /**< layer-resolution-component-precinct order */
+ RLCP = 1, /**< resolution-layer-component-precinct order */
+ RPCL = 2, /**< resolution-precinct-component-layer order */
+ PCRL = 3, /**< precinct-component-resolution-layer order */
+ CPRL = 4 /**< component-precinct-resolution-layer order */
+} porder_t;
+
+/** A.5.1 Image and tile size (SIZ)*/
+typedef struct SIZmarker_param{
+ Byte2_t Lsiz; /**< length of marker segment excluding the marker*/
+ 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*/
+} SIZmarker_param_t;
+
+/** A.6.1 Coding style default (COD)*/
+typedef struct CODmarker_param{
+ Byte2_t Lcod; /**< length of marker segment excluding the marker*/
+ Byte_t Scod; /**< Coding style for all components*/
+ porder_t prog_order; /**< progression order*/
+ Byte2_t numOflayers; /**< number of layers*/
+ Byte_t numOfdecomp; /**< number of decompositions levels*/
+ Byte4_t *XPsiz; /**< dynamic array of precinct width at successive resolution level in order*/
+ Byte4_t *YPsiz; /**< dynamic array of precinct height at successive resolution level in order*/
+} CODmarker_param_t;
+
+/** index parameters*/
+typedef struct index_param{
+ metadatalist_param_t *metadatalist; /**< metadata-bin list*/
+ OPJ_OFF_T offset; /**< codestream offset*/
+ Byte8_t length; /**< codestream length */
+ Byte8_t mhead_length; /**< main header length */
+ SIZmarker_param_t SIZ; /**< SIZ marker information*/
+ CODmarker_param_t COD; /**< COD marker information*/
+ faixbox_param_t *tilepart; /**< tile part information from tpix box*/
+ mhixbox_param_t **tileheader; /**< dynamic array of tile header information from thix box*/
+ faixbox_param_t **precpacket; /**< dynamic array of precint packet information from ppix box*/
+} 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 Image and Tile SIZ parameters
+ *
+ * @param[in] SIZ SIZ marker information
+ */
+void print_SIZ( SIZmarker_param_t SIZ);
+
+/**
+ * print Coding style default COD parameters
+ *
+ * @param[in] COD COD marker information
+ */
+void print_COD( CODmarker_param_t COD);
+
+/**
+ * delete index
+ *
+ * @param[in,out] index addressof the index pointer
+ */
+void delete_index( index_param_t **index);
+
+/**
+ * delete dynamic arrays in COD marker
+ *
+ * @param[in] COD COD marker information
+ */
+void delete_COD( CODmarker_param_t COD);
+
+
+/** 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] SIZ SIZ marker information
+ * @param[in] tile_id tile id
+ * @param[in] level decomposition level
+ * @return structured range parameter
+ */
+range_param_t get_tile_Xrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
+
+/**
+ * get vertical range of the tile in reference grid
+ *
+ * @param[in] SIZ SIZ marker information
+ * @param[in] tile_id tile id
+ * @param[in] level decomposition level
+ * @return structured range parameter
+ */
+range_param_t get_tile_Yrange( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
+
+
+/**
+ * get tile wdith at the decomposition level
+ *
+ * @param[in] SIZ SIZ marker information
+ * @param[in] tile_id tile id
+ * @param[in] level decomposition level
+ * @return tile width
+ */
+Byte4_t get_tile_XSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
+Byte4_t get_tile_YSiz( SIZmarker_param_t SIZ, Byte4_t tile_id, int level);
+
+
+/**
+ * answers if the target is feasible to JPT-stream
+ *
+ * @param[in] index index parameters
+ * @return true if JPT-stream is feasible
+ */
+bool isJPTfeasible( index_param_t index);
+
+#endif /* !INDEX_MANAGER_H_ */
diff --git a/src/lib/openjpip/j2kheader_manager.c b/src/lib/openjpip/j2kheader_manager.c
new file mode 100644
index 00000000..5a6054cc
--- /dev/null
+++ b/src/lib/openjpip/j2kheader_manager.c
@@ -0,0 +1,295 @@
+/*
+ * $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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 <math.h>
+#include <assert.h>
+#include "j2kheader_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 */
+
+
+SIZmarker_param_t get_SIZmkrdata_from_j2kstream( Byte_t *SIZstream);
+CODmarker_param_t get_CODmkrdata_from_j2kstream( Byte_t *CODstream);
+
+bool get_mainheader_from_j2kstream( Byte_t *j2kstream, SIZmarker_param_t *SIZ, CODmarker_param_t *COD)
+{
+ if( *j2kstream++ != 0xff || *j2kstream++ != 0x4f){
+ fprintf( FCGI_stderr, "Error, j2kstream is not starting with SOC marker\n");
+ return false;
+ }
+
+ if( SIZ){
+ *SIZ = get_SIZmkrdata_from_j2kstream( j2kstream);
+ if( SIZ->Lsiz == 0)
+ return false;
+
+ j2kstream += (SIZ->Lsiz+2);
+ }
+
+ if( COD){
+ if( !SIZ)
+ j2kstream += (big2( j2kstream+2) + 2);
+
+ *COD = get_CODmkrdata_from_j2kstream( j2kstream);
+ if( COD->Lcod == 0)
+ return false;
+ }
+ return true;
+}
+
+SIZmarker_param_t get_SIZmkrdata_from_j2kstream( Byte_t *SIZstream)
+{
+ SIZmarker_param_t SIZ;
+ int i;
+
+ if( *SIZstream++ != 0xff || *SIZstream++ != 0x51){
+ fprintf( FCGI_stderr, "Error, SIZ marker not found in the reconstructed j2kstream\n");
+ memset( &SIZ, 0, sizeof( SIZ ) );
+ return SIZ;
+ }
+
+ SIZ.Lsiz = big2( SIZstream);
+ SIZ.Rsiz = big2( SIZstream+2);
+ SIZ.Xsiz = big4( SIZstream+4);
+ SIZ.Ysiz = big4( SIZstream+8);
+ SIZ.XOsiz = big4( SIZstream+12);
+ SIZ.YOsiz = big4( SIZstream+16);
+ SIZ.XTsiz = big4( SIZstream+20);
+ SIZ.YTsiz = big4( SIZstream+24);
+ SIZ.XTOsiz = big4( SIZstream+28);
+ SIZ.YTOsiz = big4( SIZstream+32);
+ SIZ.Csiz = big2( SIZstream+36);
+
+ SIZ.XTnum = ( SIZ.Xsiz-SIZ.XTOsiz+SIZ.XTsiz-1)/SIZ.XTsiz;
+ SIZ.YTnum = ( SIZ.Ysiz-SIZ.YTOsiz+SIZ.YTsiz-1)/SIZ.YTsiz;
+
+ for( i=0; i<(int)SIZ.Csiz; i++){
+ SIZ.Ssiz[i] = *(SIZstream+(38+i*3));
+ SIZ.XRsiz[i] = *(SIZstream+(39+i*3));
+ SIZ.YRsiz[i] = *(SIZstream+(40+i*3));
+ }
+
+ return SIZ;
+}
+
+CODmarker_param_t get_CODmkrdata_from_j2kstream( Byte_t *CODstream)
+{
+ CODmarker_param_t COD;
+ int i;
+
+ if( *CODstream++ != 0xff || *CODstream++ != 0x52){
+ fprintf( FCGI_stderr, "Error, COD marker not found in the reconstructed j2kstream\n");
+ return COD;
+ }
+
+ COD.Lcod = big2( CODstream);
+ COD.Scod = *( CODstream+2);
+ COD.prog_order = *( CODstream+3);
+ COD.numOflayers = big2( CODstream+4);
+ COD.numOfdecomp = *( CODstream+7);
+
+ if(COD.Scod & 0x01){
+ COD.XPsiz = (Byte4_t *)malloc( (OPJ_SIZE_T)(COD.numOfdecomp+1)*sizeof(Byte4_t));
+ COD.YPsiz = (Byte4_t *)malloc( (OPJ_SIZE_T)(COD.numOfdecomp+1)*sizeof(Byte4_t));
+
+ for( i=0; i<=COD.numOfdecomp; i++){
+ /*precinct size */
+ COD.XPsiz[i] = (Byte4_t)pow( 2, *( CODstream+12+i) & 0x0F);
+ COD.YPsiz[i] = (Byte4_t)pow( 2, (*( CODstream+12+i) & 0xF0) >> 4);
+ }
+ }
+ else{
+ COD.XPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
+ COD.YPsiz = (Byte4_t *)malloc( sizeof(Byte4_t));
+ COD.XPsiz[0] = COD.YPsiz[0] = pow(2,15);
+ }
+ return COD;
+}
+
+
+bool modify_SIZmkrstream( SIZmarker_param_t SIZ, int difOfdecomplev, Byte_t *SIZstream);
+Byte2_t modify_CODmkrstream( CODmarker_param_t COD, int numOfdecomp, Byte_t *CODstream);
+
+bool modify_mainheader( Byte_t *j2kstream, int numOfdecomp, SIZmarker_param_t SIZ, CODmarker_param_t COD, Byte8_t *j2klen)
+{
+ Byte2_t newLcod;
+
+ if( *j2kstream++ != 0xff || *j2kstream++ != 0x4f){
+ fprintf( FCGI_stderr, "Error, j2kstream is not starting with SOC marker\n");
+ return false;
+ }
+
+ if(!modify_SIZmkrstream( SIZ, COD.numOfdecomp-numOfdecomp, j2kstream))
+ return false;
+
+ j2kstream += SIZ.Lsiz+2;
+ if( !(newLcod = modify_CODmkrstream( COD, numOfdecomp, j2kstream)))
+ return false;
+
+ memmove( j2kstream+2+newLcod, j2kstream+2+COD.Lcod, *j2klen - (Byte8_t)(SIZ.Lsiz+COD.Lcod+6));
+ *j2klen -= (Byte8_t)( COD.Lcod - newLcod);
+
+ return true;
+}
+
+bool modify_SIZmkrstream( SIZmarker_param_t SIZ, int difOfdecomplev, Byte_t *SIZstream)
+{
+ int i;
+
+ if( *SIZstream++ != 0xff || *SIZstream++ != 0x51){
+ fprintf( FCGI_stderr, "Error, SIZ marker not found in the reconstructed j2kstream\n");
+ return false;
+ }
+
+ for( i=0; i<difOfdecomplev; i++){
+ SIZ.Xsiz = (Byte4_t)ceil( (double)SIZ.Xsiz/2.0);
+ SIZ.Ysiz = (Byte4_t)ceil( (double)SIZ.Ysiz/2.0);
+ SIZ.XOsiz = (Byte4_t)ceil( (double)SIZ.XOsiz/2.0);
+ SIZ.YOsiz = (Byte4_t)ceil( (double)SIZ.YOsiz/2.0);
+ SIZ.XTsiz = (Byte4_t)ceil( (double)SIZ.XTsiz/2.0);
+ SIZ.YTsiz = (Byte4_t)ceil( (double)SIZ.YTsiz/2.0);
+ SIZ.XTOsiz = (Byte4_t)ceil( (double)SIZ.XTOsiz/2.0);
+ SIZ.YTOsiz = (Byte4_t)ceil( (double)SIZ.YTOsiz/2.0);
+ }
+
+ SIZstream += 4; /* skip Lsiz + Rsiz */
+
+ modify_4Bytecode( SIZ.Xsiz, SIZstream);
+ modify_4Bytecode( SIZ.Ysiz, SIZstream+4);
+ modify_4Bytecode( SIZ.XOsiz, SIZstream+8);
+ modify_4Bytecode( SIZ.YOsiz, SIZstream+12);
+ modify_4Bytecode( SIZ.XTsiz, SIZstream+16);
+ modify_4Bytecode( SIZ.YTsiz, SIZstream+20);
+ modify_4Bytecode( SIZ.XTOsiz, SIZstream+24);
+ modify_4Bytecode( SIZ.YTOsiz, SIZstream+28);
+
+ return true;
+}
+
+Byte2_t modify_CODmkrstream( CODmarker_param_t COD, int numOfdecomp, Byte_t *CODstream)
+{
+ Byte2_t newLcod;
+
+ assert( numOfdecomp >= 0 || numOfdecomp <= 255 );
+ if( *CODstream++ != 0xff || *CODstream++ != 0x52){
+ fprintf( FCGI_stderr, "Error, COD marker not found in the reconstructed j2kstream\n");
+ return 0;
+ }
+
+ if( COD.Scod & 0x01){
+ newLcod = (Byte2_t)(13+numOfdecomp);
+
+ *CODstream++ = (Byte_t)((Byte2_t)(newLcod & 0xff00) >> 8);
+ *CODstream++ = (Byte_t)(newLcod & 0x00ff);
+ }
+ else{
+ newLcod = COD.Lcod;
+ CODstream += 2;
+ }
+
+ CODstream += 5; /* skip Scod & SGcod */
+
+ /* SPcod */
+ *CODstream++ = (Byte_t) numOfdecomp;
+
+ return newLcod;
+}
+
+bool modify_COCmkrstream( int numOfdecomp, Byte_t *COCstream, Byte2_t Csiz, Byte2_t *oldLcoc, Byte2_t *newLcoc);
+
+bool modify_tileheader( Byte_t *j2kstream, Byte8_t SOToffset, int numOfdecomp, Byte2_t Csiz, Byte8_t *j2klen)
+{
+ Byte4_t Psot; /* tile part length ref A.4.2 Start of tile-part SOT */
+ Byte_t *thstream, *SOTstream, *Psot_stream;
+ Byte2_t oldLcoc, newLcoc;
+
+ SOTstream = thstream = j2kstream+SOToffset;
+
+ if( *SOTstream++ != 0xff || *SOTstream++ != 0x90){
+ fprintf( FCGI_stderr, "Error, thstream is not starting with SOT marker\n");
+ return false;
+ }
+
+ SOTstream += 4; /* skip Lsot & Isot */
+ Psot = (Byte4_t)((SOTstream[0]<<24)+(SOTstream[1]<<16)+(SOTstream[2]<<8)+(SOTstream[3]));
+ Psot_stream = SOTstream;
+
+ thstream += 12; /* move to next marker (SOT always 12bytes) */
+
+ while( !( *thstream == 0xff && *(thstream+1) == 0x93)){ /* search SOD */
+ if( numOfdecomp != -1 && *thstream == 0xff && *(thstream+1) == 0x53){ /* COC */
+ if( !modify_COCmkrstream( numOfdecomp, thstream, Csiz, &oldLcoc, &newLcoc))
+ return false;
+
+ memmove( thstream+newLcoc+2, thstream+oldLcoc+2, *j2klen - (Byte8_t)(thstream-j2kstream+oldLcoc+2));
+ *j2klen -= (Byte8_t)( oldLcoc - newLcoc);
+ }
+ thstream += 2;
+ thstream += ((thstream[0]<<8)+(thstream[1])); /* marker length */
+ }
+
+ if( (*j2klen)-SOToffset != Psot){
+ Psot = (Byte4_t)((*j2klen)-SOToffset);
+ modify_4Bytecode( Psot, Psot_stream);
+ }
+ return true;
+}
+
+bool modify_COCmkrstream( int numOfdecomp, Byte_t *COCstream, Byte2_t Csiz, Byte2_t *oldLcoc, Byte2_t *newLcoc)
+{
+ if( numOfdecomp < 0 || numOfdecomp > 255 ) return false;
+ if( *COCstream++ != 0xff || *COCstream++ != 0x53){
+ fprintf( FCGI_stderr, "Error, COC marker not found in the reconstructed j2kstream\n");
+ return false;
+ }
+
+ *oldLcoc = big2( COCstream);
+ *newLcoc = (Byte2_t)((Csiz < 257 ? 10 : 11) + numOfdecomp);
+ *COCstream++ = (Byte_t)((Byte2_t)((*newLcoc) & 0xff00) >> 8);
+ *COCstream++ = (Byte_t)((*newLcoc) & 0x00ff);
+
+ if( Csiz < 257) COCstream +=2; /* skip Ccoc & Scoc */
+ else COCstream += 3;
+
+ *COCstream = (Byte_t)numOfdecomp;
+
+ return true;
+}
diff --git a/src/lib/openjpip/j2kheader_manager.h b/src/lib/openjpip/j2kheader_manager.h
new file mode 100644
index 00000000..a6146c64
--- /dev/null
+++ b/src/lib/openjpip/j2kheader_manager.h
@@ -0,0 +1,73 @@
+/*
+ * $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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 J2KHEADER_MANAGER_H_
+# define J2KHEADER_MANAGER_H_
+
+#include "bool.h"
+#include "byte_manager.h"
+#include "index_manager.h"
+
+/**
+ * get main header information from j2k codestream
+ *
+ * @param[in] j2kstream j2k codestream
+ * @param[out] SIZ SIZ marker pointer
+ * @param[out] COD COD marker pointer
+ * @return if succeeded (true) or failed (false)
+ */
+bool get_mainheader_from_j2kstream( Byte_t *j2kstream, SIZmarker_param_t *SIZ, CODmarker_param_t *COD);
+
+/**
+ * modify main header in j2k codestream to fit with the new number of decompositions
+ *
+ * @param[in] j2kstream j2k codestream
+ * @param[in] numOfdecomp the New number of decompositions
+ * @param[in] SIZ original SIZ marker information
+ * @param[in] COD original COD marker information
+ * @param[out] j2klen pointer to the length of j2k code stream
+ * @return if succeeded (true) or failed (false)
+ */
+bool modify_mainheader( Byte_t *j2kstream, int numOfdecomp, SIZmarker_param_t SIZ, CODmarker_param_t COD, Byte8_t *j2klen);
+
+/**
+ * modify tile header in j2k codestream to fit with the tile part length, and new number of decompositions for multi-componet images
+ *
+ * @param[in] j2kstream j2k codestream
+ * @param[in] SOToffset offset of SOT marker from the beginning of j2kstream
+ * @param[in] numOfdecomp the New number of decompositions, -1 if the same as original
+ * @param[in] Csiz number of components
+ * @param[out] j2klen pointer to the length of j2k code stream
+ * @return if succeeded (true) or failed (false)
+ */
+bool modify_tileheader( Byte_t *j2kstream, Byte8_t SOToffset, int numOfdecomp, Byte2_t Csiz, Byte8_t *j2klen);
+
+#endif /* !J2KHEADER_MANAGER_H_ */
diff --git a/src/lib/openjpip/jp2k_decoder.c b/src/lib/openjpip/jp2k_decoder.c
new file mode 100644
index 00000000..9d619b09
--- /dev/null
+++ b/src/lib/openjpip/jp2k_decoder.c
@@ -0,0 +1,236 @@
+/*
+ * $Id: jp2k_decoder.c 53 2011-05-09 16:55:39Z kaori $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <limits.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( FILE *fp, ihdrbox_param_t **ihdrbox)
+{
+ Byte_t *pnmstream = NULL;
+ opj_dparameters_t parameters; /* decompression parameters */
+ opj_image_t *image = NULL;
+ opj_codec_t *l_codec = NULL; /* handle to a decompressor */
+ opj_stream_t *l_stream = NULL;
+
+
+
+ /* set decoding parameters to default values */
+ opj_set_default_decoder_parameters(&parameters);
+
+ /* set a byte stream */
+ l_stream = opj_stream_create_default_file_stream( fp, 1);
+ if (!l_stream){
+ fprintf(stderr, "ERROR -> failed to create the stream from the file\n");
+ return NULL;
+ }
+
+ /* decode the code-stream */
+ /* ---------------------- */
+
+ /* JPEG-2000 codestream */
+ /* get a decoder handle */
+ l_codec = opj_create_decompress(CODEC_J2K);
+
+ /* catch events using our callbacks and give a local context */
+ opj_set_info_handler(l_codec, info_callback,00);
+ opj_set_warning_handler(l_codec, warning_callback,00);
+ opj_set_error_handler(l_codec, error_callback,00);
+
+ /* setup the decoder decoding parameters using user parameters */
+ if ( !opj_setup_decoder(l_codec, &parameters) ){
+ fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n");
+ return NULL;
+ }
+
+ /* Read the main header of the codestream and if necessary the JP2 boxes*/
+ if(! opj_read_header( l_stream, l_codec, &image)){
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to read the header\n");
+ opj_stream_destroy(l_stream);
+ opj_destroy_codec(l_codec);
+ opj_image_destroy(image);
+ return NULL;
+ }
+
+#ifdef TODO /*decode area could be set from j2k_to_pnm call, modify the protocol between JPIP viewer and opj_dec_server*/
+ if (! opj_set_decode_area( l_codec, image, parameters.DA_x0, parameters.DA_y0, parameters.DA_x1, parameters.DA_y1)){
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to set the decoded area\n");
+ opj_stream_destroy(l_stream);
+ opj_destroy_codec(l_codec);
+ opj_image_destroy(image);
+ return NULL;
+ }
+#endif /*TODO*/
+
+ /* Get the decoded image */
+ if ( !( opj_decode(l_codec, l_stream, image) && opj_end_decompress(l_codec,l_stream) ) ) {
+ fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n");
+ opj_stream_destroy(l_stream);
+ opj_destroy_codec(l_codec);
+ opj_image_destroy(image);
+ return NULL;
+ }
+
+ fprintf(stderr, "image is decoded!\n");
+
+ /* close the byte stream */
+ opj_stream_destroy(l_stream);
+
+ /* create output image */
+ /* ------------------- */
+ if( (pnmstream = imagetopnm( image, ihdrbox))==NULL)
+ fprintf( stderr, "PNM image not generated\n");
+
+ /* free remaining structures */
+ if(l_codec) {
+ opj_destroy_codec(l_codec);
+ }
+
+ /* 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;
+ (void)msg;
+ /* fprintf(stdout, "[INFO] %s", msg); */
+}
+
+
+Byte_t * imagetopnm(opj_image_t *image, ihdrbox_param_t **ihdrbox)
+{
+ OPJ_UINT32 adjustR, adjustG=0, adjustB=0;
+ OPJ_SIZE_T datasize;
+ Byte_t *pix=NULL, *ptr=NULL;
+ OPJ_UINT32 i;
+
+ 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)
+ (*ihdrbox)->width = image->comps[0].w;
+
+ if( (*ihdrbox)->height != image->comps[0].h)
+ (*ihdrbox)->height = image->comps[0].h;
+
+ 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;
+ assert( image->comps[0].prec < 256 );
+ (*ihdrbox)->bpc = (Byte_t)image->comps[0].prec;
+ assert( image->numcomps < USHRT_MAX );
+ (*ihdrbox)->nc = (Byte2_t)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( 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;
+}
diff --git a/src/lib/openjpip/jp2k_decoder.h b/src/lib/openjpip/jp2k_decoder.h
new file mode 100644
index 00000000..c999cdf1
--- /dev/null
+++ b/src/lib/openjpip/jp2k_decoder.h
@@ -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( FILE *fp, ihdrbox_param_t **ihdrbox);
+
+#endif /* !JP2K_DECODER_H_ */
diff --git a/src/lib/openjpip/jp2k_encoder.c b/src/lib/openjpip/jp2k_encoder.c
new file mode 100644
index 00000000..23c8b2fe
--- /dev/null
+++ b/src/lib/openjpip/jp2k_encoder.c
@@ -0,0 +1,804 @@
+/*
+ * $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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 <math.h>
+#include <assert.h>
+#include "jp2k_encoder.h"
+#include "j2kheader_manager.h"
+#include "imgreg_manager.h"
+#include "opj_inttypes.h"
+
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER*/
+
+
+/**
+ * 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);
+
+/**
+ * reconstruct j2k codestream from JPT- (in future, JPP-) stream
+ *
+ * @param[in] msgqueue message queue pointer
+ * @param[in] jpipstream original JPT- JPP- stream
+ * @param[in] csn codestream number
+ * @param[in] fw reconstructing image frame width
+ * @param[in] fh reconstructing image frame height
+ * @param[out] codelen codestream length
+ * @return generated reconstructed j2k codestream
+ */
+Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *codelen);
+
+Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen)
+{
+ Byte_t *j2kstream = NULL;
+
+ if( !msgqueue)
+ return NULL;
+
+ j2kstream = recons_codestream( msgqueue, jpipstream, csn, fw, fh, 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 *jpipstream, 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, (Byte8_t)-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, jpipstream, jp2stream, jp2len);
+ ptr = ptr->next;
+ }
+
+ codestream = recons_codestream( msgqueue, jpipstream, csn, 0, 0, &codelen);
+
+ if( jp2cDBoxOffset != 0 && codelen <= jp2cDBoxlen)
+ memcpy( jp2stream+jp2cDBoxOffset, codestream, codelen);
+
+ free( codestream);
+
+ return jp2stream;
+}
+
+bool isJPPstream( Byte8_t csn, msgqueue_param_t *msgqueue);
+
+Byte_t * recons_codestream_from_JPTstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen);
+Byte_t * recons_codestream_from_JPPstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen);
+
+Byte_t * add_EOC( Byte_t *j2kstream, Byte8_t *j2klen);
+
+Byte_t * recons_codestream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *codelen)
+{
+ if( isJPPstream( csn, msgqueue))
+ return recons_codestream_from_JPPstream( msgqueue, jpipstream, csn, fw, fh, codelen);
+ else
+ return recons_codestream_from_JPTstream( msgqueue, jpipstream, csn, fw, fh, codelen);
+}
+
+bool isJPPstream( Byte8_t csn, msgqueue_param_t *msgqueue)
+{
+ message_param_t *msg;
+
+ msg = msgqueue->first;
+ while( msg){
+ if( msg->csn == csn){
+ if( msg->class_id <= 2)
+ return true;
+ else
+ if( msg->class_id == 4 || msg->class_id == 5)
+ return false;
+ }
+ msg = msg->next;
+ }
+
+ fprintf( FCGI_stderr, "Error, message of csn %" PRId64 " not found\n", csn);
+
+ return false;
+}
+
+Byte_t * add_mainhead_msgstream( msgqueue_param_t *msgqueue, Byte_t *origstream, Byte_t *j2kstream, Byte8_t csn, Byte8_t *j2klen);
+Byte8_t get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn, bool isJPPstream);
+Byte_t * add_emptytilestream( const Byte8_t tileID, Byte_t *j2kstream, Byte8_t *j2klen);
+
+Byte_t * recons_codestream_from_JPTstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen)
+{
+ Byte_t *j2kstream = NULL;
+ Byte8_t last_tileID, tileID;
+ bool found;
+ Byte8_t binOffset;
+ message_param_t *ptr;
+ SIZmarker_param_t SIZ;
+ OPJ_SIZE_T mindeclev;
+
+ *j2klen = 0;
+ j2kstream = add_mainhead_msgstream( msgqueue, jpipstream, j2kstream, csn, j2klen);
+
+ if( !get_mainheader_from_j2kstream( j2kstream, &SIZ, NULL))
+ return j2kstream;
+
+ if( fw <= 0 || fh <= 0)
+ mindeclev = 0;
+ else
+ mindeclev = (OPJ_SIZE_T)comp_decomplev( fw, fh, (int)SIZ.Xsiz, (int)SIZ.Ysiz);
+
+ last_tileID = get_last_tileID( msgqueue, csn, false);
+
+ for( tileID=0; tileID <= last_tileID; tileID++){
+ found = false;
+ binOffset = 0;
+
+ ptr = msgqueue->first;
+ while(( ptr = search_message( TILE_MSG, tileID, csn, ptr))!=NULL){
+ if( ptr->bin_offset == binOffset){
+ found = true;
+ j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+ binOffset += ptr->length;
+ }
+ ptr = ptr->next;
+ }
+ ptr = msgqueue->first;
+ while(( ptr = search_message( EXT_TILE_MSG, tileID, csn, ptr))!=NULL){
+ if( ptr->aux > mindeclev){ /* FIXME: pointer comparison ? */
+ if( ptr->bin_offset == binOffset){
+ found = true;
+ j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+ binOffset += ptr->length;
+ }
+ }
+ ptr = ptr->next;
+ }
+ if(!found)
+ j2kstream = add_emptytilestream( tileID, j2kstream, j2klen);
+ }
+
+ j2kstream = add_EOC( j2kstream, j2klen);
+
+ return j2kstream;
+}
+
+Byte_t * add_SOTmkr( Byte_t *j2kstream, Byte8_t *j2klen);
+
+Byte_t * recons_bitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_codestream_from_JPPstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen)
+{
+ Byte_t *j2kstream = NULL;
+ Byte8_t tileID, last_tileID;
+ Byte8_t SOToffset;
+ bool foundTH;
+ Byte8_t binOffset;
+ message_param_t *ptr;
+ SIZmarker_param_t SIZ;
+ CODmarker_param_t COD;
+ int max_reslev, mindeclev;
+
+ *j2klen = 0;
+ j2kstream = add_mainhead_msgstream( msgqueue, jpipstream, j2kstream, csn, j2klen);
+
+ if( !get_mainheader_from_j2kstream( j2kstream, &SIZ, &COD))
+ return j2kstream;
+
+ if( fw == 0 || fh == 0)
+ mindeclev = 0;
+ else
+ mindeclev = comp_decomplev( fw, fh, (int)SIZ.Xsiz, (int)SIZ.Ysiz);
+
+ max_reslev = -1;
+ last_tileID = get_last_tileID( msgqueue, csn, true);
+
+ for( tileID=0; tileID <= last_tileID; tileID++){
+
+ ptr = msgqueue->first;
+ binOffset = 0;
+ foundTH = false;
+ SOToffset = *j2klen;
+ while(( ptr = search_message( TILE_HEADER_MSG, tileID, csn, ptr))!=NULL){
+ if( ptr->bin_offset == binOffset){
+ j2kstream = add_SOTmkr( j2kstream, j2klen);
+ j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+ foundTH = true;
+ binOffset += ptr->length;
+ }
+ ptr = ptr->next;
+ }
+
+ if( foundTH){
+ j2kstream = recons_bitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, &max_reslev, j2klen);
+ modify_tileheader( j2kstream, SOToffset, (max_reslev<COD.numOfdecomp ? max_reslev : -1), SIZ.Csiz, j2klen);
+ }
+ else
+ j2kstream = add_emptytilestream( tileID, j2kstream, j2klen);
+ }
+
+ if( max_reslev < COD.numOfdecomp)
+ if( !modify_mainheader( j2kstream, max_reslev, SIZ, COD, j2klen)){
+ delete_COD( COD);
+ return j2kstream;
+ }
+
+ j2kstream = add_EOC( j2kstream, j2klen);
+ delete_COD( COD);
+
+ return j2kstream;
+}
+
+Byte_t * add_mainhead_msgstream( msgqueue_param_t *msgqueue, Byte_t *origstream, Byte_t *j2kstream, Byte8_t csn, Byte8_t *j2klen)
+{
+ message_param_t *ptr;
+ Byte8_t binOffset;
+
+ ptr = msgqueue->first;
+ binOffset = 0;
+
+ while(( ptr = search_message( MAINHEADER_MSG, (Byte8_t)-1, csn, ptr))!=NULL){
+ if( ptr->bin_offset == binOffset){
+ j2kstream = add_msgstream( ptr, origstream, j2kstream, j2klen);
+ binOffset += ptr->length;
+ }
+ ptr = ptr->next;
+ }
+ return j2kstream;
+}
+
+Byte_t * add_SOTmkr( Byte_t *j2kstream, Byte8_t *j2klen)
+{
+ Byte_t *buf;
+ const Byte2_t SOT = 0x90ff;
+
+ buf = (Byte_t *)malloc(( *j2klen)+2);
+
+ memcpy( buf, j2kstream, *j2klen);
+ memcpy( buf+(*j2klen), &SOT, 2);
+
+ *j2klen += 2;
+
+ if(j2kstream) free(j2kstream);
+
+ return buf;
+}
+
+Byte_t * recons_LRCPbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_RLCPbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_RPCLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_PCRLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_CPRLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen);
+
+Byte_t * recons_bitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen)
+{
+ switch( COD.prog_order){
+ case LRCP:
+ return recons_LRCPbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+ case RLCP:
+ return recons_RLCPbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+ case RPCL:
+ return recons_RPCLbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+ case PCRL:
+ return recons_PCRLbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+ case CPRL:
+ return recons_CPRLbitstream( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, mindeclev, max_reslev, j2klen);
+ default:
+ fprintf( FCGI_stderr, "Error, progression order not supported\n");
+ }
+ return j2kstream;
+}
+
+int comp_numOfprcts( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int r);
+Byte8_t comp_seqID( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int r, int p);
+
+Byte_t * recons_packet( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int *max_reslev,
+ int comp_idx, int res_idx, int prct_idx, int lay_idx, Byte8_t *j2klen);
+
+Byte_t * recons_LRCPbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen)
+{
+ int r, p, c, l, numOfprcts;
+
+ for( l=0; l<COD.numOflayers; l++)
+ for( r=0; r<=(COD.numOfdecomp-mindeclev); r++){
+ if( COD.Scod & 0x01)
+ numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+ else
+ numOfprcts = 1;
+
+ for( c=0; c<SIZ.Csiz; c++)
+ for( p=0; p<numOfprcts; p++)
+ j2kstream = recons_packet( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, p, l, j2klen);
+ }
+
+ return j2kstream;
+}
+
+Byte_t * recons_RLCPbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen)
+{
+ int r, p, c, l, numOfprcts;
+
+ for( r=0; r<=(COD.numOfdecomp-mindeclev); r++){
+ if( COD.Scod & 0x01)
+ numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+ else
+ numOfprcts = 1;
+
+ for( l=0; l<COD.numOflayers; l++)
+ for( c=0; c<SIZ.Csiz; c++)
+ for( p=0; p<numOfprcts; p++)
+ j2kstream = recons_packet( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, p, l, j2klen);
+ }
+
+ return j2kstream;
+}
+
+Byte_t * recons_precinct( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int *max_reslev,
+ int comp_idx, int res_idx, Byte8_t seqID, Byte8_t *j2klen);
+
+Byte_t * recons_RPCLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen)
+{
+ int r, p, c, numOfprcts;
+ Byte8_t seqID;
+
+ for( r=0, seqID=0; r<=(COD.numOfdecomp-mindeclev); r++){
+
+ if( COD.Scod & 0x01)
+ numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+ else
+ numOfprcts = 1;
+
+ for( p=0; p<numOfprcts; p++, seqID++)
+ for( c=0; c<SIZ.Csiz; c++)
+ j2kstream = recons_precinct( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, seqID, j2klen);
+ }
+
+ return j2kstream;
+}
+
+Byte_t * recons_PCRLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen)
+{
+ int r, p, c, min_numOfprcts, numOfprcts, min_numOfres;
+ Byte8_t seqID;
+
+ min_numOfres = COD.numOfdecomp-mindeclev + 1;
+
+ if( COD.Scod & 0x01){
+ min_numOfprcts = 0;
+ for( r=0; r<min_numOfres; r++){
+ numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+
+ if( numOfprcts < min_numOfprcts || min_numOfprcts == 0)
+ min_numOfprcts = numOfprcts;
+ }
+ }
+ else
+ min_numOfprcts = 1;
+
+ for( p=0; p<min_numOfprcts; p++)
+ for( c=0; c<SIZ.Csiz; c++)
+ for( r=0; r<min_numOfres; r++){
+ seqID = comp_seqID( tileID, SIZ, COD, r, p);
+ j2kstream = recons_precinct( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, seqID, j2klen);
+ }
+
+ return j2kstream;
+}
+
+
+Byte_t * recons_CPRLbitstream( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int mindeclev,
+ int *max_reslev, Byte8_t *j2klen)
+{
+ int r, p, c, min_numOfprcts, numOfprcts, min_numOfres;
+ Byte8_t seqID;
+
+ min_numOfres = COD.numOfdecomp-mindeclev + 1;
+
+ if( COD.Scod & 0x01){
+ min_numOfprcts = 0;
+ for( r=0; r<min_numOfres; r++){
+ numOfprcts = comp_numOfprcts( tileID, SIZ, COD, r);
+
+ if( numOfprcts < min_numOfprcts || min_numOfprcts == 0)
+ min_numOfprcts = numOfprcts;
+ }
+ }
+ else
+ min_numOfprcts = 1;
+
+ for( c=0; c<SIZ.Csiz; c++)
+ for( p=0; p<min_numOfprcts; p++)
+ for( r=0; r<min_numOfres; r++){
+ seqID = comp_seqID( tileID, SIZ, COD, r, p);
+ j2kstream = recons_precinct( msgqueue, jpipstream, j2kstream, csn, tileID, SIZ, COD, max_reslev, c, r, seqID, j2klen);
+ }
+
+ return j2kstream;
+}
+
+int comp_numOfprcts( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int r)
+{
+ int ret;
+ Byte4_t XTsiz, YTsiz;
+
+ XTsiz = get_tile_XSiz( SIZ, (Byte4_t)tileID, COD.numOfdecomp-r);
+ YTsiz = get_tile_YSiz( SIZ, (Byte4_t)tileID, COD.numOfdecomp-r);
+
+ ret = (int)(ceil((double)XTsiz/(double)COD.XPsiz[r])*ceil((double)YTsiz/(double)COD.YPsiz[r]));
+ assert( ret >= 0 );
+ return ret;
+}
+
+Byte_t * add_padding( Byte8_t padding, Byte_t *j2kstream, Byte8_t *j2klen);
+
+Byte_t * recons_packet( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int *max_reslev,
+ int comp_idx, int res_idx, int prct_idx, int lay_idx, Byte8_t *j2klen)
+{
+ Byte8_t seqID, precID, binOffset;
+ message_param_t *ptr;
+ bool foundPrec;
+ int l;
+
+ seqID = comp_seqID( tileID, SIZ, COD, res_idx, prct_idx);
+ precID = comp_precinct_id( (int)tileID, comp_idx, (int)seqID, (int)SIZ.Csiz, (int)SIZ.XTnum*(int)SIZ.YTnum);
+
+ ptr = msgqueue->first;
+ binOffset = 0;
+ foundPrec = false;
+ l = 0;
+
+ while(( ptr = search_message( PRECINCT_MSG, precID, csn, ptr))!=NULL){
+ if( ptr->bin_offset == binOffset){
+ if( lay_idx == l){
+ j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+ foundPrec = true;
+ if( *max_reslev < res_idx)
+ *max_reslev = res_idx;
+
+ break;
+ }
+ binOffset += ptr->length;
+ l++;
+ }
+ ptr = ptr->next;
+ }
+ if( !foundPrec && COD.Scod & 0x01)
+ j2kstream = add_padding( 1, j2kstream, j2klen);
+
+ return j2kstream;
+}
+
+
+Byte_t * recons_precinct( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte_t *j2kstream, Byte8_t csn,
+ Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int *max_reslev,
+ int comp_idx, int res_idx, Byte8_t seqID, Byte8_t *j2klen)
+{
+ Byte8_t precID, binOffset;
+ message_param_t *ptr;
+ bool foundPrec;
+
+ precID = comp_precinct_id( (int)tileID, comp_idx, (int)seqID, (int)SIZ.Csiz, (int)SIZ.XTnum*(int)SIZ.YTnum);
+
+ ptr = msgqueue->first;
+ binOffset = 0;
+ foundPrec = false;
+
+ while(( ptr = search_message( PRECINCT_MSG, precID, csn, ptr))!=NULL){
+ if( ptr->bin_offset == binOffset){
+ j2kstream = add_msgstream( ptr, jpipstream, j2kstream, j2klen);
+
+ foundPrec = true;
+ binOffset += ptr->length;
+ if( *max_reslev < res_idx)
+ *max_reslev = res_idx;
+
+ if( ptr->last_byte)
+ break;
+ }
+ ptr = ptr->next;
+ }
+ if(!foundPrec && COD.Scod & 0x01)
+ j2kstream = add_padding( COD.numOflayers, j2kstream, j2klen);
+
+ return j2kstream;
+}
+
+Byte8_t comp_seqID( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD, int r, int p)
+{
+ Byte8_t seqID = 0;
+ int rr;
+ assert( p >= 0);
+ assert( r >= 0);
+
+ for( rr=0; rr<r; rr++)
+ seqID += (Byte8_t)comp_numOfprcts( tileID, SIZ, COD, rr);
+
+ seqID += (Byte8_t)p;
+
+ return seqID;
+}
+
+Byte8_t get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn, bool isJPPstream)
+{
+ Byte8_t last_tileID = 0;
+ message_param_t *msg;
+
+ msg = msgqueue->first;
+ while( msg){
+ if( isJPPstream){
+ if((msg->class_id == TILE_HEADER_MSG) && msg->csn == csn && last_tileID < msg->in_class_id)
+ last_tileID = msg->in_class_id;
+ }
+ else{
+ 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 == (Byte8_t)-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;
+}
+
+
+Byte_t * gene_msgstream( message_param_t *message, Byte_t *stream, Byte8_t *length);
+Byte_t * gene_emptytilestream( const Byte8_t 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 Byte8_t 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_padding( Byte8_t padding, Byte_t *j2kstream, Byte8_t *j2klen)
+{
+ Byte_t *buf;
+
+ buf = (Byte_t *)malloc(( *j2klen)+padding);
+
+ memcpy( buf, j2kstream, *j2klen);
+ memset( buf+(*j2klen), 0, padding);
+
+ *j2klen += padding;
+
+ 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 Byte8_t 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 = 1;
+ const Byte2_t SOD = 0x93ff;
+
+ *length = 14;
+ buf = (Byte_t *)malloc(*length);
+
+ Isot = (Byte2_t)((((Byte2_t)tileID) << 8) | ((((Byte2_t)tileID) & 0xf0) >> 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;
+}
+
+Byte_t * recons_j2kmainhead( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *j2klen)
+{
+ *j2klen = 0;
+ return add_mainhead_msgstream( msgqueue, jpipstream, NULL, csn, j2klen);
+}
diff --git a/src/lib/openjpip/jp2k_encoder.h b/src/lib/openjpip/jp2k_encoder.h
new file mode 100644
index 00000000..3945e2a0
--- /dev/null
+++ b/src/lib/openjpip/jp2k_encoder.h
@@ -0,0 +1,74 @@
+/*
+ * $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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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_ENCODER_H_
+# define JP2K_ENCODER_H_
+
+#include "byte_manager.h"
+#include "msgqueue_manager.h"
+
+/**
+ * reconstruct j2k codestream from message queue
+ *
+ * @param[in] msgqueue message queue pointer
+ * @param[in] jpipstream original jpt- jpp- stream
+ * @param[in] csn codestream number
+ * @param[in] fw reconstructing image frame width
+ * @param[in] fh reconstructing image frame height
+ * @param[out] j2klen pointer to the j2k codestream length
+ * @return generated reconstructed j2k codestream
+ */
+Byte_t * recons_j2k( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, int fw, int fh, Byte8_t *j2klen);
+
+
+/**
+ * reconstruct jp2 file codestream from message queue
+ *
+ * @param[in] msgqueue message queue pointer
+ * @param[in] jpipstream original jpt- jpp- 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 *jpipstream, Byte8_t csn, Byte8_t *jp2len);
+
+/**
+ * reconstruct j2k codestream of mainheader from message queue
+ *
+ * @param[in] msgqueue message queue pointer
+ * @param[in] jpipstream original jpt- jpp- stream
+ * @param[in] csn codestream number
+ * @param[out] j2klen pointer to the j2k codestream length
+ * @return generated reconstructed j2k codestream
+ */
+Byte_t * recons_j2kmainhead( msgqueue_param_t *msgqueue, Byte_t *jpipstream, Byte8_t csn, Byte8_t *j2klen);
+
+#endif /* !JP2K_ENCODER_H_ */
diff --git a/src/lib/openjpip/jpip_parser.c b/src/lib/openjpip/jpip_parser.c
new file mode 100644
index 00000000..663214e4
--- /dev/null
+++ b/src/lib/openjpip/jpip_parser.c
@@ -0,0 +1,460 @@
+/*
+ * $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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 <math.h>
+#include "jpip_parser.h"
+#include "channel_manager.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*/
+
+
+bool identify_target( query_param_t query_param, targetlist_param_t *targetlist, target_param_t **target)
+{
+ if( query_param.tid){
+ if( strcmp( query_param.tid, "0") != 0 ){
+ if( query_param.cid[0] != '\0'){
+ fprintf( FCGI_stdout, "Reason: Target can not be specified both through tid and cid\r\n");
+ fprintf( FCGI_stdout, "Status: 400\r\n");
+ return false;
+ }
+ if( ( *target = search_targetBytid( query_param.tid, targetlist)))
+ return true;
+ }
+ }
+
+ if( query_param.target)
+ if( !( *target = search_target( query_param.target, targetlist)))
+ if(!( *target = gene_target( targetlist, query_param.target)))
+ return false;
+
+ if( *target){
+ fprintf( FCGI_stdout, "JPIP-tid: %s\r\n", (*target)->tid);
+ return true;
+ }
+ else{
+ fprintf( FCGI_stdout, "Reason: target not found\r\n");
+ fprintf( FCGI_stdout, "Status: 400\r\n");
+ return false;
+ }
+}
+
+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,
+ auxtrans_param_t auxtrans,
+ target_param_t *target,
+ session_param_t **cursession,
+ channel_param_t **curchannel)
+{
+ cachemodel_param_t *cachemodel = NULL;
+
+ if( target){
+ if( !(*cursession))
+ *cursession = gene_session( sessionlist);
+ if( !( cachemodel = search_cachemodel( target, (*cursession)->cachemodellist)))
+ if( !(cachemodel = gene_cachemodel( (*cursession)->cachemodellist, target, query_param.return_type==JPPstream)))
+ return false;
+ }
+ else
+ if( *curchannel)
+ cachemodel = (*curchannel)->cachemodel;
+
+ *curchannel = gene_channel( query_param, auxtrans, cachemodel, (*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)
+{
+ char *cclose;
+ int i;
+
+ if( query_param.cclose[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 */
+
+ for( i=0, cclose=query_param.cclose; i<query_param.numOfcclose; i++, cclose += (strlen(cclose)+1)){
+
+ /* In case of the first entry of close cid */
+ if( *cursession == NULL){
+ if( !search_session_and_channel( cclose, sessionlist, cursession, curchannel))
+ return false;
+ }
+ else /* second or more entry of close cid */
+ if( !(*curchannel=search_channel( cclose, (*cursession)->channellist))){
+ fprintf( FCGI_stdout, "Reason: Cclose id %s is from another session\r\n", cclose);
+ return false;
+ }
+ }
+
+ /* delete channels */
+ for( i=0, cclose=query_param.cclose; i<query_param.numOfcclose; i++, cclose += (strlen(cclose)+1)){
+ *curchannel = search_channel( cclose, (*cursession)->channellist);
+ delete_channel( curchannel, (*cursession)->channellist);
+ }
+
+ if( (*cursession)->channellist->first == NULL || (*cursession)->channellist->last == NULL)
+ /* In case of empty session */
+ delete_session( cursession, sessionlist);
+ }
+ return true;
+}
+
+
+/**
+ * enqueue tiles or precincts into the message queue
+ *
+ * @param[in] query_param structured query
+ * @param[in] msgqueue message queue pointer
+ */
+void enqueue_imagedata( query_param_t query_param, 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
+ * @return if succeeded (true) or failed (false)
+ */
+bool enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue);
+
+
+bool gene_JPIPstream( query_param_t query_param,
+ target_param_t *target,
+ session_param_t *cursession,
+ channel_param_t *curchannel,
+ msgqueue_param_t **msgqueue)
+{
+ index_param_t *codeidx;
+ cachemodel_param_t *cachemodel;
+
+ if( !cursession || !curchannel){ /* stateless */
+ if( !target)
+ return false;
+ if( !(cachemodel = gene_cachemodel( NULL, target, query_param.return_type==JPPstream)))
+ return false;
+ *msgqueue = gene_msgqueue( true, cachemodel);
+ }
+ else{ /* session */
+ cachemodel = curchannel->cachemodel;
+ target = cachemodel->target;
+ *msgqueue = gene_msgqueue( false, cachemodel);
+ }
+
+ codeidx = target->codeidx;
+
+ if( cachemodel->jppstream)
+ fprintf( FCGI_stdout, "Content-type: image/jpp-stream\r\n");
+ else
+ fprintf( FCGI_stdout, "Content-type: image/jpt-stream\r\n");
+
+ if( query_param.layers != -1){
+ if( query_param.layers > codeidx->COD.numOflayers){
+ fprintf( FCGI_stdout, "JPIP-layers: %d\r\n", codeidx->COD.numOflayers);
+ query_param.layers = codeidx->COD.numOflayers;
+ }
+ }
+
+ /*meta*/
+ if( query_param.box_type[0][0] != 0 && query_param.len != 0)
+ if( !enqueue_metabins( query_param, codeidx->metadatalist, *msgqueue))
+ return false;
+
+ if( query_param.metadata_only)
+ return true;
+
+ /* main header */
+ if( !cachemodel->mhead_model && query_param.len != 0)
+ enqueue_mainheader( *msgqueue);
+
+ /* image codestream */
+ if( (query_param.fx > 0 && query_param.fy > 0))
+ enqueue_imagedata( query_param, *msgqueue);
+
+ return true;
+}
+
+
+/**
+ * enqueue precinct data-bins into the queue
+ *
+ * @param[in] xmin min x coordinate in the tile at the decomposition level
+ * @param[in] xmax max x coordinate in the tile at the decomposition level
+ * @param[in] ymin min y coordinate in the tile at the decomposition level
+ * @param[in] ymax max y coordinate in the tile at the decomposition level
+ * @param[in] tile_id tile index
+ * @param[in] level decomposition level
+ * @param[in] lastcomp last component number
+ * @param[in] comps pointer to the array that stores the requested components
+ * @param[in] layers number of quality layers
+ * @param[in] msgqueue message queue
+ * @return
+ */
+void enqueue_precincts( int xmin, int xmax, int ymin, int ymax, int tile_id, int level, int lastcomp, bool *comps, int layers, msgqueue_param_t *msgqueue);
+
+/**
+ * enqueue all precincts inside a tile into the queue
+ *
+ * @param[in] tile_id tile index
+ * @param[in] level decomposition level
+ * @param[in] lastcomp last component number
+ * @param[in] comps pointer to the array that stores the requested components
+ * @param[in] layers number of quality layers
+ * @param[in] msgqueue message queue
+ * @return
+ */
+void enqueue_allprecincts( int tile_id, int level, int lastcomp, bool *comps, int layers, msgqueue_param_t *msgqueue);
+
+void enqueue_imagedata( query_param_t query_param, msgqueue_param_t *msgqueue)
+{
+ index_param_t *codeidx;
+ imgreg_param_t imgreg;
+ range_param_t tile_Xrange, tile_Yrange;
+ Byte4_t u, v, tile_id;
+ int xmin, xmax, ymin, ymax;
+ int numOfreslev;
+
+ codeidx = msgqueue->cachemodel->target->codeidx;
+
+ if( !(msgqueue->cachemodel->jppstream) && get_nmax( codeidx->tilepart) == 1) /* normally not the case */
+ numOfreslev = 1;
+ else
+ numOfreslev = codeidx->COD.numOfdecomp+1;
+
+ imgreg = map_viewin2imgreg( query_param.fx, query_param.fy,
+ query_param.rx, query_param.ry, query_param.rw, query_param.rh,
+ (int)codeidx->SIZ.XOsiz, (int)codeidx->SIZ.YOsiz, (int)codeidx->SIZ.Xsiz, (int)codeidx->SIZ.Ysiz,
+ numOfreslev );
+
+ if( query_param.len == 0)
+ return;
+
+ for( u=0, tile_id=0; u<codeidx->SIZ.YTnum; u++){
+ tile_Yrange = get_tile_Yrange( codeidx->SIZ, tile_id, imgreg.level);
+
+ for( v=0; v<codeidx->SIZ.XTnum; v++, tile_id++){
+ tile_Xrange = get_tile_Xrange( codeidx->SIZ, tile_id, imgreg.level);
+
+ if( tile_Xrange.minvalue < tile_Xrange.maxvalue && tile_Yrange.minvalue < tile_Yrange.maxvalue){
+ if( tile_Xrange.maxvalue <= (Byte4_t)(imgreg.xosiz + imgreg.ox) ||
+ tile_Xrange.minvalue >= (Byte4_t)(imgreg.xosiz + imgreg.ox + imgreg.sx) ||
+ tile_Yrange.maxvalue <= (Byte4_t)(imgreg.yosiz + imgreg.oy) ||
+ tile_Yrange.minvalue >= (Byte4_t)(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 >= (Byte4_t)(imgreg.xosiz + imgreg.ox) &&
+ tile_Xrange.maxvalue <= (Byte4_t)(imgreg.xosiz + imgreg.ox + imgreg.sx) &&
+ tile_Yrange.minvalue >= (Byte4_t)(imgreg.yosiz + imgreg.oy) &&
+ tile_Yrange.maxvalue <= (Byte4_t)(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);*/
+ if( msgqueue->cachemodel->jppstream){
+ enqueue_tileheader( (int)tile_id, msgqueue);
+ enqueue_allprecincts( (int)tile_id, imgreg.level, query_param.lastcomp, query_param.comps, query_param.layers, msgqueue);
+ }
+ else
+ 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);*/
+ if( msgqueue->cachemodel->jppstream){
+ enqueue_tileheader( (int)tile_id, msgqueue);
+
+ /* FIXME: The following code is suspicious it implicitely cast an unsigned int to int, which truncates values */
+ xmin = tile_Xrange.minvalue >= (Byte4_t)(imgreg.xosiz + imgreg.ox) ? 0 : imgreg.xosiz + imgreg.ox - (int)tile_Xrange.minvalue;
+ xmax = tile_Xrange.maxvalue <= (Byte4_t)(imgreg.xosiz + imgreg.ox + imgreg.sx) ? (int)(tile_Xrange.maxvalue - tile_Xrange.minvalue -1) : (int)(imgreg.xosiz + imgreg.ox + imgreg.sx - (int)tile_Xrange.minvalue - 1);
+ ymin = tile_Yrange.minvalue >= (Byte4_t)(imgreg.yosiz + imgreg.oy) ? 0 : imgreg.yosiz + imgreg.oy - (int)tile_Yrange.minvalue;
+ ymax = tile_Yrange.maxvalue <= (Byte4_t)(imgreg.yosiz + imgreg.oy + imgreg.sy) ? (int)(tile_Yrange.maxvalue - tile_Yrange.minvalue - 1) : (int)(imgreg.yosiz + imgreg.oy + imgreg.sy - (int)tile_Yrange.minvalue - 1);
+ enqueue_precincts( xmin, xmax, ymin, ymax, (int)tile_id, imgreg.level, query_param.lastcomp, query_param.comps, query_param.layers, msgqueue);
+ }
+ else
+ enqueue_tile( tile_id, imgreg.level, msgqueue);
+ }
+ }
+ }
+ }
+}
+
+
+void enqueue_precincts( int xmin, int xmax, int ymin, int ymax, int tile_id, int level, int lastcomp, bool *comps, int layers, msgqueue_param_t *msgqueue)
+{
+ index_param_t *codeidx;
+ int c, u, v, res_lev, dec_lev;
+ int seq_id;
+ Byte4_t XTsiz, YTsiz;
+ Byte4_t XPsiz, YPsiz;
+ Byte4_t xminP, xmaxP, yminP, ymaxP;
+
+ codeidx = msgqueue->cachemodel->target->codeidx;
+ /* MM: shouldnt xmin/xmax be Byte4_t instead ? */
+ if( xmin < 0 || xmax < 0 || ymin < 0 || ymax < 0)
+ return;
+ /* MM: I think the API should not really be int should it ? */
+ if( tile_id < 0 )
+ return;
+
+ for( c=0; c<codeidx->SIZ.Csiz; c++)
+ if( lastcomp == -1 /*all*/ || ( c<=lastcomp && comps[c])){
+ seq_id = 0;
+ for( res_lev=0, dec_lev=codeidx->COD.numOfdecomp; dec_lev>=level; res_lev++, dec_lev--){
+
+ XTsiz = get_tile_XSiz( codeidx->SIZ, (Byte4_t)tile_id, dec_lev);
+ YTsiz = get_tile_YSiz( codeidx->SIZ, (Byte4_t)tile_id, dec_lev);
+
+ XPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.XPsiz[ res_lev] : XTsiz;
+ YPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.YPsiz[ res_lev] : YTsiz;
+
+ for( u=0; u<ceil((double)YTsiz/(double)YPsiz); u++){
+ yminP = (Byte4_t)u*YPsiz;
+ ymaxP = (Byte4_t)(u+1)*YPsiz-1;
+ if( YTsiz <= ymaxP)
+ ymaxP = YTsiz-1;
+
+ for( v=0; v<ceil((double)XTsiz/(double)XPsiz); v++, seq_id++){
+ xminP = (Byte4_t)v*XPsiz;
+ xmaxP = (Byte4_t)(v+1)*XPsiz-1;
+ if( XTsiz <= xmaxP)
+ xmaxP = XTsiz-1;
+
+ if( xmaxP < (Byte4_t)xmin || xminP > (Byte4_t)xmax || ymaxP < (Byte4_t)ymin || yminP > (Byte4_t)ymax){
+ /* Precinct completely excluded from view-window */
+ }
+ else if( xminP >= (Byte4_t)xmin && xmaxP <= (Byte4_t)xmax && yminP >= (Byte4_t)ymin && ymaxP <= (Byte4_t)ymax){
+ /* Precinct completely contained within view-window
+ high priority */
+ enqueue_precinct( seq_id, tile_id, c, (dec_lev>level)?-1:layers, msgqueue);
+ }
+ else{
+ /* Precinct partially overlaps view-window
+ low priority */
+ enqueue_precinct( seq_id, tile_id, c, (dec_lev>level)?-1:layers, msgqueue);
+ }
+ }
+ }
+ }
+ }
+}
+
+void enqueue_allprecincts( int tile_id, int level, int lastcomp, bool *comps, int layers, msgqueue_param_t *msgqueue)
+{
+ index_param_t *codeidx;
+ int c, i, res_lev, dec_lev;
+ int seq_id;
+ Byte4_t XTsiz, YTsiz;
+ Byte4_t XPsiz, YPsiz;
+
+ codeidx = msgqueue->cachemodel->target->codeidx;
+ if( tile_id < 0 )
+ return;
+
+ for( c=0; c<codeidx->SIZ.Csiz; c++)
+ if( lastcomp == -1 /*all*/ || ( c<=lastcomp && comps[c])){
+ seq_id = 0;
+ for( res_lev=0, dec_lev=codeidx->COD.numOfdecomp; dec_lev>=level; res_lev++, dec_lev--){
+
+ XTsiz = get_tile_XSiz( codeidx->SIZ, (Byte4_t)tile_id, dec_lev);
+ YTsiz = get_tile_YSiz( codeidx->SIZ, (Byte4_t)tile_id, dec_lev);
+
+ XPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.XPsiz[ res_lev] : XTsiz;
+ YPsiz = ( codeidx->COD.Scod & 0x01) ? codeidx->COD.YPsiz[ res_lev] : YTsiz;
+
+ for( i=0; i<ceil((double)YTsiz/(double)YPsiz)*ceil((double)XTsiz/(double)XPsiz); i++, seq_id++)
+ enqueue_precinct( seq_id, tile_id, c, (dec_lev>level)?-1:layers, msgqueue);
+ }
+ }
+}
+
+bool enqueue_metabins( query_param_t query_param, metadatalist_param_t *metadatalist, msgqueue_param_t *msgqueue)
+{
+ int i;
+ for( i=0; query_param.box_type[i][0]!=0 && i<MAX_NUMOFBOX; i++){
+ if( query_param.box_type[i][0] == '*'){
+ fprintf( FCGI_stdout, "Status: 501\r\n");
+ fprintf( FCGI_stdout, "Reason: metareq with all box-property * not implemented\r\n");
+ return false;
+ }
+ else{
+ Byte8_t idx = search_metadataidx( query_param.box_type[i], metadatalist);
+
+ if( idx != (Byte8_t)-1)
+ enqueue_metadata( idx, msgqueue);
+ else{
+ fprintf( FCGI_stdout, "Status: 400\r\n");
+ fprintf( FCGI_stdout, "Reason: box-type %.4s not found\r\n", query_param.box_type[i]);
+ return false;
+ }
+ }
+ }
+ return true;
+}
diff --git a/src/lib/openjpip/jpip_parser.h b/src/lib/openjpip/jpip_parser.h
new file mode 100644
index 00000000..8070c8a9
--- /dev/null
+++ b/src/lib/openjpip/jpip_parser.h
@@ -0,0 +1,114 @@
+/*
+ * $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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 JPIP_PARSER_H_
+# define JPIP_PARSER_H_
+
+#include "bool.h"
+#include "query_parser.h"
+#include "session_manager.h"
+#include "target_manager.h"
+#include "msgqueue_manager.h"
+#include "channel_manager.h"
+
+/**
+ * REQUEST: target identification by target or tid request
+ *
+ * @param[in] query_param structured query
+ * @param[in] targetlist target list pointer
+ * @param[out] target address of target pointer
+ * @return if succeeded (true) or failed (false)
+ */
+bool identify_target( query_param_t query_param, targetlist_param_t *targetlist, target_param_t **target);
+
+/**
+ * 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] auxtrans auxiliary transport
+ * @param[in] target requested target 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,
+ auxtrans_param_t auxtrans,
+ target_param_t *target,
+ 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] target requested target pointer
+ * @param[in,out] cursession associated session pointer
+ * @param[in,out] curchannel associated channel pointer
+ * @param[out] msgqueue address of the message queue pointer
+ * @return if succeeded (true) or failed (false)
+ */
+bool gene_JPIPstream( query_param_t query_param,
+ target_param_t *target,
+ session_param_t *cursession,
+ channel_param_t *curchannel,
+ msgqueue_param_t **msgqueue);
+
+#endif /* !JPIP_PARSER_H_ */
diff --git a/src/lib/openjpip/jpipstream_manager.c b/src/lib/openjpip/jpipstream_manager.c
new file mode 100644
index 00000000..8cb2a77f
--- /dev/null
+++ b/src/lib/openjpip/jpipstream_manager.c
@@ -0,0 +1,120 @@
+/*
+ * $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.
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#include "jpipstream_manager.h"
+#include "jp2k_encoder.h"
+#include "jp2k_decoder.h"
+#include "ihdrbox_manager.h"
+#include "j2kheader_manager.h"
+
+Byte_t * update_JPIPstream( Byte_t *newstream, OPJ_SIZE_T newstreamlen, Byte_t *cache_stream, OPJ_SIZE_T *streamlen)
+{
+ Byte_t *stream = (Byte_t *)malloc( (*streamlen)+newstreamlen);
+ if( *streamlen > 0)
+ memcpy( stream, cache_stream, *streamlen);
+ memcpy( stream+(*streamlen), newstream, newstreamlen);
+ *streamlen += newstreamlen;
+
+ if(cache_stream)
+ free( cache_stream);
+
+ return stream;
+}
+
+void save_codestream( Byte_t *codestream, OPJ_SIZE_T streamlen, const 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");
+ if( fwrite( codestream, streamlen, 1, fp) != 1)
+ fprintf( stderr, "Error: failed to write codestream to file %s\n", filename);
+ fclose( fp);
+}
+
+
+Byte_t * jpipstream_to_pnm( Byte_t *jpipstream, 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;
+ FILE *fp;
+ const char j2kfname[] = "tmp.j2k";
+
+ j2kstream = recons_j2k( msgqueue, jpipstream, csn, fw, fh, &j2klen);
+
+ fp = fopen( j2kfname, "w+b");
+ fwrite( j2kstream, j2klen, 1, fp);
+ free( j2kstream);
+ fseek( fp, 0, SEEK_SET);
+
+ pnmstream = j2k_to_pnm( fp, ihdrbox);
+
+ fclose( fp);
+ remove( j2kfname);
+
+ return pnmstream;
+}
+
+ihdrbox_param_t * get_SIZ_from_jpipstream( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte8_t csn)
+{
+ ihdrbox_param_t *ihdrbox;
+ Byte_t *j2kstream;
+ Byte8_t j2klen;
+ SIZmarker_param_t SIZ;
+
+ j2kstream = recons_j2kmainhead( msgqueue, jpipstream, csn, &j2klen);
+ if( !get_mainheader_from_j2kstream( j2kstream, &SIZ, NULL)){
+ free( j2kstream);
+ return NULL;
+ }
+
+ ihdrbox = (ihdrbox_param_t *)malloc( sizeof(ihdrbox_param_t));
+
+ ihdrbox->width = SIZ.Xsiz;
+ ihdrbox->height = SIZ.Ysiz;
+ ihdrbox->nc = SIZ.Csiz;
+ ihdrbox->bpc = SIZ.Ssiz[0];
+
+ free( j2kstream);
+
+ return ihdrbox;
+}
diff --git a/src/lib/openjpip/jpipstream_manager.h b/src/lib/openjpip/jpipstream_manager.h
new file mode 100644
index 00000000..5328be62
--- /dev/null
+++ b/src/lib/openjpip/jpipstream_manager.h
@@ -0,0 +1,41 @@
+/*
+ * $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.
+ */
+
+#include "byte_manager.h"
+#include "msgqueue_manager.h"
+#include "ihdrbox_manager.h"
+
+Byte_t * update_JPIPstream( Byte_t *newstream, OPJ_SIZE_T newstreamlen, Byte_t *cache_stream, OPJ_SIZE_T *streamlen);
+
+void save_codestream( Byte_t *codestream, OPJ_SIZE_T streamlen, const char *fmt);
+
+Byte_t * jpipstream_to_pnm( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte8_t csn, int fw, int fh, ihdrbox_param_t **ihdrbox);
+
+ihdrbox_param_t * get_SIZ_from_jpipstream( Byte_t *jpipstream, msgqueue_param_t *msgqueue, Byte8_t csn);
diff --git a/src/lib/openjpip/manfbox_manager.c b/src/lib/openjpip/manfbox_manager.c
new file mode 100644
index 00000000..37472461
--- /dev/null
+++ b/src/lib/openjpip/manfbox_manager.c
@@ -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 */
+ OPJ_OFF_T pos; /* current position in manf_box contents; */
+
+ manf = ( manfbox_param_t *)malloc( sizeof( manfbox_param_t));
+
+ pos = 0;
+ manf->first = last = NULL;
+
+ while( (OPJ_SIZE_T)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( const 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;
+}
diff --git a/src/lib/openjpip/manfbox_manager.h b/src/lib/openjpip/manfbox_manager.h
new file mode 100644
index 00000000..ed4189e0
--- /dev/null
+++ b/src/lib/openjpip/manfbox_manager.h
@@ -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( const char type[], manfbox_param_t *manf);
+
+
+#endif /* !MANFBOX_MANAGER_H_ */
diff --git a/src/lib/openjpip/marker_manager.c b/src/lib/openjpip/marker_manager.c
new file mode 100644
index 00000000..766ecd6e
--- /dev/null
+++ b/src/lib/openjpip/marker_manager.c
@@ -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, OPJ_OFF_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, OPJ_OFF_T offset)
+{
+ return fetch_codestream1byte( &(marker.cs), marker.offset+offset);
+}
+
+Byte2_t fetch_marker2bytebigendian( marker_param_t marker, OPJ_OFF_T offset)
+{
+ return fetch_codestream2bytebigendian( &(marker.cs), marker.offset+offset);
+}
+
+Byte4_t fetch_marker4bytebigendian( marker_param_t marker, OPJ_OFF_T offset)
+{
+ return fetch_codestream4bytebigendian( &(marker.cs), marker.offset+offset);
+}
diff --git a/src/lib/openjpip/marker_manager.h b/src/lib/openjpip/marker_manager.h
new file mode 100644
index 00000000..68ea2a8b
--- /dev/null
+++ b/src/lib/openjpip/marker_manager.h
@@ -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*/
+ OPJ_OFF_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, OPJ_OFF_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, OPJ_OFF_T 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, OPJ_OFF_T 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, OPJ_OFF_T offset);
+
+
+#endif /* !MARKER_MANAGER_H_ */
diff --git a/src/lib/openjpip/metadata_manager.c b/src/lib/openjpip/metadata_manager.c
new file mode 100644
index 00000000..12b61efc
--- /dev/null
+++ b/src/lib/openjpip/metadata_manager.c
@@ -0,0 +1,253 @@
+/*
+ * $Id: metadata_manager.c 53 2011-05-09 16:55:39Z 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 "metadata_manager.h"
+#include "opj_inttypes.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits.h>
+#include <assert.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(void)
+{
+ 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;
+ Byte8_t idx;
+ Byte8_t filesize;
+
+ if(!(filesize = (Byte8_t)get_filesize( fd)))
+ return NULL;
+
+ if( !(toplev_boxlist = get_boxstructure( fd, 0, filesize))){
+ fprintf( FCGI_stderr, "Error: Not correctl JP2 format\n");
+ return NULL;
+ }
+
+ phldlist = gene_placeholderlist();
+ metadatalist = gene_metadatalist();
+
+ 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( Byte8_t 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)
+{
+ boxcontents_param_t *boxcont;
+ fprintf( logstream, "metadata-bin %" PRIu64 " info:\n", metadata->idx);
+ print_allbox( metadata->boxlist);
+ print_allplaceholder( metadata->placeholderlist);
+
+ boxcont = metadata->boxcontents;
+ if( boxcont)
+ fprintf( logstream, "box contents:\n"
+ "\t offset: %" PRId64 " %#" PRIx64 "\n"
+ "\t length: %" PRId64 " %#" PRIx64 "\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( OPJ_OFF_T offset, OPJ_SIZE_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( Byte8_t 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;
+}
+
+Byte8_t search_metadataidx( char boxtype[4], metadatalist_param_t *list)
+{
+ /* MM FIXME: what is the return type of this function ?
+ Byte8_t or int ? */
+ metadata_param_t *ptr;
+ int i;
+
+ for( 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 (Byte8_t)-1;
+}
diff --git a/src/lib/openjpip/metadata_manager.h b/src/lib/openjpip/metadata_manager.h
new file mode 100644
index 00000000..089b19a5
--- /dev/null
+++ b/src/lib/openjpip/metadata_manager.h
@@ -0,0 +1,151 @@
+/*
+ * $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{
+ OPJ_OFF_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{
+ Byte8_t 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(void);
+
+
+/**
+ * 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( Byte8_t 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( OPJ_OFF_T offset, OPJ_SIZE_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( Byte8_t 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
+ */
+Byte8_t 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_ */
diff --git a/src/lib/openjpip/mhixbox_manager.c b/src/lib/openjpip/mhixbox_manager.c
new file mode 100644
index 00000000..b311126b
--- /dev/null
+++ b/src/lib/openjpip/mhixbox_manager.c
@@ -0,0 +1,141 @@
+/*
+ * $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"
+#include "opj_inttypes.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER */
+
+
+mhixbox_param_t * gene_mhixbox( box_param_t *box)
+{
+ mhixbox_param_t *mhix;
+ markeridx_param_t *mkridx, *lastmkidx;
+ OPJ_OFF_T pos = 0;
+
+ mhix = ( mhixbox_param_t *)malloc( sizeof( mhixbox_param_t));
+
+ mhix->tlen = fetch_DBox8bytebigendian( box, (pos+=8)-8);
+
+ mhix->first = lastmkidx = NULL;
+ while( (OPJ_SIZE_T)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 = (OPJ_OFF_T)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: %#" PRIx64 "\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: %#" PRIx64 "\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: %#" PRIx64 "\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);
+}
+
+
diff --git a/src/lib/openjpip/mhixbox_manager.h b/src/lib/openjpip/mhixbox_manager.h
new file mode 100644
index 00000000..5905b25f
--- /dev/null
+++ b/src/lib/openjpip/mhixbox_manager.h
@@ -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*/
+ OPJ_OFF_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_ */
diff --git a/src/lib/openjpip/msgqueue_manager.c b/src/lib/openjpip/msgqueue_manager.c
new file mode 100644
index 00000000..29b64a26
--- /dev/null
+++ b/src/lib/openjpip/msgqueue_manager.c
@@ -0,0 +1,762 @@
+/*
+ * $Id: msgqueue_manager.c 53 2011-05-09 16:55:39Z 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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 <sys/types.h>
+#include <sys/stat.h>
+#include <string.h>
+#include <ctype.h>
+#include <assert.h>
+#include <limits.h>
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include "msgqueue_manager.h"
+#include "metadata_manager.h"
+#include "index_manager.h"
+#include "opj_inttypes.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER*/
+
+msgqueue_param_t * gene_msgqueue( bool stateless, cachemodel_param_t *cachemodel)
+{
+ msgqueue_param_t *msgqueue;
+
+ msgqueue = (msgqueue_param_t *)malloc( sizeof(msgqueue_param_t));
+
+ msgqueue->first = NULL;
+ msgqueue->last = NULL;
+
+ msgqueue->stateless = stateless;
+ msgqueue->cachemodel = cachemodel;
+
+ 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)->cachemodel)
+ delete_cachemodel( &((*msgqueue)->cachemodel));
+
+ free(*msgqueue);
+}
+
+void print_msgqueue( msgqueue_param_t *msgqueue)
+{
+ message_param_t *ptr;
+ static const char *message_class[] = { "Precinct", "Ext-Prec", "TileHead", "non",
+ "Tile", "Ext-Tile", "Main", "non", "Meta"};
+
+ if( !msgqueue)
+ return;
+
+ fprintf( logstream, "message queue:\n");
+ ptr = msgqueue->first;
+
+ while( ptr){
+ fprintf( logstream, "\t class_id: %" PRId64 " %s\n", ptr->class_id, message_class[ptr->class_id]);
+ fprintf( logstream, "\t in_class_id: %" PRId64 "\n", ptr->in_class_id );
+ fprintf( logstream, "\t csn: %" PRId64 "\n", ptr->csn );
+ fprintf( logstream, "\t bin_offset: %#" PRIx64 "\n", ptr->bin_offset );
+ fprintf( logstream, "\t length: %#" PRIx64 "\n", ptr->length );
+ if( ptr->class_id%2)
+ fprintf( logstream, "\t aux: %" PRId64 "\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: %#" PRIx64 "\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)
+{
+ cachemodel_param_t *cachemodel;
+ target_param_t *target;
+ index_param_t *codeidx;
+ message_param_t *msg;
+
+ cachemodel = msgqueue->cachemodel;
+ target = cachemodel->target;
+ codeidx = target->codeidx;
+
+ msg = (message_param_t *)malloc( sizeof(message_param_t));
+
+ msg->last_byte = true;
+ msg->in_class_id = 0;
+ msg->class_id = MAINHEADER_MSG;
+ assert( target->csn >= 0 );
+ msg->csn = (Byte8_t)target->csn;
+ msg->bin_offset = 0;
+ msg->length = codeidx->mhead_length;
+ msg->aux = 0; /* non exist*/
+ msg->res_offset = codeidx->offset;
+ msg->phld = NULL;
+ msg->next = NULL;
+
+ enqueue_message( msg, msgqueue);
+
+ cachemodel->mhead_model = true;
+}
+
+void enqueue_tileheader( int tile_id, msgqueue_param_t *msgqueue)
+{
+ cachemodel_param_t *cachemodel;
+ target_param_t *target;
+ index_param_t *codeidx;
+ message_param_t *msg;
+
+ cachemodel = msgqueue->cachemodel;
+ target = cachemodel->target;
+ codeidx = target->codeidx;
+
+ if( !cachemodel->th_model[ tile_id]){
+ msg = (message_param_t *)malloc( sizeof(message_param_t));
+ msg->last_byte = true;
+ assert( tile_id >= 0 );
+ msg->in_class_id = (Byte8_t)tile_id;
+ msg->class_id = TILE_HEADER_MSG;
+ assert( target->csn >= 0 );
+ msg->csn = (Byte8_t)target->csn;
+ msg->bin_offset = 0;
+ msg->length = codeidx->tileheader[tile_id]->tlen-2; /* SOT marker segment is removed*/
+ msg->aux = 0; /* non exist*/
+ msg->res_offset = codeidx->offset + (OPJ_OFF_T)get_elemOff(codeidx->tilepart, 0, (Byte8_t)tile_id) + 2; /* skip SOT marker seg*/
+ msg->phld = NULL;
+ msg->next = NULL;
+
+ enqueue_message( msg, msgqueue);
+ cachemodel->th_model[ tile_id] = true;
+ }
+}
+
+void enqueue_tile( Byte4_t tile_id, int level, msgqueue_param_t *msgqueue)
+{
+ cachemodel_param_t *cachemodel;
+ 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, class_id;
+ Byte8_t i;
+
+ cachemodel = msgqueue->cachemodel;
+ target = cachemodel->target;
+ codeidx = target->codeidx;
+ tilepart = codeidx->tilepart;
+
+ numOftparts = get_nmax( tilepart);
+ numOftiles = get_m( tilepart);
+
+ class_id = (numOftparts==1) ? TILE_MSG : EXT_TILE_MSG;
+
+ if( /*tile_id < 0 ||*/ numOftiles <= (Byte8_t)tile_id){
+ fprintf( FCGI_stderr, "Error, Invalid tile-id %d\n", tile_id);
+ return;
+ }
+
+ tp_model = &cachemodel->tp_model[ tile_id*numOftparts];
+
+ binOffset=0;
+ for( i=0; i<numOftparts-(Byte8_t)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);
+ msg->in_class_id = tile_id;
+ msg->class_id = class_id;
+ assert( target->csn >= 0 );
+ msg->csn = (Byte8_t)target->csn;
+ msg->bin_offset = binOffset;
+ msg->length = binLength;
+ msg->aux = numOftparts-i;
+ msg->res_offset = codeidx->offset+(OPJ_OFF_T)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_precinct( int seq_id, int tile_id, int comp_id, int layers, msgqueue_param_t *msgqueue)
+{
+ cachemodel_param_t *cachemodel;
+ index_param_t *codeidx;
+ faixbox_param_t *precpacket;
+ message_param_t *msg;
+ Byte8_t nmax, binOffset, binLength;
+ int layer_id, numOflayers;
+
+ cachemodel = msgqueue->cachemodel;
+ codeidx = cachemodel->target->codeidx;
+ precpacket = codeidx->precpacket[ comp_id];
+ numOflayers = codeidx->COD.numOflayers;
+
+ nmax = get_nmax(precpacket);
+ assert( nmax < INT_MAX );
+ if( layers < 0)
+ layers = numOflayers;
+ assert( tile_id >= 0 );
+
+ binOffset = 0;
+ for( layer_id = 0; layer_id < layers; layer_id++){
+
+ binLength = get_elemLen( precpacket, (Byte8_t)(seq_id*numOflayers+layer_id), (Byte8_t)tile_id);
+
+ if( !cachemodel->pp_model[comp_id][tile_id*(int)nmax+seq_id*numOflayers+layer_id]){
+
+ msg = (message_param_t *)malloc( sizeof(message_param_t));
+ msg->last_byte = (layer_id == (numOflayers-1));
+ msg->in_class_id = comp_precinct_id( tile_id, comp_id, seq_id, codeidx->SIZ.Csiz, (int)codeidx->SIZ.XTnum * (int) codeidx->SIZ.YTnum);
+ msg->class_id = PRECINCT_MSG;
+ msg->csn = (Byte8_t)cachemodel->target->csn;
+ msg->bin_offset = binOffset;
+ msg->length = binLength;
+ msg->aux = 0;
+ msg->res_offset = codeidx->offset+(OPJ_OFF_T)get_elemOff( precpacket, (Byte8_t)(seq_id*numOflayers+layer_id), (Byte8_t)tile_id);
+ msg->phld = NULL;
+ msg->next = NULL;
+
+ enqueue_message( msg, msgqueue);
+
+ cachemodel->pp_model[comp_id][tile_id*(int)nmax+seq_id*numOflayers+layer_id] = true;
+ }
+ binOffset += binLength;
+ }
+}
+
+/* MM FIXME: each params is coded on int, this is really not clear from the specs what it should be */
+Byte8_t comp_precinct_id( int t, int c, int s, int num_components, int num_tiles)
+{
+ return (Byte8_t)(t + (c + s * num_components ) * num_tiles);
+}
+
+void enqueue_box( Byte8_t meta_id, boxlist_param_t *boxlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
+void enqueue_phld( Byte8_t meta_id, placeholderlist_param_t *phldlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
+void enqueue_boxcontents( Byte8_t meta_id, boxcontents_param_t *boxcontents, msgqueue_param_t *msgqueue, Byte8_t *binOffset);
+
+void enqueue_metadata( Byte8_t meta_id, msgqueue_param_t *msgqueue)
+{
+ metadatalist_param_t *metadatalist;
+ metadata_param_t *metadata;
+ Byte8_t binOffset;
+
+ metadatalist = msgqueue->cachemodel->target->codeidx->metadatalist;
+ metadata = search_metadata( meta_id, metadatalist);
+
+ if( !metadata){
+ fprintf( FCGI_stderr, "Error: metadata-bin %" PRIu64 " 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( Byte8_t meta_id, Byte8_t binoffset, Byte8_t length, OPJ_OFF_T res_offset, placeholder_param_t *phld, Byte8_t csn);
+
+void enqueue_box( Byte8_t meta_id, boxlist_param_t *boxlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset)
+{
+ box_param_t *box;
+ message_param_t *msg;
+
+ box = boxlist->first;
+ assert( msgqueue->cachemodel->target->csn >= 0);
+ while( box){
+ msg = gene_metamsg( meta_id, *binOffset, box->length, box->offset, NULL, (Byte8_t)msgqueue->cachemodel->target->csn);
+ enqueue_message( msg, msgqueue);
+
+ *binOffset += box->length;
+ box = box->next;
+ }
+}
+
+void enqueue_phld( Byte8_t meta_id, placeholderlist_param_t *phldlist, msgqueue_param_t *msgqueue, Byte8_t *binOffset)
+{
+ placeholder_param_t *phld;
+ message_param_t *msg;
+
+ phld = phldlist->first;
+ assert( msgqueue->cachemodel->target->csn >= 0);
+ while( phld){
+ msg = gene_metamsg( meta_id, *binOffset, phld->LBox, 0, phld, (Byte8_t)msgqueue->cachemodel->target->csn);
+ enqueue_message( msg, msgqueue);
+
+ *binOffset += phld->LBox;
+ phld = phld->next;
+ }
+}
+
+void enqueue_boxcontents( Byte8_t meta_id, boxcontents_param_t *boxcontents, msgqueue_param_t *msgqueue, Byte8_t *binOffset)
+{
+ message_param_t *msg;
+
+ assert(msgqueue->cachemodel->target->csn >= 0);
+ msg = gene_metamsg( meta_id, *binOffset, boxcontents->length,
+ boxcontents->offset, NULL, (Byte8_t)msgqueue->cachemodel->target->csn);
+ enqueue_message( msg, msgqueue);
+
+ *binOffset += boxcontents->length;
+}
+
+message_param_t * gene_metamsg( Byte8_t meta_id, Byte8_t binOffset, Byte8_t length, OPJ_OFF_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 add_bin_id_vbas_stream( Byte_t bb, Byte_t c, Byte8_t in_class_id, int tmpfd);
+void add_vbas_stream( Byte8_t code, int tmpfd);
+void add_body_stream( message_param_t *msg, int fd, int tmpfd);
+void add_placeholder_stream( placeholder_param_t *phld, int tmpfd);
+
+void recons_stream_from_msgqueue( msgqueue_param_t *msgqueue, int tmpfd)
+{
+ message_param_t *msg;
+ Byte8_t class_id, csn;
+ Byte_t bb, c;
+
+ if( !(msgqueue))
+ return;
+
+ msg = msgqueue->first;
+ class_id = (Byte8_t)-1;
+ csn = (Byte8_t)-1;
+ 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;
+
+ add_bin_id_vbas_stream( bb, c, msg->in_class_id, tmpfd);
+
+ if( bb >= 2)
+ add_vbas_stream( class_id, tmpfd);
+ if (bb == 3)
+ add_vbas_stream( csn, tmpfd);
+
+ add_vbas_stream( msg->bin_offset, tmpfd);
+ add_vbas_stream (msg->length, tmpfd);
+
+ if( msg->class_id%2) /* Aux is present only if the id is odd*/
+ add_vbas_stream( msg->aux, tmpfd);
+
+ if( msg->phld)
+ add_placeholder_stream( msg->phld, tmpfd);
+ else
+ add_body_stream( msg, msgqueue->cachemodel->target->fd, tmpfd);
+
+ msg = msg->next;
+ }
+}
+
+void add_vbas_with_bytelen_stream( Byte8_t code, int bytelength, int tmpfd);
+void print_binarycode( Byte8_t n, int segmentlen);
+
+void add_bin_id_vbas_stream( Byte_t bb, Byte_t c, Byte8_t in_class_id, int tmpfd)
+{
+ 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 |= (Byte8_t)((((bb & 3) << 5) | (c & 1) << 4) << ((bytelength-1)*7));
+
+ add_vbas_with_bytelen_stream( in_class_id, bytelength, tmpfd);
+}
+
+void add_vbas_stream( Byte8_t code, int tmpfd)
+{
+ int bytelength;
+ Byte8_t tmp;
+
+ bytelength = 1;
+ tmp = code;
+ while( tmp >>= 7)
+ bytelength ++;
+
+ add_vbas_with_bytelen_stream( code, bytelength, tmpfd);
+}
+
+void add_vbas_with_bytelen_stream( Byte8_t code, int bytelength, int tmpfd)
+{
+ int n;
+ Byte8_t seg;
+
+ n = bytelength - 1;
+ while( n >= 0) {
+ seg = ( code >> (n*7)) & 0x7f;
+ if( n)
+ seg |= 0x80;
+ if( write( tmpfd, ( Byte4_t *)&seg, 1) != 1){
+ fprintf( FCGI_stderr, "Error: failed to write vbas\n");
+ return;
+ }
+ n--;
+ }
+}
+
+void add_body_stream( message_param_t *msg, int fd, int tmpfd)
+{
+ Byte_t *data;
+
+ if( !(data = fetch_bytes( fd, msg->res_offset, msg->length))){
+ fprintf( FCGI_stderr, "Error: fetch_bytes in add_body_stream()\n");
+ return;
+ }
+
+ if( write( tmpfd, data, msg->length) < 1){
+ free( data);
+ fprintf( FCGI_stderr, "Error: fwrite in add_body_stream()\n");
+ return;
+ }
+ free(data);
+}
+
+void add_bigendian_bytestream( Byte8_t code, int bytelength, int tmpfd);
+
+void add_placeholder_stream( placeholder_param_t *phld, int tmpfd)
+{
+ add_bigendian_bytestream( phld->LBox, 4, tmpfd);
+ if( write( tmpfd, phld->TBox, 4) < 1){
+ fprintf( FCGI_stderr, "Error: fwrite in add_placeholder_stream()\n");
+ return;
+ }
+ add_bigendian_bytestream( phld->Flags, 4, tmpfd);
+ add_bigendian_bytestream( phld->OrigID, 8, tmpfd);
+
+ if( write( tmpfd, phld->OrigBH, phld->OrigBHlen) < 1){
+ fprintf( FCGI_stderr, "Error: fwrite in add_placeholder_stream()\n");
+ return;
+ }
+}
+
+void add_bigendian_bytestream( Byte8_t code, int bytelength, int tmpfd)
+{
+ int n;
+ Byte8_t seg;
+
+ n = bytelength - 1;
+ while( n >= 0) {
+ seg = ( code >> (n*8)) & 0xff;
+ if( write( tmpfd, ( Byte4_t *)&seg, 1) != 1){
+ fprintf( FCGI_stderr, "ERROR: failed to write bigendian_bytestream\n");
+ return;
+ }
+ n--;
+ }
+}
+
+void print_binarycode( Byte8_t n, int segmentlen)
+{
+ char buf[256];
+ int i=0, j, k;
+
+ do{
+ buf[i++] = n%2 ? '1' : '0';
+ }while((n=n/2));
+
+ for( j=segmentlen-1; j>=i; j--)
+ putchar('0');
+
+ for( 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_JPIPstream( Byte_t *JPIPstream, Byte8_t streamlen, OPJ_OFF_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 = (Byte8_t)-1; /* dummy*/
+ csn = (Byte8_t)-1;
+ ptr = JPIPstream;
+ while( (Byte8_t)(ptr-JPIPstream) < streamlen){
+ 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);
+
+ 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-JPIPstream+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 streamlen, metadatalist_param_t *metadatalist)
+{
+ message_param_t *msg;
+ (void)streamlen;
+
+ 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)
+{
+ box_param_t *box;
+ placeholder_param_t *phld;
+ char *boxtype = (char *)(datastream+4);
+
+ msg->phld = NULL;
+
+ if( strncmp( boxtype, "phld", 4) == 0){
+ if( !metadata->placeholderlist)
+ metadata->placeholderlist = gene_placeholderlist();
+
+ 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])||isspace(boxtype[2])) &&
+ (isalpha(boxtype[3])||isspace(boxtype[3]))){
+ if( !metadata->boxlist)
+ metadata->boxlist = gene_boxlist();
+
+ 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 = (Byte_t)(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;
+}
+
+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);
+}
diff --git a/src/lib/openjpip/msgqueue_manager.h b/src/lib/openjpip/msgqueue_manager.h
new file mode 100644
index 00000000..e54f2dc1
--- /dev/null
+++ b/src/lib/openjpip/msgqueue_manager.h
@@ -0,0 +1,188 @@
+/*
+ * $Id: msgqueue_manager.h 53 2011-05-09 16:55:39Z 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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 "bool.h"
+#include "byte_manager.h"
+#include "cachemodel_manager.h"
+#include "placeholder_manager.h"
+
+#define PRECINCT_MSG 0
+#define EXT_PRECINCT_MSG 1
+#define TILE_HEADER_MSG 2
+#define TILE_MSG 4
+#define EXT_TILE_MSG 5
+#define MAINHEADER_MSG 6
+#define METADATA_MSG 8
+
+/** 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; /**<*/
+ OPJ_OFF_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*/
+ cachemodel_param_t *cachemodel; /**< reference cachemodel pointer*/
+} msgqueue_param_t;
+
+/**
+ * generate message queue
+ *
+ * @param[in] stateless if this is a stateless message queue
+ * @param[in] cachemodel cachemodel pointer
+ * @return generated message queue pointer
+ */
+msgqueue_param_t * gene_msgqueue( bool stateless, cachemodel_param_t *cachemodel);
+
+/**
+ * delete message queue
+ *
+ * @param[in] msgqueue address of the message queue pointer
+ */
+void delete_msgqueue( msgqueue_param_t **msgqueue);
+
+/**
+ * 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);
+
+/**
+ * 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 headers data-bin into message queue
+ *
+ * @param[in] tile_id tile id starting from 0
+ * @param[in,out] msgqueue message queue pointer
+ */
+void enqueue_tileheader( int tile_id, 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( Byte4_t tile_id, int level, msgqueue_param_t *msgqueue);
+
+/**
+ * enqueue precinct data-bin into message queue
+ *
+ * @param[in] seq_id precinct sequence number within its tile
+ * @param[in] tile_id tile index
+ * @param[in] comp_id component number
+ * @param[in] layers num of layers
+ * @param[in,out] msgqueue message queue
+ */
+void enqueue_precinct( int seq_id, int tile_id, int comp_id, int layers, 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( Byte8_t meta_id, msgqueue_param_t *msgqueue);
+
+
+/**
+ * reconstruct JPT/JPP-stream from message queue
+ *
+ * @param[in] msgqueue message queue pointer
+ * @param[in] tmpfd file discriptor to write JPT/JPP-stream
+ */
+void recons_stream_from_msgqueue( msgqueue_param_t *msgqueue, int tmpfd);
+
+
+/**
+ * parse JPT- JPP- stream to message queue
+ *
+ * @param[in] JPIPstream JPT- JPP- stream data pointer
+ * @param[in] streamlen JPIPstream length
+ * @param[in] offset offset of the stream from the whole beginning
+ * @param[in,out] msgqueue adding message queue pointer
+ */
+void parse_JPIPstream( Byte_t *JPIPstream, Byte8_t streamlen, OPJ_OFF_T offset, msgqueue_param_t *msgqueue);
+
+/**
+ * parse JPT- JPP- stream to message queue
+ *
+ * @param[in] msgqueue reference message queue pointer
+ * @param[in] stream stream data pointer
+ * @param[in] streamlen stream length
+ * @param[in] metadatalist adding metadata list pointer
+ */
+void parse_metamsg( msgqueue_param_t *msgqueue, Byte_t *stream, Byte8_t streamlen, metadatalist_param_t *metadatalist);
+
+/**
+ * compute precinct ID A.3.2.1
+ *
+ * @param[in] t tile index
+ * @param[in] c component index
+ * @param[in] s sequence number
+ * @param[in] num_components total number of components
+ * @param[in] num_tiles total number of tiles
+ * @return precicnt id
+ */
+Byte8_t comp_precinct_id( int t, int c, int s, int num_components, int num_tiles);
+
+#endif /* !MSGQUEUE_MANAGER_H_ */
diff --git a/src/lib/openjpip/openjpip.c b/src/lib/openjpip/openjpip.c
new file mode 100644
index 00000000..de6293d4
--- /dev/null
+++ b/src/lib/openjpip/openjpip.c
@@ -0,0 +1,450 @@
+/*
+ * $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.
+ */
+
+#include <stdlib.h>
+#include "openjpip.h"
+#include "jpip_parser.h"
+#include "channel_manager.h"
+#include "byte_manager.h"
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+
+#ifdef SERVER
+#include "auxtrans_manager.h"
+#endif
+
+#include <stdio.h>
+#include "dec_clientmsg_handler.h"
+#include "jpipstream_manager.h"
+
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include "jp2k_encoder.h"
+
+#ifdef SERVER
+
+server_record_t * init_JPIPserver( int tcp_auxport, int udp_auxport)
+{
+ server_record_t *record = (server_record_t *)malloc( sizeof(server_record_t));
+
+ record->sessionlist = gene_sessionlist();
+ record->targetlist = gene_targetlist();
+ record->auxtrans = init_aux_transport( tcp_auxport, udp_auxport);
+
+ return record;
+}
+
+void terminate_JPIPserver( server_record_t **rec)
+{
+ delete_sessionlist( &(*rec)->sessionlist);
+ delete_targetlist( &(*rec)->targetlist);
+ close_aux_transport( (*rec)->auxtrans);
+
+ free( *rec);
+}
+
+QR_t * parse_querystring( const char *query_string)
+{
+ QR_t *qr;
+
+ qr = (QR_t *)malloc( sizeof(QR_t));
+
+ qr->query = parse_query( query_string);
+ qr->msgqueue = NULL;
+ qr->channel = NULL;
+
+ return qr;
+}
+
+bool process_JPIPrequest( server_record_t *rec, QR_t *qr)
+{
+ target_param_t *target = NULL;
+ session_param_t *cursession = NULL;
+ channel_param_t *curchannel = NULL;
+
+ if( qr->query->target || qr->query->tid){
+ if( !identify_target( *(qr->query), rec->targetlist, &target))
+ return false;
+ }
+
+ if( qr->query->cid){
+ if( !associate_channel( *(qr->query), rec->sessionlist, &cursession, &curchannel))
+ return false;
+ qr->channel = curchannel;
+ }
+
+ if( qr->query->cnew != non){
+ if( !open_channel( *(qr->query), rec->sessionlist, rec->auxtrans, target, &cursession, &curchannel))
+ return false;
+ qr->channel = curchannel;
+ }
+
+ if( qr->query->cclose)
+ if( !close_channel( *(qr->query), rec->sessionlist, &cursession, &curchannel))
+ return false;
+
+ if( (qr->query->fx > 0 && qr->query->fy > 0) || qr->query->box_type[0][0] != 0 || qr->query->len > 0)
+ if( !gene_JPIPstream( *(qr->query), target, cursession, curchannel, &qr->msgqueue))
+ return false;
+
+ return true;
+}
+
+void add_EORmsg( int fd, QR_t *qr);
+
+void send_responsedata( server_record_t *rec, QR_t *qr)
+{
+ int fd;
+ const char tmpfname[] = "tmpjpipstream.jpp";
+ Byte_t *jpipstream;
+ Byte8_t len_of_jpipstream;
+
+ if( (fd = open( tmpfname, O_RDWR|O_CREAT|O_EXCL, S_IRWXU)) == -1){
+ fprintf( FCGI_stderr, "file open error %s", tmpfname);
+ fprintf( FCGI_stdout, "Status: 503\r\n");
+ fprintf( FCGI_stdout, "Reason: Implementation failed\r\n");
+ return;
+ }
+
+ recons_stream_from_msgqueue( qr->msgqueue, fd);
+
+ add_EORmsg( fd, qr); /* needed at least for tcp and udp */
+
+ len_of_jpipstream = (Byte8_t)get_filesize( fd);
+ jpipstream = fetch_bytes( fd, 0, len_of_jpipstream);
+
+ close( fd);
+ remove( tmpfname);
+
+ fprintf( FCGI_stdout, "\r\n");
+
+ if( len_of_jpipstream){
+
+ if( qr->channel)
+ if( qr->channel->aux == tcp || qr->channel->aux == udp){
+ send_responsedata_on_aux( qr->channel->aux==tcp, rec->auxtrans, qr->channel->cid, jpipstream, len_of_jpipstream, 1000); /* 1KB per frame*/
+ return;
+ }
+
+ if( fwrite( jpipstream, len_of_jpipstream, 1, FCGI_stdout) != 1)
+ fprintf( FCGI_stderr, "Error: failed to write jpipstream\n");
+ }
+
+ free( jpipstream);
+
+ return;
+}
+
+void add_EORmsg( int fd, QR_t *qr)
+{
+ unsigned char EOR[3];
+
+ if( qr->channel){
+ EOR[0] = 0x00;
+ EOR[1] = is_allsent( *(qr->channel->cachemodel)) ? 0x01 : 0x02;
+ EOR[2] = 0x00;
+ if( write( fd, EOR, 3) != 3)
+ fprintf( FCGI_stderr, "Error: failed to write EOR message\n");
+ }
+}
+
+void end_QRprocess( server_record_t *rec, QR_t **qr)
+{
+ /* TODO: record client preferences if necessary*/
+ (void)rec; /* unused */
+ delete_query( &((*qr)->query));
+ delete_msgqueue( &((*qr)->msgqueue));
+ free( *qr);
+}
+
+
+void local_log( bool query, bool messages, bool sessions, bool targets, QR_t *qr, server_record_t *rec)
+{
+ if( query)
+ print_queryparam( *qr->query);
+
+ if( messages)
+ print_msgqueue( qr->msgqueue);
+
+ if( sessions)
+ print_allsession( rec->sessionlist);
+
+ if( targets)
+ print_alltarget( rec->targetlist);
+}
+
+#endif /*SERVER*/
+
+#ifndef SERVER
+
+dec_server_record_t * init_dec_server( int port)
+{
+ dec_server_record_t *record = (dec_server_record_t *)malloc( sizeof(dec_server_record_t));
+
+ record->cachelist = gene_cachelist();
+ record->jpipstream = NULL;
+ record->jpipstreamlen = 0;
+ record->msgqueue = gene_msgqueue( true, NULL);
+ record->listening_socket = open_listeningsocket( (uint16_t)port);
+
+ return record;
+}
+
+void terminate_dec_server( dec_server_record_t **rec)
+{
+ delete_cachelist( &(*rec)->cachelist);
+ free( (*rec)->jpipstream);
+
+ if( (*rec)->msgqueue)
+ delete_msgqueue( &((*rec)->msgqueue));
+
+ if( close_socket( (*rec)->listening_socket) != 0)
+ perror("close");
+
+ free( *rec);
+}
+
+client_t accept_connection( dec_server_record_t *rec)
+{
+ client_t client;
+
+ client = accept_socket( rec->listening_socket);
+ if( client == -1)
+ fprintf( stderr, "error: failed to connect to client\n");
+
+ return client;
+}
+
+bool handle_clientreq( client_t client, dec_server_record_t *rec)
+{
+ bool quit = false;
+ msgtype_t msgtype = identify_clientmsg( client);
+
+ switch( msgtype){
+ case JPIPSTREAM:
+ handle_JPIPstreamMSG( client, rec->cachelist, &rec->jpipstream, &rec->jpipstreamlen, rec->msgqueue);
+ break;
+
+ case PNMREQ:
+ handle_PNMreqMSG( client, rec->jpipstream, rec->msgqueue, rec->cachelist);
+ break;
+
+ case XMLREQ:
+ handle_XMLreqMSG( client, rec->jpipstream, rec->cachelist);
+ break;
+
+ case TIDREQ:
+ handle_TIDreqMSG( client, rec->cachelist);
+ break;
+
+ case CIDREQ:
+ handle_CIDreqMSG( client, rec->cachelist);
+ break;
+
+ case CIDDST:
+ handle_dstCIDreqMSG( client, rec->cachelist);
+ break;
+
+ case SIZREQ:
+ handle_SIZreqMSG( client, rec->jpipstream, rec->msgqueue, rec->cachelist);
+ break;
+
+ case JP2SAVE:
+ handle_JP2saveMSG( client, rec->cachelist, rec->msgqueue, rec->jpipstream);
+ break;
+
+ case QUIT:
+ quit = true;
+ save_codestream( rec->jpipstream, rec->jpipstreamlen, "jpt");
+ break;
+ case MSGERROR:
+ break;
+ }
+
+ fprintf( stderr, "\t end of the connection\n\n");
+ if( close_socket(client) != 0){
+ perror("close");
+ return false;
+ }
+
+ if( quit)
+ return false;
+
+ return true;
+}
+
+
+jpip_dec_param_t * init_jpipdecoder( bool jp2)
+{
+ jpip_dec_param_t *dec;
+
+ dec = (jpip_dec_param_t *)calloc( 1, sizeof(jpip_dec_param_t));
+
+ dec->msgqueue = gene_msgqueue( true, NULL);
+
+ if( jp2)
+ dec->metadatalist = gene_metadatalist();
+
+ return dec;
+}
+
+
+bool fread_jpip( const char fname[], jpip_dec_param_t *dec)
+{
+ int infd;
+
+ if(( infd = open( fname, O_RDONLY)) == -1){
+ fprintf( stderr, "file %s not exist\n", fname);
+ return false;
+ }
+
+ if(!(dec->jpiplen = (Byte8_t)get_filesize(infd)))
+ return false;
+
+ dec->jpipstream = (Byte_t *)malloc( dec->jpiplen);
+
+ if( read( infd, dec->jpipstream, dec->jpiplen) != (int)dec->jpiplen){
+ fprintf( stderr, "file reading error\n");
+ free( dec->jpipstream);
+ return false;
+ }
+
+ close(infd);
+
+ return true;
+}
+
+void decode_jpip( jpip_dec_param_t *dec)
+{
+ parse_JPIPstream( dec->jpipstream, dec->jpiplen, 0, dec->msgqueue);
+
+ if( dec->metadatalist){ /* JP2 encoding*/
+ parse_metamsg( dec->msgqueue, dec->jpipstream, dec->jpiplen, dec->metadatalist);
+ dec->ihdrbox = gene_ihdrbox( dec->metadatalist, dec->jpipstream);
+
+ dec->jp2kstream = recons_jp2( dec->msgqueue, dec->jpipstream, dec->msgqueue->first->csn, &dec->jp2klen);
+ }
+ else /* J2k encoding */
+ /* Notice: arguments fw, fh need to be set for LRCP, PCRL, CPRL*/
+ dec->jp2kstream = recons_j2k( dec->msgqueue, dec->jpipstream, dec->msgqueue->first->csn, 0, 0, &dec->jp2klen);
+}
+
+bool fwrite_jp2k( const char fname[], jpip_dec_param_t *dec)
+{
+ int outfd;
+
+#ifdef _WIN32
+ if(( outfd = open( fname, O_WRONLY|O_CREAT, _S_IREAD | _S_IWRITE)) == -1){
+#else
+ if(( outfd = open( fname, O_WRONLY|O_CREAT, S_IRWXU|S_IRWXG)) == -1){
+#endif
+ fprintf( stderr, "file %s open error\n", fname);
+ return false;
+ }
+
+ if( write( outfd, dec->jp2kstream, dec->jp2klen) != (int)dec->jp2klen)
+ fprintf( stderr, "j2k file write error\n");
+
+ close(outfd);
+
+ return true;
+}
+
+void output_log( bool messages, bool metadata, bool ihdrbox, jpip_dec_param_t *dec)
+{
+ if( messages)
+ print_msgqueue( dec->msgqueue);
+
+ if( metadata)
+ print_allmetadata( dec->metadatalist);
+
+ if( ihdrbox){
+ printf("W*H: %d*%d\n", dec->ihdrbox->height, dec->ihdrbox->width);
+ printf("NC: %d, bpc: %d\n", dec->ihdrbox->nc, dec->ihdrbox->bpc);
+ }
+}
+
+void destroy_jpipdecoder( jpip_dec_param_t **dec)
+{
+ free( (*dec)->jpipstream);
+ delete_msgqueue( &(*dec)->msgqueue);
+ if( (*dec)->metadatalist){
+ delete_metadatalist( &(*dec)->metadatalist);
+ free( (*dec)->ihdrbox);
+ }
+
+ free( (*dec)->jp2kstream);
+ free( *dec);
+}
+
+index_t * get_index_from_JP2file( int fd)
+{
+ char *data;
+
+ /* Check resource is a JP family file.*/
+ if( lseek( fd, 0, SEEK_SET)==-1){
+ fprintf( stderr, "Error: File broken (lseek error)\n");
+ return NULL;
+ }
+
+ data = (char *)malloc( 12); /* size of header*/
+ if( read( fd, data, 12) != 12){
+ free( data);
+ fprintf( stderr, "Error: File broken (read error)\n");
+ return NULL;
+ }
+
+ if( *data || *(data + 1) || *(data + 2) ||
+ *(data + 3) != 12 || strncmp (data + 4, "jP \r\n\x87\n", 8)){
+ free( data);
+ fprintf( stderr, "Error: No JPEG 2000 Signature box in this file\n");
+ return NULL;
+ }
+ free( data);
+
+ return parse_jp2file( fd);
+}
+
+void destroy_index( index_t **idx)
+{
+ delete_index( idx);
+}
+
+void output_index( index_t *index)
+{
+ print_index( *index);
+}
+
+#endif /*SERVER*/
diff --git a/src/lib/openjpip/openjpip.h b/src/lib/openjpip/openjpip.h
new file mode 100644
index 00000000..c08c3d86
--- /dev/null
+++ b/src/lib/openjpip/openjpip.h
@@ -0,0 +1,308 @@
+/*
+ * $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.
+ */
+
+#ifndef OPENJPIP_H_
+# define OPENJPIP_H_
+
+#include "session_manager.h"
+#include "target_manager.h"
+#include "query_parser.h"
+#include "msgqueue_manager.h"
+#include "bool.h"
+#include "sock_manager.h"
+#include "auxtrans_manager.h"
+
+#ifdef SERVER
+
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+
+#else
+
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+
+#include "cache_manager.h"
+#include "byte_manager.h"
+#include "imgsock_manager.h"
+
+#include "metadata_manager.h"
+#include "ihdrbox_manager.h"
+#include "index_manager.h"
+
+#endif /*SERVER*/
+
+/*
+ *==========================================================
+ * JPIP server API
+ *==========================================================
+ */
+
+ #ifdef SERVER
+
+/** Server static records*/
+typedef struct server_record{
+ sessionlist_param_t *sessionlist; /**< list of session records*/
+ targetlist_param_t *targetlist; /**< list of target records*/
+ auxtrans_param_t auxtrans;
+} server_record_t;
+
+/** Query/response data for each client*/
+typedef struct QR{
+ query_param_t *query; /**< query parameters*/
+ msgqueue_param_t *msgqueue; /**< message queue*/
+ channel_param_t *channel; /**< channel, (NULL if stateless)*/
+} QR_t;
+
+/**
+ * Initialize the JPIP server
+ *
+ * @param[in] tcp_auxport opening tcp auxiliary port ( 0 not to open, valid No. 49152-65535)
+ * @param[in] udp_auxport opening udp auxiliary port ( 0 not to open, valid No. 49152-65535)
+ * @return intialized server record pointer
+ */
+server_record_t * init_JPIPserver( int tcp_auxport, int udp_auxport);
+
+/**
+ * Terminate the JPIP server
+ *
+ * @param[in] rec address of deleting server static record pointer
+ */
+void terminate_JPIPserver( server_record_t **rec);
+
+/**
+ * 1st process per client request; parse query string
+ *
+ * @param[in] query_string request query string
+ * @return initialized query/response data pointer
+ */
+QR_t * parse_querystring( const char *query_string);
+
+/**
+ * 2nd process; process JPIP request and construct message queue
+ *
+ * @param[in] rec server static record pointer
+ * @param[in] qr query/response data pointer
+ * @return true if succeed, otherwise false
+ */
+bool process_JPIPrequest( server_record_t *rec, QR_t *qr);
+
+/**
+ * 3rd process; send response data JPT/JPP-stream
+ *
+ * @param[in] rec server static record pointer
+ * @param[in] qr query/response data pointer
+ */
+void send_responsedata( server_record_t *rec, QR_t *qr);
+
+/**
+ * 4th (last) process;
+ *
+ * @param[in] rec server static record pinter
+ * @param[in] qr address of query/response data pointer
+ */
+void end_QRprocess( server_record_t *rec, QR_t **qr);
+
+/**
+ * Option for local tests; print out parameter values to logstream (stderr)
+ *
+ * @param[in] query true if query parameters are to be printed out
+ * @param[in] messages true if queue of messages is to be printed out
+ * @param[in] sessions true if session list is to be printed out
+ * @param[in] targets true if target list is to be printed out
+ * @param[in] qr query/response data pointer
+ * @param[in] rec server static record pinter
+ */
+void local_log( bool query, bool messages, bool sessions, bool targets, QR_t *qr, server_record_t *rec);
+
+#endif /*SERVER*/
+
+/*
+ *==========================================================
+ * JPIP decoding server API
+ *==========================================================
+ */
+
+#ifndef SERVER
+
+/** Decoding server static records*/
+typedef struct dec_server_record{
+ cachelist_param_t *cachelist; /**< cache list*/
+ Byte_t *jpipstream; /**< JPT/JPP stream*/
+ OPJ_SIZE_T jpipstreamlen; /**< length of jpipstream*/
+ msgqueue_param_t *msgqueue; /**< parsed message queue of jpipstream*/
+ SOCKET listening_socket; /**< listenning socket*/
+} dec_server_record_t;
+
+
+/** Client socket identifier*/
+typedef SOCKET client_t;
+
+/**
+ * Initialize the image decoding server
+ *
+ * @param[in] port opening tcp port (valid No. 49152-65535)
+ * @return intialized decoding server record pointer
+ */
+dec_server_record_t * init_dec_server( int port);
+
+/**
+ * Terminate the image decoding server
+ *
+ * @param[in] rec address of deleting decoding server static record pointer
+ */
+void terminate_dec_server( dec_server_record_t **rec);
+
+/**
+ * Accept client connection
+ *
+ * @param[in] rec decoding server static record pointer
+ * @return client socket ID, -1 if failed
+ */
+client_t accept_connection( dec_server_record_t *rec);
+
+ /**
+ * Handle client request
+ *
+ * @param[in] client client socket ID
+ * @param[in] rec decoding server static record pointer
+ * @return true if succeed
+ */
+bool handle_clientreq( client_t client, dec_server_record_t *rec);
+
+#endif /*SERVER*/
+
+/*
+ *==========================================================
+ * JPIP tool API
+ *==========================================================
+ */
+
+#ifndef SERVER
+
+/*
+ * jpip to JP2 or J2K
+ */
+
+/** JPIP decoding parameters*/
+typedef struct jpip_dec_param{
+ Byte_t *jpipstream; /**< JPT/JPP-stream*/
+ Byte8_t jpiplen; /**< length of jpipstream*/
+ msgqueue_param_t *msgqueue; /**< message queue*/
+ metadatalist_param_t *metadatalist; /**< metadata list going into JP2 file*/
+ ihdrbox_param_t *ihdrbox; /**< ihdr box going into JP2 file*/
+ Byte_t *jp2kstream; /**< J2K codestream or JP2 file codestream*/
+ Byte8_t jp2klen; /**< length of j2kstream or JP2 file*/
+} jpip_dec_param_t;
+
+/**
+ * Initialize jpip decoder
+ *
+ * @param[in] jp2 true in case of jp2 file encoding, else j2k file encoding
+ * @return JPIP decoding parameters pointer
+ */
+jpip_dec_param_t * init_jpipdecoder( bool jp2);
+
+/**
+ * Destroy jpip decoding parameters
+ *
+ * @param[in] dec address of JPIP decoding parameters pointer
+ */
+void destroy_jpipdecoder( jpip_dec_param_t **dec);
+
+/**
+ * Read jpip codestream from a file
+ *
+ * @param[in] fname file name
+ * @param[in] dec JPIP decoding parameters pointer
+ * @return true if succeed
+ */
+bool fread_jpip( const char fname[], jpip_dec_param_t *dec);
+
+/**
+ * Decode jpip codestream
+ *
+ * @param[in] dec JPIP decoding parameters pointer
+ */
+void decode_jpip( jpip_dec_param_t *dec);
+
+/**
+ * Write J2K/JP2 codestream to a file
+ *
+ * @param[in] fname file name
+ * @param[in] dec JPIP decoding parameters pointer
+ * @return true if succeed
+ */
+bool fwrite_jp2k( const char fname[], jpip_dec_param_t *dec);
+
+/**
+ * Option; print out parameter values to stderr
+ *
+ * @param[in] messages true if queue of messages is to be printed out
+ * @param[in] metadata true if metadata is to be printed out
+ * @param[in] ihdrbox true if image header data is to be printed out
+ * @param[in] dec JPIP decoding parameters pointer
+ */
+void output_log( bool messages, bool metadata, bool ihdrbox, jpip_dec_param_t *dec);
+
+/*
+ * test the format of index (cidx) box in JP2 file
+ */
+
+/** Redefinition of index parameters*/
+typedef index_param_t index_t;
+
+/**
+ * Parse JP2 file and get index information from cidx box inside
+ *
+ * @param[in] fd file descriptor of the JP2 file
+ * @return pointer to the generated structure of index parameters
+ */
+index_t * get_index_from_JP2file( int fd);
+
+/**
+ * Destroy index parameters
+ *
+ * @param[in,out] idx addressof the index pointer
+ */
+void destroy_index( index_t **idx);
+
+
+/**
+ * print index parameters
+ *
+ * @param[in] index index parameters
+ */
+void output_index( index_t *index);
+
+#endif /*SERVER*/
+
+#endif /* !OPENJPIP_H_ */
diff --git a/src/lib/openjpip/placeholder_manager.c b/src/lib/openjpip/placeholder_manager.c
new file mode 100644
index 00000000..4a37a13b
--- /dev/null
+++ b/src/lib/openjpip/placeholder_manager.c
@@ -0,0 +1,143 @@
+/*
+ * $Id: placeholder_manager.c 53 2011-05-09 16:55:39Z 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 "placeholder_manager.h"
+#include "opj_inttypes.h"
+
+#ifdef SERVER
+#include "fcgi_stdio.h"
+#define logstream FCGI_stdout
+#else
+#define FCGI_stdout stdout
+#define FCGI_stderr stderr
+#define logstream stderr
+#endif /*SERVER*/
+
+
+
+placeholderlist_param_t * gene_placeholderlist(void)
+{
+ 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, Byte8_t 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+(Byte4_t)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)
+{
+ int i;
+
+ 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: %" PRId64 "\n", phld->OrigID);
+ fprintf( logstream, "\t OrigBH: ");
+
+ for( i=0; i< phld->OrigBHlen; i++)
+ fprintf( logstream, "%02x ", phld->OrigBH[i]);
+ fprintf( logstream, "\t");
+
+ for( 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;
+ }
+}
diff --git a/src/lib/openjpip/placeholder_manager.h b/src/lib/openjpip/placeholder_manager.h
new file mode 100644
index 00000000..ced20854
--- /dev/null
+++ b/src/lib/openjpip/placeholder_manager.h
@@ -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(void);
+
+
+/**
+ * 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, Byte8_t 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_ */
diff --git a/src/lib/openjpip/query_parser.c b/src/lib/openjpip/query_parser.c
new file mode 100644
index 00000000..460a5eb6
--- /dev/null
+++ b/src/lib/openjpip/query_parser.c
@@ -0,0 +1,429 @@
+/*
+ * $Id: query_parser.c 53 2011-05-09 16:55:39Z 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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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.
+ */
+
+
+#ifdef _WIN32
+#include <windows.h>
+#define strcasecmp _stricmp
+#define strncasecmp _strnicmp
+#else
+#include <strings.h>
+#endif
+
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+#include <stdlib.h>
+#include "query_parser.h"
+#include "opj_stdint.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*/
+
+
+/**
+ * Get initialized query parameters
+ *
+ * @return initial query parameters
+ */
+query_param_t * get_initquery(void);
+
+/*
+ * get a pair of field name and value from the string starting fieldname=fieldval&... format
+ *
+ * @param[in] stringptr pointer to the beginning of the parsing string
+ * @param[out] fieldname string to copy the field name, if not found, NULL
+ * @param[out] fieldval string to copy the field value, if not found, NULL
+ * @return pointer to the next field string, if there is none, NULL
+ */
+char * get_fieldparam( const char *stringptr, char *fieldname, char *fieldval);
+
+void parse_cclose( char *src, query_param_t *query_param);
+void parse_metareq( char *field, query_param_t *query_param);
+
+/* parse the requested components (parses forms like:a; a,b; a-b; a-b,c; a,b-c)*/
+void parse_comps( char *field, query_param_t *query_param);
+
+
+/** maximum length of field name*/
+#define MAX_LENOFFIELDNAME 10
+
+/** maximum length of field value*/
+#define MAX_LENOFFIELDVAL 128
+
+query_param_t * parse_query( const char *query_string)
+{
+ query_param_t *query_param;
+ const char *pquery;
+ char fieldname[MAX_LENOFFIELDNAME], fieldval[MAX_LENOFFIELDVAL];
+
+ query_param = get_initquery();
+
+ pquery = query_string;
+
+ while( pquery!=NULL) {
+
+ pquery = get_fieldparam( pquery, fieldname, fieldval);
+
+ if( fieldname[0] != '\0'){
+ if( strcasecmp( fieldname, "target") == 0)
+ query_param->target = strdup( fieldval);
+
+ else if( strcasecmp( fieldname, "tid") == 0)
+ query_param->tid = strdup( fieldval);
+
+ else if( strcasecmp( fieldname, "fsiz") == 0)
+ sscanf( fieldval, "%d,%d", &query_param->fx, &query_param->fy);
+
+ else if( strcasecmp( fieldname, "roff") == 0)
+ sscanf( fieldval, "%d,%d", &query_param->rx, &query_param->ry);
+
+ else if( strcasecmp( fieldname, "rsiz") == 0)
+ sscanf( fieldval, "%d,%d", &query_param->rw, &query_param->rh);
+
+ else if( strcasecmp( fieldname, "layers") == 0)
+ sscanf( fieldval, "%d", &query_param->layers);
+
+ else if( strcasecmp( fieldname, "cid") == 0)
+ query_param->cid = strdup( fieldval);
+
+ else if( strcasecmp( fieldname, "cnew") == 0){
+ if( strncasecmp( fieldval, "http-tcp", 8) == 0)
+ query_param->cnew = tcp;
+ else if( strncasecmp( fieldval, "http", 4) == 0)
+ query_param->cnew = http;
+ }
+
+ else if( strcasecmp( fieldname, "cclose") == 0)
+ parse_cclose( fieldval, query_param);
+
+ else if( strcasecmp( fieldname, "metareq") == 0)
+ parse_metareq( fieldval, query_param);
+
+ else if( strcasecmp( fieldname, "comps") == 0)
+ parse_comps( fieldval, query_param);
+
+ else if( strcasecmp( fieldname, "type") == 0){
+ if( strncasecmp( fieldval, "jpp-stream", 10) == 0)
+ query_param->return_type = JPPstream;
+ else if( strncasecmp( fieldval, "jpt-stream", 10) == 0)
+ query_param->return_type = JPTstream;
+ }
+
+ else if( strcasecmp( fieldname, "len") == 0){
+ sscanf( fieldval, "%d", &query_param->len);
+ if( query_param->len == 2000) /* for kakadu client*/
+ strncpy( query_param->box_type[0], "ftyp", 4);
+ }
+ }
+ }
+ return query_param;
+}
+
+query_param_t * get_initquery(void)
+{
+ query_param_t *query;
+ int i;
+
+ query = (query_param_t *)malloc( sizeof(query_param_t));
+
+ query->target = NULL;
+ query->tid = NULL;
+ query->fx = -1;
+ query->fy = -1;
+ query->rx = -1;
+ query->ry = -1;
+ query->rw = -1;
+ query->rh = -1;
+ query->layers = -1;
+ query->lastcomp = -1;
+ query->comps = NULL;
+ query->cid = NULL;
+ query->cnew = non;
+ query->cclose = NULL;
+ query->numOfcclose = 0;
+ memset( query->box_type, 0, MAX_NUMOFBOX*4);
+ memset( query->limit, 0, MAX_NUMOFBOX*sizeof(int));
+ for( i=0; i<MAX_NUMOFBOX; i++){
+ query->w[i] = false;
+ query->s[i] = false;
+ query->g[i] = false;
+ query->a[i] = false;
+ query->priority[i] = false;
+ }
+ query->root_bin = 0;
+ query->max_depth = -1;
+ query->metadata_only = false;
+ query->return_type = UNKNOWN;
+ query->len = -1;
+
+ return query;
+}
+
+
+char * get_fieldparam( const char *stringptr, char *fieldname, char *fieldval)
+{
+ char *eqp, *andp, *nexfieldptr;
+
+ if((eqp = strchr( stringptr, '='))==NULL){
+ fprintf( stderr, "= not found\n");
+ strcpy( fieldname, "");
+ strcpy( fieldval, "");
+ return NULL;
+ }
+ if((andp = strchr( stringptr, '&'))==NULL){
+ andp = strchr( stringptr, '\0');
+ nexfieldptr = NULL;
+ }
+ else
+ nexfieldptr = andp+1;
+
+ assert( (size_t)(eqp-stringptr));
+ strncpy( fieldname, stringptr, (size_t)(eqp-stringptr));
+ fieldname[eqp-stringptr]='\0';
+ assert( andp-eqp-1 >= 0);
+ strncpy( fieldval, eqp+1, (size_t)(andp-eqp-1));
+ fieldval[andp-eqp-1]='\0';
+
+ return nexfieldptr;
+}
+
+void print_queryparam( query_param_t query_param)
+{
+ int i;
+ char *cclose;
+
+ fprintf( logstream, "query parameters:\n");
+
+ if( query_param.target)
+ fprintf( logstream, "\t target: %s\n", query_param.target);
+
+ if( query_param.tid)
+ fprintf( logstream, "\t tid: %s\n", query_param.tid);
+
+ 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 layers: %d\n", query_param.layers);
+ fprintf( logstream, "\t components: ");
+
+ if( query_param.lastcomp == -1)
+ fprintf( logstream, "ALL\n");
+ else{
+ for( i=0; i<=query_param.lastcomp; i++)
+ if( query_param.comps[i])
+ fprintf( logstream, "%d ", i);
+ fprintf( logstream, "\n");
+ }
+ fprintf( logstream, "\t cnew: %d\n", query_param.cnew);
+
+ if( query_param.cid)
+ fprintf( logstream, "\t cid: %s\n", query_param.cid);
+
+ if( query_param.cclose){
+ fprintf( logstream, "\t cclose: ");
+
+ for( i=0, cclose=query_param.cclose; i<query_param.numOfcclose; i++){
+ fprintf( logstream, "%s ", cclose);
+ cclose += (strlen(cclose)+1);
+ }
+ fprintf(logstream, "\n");
+ }
+
+ fprintf( logstream, "\t req-box-prop\n");
+ for( 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);
+ fprintf( logstream, "\t image return type: %d, [JPP-stream=0, JPT-stream=1, UNKNOWN=-1]\n", query_param.return_type);
+ fprintf( logstream, "\t len: %d\n", query_param.len);
+}
+
+void parse_cclose( char *src, query_param_t *query_param)
+{
+ size_t i;
+ size_t len;
+
+ len = strlen( src);
+ query_param->cclose = strdup( src);
+
+ for( i=0; i<len; i++)
+ if( query_param->cclose[i] == ','){
+ query_param->cclose[i] = '\0';
+ query_param->numOfcclose ++;
+ }
+
+ query_param->numOfcclose ++;
+}
+
+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;
+
+ memset( req_box_prop, 0, 20);
+
+ /* req-box-prop*/
+ ptr = strchr( field, '[');
+ ptr++;
+ src = ptr;
+ while( *ptr != ']'){
+ if( *ptr == ';'){
+ assert( ptr-src >= 0);
+ strncpy( req_box_prop, src, (size_t)(ptr-src));
+ parse_req_box_prop( req_box_prop, numofboxreq++, query_param);
+ ptr++;
+ src = ptr;
+ memset( req_box_prop, 0, 20);
+ }
+ ptr++;
+ }
+ assert(ptr-src>=0);
+ strncpy( req_box_prop, src, (size_t)(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++;
+}
+
+void parse_comps( char *field, query_param_t *query_param)
+{
+ int i,start,stop,aux = -1;
+ char *ptr1,*ptr2;
+
+ ptr1 = strchr( field, '-');
+ ptr2 = strchr( field, ',');
+
+ if( ptr1 && ptr2)
+ if( ptr1 > ptr2)
+ sscanf( field, "%d,%d-%d",&aux, &start, &stop);
+ else
+ sscanf( field, "%d-%d,%d", &start, &stop, &aux);
+ else
+ if(ptr1)
+ sscanf( field, "%d-%d", &start, &stop);
+ else if(ptr2){
+ sscanf( field, "%d,%d", &start, &stop);
+ aux = start;
+ start = stop;
+ }
+ else{
+ sscanf( field, "%d", &stop);
+ start = stop;
+ }
+
+ query_param->lastcomp = stop > aux ? stop : aux;
+ query_param->comps = (bool *)calloc( 1, (OPJ_SIZE_T)(query_param->lastcomp+1)*sizeof(bool));
+
+ for( i=start; i<=stop; i++)
+ query_param->comps[i]=true;
+
+ if(aux!=-1)
+ query_param->comps[aux] = true;
+}
+
+void delete_query( query_param_t **query)
+{
+ if( (*query)->target)
+ free( (*query)->target);
+
+ if( (*query)->tid)
+ free( (*query)->tid);
+
+ if( (*query)->comps)
+ free((*query)->comps);
+
+ if( (*query)->cid)
+ free( (*query)->cid);
+
+ if( (*query)->cclose)
+ free( (*query)->cclose);
+
+ free( *query);
+}
diff --git a/src/lib/openjpip/query_parser.h b/src/lib/openjpip/query_parser.h
new file mode 100644
index 00000000..d60cafe6
--- /dev/null
+++ b/src/lib/openjpip/query_parser.h
@@ -0,0 +1,97 @@
+/*
+ * $Id: query_parser.h 53 2011-05-09 16:55:39Z 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
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * 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 "bool.h"
+
+/** maximum number of meta request box */
+#define MAX_NUMOFBOX 10
+
+/** cnew aux transport name */
+typedef enum cnew_transport { non, http, tcp, udp} cnew_transport_t;
+
+/** image return type */
+typedef enum image_return { JPPstream, JPTstream, UNKNOWN=-1} image_return_t;
+
+/** Query parameters */
+typedef struct query_param{
+ char *target; /**< target name */
+ char *tid; /**< target identifier */
+ int fx, fy; /**< frame size (fx,fy) */
+ int rx, ry, rw, rh; /**< roi region */
+ int layers; /**< quality layers */
+ int lastcomp; /**< last component number */
+ bool *comps; /**< components (dynamic array) for jpp-stream, null means all components */
+ char *cid; /**< channel identifier */
+ cnew_transport_t cnew; /**< transport name if there is new channel request, else non */
+ char *cclose; /**< list of closing channel identifiers, separated by '\0' */
+ int numOfcclose; /**< number of closing channels */
+ 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 */
+ image_return_t return_type; /**< image return type */
+ int len; /**< maximum response length */
+} query_param_t;
+
+
+/**
+ * parse query
+ *
+ * @param[in] query_string request query string
+ * @return pointer to query parameters
+ */
+query_param_t * parse_query( const char *query_string);
+
+/**
+ * print query parameters
+ *
+ * @param[in] query_param query parameters
+ */
+void print_queryparam( query_param_t query_param);
+
+
+/**
+ * delete query
+ *
+ * @param[in] query address of the deleting query pointer
+ */
+void delete_query( query_param_t **query);
+
+#endif /* !QUERY_PARSER_H_ */
diff --git a/src/lib/openjpip/session_manager.c b/src/lib/openjpip/session_manager.c
new file mode 100644
index 00000000..5c1d7588
--- /dev/null
+++ b/src/lib/openjpip/session_manager.c
@@ -0,0 +1,196 @@
+/*
+ * $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"
+#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 */
+
+
+sessionlist_param_t * gene_sessionlist(void)
+{
+ 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->cachemodellist = gene_cachemodellist();
+
+ 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_cachemodel_into_session( session_param_t *session, cachemodel_param_t *cachemodel)
+{
+ if(!cachemodel)
+ return;
+
+#ifndef SERVER
+ fprintf( logstream, "local log: insert cachemodel into session\n");
+#endif
+ if( session->cachemodellist->first != NULL)
+ session->cachemodellist->last->next = cachemodel;
+ else
+ session->cachemodellist->first = cachemodel;
+ session->cachemodellist->last = cachemodel;
+}
+
+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_cachemodellist( &((*session)->cachemodellist));
+
+#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_cachemodellist( &(sessionPtr->cachemodellist));
+
+#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;
+ cachemodel_param_t *cachemodel;
+ 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);
+ cachemodel = ptr->cachemodellist->first;
+ while( cachemodel){
+ print_target( cachemodel->target);
+ cachemodel = cachemodel->next;
+ }
+ ptr=ptr->next;
+ }
+}
diff --git a/src/lib/openjpip/session_manager.h b/src/lib/openjpip/session_manager.h
new file mode 100644
index 00000000..03df4f4b
--- /dev/null
+++ b/src/lib/openjpip/session_manager.h
@@ -0,0 +1,116 @@
+/*
+ * $Id: session_manager.h 53 2011-05-09 16:55:39Z 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 "bool.h"
+#include "channel_manager.h"
+#include "cachemodel_manager.h"
+
+/** Session parameters*/
+typedef struct session_param{
+ channellist_param_t *channellist; /**< channel list pointer*/
+ cachemodellist_param_t *cachemodellist; /**< cache 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(void);
+
+
+/**
+ * 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 cache model into a session
+ *
+ * @param[in] session session pointer
+ * @param[in] cachemodel cachemodel pointer
+ */
+void insert_cachemodel_into_session( session_param_t *session, cachemodel_param_t *cachemodel);
+
+
+/**
+ * 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_ */
diff --git a/src/lib/openjpip/sock_manager.c b/src/lib/openjpip/sock_manager.c
new file mode 100644
index 00000000..432b03fa
--- /dev/null
+++ b/src/lib/openjpip/sock_manager.c
@@ -0,0 +1,181 @@
+/*
+ * $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.
+ */
+
+#ifdef _WIN32
+#include <windows.h>
+#else
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "sock_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*/
+
+SOCKET open_listeningsocket( uint16_t port)
+{
+ SOCKET listening_socket;
+ struct sockaddr_in sin;
+ int sock_optval = 1;
+
+ listening_socket = socket(AF_INET, SOCK_STREAM, 0);
+ if ( listening_socket == -1 ){
+ perror("socket");
+ exit(1);
+ }
+
+ if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR, (const char *)&sock_optval, sizeof(sock_optval)) == -1 ){
+ perror("setsockopt");
+ exit(1);
+ }
+
+ memset(&sin, 0, sizeof(sin));
+ 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");
+ close_socket(listening_socket);
+ exit(1);
+ }
+
+ if( listen(listening_socket, SOMAXCONN) == -1){
+ perror("listen");
+ close_socket(listening_socket);
+ exit(1);
+ }
+ fprintf( FCGI_stderr, "port %d is listened\n", port);
+
+ return listening_socket;
+}
+
+SOCKET accept_socket( SOCKET listening_socket)
+{
+ struct sockaddr_in peer_sin;
+ unsigned int addrlen = sizeof(peer_sin);
+
+ return accept( listening_socket, (struct sockaddr *)&peer_sin, &addrlen);
+}
+
+void send_stream( SOCKET connected_socket, const void *stream, OPJ_SIZE_T length)
+{
+ char *ptr = (char*)stream;
+ OPJ_SIZE_T remlen = length;
+
+ while( remlen > 0){
+ ssize_t sentlen = send( connected_socket, ptr, remlen, 0);
+ if( sentlen == -1){
+ fprintf( FCGI_stderr, "sending stream error\n");
+ break;
+ }
+ remlen = remlen - (OPJ_SIZE_T)sentlen;
+ ptr = ptr + sentlen;
+ }
+}
+
+void * receive_stream( SOCKET connected_socket, OPJ_SIZE_T length)
+{
+ char *stream, *ptr;
+ OPJ_SIZE_T remlen;
+
+ ptr = stream = malloc( length);
+ remlen = length;
+
+ while( remlen > 0){
+ ssize_t redlen = recv( connected_socket, ptr, remlen, 0);
+ if( redlen == -1){
+ fprintf( FCGI_stderr, "receive stream error\n");
+ free( stream);
+ stream = NULL;
+ break;
+ }
+ remlen -= (OPJ_SIZE_T)redlen;
+ ptr = ptr + redlen;
+ }
+ return stream;
+}
+
+OPJ_SIZE_T receive_line(SOCKET connected_socket, char *p)
+{
+ OPJ_SIZE_T len = 0;
+ while (1){
+ ssize_t ret;
+ ret = recv( connected_socket, p, 1, 0);
+ if ( ret == -1 ){
+ perror("receive");
+ exit(1);
+ } else if ( ret == 0 ){
+ break;
+ }
+ if ( *p == '\n' )
+ break;
+ p++;
+ len++;
+ }
+ *p = '\0';
+
+ if( len == 0)
+ fprintf( FCGI_stderr, "Header receive error\n");
+
+ return len;
+}
+
+char * receive_string( SOCKET connected_socket)
+{
+ char buf[BUF_LEN];
+
+ /* MM FIXME: there is a nasty bug here, size of buf if BUF_LEN which is never
+ indicated to downstream receive_line */
+ receive_line( connected_socket, buf);
+
+ return strdup(buf);
+}
+
+int close_socket( SOCKET sock)
+{
+#ifdef _WIN32
+ return closesocket( sock);
+#else
+ return close( sock);
+#endif
+}
diff --git a/src/lib/openjpip/sock_manager.h b/src/lib/openjpip/sock_manager.h
new file mode 100644
index 00000000..ee67131e
--- /dev/null
+++ b/src/lib/openjpip/sock_manager.h
@@ -0,0 +1,106 @@
+/*
+ * $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.
+ */
+
+#ifndef SOCK_MANAGER_H_
+# define SOCK_MANAGER_H_
+
+#include "bool.h"
+#include "byte_manager.h"
+#include "opj_stdint.h"
+
+#ifdef _WIN32
+#include <winsock.h>
+#else
+typedef int SOCKET;
+#endif /*_WIN32*/
+
+#define BUF_LEN 256
+
+/**
+ * open listening socket
+ *
+ * @param port opening port number
+ * @return new socket
+ */
+SOCKET open_listeningsocket( uint16_t port);
+
+/**
+ * accept a new connection to the listenning socket
+ *
+ * @param listening_socket listenning socket
+ * @return connected socket (-1 if error occurs)
+ */
+SOCKET accept_socket( SOCKET listening_socket);
+
+
+/**
+ * receive 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
+ */
+OPJ_SIZE_T receive_line(SOCKET connected_socket, char *buf);
+
+/**
+ * receive a string line (ending with '\n') from client, return malloc string
+ *
+ * @param [in] connected_socket file descriptor of the connected socket
+ * @return pointer to the string (memory allocated)
+ */
+char * receive_string( SOCKET connected_socket);
+
+/**
+ * receive data stream to client
+ *
+ * @param [in] connected_socket file descriptor of the connected socket
+ * @param [in] length length of the receiving stream
+ * @return pointer to the data stream (memory allocated), NULL if failed
+ */
+void * receive_stream( SOCKET connected_socket, OPJ_SIZE_T length);
+
+/**
+ * send data stream to client
+ *
+ * @param [in] connected_socket file descriptor of the connected socket
+ * @param [in] stream data stream
+ * @param [in] length length of data stream
+ */
+void send_stream( SOCKET connected_socket, const void *stream, OPJ_SIZE_T length);
+
+/**
+ * close socket
+ *
+ * @param [in] sock closing socket
+ * @return 0 if succeed, -1 if failed
+ */
+int close_socket( SOCKET sock);
+
+#endif /* !SOCK_MANAGER_H_ */
diff --git a/src/lib/openjpip/target_manager.c b/src/lib/openjpip/target_manager.c
new file mode 100644
index 00000000..8b4763a5
--- /dev/null
+++ b/src/lib/openjpip/target_manager.c
@@ -0,0 +1,345 @@
+/*
+ * $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 <assert.h>
+#ifdef _WIN32
+#define snprintf _snprintf /* Visual Studio */
+#include <io.h>
+#else
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <time.h>
+#include "target_manager.h"
+
+#ifdef SERVER
+#include <curl/curl.h>
+#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(void)
+{
+ 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] filepath file name (.jp2)
+ * @param[out] tmpfname new file name if filepath is a URL
+ * @return file descriptor
+ */
+int open_jp2file( const char filepath[], char tmpfname[]);
+
+target_param_t * gene_target( targetlist_param_t *targetlist, char *targetpath)
+{
+ target_param_t *target;
+ int fd;
+ index_param_t *jp2idx;
+ char tmpfname[MAX_LENOFTID];
+ static int last_csn = 0;
+
+ if( targetpath[0]=='\0'){
+ fprintf( FCGI_stderr, "Error: exception, no targetpath in gene_target()\n");
+ return NULL;
+ }
+
+ if((fd = open_jp2file( targetpath, tmpfname)) == -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));
+ snprintf( target->tid, MAX_LENOFTID, "%x-%x", (unsigned int)time(NULL), (unsigned int)rand());
+ target->targetname = strdup( targetpath);
+ target->fd = fd;
+#ifdef SERVER
+ if( tmpfname[0])
+ target->tmpfname = strdup( tmpfname);
+ else
+ target->tmpfname = NULL;
+#endif
+ target->csn = last_csn++;
+ target->codeidx = jp2idx;
+ target->num_of_use = 0;
+ target->jppstream = true;
+ target->jptstream = isJPTfeasible( *jp2idx);
+ target->next=NULL;
+
+ if( targetlist->first) /* there are one or more entries*/
+ targetlist->last->next = target;
+ else /* first entry*/
+ targetlist->first = target;
+ targetlist->last = target;
+
+#ifndef SERVER
+ fprintf( logstream, "local log: target %s generated\n", targetpath);
+#endif
+
+ return target;
+}
+
+void refer_target( target_param_t *reftarget, target_param_t **ptr)
+{
+ *ptr = reftarget;
+ reftarget->num_of_use++;
+}
+
+void unrefer_target( target_param_t *target)
+{
+ target->num_of_use--;
+}
+
+void delete_target( target_param_t **target)
+{
+ close( (*target)->fd);
+
+#ifdef SERVER
+ if( (*target)->tmpfname){
+ fprintf( FCGI_stderr, "Temporal file %s is deleted\n", (*target)->tmpfname);
+ remove( (*target)->tmpfname);
+ }
+#endif
+
+ if( (*target)->codeidx)
+ delete_index ( &(*target)->codeidx);
+
+#ifndef SERVER
+ fprintf( logstream, "local log: target: %s deleted\n", (*target)->targetname);
+#endif
+
+ free( (*target)->targetname);
+
+ 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_target( target_param_t *target)
+{
+ fprintf( logstream, "target:\n");
+ fprintf( logstream, "\t tid=%s\n", target->tid);
+ fprintf( logstream, "\t csn=%d\n", target->csn);
+ fprintf( logstream, "\t target=%s\n\n", target->targetname);
+}
+
+void print_alltarget( targetlist_param_t *targetlist)
+{
+ target_param_t *ptr;
+
+ ptr = targetlist->first;
+ while( ptr != NULL){
+ print_target( ptr);
+ ptr=ptr->next;
+ }
+}
+
+target_param_t * search_target( const char targetname[], targetlist_param_t *targetlist)
+{
+ target_param_t *foundtarget;
+
+ foundtarget = targetlist->first;
+
+ while( foundtarget != NULL){
+
+ if( strcmp( targetname, foundtarget->targetname) == 0)
+ return foundtarget;
+
+ foundtarget = foundtarget->next;
+ }
+ return NULL;
+}
+
+target_param_t * search_targetBytid( const char tid[], targetlist_param_t *targetlist)
+{
+ target_param_t *foundtarget;
+
+ foundtarget = targetlist->first;
+
+ while( foundtarget != NULL){
+
+ if( strcmp( tid, foundtarget->tid) == 0)
+ return foundtarget;
+
+ foundtarget = foundtarget->next;
+ }
+
+ return NULL;
+}
+
+int open_remotefile( const char filepath[], char tmpfname[]);
+
+int open_jp2file( const char filepath[], char tmpfname[])
+{
+ int fd;
+ char *data;
+
+ /* download remote target file to local storage*/
+ if( strncmp( filepath, "http://", 7) == 0){
+ if( (fd = open_remotefile( filepath, tmpfname)) == -1)
+ return -1;
+ }
+ else{
+ tmpfname[0] = 0;
+ if( (fd = open( filepath, O_RDONLY)) == -1){
+ fprintf( FCGI_stdout, "Reason: Target %s not found\r\n", filepath);
+ 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", filepath);
+ 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", filepath);
+ 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", filepath);
+ return -1;
+ }
+
+ free( data);
+
+ return fd;
+}
+
+#ifdef SERVER
+static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream);
+#endif
+
+int open_remotefile( const char filepath[], char tmpfname[])
+{
+#ifndef SERVER
+ (void)filepath;
+ (void)tmpfname;
+ fprintf( FCGI_stderr, "Remote file can not be opened in local mode\n");
+ return -1;
+
+#else
+
+ CURL *curl_handle;
+ int fd;
+
+ curl_handle = curl_easy_init();
+ curl_easy_setopt(curl_handle, CURLOPT_URL, filepath);
+ curl_easy_setopt(curl_handle, CURLOPT_NOPROGRESS, 1L);
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEFUNCTION, write_data);
+
+ snprintf( tmpfname, MAX_LENOFTID, "%x-%x.jp2", (unsigned int)time(NULL), (unsigned int)rand());
+ fprintf( FCGI_stderr, "%s is downloaded to a temporal new file %s\n", filepath, tmpfname);
+ if( (fd = open( tmpfname, O_RDWR|O_CREAT|O_EXCL, S_IRWXU)) == -1){
+ fprintf( FCGI_stdout, "Reason: File open error %s\r\n", tmpfname);
+ curl_easy_cleanup(curl_handle);
+ return -1;
+ }
+ curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &fd);
+ curl_easy_perform(curl_handle);
+ curl_easy_cleanup(curl_handle);
+
+ return fd;
+#endif /*SERVER*/
+}
+
+#ifdef SERVER
+static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
+{
+ int *fd = (int *)stream;
+ ssize_t written = write( *fd, ptr, size*nmemb);
+ assert( written >= 0 );
+
+ return (size_t)written;
+}
+#endif /*SERVER*/
diff --git a/src/lib/openjpip/target_manager.h b/src/lib/openjpip/target_manager.h
new file mode 100644
index 00000000..275adc4a
--- /dev/null
+++ b/src/lib/openjpip/target_manager.h
@@ -0,0 +1,159 @@
+/*
+ * $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 "bool.h"
+#include "index_manager.h"
+
+/** maximum length of target identifier*/
+#define MAX_LENOFTID 30
+
+/** target parameters*/
+typedef struct target_param{
+ char tid[MAX_LENOFTID]; /**< target identifier*/
+ char *targetname; /**< local file path or URL ( URL is suported only with SERVER mode)*/
+ int fd; /**< file descriptor*/
+#ifdef SERVER
+ char *tmpfname; /**< temporal file name to download a remote target file*/
+#endif
+ int csn; /**< codestream number */
+ index_param_t *codeidx; /**< index information of codestream */
+ int num_of_use; /**< numbers of sessions refering to this target */
+ bool jppstream; /**< if this target can return JPP-stream */
+ bool jptstream; /**< if this target can return JPP-stream */
+ 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(void);
+
+
+/**
+ * generate a target
+ *
+ * @param[in] targetlist target list to insert the generated target
+ * @param[in] targetpath file path or URL of the target
+ * @return pointer to the generated target
+ */
+target_param_t * gene_target( targetlist_param_t *targetlist, char *targetpath);
+
+
+/**
+ * refer a target, used to make a new cache model
+ *
+ * @param[in] reftarget reference target pointer
+ * @param[out] ptr address of feeding target pointer
+ */
+void refer_target( target_param_t *reftarget, target_param_t **ptr);
+
+
+/**
+ * refer a target, used to make a new cache model
+ *
+ * @param[in] target reference pointer to the target
+ */
+void unrefer_target( target_param_t *target);
+
+/**
+ * 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 target parameters
+ *
+ * @param[in] target target pointer
+ */
+void print_target( target_param_t *target);
+
+/**
+ * print all target parameters
+ *
+ * @param[in] targetlist target list pointer
+ */
+void print_alltarget( targetlist_param_t *targetlist);
+
+
+/**
+ * search a target by target name
+ *
+ * @param[in] targetname target name
+ * @param[in] targetlist target list pointer
+ * @return found target pointer
+ */
+target_param_t * search_target( const char targetname[], targetlist_param_t *targetlist);
+
+
+/**
+ * search a target by tid
+ *
+ * @param[in] tid target identifier
+ * @param[in] targetlist target list pointer
+ * @return found target pointer
+ */
+target_param_t * search_targetBytid( const char tid[], targetlist_param_t *targetlist);
+
+#endif /* !TARGET_MANAGER_H_ */
+