[1.5][JPIP] TCP return (http-tcp) implemented
This commit is contained in:
parent
0c350f4908
commit
c6e0b71633
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
----------
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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_ */
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -34,11 +34,16 @@
|
|||
#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
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -28,76 +28,11 @@
|
|||
* 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);
|
||||
}
|
||||
|
|
|
@ -33,28 +33,7 @@
|
|||
|
||||
#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
|
||||
|
|
|
@ -48,17 +48,19 @@
|
|||
|
||||
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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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--;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -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"
|
||||
|
@ -44,21 +46,23 @@
|
|||
#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)
|
||||
{
|
||||
// Currently HTTP support only, find a way for TCP, UDP case
|
||||
emit_stream_from_msgqueue( qr->msgqueue);
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
|
|
|
@ -36,6 +36,19 @@
|
|||
#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"
|
||||
|
@ -45,13 +58,6 @@
|
|||
#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
|
||||
|
||||
/*
|
||||
|
@ -64,20 +70,24 @@
|
|||
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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -34,36 +34,28 @@
|
|||
|
||||
#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
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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_ */
|
|
@ -36,10 +36,10 @@
|
|||
#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
|
||||
|
|
|
@ -40,9 +40,11 @@
|
|||
//! 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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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))
|
||||
|
|
|
@ -54,11 +54,23 @@
|
|||
#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;
|
||||
}
|
||||
|
|
Binary file not shown.
Binary file not shown.
|
@ -1 +1 @@
|
|||
opj_viewer-20111116.jar
|
||||
opj_viewer-20111130.jar
|
|
@ -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){
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
||||
|
|
|
@ -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,92 +168,17 @@ public class JPIPHttpClient
|
|||
urlconn.setRequestMethod("GET");
|
||||
urlconn.setInstanceFollowRedirects(false);
|
||||
urlconn.connect();
|
||||
|
||||
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"));
|
||||
|
||||
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;
|
||||
set_responseheader( urlconn);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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-cnew")) != null){
|
||||
hvalueline = hvaluelist.get(0);
|
||||
cid = hvalueline.substring( hvalueline.indexOf('=')+1, hvalueline.indexOf(','));
|
||||
System.err.println("cid: " + cid);
|
||||
}
|
||||
|
||||
if(( hvaluelist = headers.get("JPIP-tid")) != null){
|
||||
hvalueline = hvaluelist.get(0);
|
||||
tid = hvalueline.substring( hvalueline.indexOf('=')+1);
|
||||
System.err.println("tid: " + tid);
|
||||
}
|
||||
|
||||
InputStream input = urlconn.getInputStream();
|
||||
buflen = input.available();
|
||||
|
||||
if( buflen > 0){
|
||||
ByteArrayOutputStream tmpstream = new ByteArrayOutputStream();
|
||||
byte[] buf = new byte[ 1024];
|
||||
|
||||
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();
|
||||
|
||||
tmpstream = null;
|
||||
|
||||
System.err.println("jpiplen: " + buflen);
|
||||
System.err.println(" succeeded");
|
||||
if( !aux){
|
||||
jpipstream = receive_httpchunk( urlconn);
|
||||
urlconn.disconnect();
|
||||
}
|
||||
else{
|
||||
System.err.println("No new jpipstream");
|
||||
urlconn.disconnect();
|
||||
jpipstream = receive_tcpaux( comURL.substring( 7, comURL.indexOf('/', 7)), port, cid);
|
||||
}
|
||||
input.close();
|
||||
}
|
||||
catch ( MalformedURLException e){
|
||||
e.printStackTrace();
|
||||
|
@ -272,18 +198,217 @@ public class JPIPHttpClient
|
|||
catch ( IOException e){
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
urlconn.disconnect();
|
||||
|
||||
|
||||
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"));
|
||||
|
||||
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(( 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);
|
||||
}
|
||||
|
||||
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-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( transport.matches("http-tcp")){
|
||||
aux = true;
|
||||
tcp = true;
|
||||
}
|
||||
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(( 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...");
|
||||
|
||||
do{
|
||||
redlen = input.read( buf);
|
||||
|
||||
if( redlen == -1)
|
||||
break;
|
||||
tmpstream.write( buf, 0, redlen);
|
||||
}while( redlen > 0);
|
||||
|
||||
buflen = tmpstream.size();
|
||||
chunk = tmpstream.toByteArray();
|
||||
|
||||
buf = null;
|
||||
tmpstream = null;
|
||||
|
||||
System.err.println("jpiplen: " + buflen);
|
||||
System.err.println(" succeeded");
|
||||
}
|
||||
else{
|
||||
System.err.println("No new jpipstream");
|
||||
}
|
||||
input.close();
|
||||
}
|
||||
catch ( IOException 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();
|
||||
}
|
||||
|
||||
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,
|
||||
String reqtid,
|
||||
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( "&");
|
||||
|
|
Binary file not shown.
BIN
applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111130.jar
vendored
Normal file
BIN
applications/jpip/util/opj_viewer_xerces/dist/opj_viewer_xerces-20111130.jar
vendored
Normal file
Binary file not shown.
|
@ -1 +1 @@
|
|||
opj_viewer_xerces-20111116.jar
|
||||
opj_viewer_xerces-20111130.jar
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in New Issue