[1.5][JPIP] TCP return (http-tcp) implemented
authorKaori Hagihara <khagihara@users.noreply.github.com>
Wed, 30 Nov 2011 14:54:41 +0000 (14:54 +0000)
committerKaori Hagihara <khagihara@users.noreply.github.com>
Wed, 30 Nov 2011 14:54:41 +0000 (14:54 +0000)
42 files changed:
applications/jpip/CHANGES
applications/jpip/README
applications/jpip/libopenjpip/CMakeLists.txt
applications/jpip/libopenjpip/Makefile.am
applications/jpip/libopenjpip/auxtrans_manager.c [new file with mode: 0644]
applications/jpip/libopenjpip/auxtrans_manager.h [new file with mode: 0644]
applications/jpip/libopenjpip/cachemodel_manager.c
applications/jpip/libopenjpip/cachemodel_manager.h
applications/jpip/libopenjpip/channel_manager.c
applications/jpip/libopenjpip/channel_manager.h
applications/jpip/libopenjpip/comMakefile.mk
applications/jpip/libopenjpip/dec_clientmsg_handler.c
applications/jpip/libopenjpip/imgsock_manager.c
applications/jpip/libopenjpip/imgsock_manager.h
applications/jpip/libopenjpip/jpip_parser.c
applications/jpip/libopenjpip/jpip_parser.h
applications/jpip/libopenjpip/msgqueue_manager.c
applications/jpip/libopenjpip/msgqueue_manager.h
applications/jpip/libopenjpip/openjpip.c
applications/jpip/libopenjpip/openjpip.h
applications/jpip/libopenjpip/query_parser.c
applications/jpip/libopenjpip/query_parser.h
applications/jpip/libopenjpip/sock_manager.c [new file with mode: 0644]
applications/jpip/libopenjpip/sock_manager.h [new file with mode: 0644]
applications/jpip/libopenjpip/target_manager.c
applications/jpip/libopenjpip/target_manager.h
applications/jpip/util/Makefile.nix
applications/jpip/util/opj_dec_server.c
applications/jpip/util/opj_server.c
applications/jpip/util/opj_viewer/dist/opj_viewer-20111116.jar [deleted file]
applications/jpip/util/opj_viewer/dist/opj_viewer-20111130.jar [new file with mode: 0644]
applications/jpip/util/opj_viewer/dist/opj_viewer.jar
applications/jpip/util/opj_viewer/src/ImageManager.java
applications/jpip/util/opj_viewer/src/ImageViewer.java
applications/jpip/util/opj_viewer/src/ImageWindow.java
applications/jpip/util/opj_viewer/src/ImgdecClient.java
applications/jpip/util/opj_viewer/src/JPIPHttpClient.java
applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111116.jar [deleted file]
applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111130.jar [new file with mode: 0644]
applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces.jar
applications/jpip/util/opj_viewer_xerces/src/ImageViewer.java
applications/jpip/util/opj_viewer_xerces/src/ImageWindow.java

index 44efc7308fa0464cff7e40b66c493e34b160d58a..4ae2b787f7985d7b15b3225dece0355e5e2784d1 100644 (file)
@@ -5,6 +5,9 @@ What's New for OpenJPIP
 ! : changed
 + : added
 
+November 30, 2011
++ [kaori] TCP return (http-tcp) implemented
+
 November 16, 2011
 * [kaori] fixed Region of Interest option, and memory leak of opj_dec_server
 + [kaori] new feature to target JP2 files from www (libcurl required)
index c6bb3028024a95201cbaf7e3baa8a5327b3317be..219e0c418d8fc9c6bb45bda85df2cf1e274ea03e 100644 (file)
@@ -29,7 +29,7 @@ The current implementation uses some results from the 2KAN project (http://www.2
 Version 2.1 covers:
  - JPT-stream (Tile) and JPP-stream (Precinct) media types
  - Session, channels, cache model managements
- - JPIP over HTTP
+ - JPIP over HTTP, HTTP requests and TCP return
  - Indexing JPEG 2000 files
  - Embedding XML formatted metadata
  - Region Of Interest (ROI) requests
@@ -104,12 +104,13 @@ Client:
     % ../opj_dec_server
 
  2. Open image viewers (as many as needed)
-    % java -jar opj_viewer.jar http://hostname/myFCGI path/filename.jp2 [stateless/session] [jptstream/jppstream]
+    % java -jar opj_viewer.jar http://hostname/myFCGI path/filename.jp2 [stateless/session] [jptstream/jppstream] [tcp/udp]
     ( The arguments 
       - http://hostname/myFCGI is the HTTP server URI (myFCGI refers to opj_server by the server setting)
       - path/filename.jp2 is the server local path or URL of a JP2 file
       - request type stateless for no caching, session (default) for caching
-      - return media type, JPT-stream tile based stream, or JPP-stream (default) precinct based stream  
+      - return media type, JPT-stream tile based stream, or JPP-stream (default) precinct based stream
+      - auxiliary return protocol, tcp or udp (udp is not implemented yet), if not given, return data is filled in http chunk
     Image viewer GUI instructions:
       Scale up request: Enlarge the window
       ROI request:      Select a region by mouse click and drag, then click inside the red frame of the selected region
@@ -119,7 +120,7 @@ Client:
       Open a new window presenting an aligned image with a locally stored image: Click button "Image Registration" (Under Construction)
 
  3. Quit the image decoding server through the telnet, be sure all image viewers are closed
-    % telnet localhost 5000
+    % telnet localhost 50000
       quit
 
 ----------
index 2dce25f784ed6f427bc625d5cbb079e183a12f30..df07b819476a7d13a19c13161a83a665aa592bc6 100644 (file)
@@ -31,6 +31,8 @@ ${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
+${CMAKE_CURRENT_SOURCE_DIR}/auxtrans_manager.c
 )
 
 SET(LOCAL_SRCS
index ce9c119529a82f784bd8ad9b8aaaa208f2265d50..fc79ef6eb0e6c761552d0693ebcbb03077eaf251 100644 (file)
@@ -29,6 +29,8 @@ target_manager.c \
 cachemodel_manager.c \
 j2kheader_manager.c \
 jp2k_encoder.c \
+sock_manager.c \
+auxtrans_manager.c \
 openjpip.h \
 bool.h \
 boxheader_manager.h \
@@ -53,7 +55,9 @@ query_parser.h \
 channel_manager.h \
 session_manager.h \
 jpip_parser.h \
-jp2k_decoder.h
+jp2k_decoder.h \
+sock_manager.h \
+auxtrans_manager.h
 
 LOCAL_SRC = jp2k_decoder.c \
 imgsock_manager.c \
diff --git a/applications/jpip/libopenjpip/auxtrans_manager.c b/applications/jpip/libopenjpip/auxtrans_manager.c
new file mode 100644 (file)
index 0000000..a0804a9
--- /dev/null
@@ -0,0 +1,266 @@
+/*
+ * $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 __linux__
+#include <pthread.h>
+#else
+#include <process.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( 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
+  int datalen;          //!< length of data
+  int 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, char cid[], void *data, int datalen, int maxlenPerFrame);
+
+void delete_auxresponse( aux_response_param_t **auxresponse);
+
+#ifdef __linux__
+void * aux_streaming( void *arg);
+#else
+unsigned __stdcall aux_streaming( void *arg);
+#endif
+
+void send_responsedata_on_aux( bool istcp, auxtrans_param_t auxtrans, char cid[], void *data, int datalen, int maxlenPerFrame)
+{
+  aux_response_param_t *auxresponse;
+#ifdef __linux__
+  pthread_t thread;
+  int status;
+#else
+  unsigned int threadId;
+#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 __linux__
+    status = pthread_create( &thread, NULL, &aux_streaming, auxresponse);
+    if( status != 0)
+      fprintf( FCGI_stderr,"ERROR: pthread_create() %s",strerror(status));
+#else
+    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));
+#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, char cid[], void *data, int datalen, int 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 __linux__
+void * aux_streaming( void *arg)
+#else
+unsigned __stdcall aux_streaming( void *arg)
+#endif
+{
+  SOCKET connected_socket;
+  unsigned char *chunk, *ptr;
+  int maxLenOfBody, remlen, chunklen;
+  const int headlen = 8;
+  
+  aux_response_param_t *auxresponse = (aux_response_param_t *)arg;
+
+#ifdef __linux__
+  pthread_detach( pthread_self());
+#else
+  CloseHandle( auxresponse->hTh);
+#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 __linux__
+  pthread_exit(0);
+#else
+  _endthreadex(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/applications/jpip/libopenjpip/auxtrans_manager.h b/applications/jpip/libopenjpip/auxtrans_manager.h
new file mode 100644 (file)
index 0000000..62107dc
--- /dev/null
@@ -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, char cid[], void *data, int length, int maxlenPerFrame);
+
+#endif /* !AUXTRANS_MANAGER_H_ */
index 4c2d3a7a507d8c9577241ef1704ee1db38c38d37..62566268e44ffe3eedc367a57bf82230a83c7abf 100644 (file)
@@ -193,3 +193,41 @@ void delete_cachemodel( cachemodel_param_t **cachemodel)
 #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
+  int i, j, k, n;
+
+  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;
+  }
+}
index 77387a29d8fd2af1b2b510842d8491cfcfa3aa6c..7452bcbb9db22e76fc05ceed26355afe0d0c438a 100644 (file)
@@ -88,6 +88,15 @@ void print_cachemodel( cachemodel_param_t cachemodel);
 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
  *
index e4727f2b8ebb04eef39283e28fb713a0f6fdd60a..240cdd9b297e4ce444b364eb9925a0c9041cda2b 100644 (file)
@@ -54,9 +54,10 @@ channellist_param_t * gene_channellist()
   return channellist;
 }
 
-channel_param_t * gene_channel( query_param_t query_param, cachemodel_param_t *cachemodel, channellist_param_t *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;
+  char transport[4][10] = { "non", "http", "http-tcp", "http-udp"};
   
   if( !cachemodel){
     fprintf( FCGI_stdout, "Status: 404\r\n"); 
@@ -70,6 +71,12 @@ channel_param_t * gene_channel( query_param_t query_param, cachemodel_param_t *c
   // 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);
@@ -81,8 +88,12 @@ channel_param_t * gene_channel( query_param_t query_param, cachemodel_param_t *c
   channellist->last = channel;
   
   fprintf( FCGI_stdout, "JPIP-cnew: cid=%s", channel->cid);
-  // only http implemented for now
-  fprintf( FCGI_stdout, ",transport=http\r\n");
+  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;
 }
index b42a2eb7fbaaa692972c1222636b7aba7498cd33..fe8281faf10eb93b59865782d41089e47506c1ab 100644 (file)
 #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
@@ -64,11 +69,12 @@ channellist_param_t * gene_channellist();
  * 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, cachemodel_param_t *cachemodel, channellist_param_t *channellist);
+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
index 1401b70f08b9557d350bb58233d35ec9da026c65..9f326f692e237e31da8580a05ab81c2407670259 100644 (file)
@@ -14,7 +14,7 @@ $(LIBNAME): openjpip.o target_manager.o byte_manager.o box_manager.o boxheader_m
        mhixbox_manager.o marker_manager.o codestream_manager.o faixbox_manager.o index_manager.o \
        msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o \
        cachemodel_manager.o j2kheader_manager.o jp2k_encoder.o query_parser.o channel_manager.o \
-       session_manager.o jpip_parser.o
+       session_manager.o jpip_parser.o sock_manager.o auxtrans_manager.o
        ar r $@ $^
 else
 $(LIBNAME): openjpip.o target_manager.o byte_manager.o box_manager.o boxheader_manager.o manfbox_manager.o \
@@ -22,7 +22,7 @@ $(LIBNAME): openjpip.o target_manager.o byte_manager.o box_manager.o boxheader_m
        msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o \
        cachemodel_manager.o j2kheader_manager.o jp2k_encoder.o  query_parser.o channel_manager.o \
        session_manager.o jpip_parser.o jp2k_decoder.o imgsock_manager.o jpipstream_manager.o cache_manager.o \
-       dec_clientmsg_handler.o
+       dec_clientmsg_handler.o sock_manager.o auxtrans_manager.o
        ar r $@ $^
 endif
 clean:
index 5fd3b038920d42492cbf6f3e4e199d8eaf6757d6..e8faa81a701ff730ffb803a86639fd09a08fa084 100644 (file)
@@ -48,6 +48,8 @@ void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist
   
   newjpipstream = receive_JPIPstream( connected_socket, &target, &tid, &cid, &newstreamlen);
 
+  fprintf( stderr, "newjpipstream length: %d\n", newstreamlen);
+  
   parse_JPIPstream( newjpipstream, newstreamlen, *streamlen, msgqueue);
 
   *jpipstream = update_JPIPstream( newjpipstream, newstreamlen, *jpipstream, streamlen);
index 0c1cbe6f00836a6d156034f3ee7c315b74950ff9..4dc4bcc604b7883e11c1d2f91dd7cf4c05da3e59 100644 (file)
  * POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifdef _WIN32
-#include <windows.h>
-#define strcasecmp  _stricmp
-#else
-#include <strings.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/uio.h>
-#include <sys/param.h>
-#include <netinet/in.h>
-#include <arpa/inet.h>
-#include <netdb.h>
-#endif
-
 #include <stdio.h>
 #include <string.h>
 #include <stdlib.h>
-#include <unistd.h>
 #include "imgsock_manager.h"
 
-#define BUF_LEN 256
-
-SOCKET open_listeningsocket()
-{
-  SOCKET listening_socket;
-  struct sockaddr_in sin;
-  int sock_optval = 1;
-  int port = 5000;
-  
-  listening_socket = socket(AF_INET, SOCK_STREAM, 0);
-  if ( listening_socket == -1 ){
-    perror("socket");
-    exit(1);
-  }
-  
-  if ( setsockopt(listening_socket, SOL_SOCKET, SO_REUSEADDR,
-                 &sock_optval, sizeof(sock_optval)) == -1 ){
-    perror("setsockopt");
-    exit(1);
-  }
-
-  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( 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);
-}
-
 msgtype_t identify_clientmsg( SOCKET connected_socket)
 {
   int receive_size;
@@ -125,9 +60,9 @@ msgtype_t identify_clientmsg( SOCKET connected_socket)
 
 Byte_t * receive_JPIPstream( SOCKET connected_socket, char **target, char **tid, char **cid, int *streamlen)
 {
-  Byte_t *jpipstream=NULL, *ptr;
   char buf[BUF_LEN], versionstring[] = "version 1.2";
-  int linelen, redlen, remlen;
+  int linelen, datalen;
+  Byte_t *jpipstream;
   
   *target = *cid = *tid = NULL;
   
@@ -159,27 +94,20 @@ Byte_t * receive_JPIPstream( SOCKET connected_socket, char **target, char **tid,
       return NULL;
   }
 
-  *streamlen = atoi( buf);
-  fprintf( stderr, "Receive Data: %d Bytes\n", *streamlen);
+  datalen = atoi( buf);
+  fprintf( stderr, "Receive Data: %d 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;
   
-  jpipstream = (unsigned  char *)malloc( (*streamlen));
-  ptr = jpipstream;
-  remlen = (*streamlen);
-  while( remlen > 0){
-    redlen = recv( connected_socket, ptr, remlen, 0);
-    if( redlen == -1){
-      fprintf( stderr, "receive JPT- JPP- stream error\n");
-      break;
-    }
-    remlen -= redlen;
-    ptr = ptr + redlen;
-  }
-    
   return jpipstream;
 }
 
-void send_stream( SOCKET connected_socket, void *stream, int length);
-
 void send_XMLstream( SOCKET connected_socket, Byte_t *xmlstream, int length)
 {
   Byte_t header[5];
@@ -255,56 +183,6 @@ void send_SIZstream( SOCKET connected_socket, unsigned int width, unsigned int h
   send_stream( connected_socket, responce, 9);
 }
 
-void send_stream( SOCKET connected_socket, void *stream, int length)
-{
-  void *ptr = stream;
-  int remlen = length;
-
-  while( remlen > 0){
-    int sentlen = send( connected_socket, ptr, remlen, 0);
-    if( sentlen == -1){
-      fprintf( stderr, "sending stream error\n");
-      break;
-    }
-    remlen = remlen - sentlen;
-    ptr = ptr + sentlen;
-  }
-}
-
-int receive_line(SOCKET connected_socket, char *p)
-{
-  int len = 0;
-  while (1){
-    int 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( stderr, "Header receive error\n");
-
-  return len;
-}
-
-char * receive_string( SOCKET connected_socket)
-{
-  char buf[BUF_LEN];
-  
-  receive_line( connected_socket, buf);
-    
-  return strdup(buf);
-}
-
 void response_signal( SOCKET connected_socket, bool succeed)
 {
   Byte_t code;
@@ -314,15 +192,5 @@ void response_signal( SOCKET connected_socket, bool succeed)
   else
     code = 0;
 
-  if( send( connected_socket, &code, 1, 0) != 1)
-    fprintf( stderr, "Response signalling error\n");
-}
-
-int close_socket( SOCKET sock)
-{
-#ifdef _WIN32
-  return closesocket( sock);
-#else
-  return close( sock);
-#endif
+  send_stream( connected_socket, &code, 1);
 }
index 7da94b90c9921ae55ecd10649957d9e3c4c73e54..7011c6bef023884d03d81dd2554d799aec444f09 100644 (file)
 
 #include "bool.h"
 #include "byte_manager.h"
-
-#ifdef _WIN32
-#include <winsock2.h>
-#else
-typedef int SOCKET;
-#endif //_WIN32
-
-/**
- * open listening socket
- *
- * @return new socket
- */
-SOCKET open_listeningsocket();
-
-/**
- * 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);
-
+#include "sock_manager.h"
 
 #define NUM_OF_MSGTYPES 9
 typedef enum eMSGTYPE{ JPIPSTREAM, PNMREQ, XMLREQ, TIDREQ, CIDREQ, CIDDST, SIZREQ, JP2SAVE, QUIT, MSGERROR} msgtype_t;
@@ -135,31 +114,6 @@ void send_SIZstream( SOCKET connected_socket, unsigned int width, unsigned int h
  */
 void response_signal( SOCKET connected_socket, bool succeed);
 
-/**
- * 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
- */
-int 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);
-
-/**
- * close socket
- *
- * @param [in] sock closing socket
- * @return     0 if succeed, -1 if failed
- */
-int close_socket( SOCKET sock);
-
 #endif /* !IMGSOCK_MANAGER_H_ */
 
 /*! \file
index eb4e76f0b14c67e1c04b74da821635609d16aa73..7697297decb22d32648a2b29e2a9beb2d43dcec6 100644 (file)
 
 bool identify_target( query_param_t query_param, targetlist_param_t *targetlist, target_param_t **target)
 {
-  if( query_param.tid[0] !='\0' && 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( 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( ( *target = search_targetBytid( query_param.tid, targetlist)))
-      return true;
   }
 
-  if( query_param.target[0] !='\0')
+  if( query_param.target)
     if( !( *target = search_target( query_param.target, targetlist)))
       if(!( *target = gene_target( targetlist, query_param.target)))
        return false;
@@ -93,6 +95,7 @@ bool associate_channel( query_param_t    query_param,
 
 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)
@@ -110,7 +113,7 @@ bool open_channel( query_param_t query_param,
     if( *curchannel)
       cachemodel = (*curchannel)->cachemodel;
 
-  *curchannel = gene_channel( query_param, cachemodel, (*cursession)->channellist);
+  *curchannel = gene_channel( query_param, auxtrans, cachemodel, (*cursession)->channellist);
   if( *curchannel == NULL)
     return false;
 
@@ -122,7 +125,10 @@ bool close_channel( query_param_t query_param,
                    session_param_t **cursession, 
                    channel_param_t **curchannel)
 {
-  if( query_param.cclose[0][0] =='*'){
+  char *cclose;
+  int i;
+  
+  if( query_param.cclose[0] =='*'){
 #ifndef SERVER
     fprintf( logstream, "local log: close all\n");
 #endif
@@ -132,28 +138,25 @@ bool close_channel( query_param_t query_param,
   }
   else{
     // check if all entry belonging to the same session
-    int i=0;
-    while( query_param.cclose[i][0] !='\0'){
+    
+    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( query_param.cclose[i], sessionlist, cursession, curchannel))
+       if( !search_session_and_channel( cclose, sessionlist, cursession, curchannel))
          return false;
       }
       else // second or more entry of close cid
-       if( !(*curchannel=search_channel( query_param.cclose[i], (*cursession)->channellist))){
-         fprintf( FCGI_stdout, "Reason: Cclose id %s is from another session\r\n", query_param.cclose[i]); 
+       if( !(*curchannel=search_channel( cclose, (*cursession)->channellist))){
+         fprintf( FCGI_stdout, "Reason: Cclose id %s is from another session\r\n", cclose); 
          return false;
        }
-      i++;
     }
+
     // delete channels
-    i=0;
-    while( query_param.cclose[i][0] !='\0'){
-      
-      *curchannel = search_channel( query_param.cclose[i], (*cursession)->channellist);
+    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);
-      i++;
     }
     
     if( (*cursession)->channellist->first == NULL || (*cursession)->channellist->last == NULL)
index 9f3cd8a45fcef29cfc6ac818691943268428a506..8070c8a92da8ee1eb638aebc8c3df80f4f600b4f 100644 (file)
@@ -68,6 +68,7 @@ bool associate_channel( query_param_t    query_param,
  *
  * @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
@@ -75,6 +76,7 @@ bool associate_channel( query_param_t    query_param,
  */
 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);
index 8244de06e8b9f5f1c180f9fafaf9a6816a8f626e..279054f68b4dc15daaea00bd356f534f5c4081b3 100644 (file)
@@ -383,13 +383,12 @@ void enqueue_message( message_param_t *msg, msgqueue_param_t *msgqueue)
   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 emit_bin_id_vbas( Byte_t bb, Byte_t c, Byte8_t in_class_id);
-void emit_vbas( Byte8_t code);
-void emit_body( message_param_t *msg, int fd);
-void emit_placeholder( placeholder_param_t *phld);
-
-void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue)
+void recons_stream_from_msgqueue( msgqueue_param_t *msgqueue, int tmpfd)
 {
   message_param_t *msg;
   Byte8_t class_id, csn;
@@ -417,33 +416,33 @@ void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue)
     }
 
     c = msg->last_byte ? 1 : 0;
-      
-    emit_bin_id_vbas( bb, c, msg->in_class_id);
+    
+    add_bin_id_vbas_stream( bb, c, msg->in_class_id, tmpfd);
     
     if( bb >= 2)
-      emit_vbas( class_id);
+      add_vbas_stream( class_id, tmpfd);
     if (bb == 3)
-      emit_vbas( csn);
+      add_vbas_stream( csn, tmpfd);
     
-    emit_vbas( msg->bin_offset);
-    emit_vbas (msg->length);
+    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
-      emit_vbas( msg->aux);
+      add_vbas_stream( msg->aux, tmpfd);
 
     if( msg->phld)
-      emit_placeholder( msg->phld);
+      add_placeholder_stream( msg->phld, tmpfd);
     else
-      emit_body( msg, msgqueue->cachemodel->target->fd);
+      add_body_stream( msg, msgqueue->cachemodel->target->fd, tmpfd);
 
     msg = msg->next;
   }
 }
 
-void emit_vbas_with_bytelen( Byte8_t code, int bytelength);
+void add_vbas_with_bytelen_stream( Byte8_t code, int bytelength, int tmpfd);
 void print_binarycode( Byte8_t n, int segmentlen);
 
-void emit_bin_id_vbas( Byte_t bb, Byte_t c, Byte8_t in_class_id)
+void add_bin_id_vbas_stream( Byte_t bb, Byte_t c, Byte8_t in_class_id, int tmpfd)
 {
   int bytelength;
   Byte8_t tmp;
@@ -459,10 +458,10 @@ void emit_bin_id_vbas( Byte_t bb, Byte_t c, Byte8_t in_class_id)
 
   in_class_id |= (((bb & 3) << 5) | (c & 1) << 4) << ((bytelength-1)*7);
   
-  emit_vbas_with_bytelen( in_class_id, bytelength);
+  add_vbas_with_bytelen_stream( in_class_id, bytelength, tmpfd);
 }
 
-void emit_vbas( Byte8_t code)
+void add_vbas_stream( Byte8_t code, int tmpfd)
 {
   int bytelength;
   Byte8_t tmp;
@@ -472,10 +471,10 @@ void emit_vbas( Byte8_t code)
   while( tmp >>= 7)
     bytelength ++;
 
-  emit_vbas_with_bytelen( code, bytelength);
+  add_vbas_with_bytelen_stream( code, bytelength, tmpfd);
 }
 
-void emit_vbas_with_bytelen( Byte8_t code, int bytelength)
+void add_vbas_with_bytelen_stream( Byte8_t code, int bytelength, int tmpfd)
 {
   int n;
   Byte8_t seg;
@@ -485,47 +484,47 @@ void emit_vbas_with_bytelen( Byte8_t code, int bytelength)
     seg = ( code >> (n*7)) & 0x7f;
     if( n)
       seg |= 0x80;
-    fputc(( Byte4_t)seg, FCGI_stdout);
+    write( tmpfd, ( Byte4_t *)&seg, 1);
     n--;
   }
 }
 
-void emit_body( message_param_t *msg, int fd)
+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 emit_body()\n");
+    fprintf( FCGI_stderr, "Error: fetch_bytes in add_body_stream()\n");
     return;
   }
 
-  if( fwrite( data, msg->length, 1, FCGI_stdout) < 1){
+  if( write( tmpfd, data, msg->length) < 1){
     free( data);
-    fprintf( FCGI_stderr, "Error: fwrite in emit_body()\n");
+    fprintf( FCGI_stderr, "Error: fwrite in add_body_stream()\n");
     return;
   }
   free(data);
 }
 
-void emit_bigendian_bytes( Byte8_t code, int bytelength);
+void add_bigendian_bytestream( Byte8_t code, int bytelength, int tmpfd);
 
-void emit_placeholder( placeholder_param_t *phld)
+void add_placeholder_stream( placeholder_param_t *phld, int tmpfd)
 {
-  emit_bigendian_bytes( phld->LBox, 4);
-  if( fwrite( phld->TBox, 4, 1, FCGI_stdout) < 1){
-    fprintf( FCGI_stderr, "Error: fwrite in emit_placeholder()\n");
+  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;
   }
-  emit_bigendian_bytes( phld->Flags, 4);
-  emit_bigendian_bytes( phld->OrigID, 8);
+  add_bigendian_bytestream( phld->Flags, 4, tmpfd);
+  add_bigendian_bytestream( phld->OrigID, 8, tmpfd);
 
-  if( fwrite( phld->OrigBH, phld->OrigBHlen, 1, FCGI_stdout) < 1){
-    fprintf( FCGI_stderr, "Error: fwrite in emit_placeholder()\n");
+  if( write( tmpfd, phld->OrigBH, phld->OrigBHlen) < 1){
+    fprintf( FCGI_stderr, "Error: fwrite in add_placeholder_stream()\n");
     return;
   }
 }
 
-void emit_bigendian_bytes( Byte8_t code, int bytelength)
+void add_bigendian_bytestream( Byte8_t code, int bytelength, int tmpfd)
 {
   int n;
   Byte8_t seg;
@@ -533,7 +532,7 @@ void emit_bigendian_bytes( Byte8_t code, int bytelength)
   n = bytelength - 1;
   while( n >= 0) {
     seg = ( code >> (n*8)) & 0xff;
-    fputc(( Byte4_t)seg, FCGI_stdout);
+    write( tmpfd, ( Byte4_t *)&seg, 1);
     n--;
   }
 }
index 7236d89c607c39ab7eb0d9842bbafc98f18afb9e..23dad76b8da2770ccbcf8dda028593a14aa779f7 100644 (file)
@@ -145,11 +145,12 @@ void enqueue_metadata( int meta_id, msgqueue_param_t *msgqueue);
 
 
 /**
- * emit stream from message queue
+ * reconstruct JPT/JPP-stream from message queue
  *
  * @param[in] msgqueue message queue pointer
+ * @param[in] tmpfd    file discriptor to write JPT/JPP-stream
  */
-void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue);
+void recons_stream_from_msgqueue( msgqueue_param_t *msgqueue, int tmpfd);
 
 
 /**
index 00f9a7a32afc2acaec6a2ea6ae91eae90fcbf7bd..df1e3eb6b292480c58a534ca4ee470c8af3aab00 100644 (file)
@@ -32,6 +32,8 @@
 #include "openjpip.h"
 #include "jpip_parser.h"
 #include "channel_manager.h"
+#include "byte_manager.h"
+#include "auxtrans_manager.h"
 
 #include <stdio.h>
 #include "dec_clientmsg_handler.h"
 #include <unistd.h>
 #include "jp2k_encoder.h"
 
-server_record_t * init_JPIPserver()
+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);
-
+  delete_targetlist( &(*rec)->targetlist); 
+  close_aux_transport( (*rec)->auxtrans);
+   
   free( *rec);
 }
 
@@ -69,8 +73,8 @@ QR_t * parse_querystring( char *query_string)
   qr = (QR_t *)malloc( sizeof(QR_t));
     
   qr->query = parse_query( query_string);
-  
   qr->msgqueue = NULL;
+  qr->channel = NULL;
 
   return qr;
 }
@@ -81,35 +85,83 @@ bool process_JPIPrequest( server_record_t *rec, QR_t *qr)
   session_param_t *cursession = NULL;
   channel_param_t *curchannel = NULL;
 
-  if( qr->query->target[0] != '\0' || qr->query->tid[0] != '\0'){
+  if( qr->query->target || qr->query->tid){
     if( !identify_target( *(qr->query), rec->targetlist, &target))
       return false;
   }
 
-  if( qr->query->cid[0] != '\0'){
+  if( qr->query->cid){
     if( !associate_channel( *(qr->query), rec->sessionlist, &cursession, &curchannel))
       return false;
+    qr->channel = curchannel;
   }
-
-  if( qr->query->cnew){
-    if( !open_channel( *(qr->query), rec->sessionlist, target, &cursession, &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[0][0] != '\0')
+  
+  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)
     if( !gene_JPIPstream( *(qr->query), target, cursession, curchannel, &qr->msgqueue))
       return false;
-  
+
   return true;
 }
 
-void send_responsedata( QR_t *qr)
+void add_EORmsg( int fd, QR_t *qr);
+
+void send_responsedata( server_record_t *rec, QR_t *qr)
+{
+  int fd;
+  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 = get_filesize( fd);
+  jpipstream = fetch_bytes( fd, 0, len_of_jpipstream);
+
+  close( fd);
+  remove( tmpfname);
+
+  fprintf( FCGI_stdout, "\r\n");
+
+  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;
+    }
+  
+  fwrite( jpipstream, len_of_jpipstream, 1, FCGI_stdout);
+  free( jpipstream);
+  return;
+}
+
+void add_EORmsg( int fd, QR_t *qr)
 {
-  // Currently HTTP support only, find a way for TCP, UDP case
-  emit_stream_from_msgqueue( qr->msgqueue);
+  unsigned char EOR[3];
+
+  if( qr->channel){
+    EOR[0] = 0x00;   
+    EOR[1] = is_allsent( *(qr->channel->cachemodel)) ? 0x01 : 0x02;
+    EOR[2] = 0x00;
+    write( fd, EOR, 3);
+  }
 }
 
 void end_QRprocess( server_record_t *rec, QR_t **qr)
@@ -138,7 +190,7 @@ void local_log( bool query, bool messages, bool sessions, bool targets, QR_t *qr
 
 #ifndef SERVER
 
-dec_server_record_t * init_dec_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));
 
@@ -146,7 +198,7 @@ dec_server_record_t * init_dec_server()
   record->jpipstream = NULL;
   record->jpipstreamlen = 0;
   record->msgqueue = gene_msgqueue( true, NULL);
-  record->listening_socket = open_listeningsocket();
+  record->listening_socket = open_listeningsocket( port);
 
   return record;
 }
@@ -221,12 +273,13 @@ bool handle_clientreq( client_t client, dec_server_record_t *rec)
   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;
 
index c4011f8555f57f435560a415665a0204b7cbb2b9..4f7941fed75aae77d03bccb928b9c92b98309dbd 100644 (file)
 #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 "ihdrbox_manager.h"
 #include "index_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
 
 /* 
 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;
-  msgqueue_param_t *msgqueue;
+  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
  *
- * @return intialized server record pointer
+ * @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();
+server_record_t * init_JPIPserver( int tcp_auxport, int udp_auxport);
 
 /**
  * Terminate the JPIP server
@@ -106,9 +116,10 @@ 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( QR_t *qr);
+void send_responsedata( server_record_t *rec, QR_t *qr);
 
 /**
  * 4th (last) process; 
@@ -158,9 +169,10 @@ typedef SOCKET client_t;
 /**
  * Initialize the image decoding server
  *
- * @return intialized decoding server record pointer
+ * @param[in] port opening tcp port (valid No. 49152–65535)
+ * @return         intialized decoding server record pointer
  */
-dec_server_record_t * init_dec_server();
+dec_server_record_t * init_dec_server( int port);
 
 /**
  * Terminate the  image decoding server
index 1293c0a814a37680e2125331f5abe46608297f9d..f8449debd1b144d31054d30feac273d50ea35980 100644 (file)
@@ -69,14 +69,7 @@ query_param_t * get_initquery();
  */
 char * get_fieldparam( char *stringptr, char *fieldname, char *fieldval);
 
-/**
- * parse string to string array
- *
- * @param[in]  src src string
- * @param[out] cclose parsed string array
- */
-void str2cclose( char *src, char cclose[][MAX_LENOFCID]);
-
+void parse_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)
@@ -104,10 +97,10 @@ query_param_t * parse_query( char *query_string)
 
     if( fieldname[0] != '\0'){
       if( strcasecmp( fieldname, "target") == 0)
-       strcpy( query_param->target,fieldval);
+       query_param->target = strdup( fieldval);
       
       else if( strcasecmp( fieldname, "tid") == 0)
-       strcpy( query_param->tid, fieldval);
+       query_param->tid = strdup( fieldval);
 
       else if( strcasecmp( fieldname, "fsiz") == 0)
        sscanf( fieldval, "%d,%d", &query_param->fx, &query_param->fy);
@@ -122,13 +115,17 @@ query_param_t * parse_query( char *query_string)
        sscanf( fieldval, "%d", &query_param->layers);
       
       else if( strcasecmp( fieldname, "cid") == 0)
-       strcpy( query_param->cid, fieldval);
+       query_param->cid = strdup( fieldval);
 
-      else if( strcasecmp( fieldname, "cnew") == 0)
-       query_param->cnew = true;
+      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)
-       str2cclose( fieldval, query_param->cclose);
+       parse_cclose( fieldval, query_param);
       
       else if( strcasecmp( fieldname, "metareq") == 0)
        parse_metareq( fieldval, query_param);
@@ -157,8 +154,8 @@ query_param_t * get_initquery()
 
   query = (query_param_t *)malloc( sizeof(query_param_t));
 
-  query->target[0] = '\0';
-  query->tid[0] = '\0';
+  query->target = NULL;
+  query->tid = NULL;
   query->fx = -1;
   query->fy = -1;
   query->rx = -1;
@@ -168,9 +165,10 @@ query_param_t * get_initquery()
   query->layers = -1;
   query->lastcomp = -1;
   query->comps = NULL;  
-  query->cid[0] = '\0';
-  query->cnew = false;
-  memset( query->cclose, 0, MAX_NUMOFCCLOSE*MAX_LENOFCID);
+  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++){
@@ -218,14 +216,21 @@ char * get_fieldparam( char *stringptr, char *fieldname, char *fieldval)
 void print_queryparam( query_param_t query_param)
 {
   int i;
+  char *cclose;
 
   fprintf( logstream, "query parameters:\n");
-  fprintf( logstream, "\t target: %s\n", query_param.target);
-  fprintf( logstream, "\t tid: %s\n", query_param.tid);
+  
+  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{
@@ -235,13 +240,20 @@ void print_queryparam( query_param_t query_param)
     fprintf( logstream, "\n");
   }
   fprintf( logstream, "\t cnew: %d\n", query_param.cnew);
-  fprintf( logstream, "\t cid: %s\n", query_param.cid);
   
-  fprintf( logstream, "\t cclose: ");
-  for( i=0; query_param.cclose[i][0]!=0 && i<MAX_NUMOFCCLOSE; i++)
-    fprintf( logstream, "%s ", query_param.cclose[i]);
-  fprintf(logstream, "\n");
+  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]);
@@ -254,20 +266,21 @@ void print_queryparam( query_param_t query_param)
   fprintf( logstream, "\t len:  %d\n", query_param.len);
 }
 
-void str2cclose( char *src, char cclose[][MAX_LENOFCID])
+void parse_cclose( char *src, query_param_t *query_param)
 {
-  int i, u, v;
-
-  size_t len = strlen( src);
+  int i;
+  size_t len;
   
-  for( i=0, u=0, v=0; i<len; i++){
-    if( src[i]==','){
-      u++;
-      v=0;
+  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 ++;
     }
-    else
-      cclose[u][v++] = src[i];
-  }
+  
+  query_param->numOfcclose ++;
 }
 
 void parse_req_box_prop( char *req_box_prop, int idx, query_param_t *query_param);
@@ -386,6 +399,20 @@ void parse_comps( char *field, query_param_t *query_param)
 
 void delete_query( query_param_t **query)
 {
-  free((*query)->comps);
+  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);
 }
index d42385ae67c2522909feae4652651ffc2a3f138f..7774b3d8233fb3f285fea7edd535e9d531ac5361 100644 (file)
 
 #include "bool.h"
 
-//! maximum length of target name
-#define MAX_LENOFTARGET 128
-//! maximum length of target identifier
-#define MAX_LENOFTID 30
-
-//! maximum length of channel identifier
-#define MAX_LENOFCID 30
-
-//! maximum number of closing channel
-#define MAX_NUMOFCCLOSE 10
-
 //! maximum number of meta request box
 #define MAX_NUMOFBOX 10
 
+//! 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[MAX_LENOFTARGET];               //!< target name
-  char tid[MAX_LENOFTID];                     //!< target identifier
+  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[MAX_LENOFCID];                     //!< channel identifier
-  bool cnew;                                  //!< if there is new channel request(true) or not (false)
-  char cclose[MAX_NUMOFCCLOSE][MAX_LENOFCID]; //!< closing channel identifiers
+  char *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
diff --git a/applications/jpip/libopenjpip/sock_manager.c b/applications/jpip/libopenjpip/sock_manager.c
new file mode 100644 (file)
index 0000000..b84bc98
--- /dev/null
@@ -0,0 +1,179 @@
+/*
+ * $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>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.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( int 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, void *stream, int length)
+{
+  void *ptr = stream;
+  int remlen = length;
+
+  while( remlen > 0){
+    int sentlen = send( connected_socket, ptr, remlen, 0);
+    if( sentlen == -1){
+      fprintf( FCGI_stderr, "sending stream error\n");
+      break;
+    }
+    remlen = remlen - sentlen;
+    ptr = ptr + sentlen;
+  }
+}
+
+void * receive_stream( SOCKET connected_socket, int length)
+{
+  void *stream, *ptr;
+  int remlen, redlen;
+
+  ptr = stream = malloc( length);
+  remlen = length;
+
+  while( remlen > 0){
+    redlen = recv( connected_socket, ptr, remlen, 0);
+    if( redlen == -1){
+      fprintf( FCGI_stderr, "receive stream error\n");
+      free( stream);
+      stream = NULL;
+      break;
+    }
+    remlen -= redlen;
+    ptr = ptr + redlen;
+  }
+  return stream;
+}
+
+int receive_line(SOCKET connected_socket, char *p)
+{
+  int len = 0;
+  while (1){
+    int 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];
+  
+  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/applications/jpip/libopenjpip/sock_manager.h b/applications/jpip/libopenjpip/sock_manager.h
new file mode 100644 (file)
index 0000000..82591c0
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * $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"
+
+#ifdef _WIN32
+#include <winsock2.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( int 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
+ */
+int 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, int 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, void *stream, int length);
+
+/**
+ * close socket
+ *
+ * @param [in] sock closing socket
+ * @return     0 if succeed, -1 if failed
+ */
+int close_socket( SOCKET sock);
+
+#endif /* !SOCK_MANAGER_H_ */
index 56f23a6f1b5f5878554650a3e6bca190fd7752a5..9a8260751f29ed9cea846d9e1bfafafa04d3e1c9 100644 (file)
 #include <unistd.h>
 #include <fcntl.h>
 #include <time.h>
-#include <curl/curl.h>
 #include "target_manager.h"
 
 #ifdef SERVER
+#include <curl/curl.h>
 #include "fcgi_stdio.h"
 #define logstream FCGI_stdout
 #else
@@ -48,7 +48,6 @@
 #define logstream stderr
 #endif //SERVER
 
-
 targetlist_param_t * gene_targetlist()
 {
   targetlist_param_t *targetlist;
@@ -98,10 +97,12 @@ target_param_t * gene_target( targetlist_param_t *targetlist, char *targetpath)
   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; 
@@ -137,10 +138,12 @@ 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);
@@ -239,31 +242,17 @@ target_param_t * search_targetBytid( char tid[], targetlist_param_t *targetlist)
   return NULL;
 }
 
-static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream);
+int open_remotefile( char filepath[], char tmpfname[]);
 
 int open_jp2file( char filepath[], char tmpfname[])
 {
   int fd;
   char *data;
-  CURL *curl_handle;
   
   // download remote target file to local storage
   if( strncmp( filepath, "http://", 7) == 0){
-    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);
+    if( (fd = open_remotefile( filepath, tmpfname)) == -1)
       return -1;
-    }
-    curl_easy_setopt(curl_handle, CURLOPT_WRITEDATA, &fd);
-    curl_easy_perform(curl_handle);
-    curl_easy_cleanup(curl_handle);
   }
   else{
     tmpfname[0] = 0;
@@ -301,6 +290,43 @@ int open_jp2file( char filepath[], char tmpfname[])
   return fd;
 }
 
+#ifdef SERVER
+static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream);
+#endif
+
+int open_remotefile( char filepath[], char tmpfname[])
+{
+#ifndef SERVER
+
+  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;
@@ -308,3 +334,4 @@ static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
 
   return written;
 }
+#endif //SERVER
index f51b6a4106f2e963119d1aa958d6b27a2c174458..28dc9ab0772c602807c716f4f861360bf89c6a1f 100644 (file)
 //! target parameters
 typedef struct target_param{
   char tid[MAX_LENOFTID];         //!< taregt identifier
-  char *targetname;               //!< local file path or URL
+  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
index 418c5da385fe3998a5818e4ce3de2f28c527b120..044121eadabebb6500bf6eef3857faf112b7c502 100644 (file)
@@ -2,13 +2,13 @@ JPIPLIBDIR = ../libopenjpip
 
 SLIBFNAME = $(JPIPLIBDIR)/libopenjpip_server.a
 SCFLAGS  = -O3 -Wall -m32 -I$(JPIPLIBDIR) -DSERVER -DQUIT_SIGNAL=\"quitJPIP\"
-SLDFLAGS = -L$(JPIPLIBDIR) -lm -lfcgi -lcurl -lopenjpip_server
+SLDFLAGS = -L$(JPIPLIBDIR) -lm -lfcgi -lcurl -lpthread -lopenjpip_server
 
 J2KINCDIR = ../../../libopenjpeg
 J2KLIBDIR = $(J2KINCDIR)/.libs
 LIBFNAME = $(JPIPLIBDIR)/libopenjpip_local.a $(J2KLIBDIR)/libopenjpeg.a
 CFLAGS  = -O3 -Wall -I$(JPIPLIBDIR)
-LDFLAGS = -L$(JPIPLIBDIR) -L$(J2KLIBDIR) -lm -lcurl -lopenjpip_local
+LDFLAGS = -L$(JPIPLIBDIR) -L$(J2KLIBDIR) -lm -lpthread -lopenjpip_local
 
 ALL = opj_server opj_dec_server jpip_to_jp2 jpip_to_j2k test_index addXMLinJP2
 
index 7eee9a84354bc26f66a8fda09d8499989a17d93d..0ad3a0526aacf3369d42263afe4187967ca1d479 100644 (file)
@@ -64,7 +64,7 @@ int main(int argc, char *argv[]){
     printf( "Initialisation Winsock\n");
 #endif //_WIN32
   
-  server_record = init_dec_server(); 
+  server_record = init_dec_server( 50000);
   
   while(( client = accept_connection( server_record)) != -1 )
     if(!handle_clientreq( client, server_record))
index 5b435cfb938842993d35c84971de59b4a42e0cb7..d66a2c65e08b43e29d1ff14bda5165495ea8c980 100644 (file)
 #define QUIT_SIGNAL "quitJPIP"
 #endif
 
+#ifdef _WIN32
+WSADATA initialisation_win32;
+#endif //_WIN32
+
 int main(void)
 { 
   server_record_t *server_record;
 
-  server_record = init_JPIPserver();
+#ifdef _WIN32
+  int erreur = WSAStartup(MAKEWORD(2,2),&initialisation_win32);
+  if( erreur!=0)
+    fprintf( stderr, "Erreur initialisation Winsock error : %d %d\n",erreur,WSAGetLastError());
+  else
+    fprintf( stderr, "Initialisation Winsock\n");
+#endif //_WIN32
+
+  server_record = init_JPIPserver( 60000, 0);
 
 #ifdef SERVER
 
@@ -89,10 +101,8 @@ int main(void)
       local_log( true, true, parse_status, false, qr, server_record);
 #endif
             
-      fprintf( FCGI_stdout, "\r\n");
-
       if( parse_status)
-       send_responsedata( qr);
+       send_responsedata( server_record, qr);
       else
        fprintf( FCGI_stderr, "Error: JPIP request failed\n");
       
@@ -103,5 +113,13 @@ int main(void)
 
   terminate_JPIPserver( &server_record);
 
+#ifdef _WIN32
+  if( WSACleanup() != 0){
+    fprintf( stderr, "\nError in WSACleanup : %d %d",erreur,WSAGetLastError());
+  }else{
+    fprintf( stderr, "\nWSACleanup OK\n");
+  }
+#endif
+
   return 0;
 }
diff --git a/applications/jpip/util/opj_viewer/dist/opj_viewer-20111116.jar b/applications/jpip/util/opj_viewer/dist/opj_viewer-20111116.jar
deleted file mode 100644 (file)
index cfdf660..0000000
Binary files a/applications/jpip/util/opj_viewer/dist/opj_viewer-20111116.jar and /dev/null differ
diff --git a/applications/jpip/util/opj_viewer/dist/opj_viewer-20111130.jar b/applications/jpip/util/opj_viewer/dist/opj_viewer-20111130.jar
new file mode 100644 (file)
index 0000000..b3e7cf0
Binary files /dev/null and b/applications/jpip/util/opj_viewer/dist/opj_viewer-20111130.jar differ
index 07d0dbd54133c5a2eba04c7d10e6296bd734ebe9..3a74bc3158f8dbaa8bda537187660f3ca26c31a9 120000 (symlink)
@@ -1 +1 @@
-opj_viewer-20111116.jar
\ No newline at end of file
+opj_viewer-20111130.jar
\ No newline at end of file
index bd4cadd192c210c1f2ecad238208952908b2a79f..744d20603e3aabc8e54da6ea123f0f89816c5d25 100644 (file)
@@ -60,7 +60,7 @@ public class ImageManager extends JPIPHttpClient
     }
     public int getOrigHeight(){ return origheight;}
     
-    public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew, boolean reqJPP, boolean reqJPT)
+    public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
     {
        System.err.println();
        
@@ -69,17 +69,17 @@ public class ImageManager extends JPIPHttpClient
        
        // Todo: check if the cid is for the same stream type
        if( reqcnew)
-           refcid = ImgdecClient.query_cid( j2kfilename);      
+           refcid = ImgdecClient.query_cid( j2kfilename);
        
        if( refcid == null){
            String reftid = ImgdecClient.query_tid( j2kfilename);
            if( reftid == null)
-               jpipstream = super.requestViewWindow( j2kfilename, reqfw, reqfh, reqcnew, reqJPP, reqJPT);
+               jpipstream = super.requestViewWindow( j2kfilename, reqfw, reqfh, reqcnew, reqaux, reqJPP, reqJPT);
            else
-               jpipstream = super.requestViewWindow( j2kfilename, reftid, reqfw, reqfh, reqcnew, reqJPP, reqJPT);
+               jpipstream = super.requestViewWindow( j2kfilename, reftid, reqfw, reqfh, reqcnew, reqaux, reqJPP, reqJPT);
        }
        else
-           jpipstream = super.requestViewWindow( reqfw, reqfh, refcid, reqcnew, reqJPP, reqJPT);
+           jpipstream = super.requestViewWindow( reqfw, reqfh, refcid, reqcnew, reqaux, reqJPP, reqJPT);
        
        System.err.println( "decoding to PNM image");
        if((pnmimage = ImgdecClient.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh))!=null){
index dcd661412def80ca0c151f6d8b1afcc40fd66688..163193b9284211015f1c549de6b552b8df5a2845 100644 (file)
@@ -53,7 +53,7 @@ public class ImageViewer extends JPanel
     private Rectangle roirect[] = null;
     private String roiname[] = null;
       
-    public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream)
+    public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream, int aux)
     {
        String str;
        MML myMML;
@@ -69,8 +69,8 @@ public class ImageViewer extends JPanel
 
        imgmanager = manager;
 
-       img = imgmanager.getImage( j2kfilename, vw, vh, session, jppstream, !jppstream);
-
+       img = imgmanager.getImage( j2kfilename, vw, vh, session, aux, jppstream, !jppstream);
+       
        addMouseListener(myMML);
        addMouseMotionListener(myMML);
        addComponentListener( new ResizeListener(this));
index 4f44cced129eece0a42da72af618b9b4ed22c98e..5cf94db649e32280708695f0e92dedf331f54003 100644 (file)
@@ -37,13 +37,13 @@ public class ImageWindow extends JFrame
     private ImageViewer imgviewer;
     private ImageManager imgmanager;
     
-    public ImageWindow( String uri, String j2kfilename, boolean session, boolean jppstream)
+    public ImageWindow( String uri, String j2kfilename, boolean session, boolean jppstream, int aux)
     {
        super( j2kfilename);
 
        imgmanager = new ImageManager( uri);
-    
-       imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream);
+       
+       imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream, aux);
        imgviewer.setOpaque(true); //content panes must be opaque
 
        JPanel panel = new JPanel();
@@ -68,6 +68,7 @@ public class ImageWindow extends JFrame
     {
        String j2kfilename, uri;
        boolean session, jppstream;
+       int aux; // 0: none, 1: tcp, 2: udp
 
        if(s.length >= 2){
            uri = s[0];
@@ -81,12 +82,21 @@ public class ImageWindow extends JFrame
                jppstream = !s[3].equalsIgnoreCase( "JPT");
            else
                jppstream = true;
+
+           if( s.length > 4){
+               if( s[4].equalsIgnoreCase("udp"))
+                   aux = 2;
+               else
+                   aux = 1;
+           }
+           else
+               aux = 0;
        }
        else{
-           System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2 [stateless/session] [JPT/JPP]");
+           System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2 [stateless/session] [JPT/JPP] [tcp/udp]");
            return;
        }
-       ImageWindow frame = new ImageWindow( uri, j2kfilename, session, jppstream);
+       ImageWindow frame = new ImageWindow( uri, j2kfilename, session, jppstream, aux);
     
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
index f956d05b1f4c4718a8aab7b3c176130b8d7d67db..27750de7af87f744ab94574544539bbdb07c435e 100644 (file)
@@ -49,7 +49,7 @@ public class ImgdecClient{
     public static void send_JPIPstream( byte[] jpipstream)
     {
        try{
-           Socket imgdecSocket = new Socket( "localhost", 5000);
+           Socket imgdecSocket = new Socket( "localhost", 50000);
            DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
            DataInputStream  is = new DataInputStream( imgdecSocket.getInputStream());
       
@@ -74,7 +74,7 @@ public class ImgdecClient{
     public static void send_JPIPstream( byte[] jpipstream, String j2kfilename, String tid, String cid)
     {
        try{
-           Socket imgdecSocket = new Socket( "localhost", 5000);
+           Socket imgdecSocket = new Socket( "localhost", 50000);
            DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
            DataInputStream  is = new DataInputStream( imgdecSocket.getInputStream());
            int length = 0;
@@ -114,7 +114,7 @@ public class ImgdecClient{
        PnmImage pnmstream = null;
        
        try {
-           Socket imgdecSocket = new Socket( "localhost", 5000);
+           Socket imgdecSocket = new Socket( "localhost", 50000);
            DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
            DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
            byte []header = new byte[7];
@@ -171,7 +171,7 @@ public class ImgdecClient{
        byte []xmldata = null;
 
        try{
-           Socket imgdecSocket = new Socket( "localhost", 5000);
+           Socket imgdecSocket = new Socket( "localhost", 50000);
            DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
            DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
            byte []header = new byte[5];
@@ -222,7 +222,7 @@ public class ImgdecClient{
        String id = null;
        
        try{
-           Socket imgdecSocket = new Socket( "localhost", 5000);
+           Socket imgdecSocket = new Socket( "localhost", 50000);
            DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
            DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
            byte []header = new byte[4];
@@ -259,7 +259,7 @@ public class ImgdecClient{
        java.awt.Dimension dim = null;
 
        try{
-           Socket imgdecSocket = new Socket( "localhost", 5000);
+           Socket imgdecSocket = new Socket( "localhost", 50000);
            DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
            DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
            byte []header = new byte[3];
@@ -321,7 +321,7 @@ public class ImgdecClient{
     public static void destroy_cid( String cid)
     {
        try{
-           Socket imgdecSocket = new Socket( "localhost", 5000);
+           Socket imgdecSocket = new Socket( "localhost", 50000);
            DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
            DataInputStream  is = new DataInputStream( imgdecSocket.getInputStream());
            
index e4c86a97c3d29e382f4afaaa3ef41d8a5fcb1989..ce9a301d51bb4ecc8170f25d49542b0370cd1eff 100644 (file)
@@ -43,6 +43,9 @@ public class JPIPHttpClient
     protected String tid;
     private boolean JPTstream;
     private boolean JPPstream;
+    private boolean aux;
+    private boolean tcp; // true: tcp, false: udp
+    private int port;
     
     public JPIPHttpClient( String URI)
     {
@@ -52,8 +55,8 @@ public class JPIPHttpClient
        rw = rh = -1;
        cid = null;
        tid = null;
-       JPTstream = false;
-       JPPstream = false;
+       JPTstream = JPPstream = aux = false;
+       port = 0;
     }
 
     public int getFw(){ return fw;}
@@ -77,51 +80,50 @@ public class JPIPHttpClient
            return requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh, cid);
        else
            if( tid != null)
-               return requestViewWindow( null, tid, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false, false, false);
+               return requestViewWindow( null, tid, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false, 0, false, false);
            else
                return null;
     }
 
     public byte[] requestViewWindow( int reqfw, int reqfh, String reqcid)
     {
-       return requestViewWindow( null, null, reqfw, reqfh, -1, -1, -1, -1, reqcid, false, false, false);
+       return requestViewWindow( null, null, reqfw, reqfh, -1, -1, -1, -1, reqcid, false, 0, false, false);
     }
 
     public byte[] requestViewWindow( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh, String reqcid)
     {
-       return requestViewWindow( null, null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, false, false, false);
+       return requestViewWindow( null, null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, false, 0, false, false);
     }
 
     public byte[] requestViewWindow( String target, int reqfw, int reqfh)
     {
-       return requestViewWindow( target, null, reqfw, reqfh, -1, -1, -1, -1, null, false, false, false);
+       return requestViewWindow( target, null, reqfw, reqfh, -1, -1, -1, -1, null, false, 0, false, false);
     }
     
-    public byte[] requestViewWindow( String target, int reqfw, int reqfh, boolean reqcnew, boolean reqJPP, boolean reqJPT)
+    public byte[] requestViewWindow( String target, int reqfw, int reqfh, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
     {
        if( cid == null) // 1 channel allocation only
-           return requestViewWindow( target, null, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew, reqJPP, reqJPT);
+           return requestViewWindow( target, null, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew, reqaux, reqJPP, reqJPT);
        else
            return null;
     }
 
-    public byte[] requestViewWindow( String target, String reqtid, int reqfw, int reqfh, boolean reqcnew, boolean reqJPP, boolean reqJPT)
+    public byte[] requestViewWindow( String target, String reqtid, int reqfw, int reqfh, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
     {
        if( cid == null) // 1 channel allocation only
-           return requestViewWindow( target, reqtid, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew, reqJPP, reqJPT);
+           return requestViewWindow( target, reqtid, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew, reqaux, reqJPP, reqJPT);
        else
            return null;
     }
     
     public byte[] requestViewWindow( String target, int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
     {
-       return requestViewWindow( target, null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false, false, false);
+       return requestViewWindow( target, null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false, 0, false, false);
     }
-
  
-    public byte[] requestViewWindow( int reqfw, int reqfh, String reqcid, boolean reqcnew, boolean reqJPP, boolean reqJPT)
+    public byte[] requestViewWindow( int reqfw, int reqfh, String reqcid, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
     {
-       return requestViewWindow( null, null, reqfw, reqfh, -1, -1, -1, -1, reqcid, reqcnew, reqJPP, reqJPT);
+       return requestViewWindow( null, null, reqfw, reqfh, -1, -1, -1, -1, reqcid, reqcnew, reqaux, reqJPP, reqJPT);
     }
     
     public byte[] requestViewWindow( String target,
@@ -129,12 +131,12 @@ public class JPIPHttpClient
                                     int reqfw, int reqfh, 
                                     int reqrx, int reqry, 
                                     int reqrw, int reqrh, 
-                                    String reqcid, boolean reqcnew, boolean reqJPP, boolean reqJPT)
+                                    String reqcid, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
     {
        if( reqtid != null)
            tid = reqtid;
 
-       String urlstring = const_urlstring( target, reqtid, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, reqcnew, reqJPP, reqJPT);
+       String urlstring = const_urlstring( target, reqtid, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, reqcnew, reqaux, reqJPP, reqJPT);
        return GETrequest( urlstring);
     }
     
@@ -153,7 +155,6 @@ public class JPIPHttpClient
   
     private byte[] GETrequest( String urlstring)
     {
-       int buflen = 0;
        URL url = null;
        HttpURLConnection urlconn = null;
        byte[] jpipstream = null;
@@ -167,115 +168,239 @@ public class JPIPHttpClient
            urlconn.setRequestMethod("GET");
            urlconn.setInstanceFollowRedirects(false);
            urlconn.connect();
+
+           set_responseheader( urlconn);
            
-           Map<String,java.util.List<String>> headers = urlconn.getHeaderFields();
-           java.util.List<String> hvaluelist;
-           String hvalueline;
-           
-           String status = headers.get(null).get(0);
+           if( !aux){
+               jpipstream = receive_httpchunk( urlconn);
+               urlconn.disconnect();
+           }
+           else{
+               urlconn.disconnect();
+               jpipstream = receive_tcpaux( comURL.substring( 7, comURL.indexOf('/', 7)), port, cid);
+           }
+       }
+       catch ( MalformedURLException e){
+           e.printStackTrace();
+       }
+       catch ( ProtocolException e){
+           e.printStackTrace();
+       }    
+       catch( ClassCastException  e){
+           e.printStackTrace();
+       }
+       catch( NullPointerException e){
+           e.printStackTrace();
+       }  
+       catch( UnknownServiceException e){
+           e.printStackTrace();
+       }
+       catch ( IOException e){
+           e.printStackTrace();
+       }
+       
+       return jpipstream;
+    }
+
+    private void set_responseheader( HttpURLConnection urlconn)
+    {
+       Map<String,java.util.List<String>> headers = urlconn.getHeaderFields();
+       java.util.List<String> hvaluelist;
+       String hvalueline;
+       
+       String status = headers.get(null).get(0);
            
-           System.err.println( status);
-           if( !status.contains("OK"))
-               System.err.println( headers.get("Reason"));
+       System.err.println( status);
+       if( !status.contains("OK"))
+           System.err.println( headers.get("Reason"));
            
-           if(( hvaluelist = headers.get("Content-type")) == null)
-               hvaluelist = headers.get("Content-Type");
-           hvalueline = hvaluelist.get(0);
-           System.err.println( hvalueline);
+       if(( hvaluelist = headers.get("Content-type")) == null)
+           hvaluelist = headers.get("Content-Type");
+       hvalueline = hvaluelist.get(0);
+       System.err.println( hvalueline);
 
-           if( hvalueline.endsWith("jpt-stream"))
-               JPTstream = true;
-           else if( hvalueline.endsWith("jpp-stream"))
-               JPPstream = true;
+       if( hvalueline.endsWith("jpt-stream"))
+           JPTstream = true;
+       else if( hvalueline.endsWith("jpp-stream"))
+           JPPstream = true;
            
-           if(( hvaluelist = headers.get("JPIP-fsiz")) != null){
-               hvalueline = hvaluelist.get(0);
-               fw = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
-               fh = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
+       if(( hvaluelist = headers.get("JPIP-fsiz")) != null){
+           hvalueline = hvaluelist.get(0);
+           fw = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
+           fh = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
        
-               System.err.println("fw,fh: " + fw + "," + fh);
-           }
+           System.err.println("fw,fh: " + fw + "," + fh);
+       }
       
-           if(( hvaluelist = headers.get("JPIP-roff")) != null){
-               hvalueline = hvaluelist.get(0);
-               rx = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
-               ry = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
-               System.err.println("rx,ry: " + rx + "," + ry);
-           }
+       if(( hvaluelist = headers.get("JPIP-roff")) != null){
+           hvalueline = hvaluelist.get(0);
+           rx = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
+           ry = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
+           System.err.println("rx,ry: " + rx + "," + ry);
+       }
     
-           if(( hvaluelist = headers.get("JPIP-rsiz")) != null){
-               hvalueline = hvaluelist.get(0);
-               rw = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
-               rh = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
-               System.err.println("rw,rh: " + rw + "," + rh);
-           }
+       if(( hvaluelist = headers.get("JPIP-rsiz")) != null){
+           hvalueline = hvaluelist.get(0);
+           rw = Integer.valueOf( hvalueline.substring( 0, hvalueline.indexOf(','))).intValue();
+           rh = Integer.valueOf( hvalueline.substring( hvalueline.indexOf(',')+1 )).intValue();
+           System.err.println("rw,rh: " + rw + "," + rh);
+       }
            
-           if(( hvaluelist = headers.get("JPIP-cnew")) != null){
-               hvalueline = hvaluelist.get(0);
-               cid = hvalueline.substring( hvalueline.indexOf('=')+1, hvalueline.indexOf(','));
-               System.err.println("cid: " + cid);
-           }
+       if(( hvaluelist = headers.get("JPIP-cnew")) != null){
+           hvalueline = hvaluelist.get(0);
+           cid = hvalueline.substring( hvalueline.indexOf('=')+1, hvalueline.indexOf(','));
+               
+           int idxOfcid = hvalueline.indexOf("transport")+10;
+           int idxOfcid2 = hvalueline.indexOf(',', idxOfcid);
+           String transport;
+           if( idxOfcid2 != -1)
+               transport = hvalueline.substring( idxOfcid, idxOfcid2);
+           else
+               transport = hvalueline.substring( idxOfcid);
 
-           if(( hvaluelist = headers.get("JPIP-tid")) != null){
-               hvalueline = hvaluelist.get(0);
-               tid = hvalueline.substring( hvalueline.indexOf('=')+1);
-               System.err.println("tid: " + tid);
+           if( transport.matches("http-tcp")){
+               aux = true;
+               tcp = true;
            }
-           
-           InputStream input = urlconn.getInputStream();
-           buflen = input.available();
+           else if( transport.matches("http-udp")){
+               aux = true;
+               tcp = false;
+           }
+           else
+               aux = false;
+               
+           if( aux){
+               idxOfcid = hvalueline.indexOf("auxport")+8;
+               port = Integer.valueOf( hvalueline.substring( idxOfcid)).intValue();
+               System.err.println("cid: " + cid + ", transport: " + transport + ", auxport: " + port);
+           }
+           else                
+               System.err.println("cid: " + cid + ", transport: " + transport);
+       }
 
-           if( buflen > 0){
+       if(( hvaluelist = headers.get("JPIP-tid")) != null){
+           hvalueline = hvaluelist.get(0);
+           tid = hvalueline.substring( hvalueline.indexOf('=')+1);
+           System.err.println("tid: " + tid);
+       }
+    }
+
+    private static byte[] receive_httpchunk( HttpURLConnection urlconn)
+    {  
+       byte[] chunk = null;
+       InputStream input;
+
+       try{
+           input = urlconn.getInputStream();
+               
+           if( input.available() > 0){    
                ByteArrayOutputStream tmpstream = new ByteArrayOutputStream();
                byte[] buf = new byte[ 1024];
-       
+               int redlen, buflen;
+
                System.err.println("reading jpipstream...");
-       
-               int redlen;
+           
                do{
                    redlen = input.read( buf);
-         
+               
                    if( redlen == -1)
                        break;
                    tmpstream.write( buf, 0, redlen);
                }while( redlen > 0);
       
                buflen = tmpstream.size();
-       
-               jpipstream = tmpstream.toByteArray();
+               chunk = tmpstream.toByteArray();
             
+               buf = null;
                tmpstream = null;
-      
+
                System.err.println("jpiplen: " + buflen);
-               System.err.println("    succeeded");  
+               System.err.println("    succeeded");
            }
            else{
                System.err.println("No new jpipstream");
            }
            input.close();
        }
-       catch ( MalformedURLException e){
-           e.printStackTrace();
-       }
-       catch ( ProtocolException e){
-           e.printStackTrace();
-       }    
-       catch( ClassCastException  e){
+       catch ( IOException e){
            e.printStackTrace();
        }
-       catch( NullPointerException e){
-           e.printStackTrace();
-       }  
-       catch( UnknownServiceException e){
-           e.printStackTrace();
+
+       return chunk;
+    }
+
+    private static byte[] receive_tcpaux( String host, int port, String cid)
+    {  
+       Socket jpipsocket;
+       DataOutputStream os;
+       DataInputStream  is;
+       byte []auxheader;
+       byte []chunkbody = null;
+       byte []stream = null;
+       int chunkbodylen, streamlen, headlen = 8;
+       ByteArrayOutputStream tmpstream;
+
+       try{
+           jpipsocket = new Socket( host, port);
+           os = new DataOutputStream( jpipsocket.getOutputStream());
+           is = new DataInputStream( jpipsocket.getInputStream());
+           auxheader = new byte[headlen];
+           tmpstream = new ByteArrayOutputStream();
+       
+           os.writeBytes( cid + "\r\n");
+
+           do{
+               read_stream( is, auxheader, headlen);
+            
+               chunkbodylen = ((auxheader[0]&0xff)<<8 | (auxheader[1]&0xff)) - headlen;
+               
+               chunkbody = new byte [ chunkbodylen];
+               read_stream( is, chunkbody, chunkbodylen);
+               tmpstream.write( chunkbody, 0, chunkbodylen);
+
+               os.write( auxheader, 0, headlen);
+           }while( !(chunkbody[chunkbodylen-3]==0x00 && ( chunkbody[chunkbodylen-2]==0x01 || chunkbody[chunkbodylen-2]== 0x02)));
+       
+           streamlen = tmpstream.size();
+           stream = tmpstream.toByteArray();
+           
+           System.err.println("jpiplen: " + streamlen);
+           System.err.println("    succeeded");
+       
+           chunkbody = null;
+           tmpstream = null;
+           
+           os.close();
+           is.close();
+           
+           jpipsocket.close();
        }
        catch ( IOException e){
            e.printStackTrace();
        }
 
-       urlconn.disconnect();     
-               
-       return jpipstream;
+       return stream;
+    }
+    
+    private static void read_stream( InputStream is, byte []stream, int length)
+    {
+        int remlen = length;
+        int off = 0;
+
+        try{
+            while( remlen > 0){
+                int redlen = is.read( stream, off, remlen);
+
+                if( redlen == -1){
+                    System.err.println("    failed to read_stream()");
+                    break;
+                }
+                off += redlen;
+                remlen -= redlen;
+            }
+        } catch (IOException e) {
+            System.err.println("IOException: " + e);
+        }
     }
   
     private String const_urlstring( String target,
@@ -283,7 +408,7 @@ public class JPIPHttpClient
                                    int reqfw, int reqfh, 
                                    int reqrx, int reqry, 
                                    int reqrw, int reqrh, 
-                                   String reqcid, boolean reqcnew, boolean reqJPP, boolean reqJPT)
+                                   String reqcid, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
     {
        String urlstring = comURL;
 
@@ -323,9 +448,13 @@ public class JPIPHttpClient
        if( reqcnew){
            if( !urlstring.endsWith("?"))
                urlstring = urlstring.concat( "&");
-           urlstring = urlstring.concat( "cnew=http");
+           if( reqaux == 1)
+               urlstring = urlstring.concat( "cnew=http-tcp");
+           else if( reqaux == 2)
+               urlstring = urlstring.concat( "cnew=http-udp");
+           else
+               urlstring = urlstring.concat( "cnew=http");
        }
-
        if( reqJPP && !JPTstream){
            if( !urlstring.endsWith("?"))
                urlstring = urlstring.concat( "&");
diff --git a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111116.jar b/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111116.jar
deleted file mode 100644 (file)
index 0c3e0db..0000000
Binary files a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111116.jar and /dev/null differ
diff --git a/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111130.jar b/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111130.jar
new file mode 100644 (file)
index 0000000..ed17b21
Binary files /dev/null and b/applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111130.jar differ
index 7e6617732ddf3e4ebf052752d806aa0149ed2ca8..f5d06ba50e3c5dc8036c72d02ced7cc45497b026 120000 (symlink)
@@ -1 +1 @@
-opj_viewer_xerces-20111116.jar
\ No newline at end of file
+opj_viewer_xerces-20111130.jar
\ No newline at end of file
index 0fa2a84ec271267852b4ba698c2022d785672f64..52f0522a3cc86217bb0ac54cc52f168731883835 100644 (file)
@@ -53,7 +53,7 @@ public class ImageViewer extends JPanel
     private Rectangle roirect[] = null;
     private String roiname[] = null;
 
-    public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream)      
+    public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream, int aux)
     {
        String str;
        MML myMML;
@@ -69,7 +69,7 @@ public class ImageViewer extends JPanel
        
        imgmanager = manager;
 
-       img = imgmanager.getImage( j2kfilename, vw, vh, session, jppstream, !jppstream);
+       img = imgmanager.getImage( j2kfilename, vw, vh, session, aux, jppstream, !jppstream);
 
        addMouseListener(myMML);
        addMouseMotionListener(myMML);
index cbf546cca424aee4095c2ccadb9935e35abacd50..a7c8abd92d9b31cf7d014115d4f1ea0d998459f3 100644 (file)
@@ -38,13 +38,13 @@ public class ImageWindow extends JFrame
     private OptionPanel optpanel;
     private ImageManager imgmanager;
     
-    public ImageWindow( String uri, String j2kfilename, boolean session, boolean jppstream)
+    public ImageWindow( String uri, String j2kfilename, boolean session, boolean jppstream, int aux)
     {
        super( j2kfilename);
 
        imgmanager = new ImageManager( uri);
 
-       imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream);
+       imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream, aux);
        imgviewer.setOpaque(true); //content panes must be opaque
     
        optpanel = new OptionPanel( imgmanager, imgviewer);
@@ -72,6 +72,7 @@ public class ImageWindow extends JFrame
     {
        String j2kfilename, uri;
        boolean session, jppstream;
+       int aux; // 0: none, 1: tcp, 2: udp
 
        if(s.length >= 2){
            uri = s[0];
@@ -85,12 +86,21 @@ public class ImageWindow extends JFrame
                jppstream = !s[3].equalsIgnoreCase( "JPT");
            else
                jppstream = true;
+           
+           if( s.length > 4){
+               if( s[4].equalsIgnoreCase("udp"))
+                   aux = 2;
+               else
+                   aux = 1;
+           }
+           else
+               aux = 0;
        }
        else{
-           System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2 [stateless/session] [JPT/JPP]");
+           System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2 [stateless/session] [JPT/JPP] [tcp/udp]");
            return;
        }
-       ImageWindow frame = new ImageWindow( uri, j2kfilename, session, jppstream);
+       ImageWindow frame = new ImageWindow( uri, j2kfilename, session, jppstream, aux);
     
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);