[1.5][JPIP] TCP return (http-tcp) implemented

This commit is contained in:
Kaori Hagihara 2011-11-30 14:54:41 +00:00
parent 0c350f4908
commit c6e0b71633
42 changed files with 1313 additions and 508 deletions

View File

@ -5,6 +5,9 @@ What's New for OpenJPIP
! : changed
+ : added
November 30, 2011
+ [kaori] TCP return (http-tcp) implemented
November 16, 2011
* [kaori] fixed Region of Interest option, and memory leak of opj_dec_server
+ [kaori] new feature to target JP2 files from www (libcurl required)

View File

@ -29,7 +29,7 @@ The current implementation uses some results from the 2KAN project (http://www.2
Version 2.1 covers:
- JPT-stream (Tile) and JPP-stream (Precinct) media types
- Session, channels, cache model managements
- JPIP over HTTP
- JPIP over HTTP, HTTP requests and TCP return
- Indexing JPEG 2000 files
- Embedding XML formatted metadata
- Region Of Interest (ROI) requests
@ -104,12 +104,13 @@ Client:
% ../opj_dec_server
2. Open image viewers (as many as needed)
% java -jar opj_viewer.jar http://hostname/myFCGI path/filename.jp2 [stateless/session] [jptstream/jppstream]
% java -jar opj_viewer.jar http://hostname/myFCGI path/filename.jp2 [stateless/session] [jptstream/jppstream] [tcp/udp]
( The arguments
- http://hostname/myFCGI is the HTTP server URI (myFCGI refers to opj_server by the server setting)
- path/filename.jp2 is the server local path or URL of a JP2 file
- request type stateless for no caching, session (default) for caching
- return media type, JPT-stream tile based stream, or JPP-stream (default) precinct based stream
- return media type, JPT-stream tile based stream, or JPP-stream (default) precinct based stream
- auxiliary return protocol, tcp or udp (udp is not implemented yet), if not given, return data is filled in http chunk
Image viewer GUI instructions:
Scale up request: Enlarge the window
ROI request: Select a region by mouse click and drag, then click inside the red frame of the selected region
@ -119,7 +120,7 @@ Client:
Open a new window presenting an aligned image with a locally stored image: Click button "Image Registration" (Under Construction)
3. Quit the image decoding server through the telnet, be sure all image viewers are closed
% telnet localhost 5000
% telnet localhost 50000
quit
----------

View File

@ -31,6 +31,8 @@ ${CMAKE_CURRENT_SOURCE_DIR}/query_parser.c
${CMAKE_CURRENT_SOURCE_DIR}/channel_manager.c
${CMAKE_CURRENT_SOURCE_DIR}/session_manager.c
${CMAKE_CURRENT_SOURCE_DIR}/jpip_parser.c
${CMAKE_CURRENT_SOURCE_DIR}/sock_manager.c
${CMAKE_CURRENT_SOURCE_DIR}/auxtrans_manager.c
)
SET(LOCAL_SRCS

View File

@ -29,6 +29,8 @@ target_manager.c \
cachemodel_manager.c \
j2kheader_manager.c \
jp2k_encoder.c \
sock_manager.c \
auxtrans_manager.c \
openjpip.h \
bool.h \
boxheader_manager.h \
@ -53,7 +55,9 @@ query_parser.h \
channel_manager.h \
session_manager.h \
jpip_parser.h \
jp2k_decoder.h
jp2k_decoder.h \
sock_manager.h \
auxtrans_manager.h
LOCAL_SRC = jp2k_decoder.c \
imgsock_manager.c \

View File

@ -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;
}

View File

@ -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. 4915265535)
* @param[in] udp_auxport opening udp auxiliary port ( 0 not to open, valid No. 4915265535)
* @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_ */

View File

@ -193,3 +193,41 @@ void delete_cachemodel( cachemodel_param_t **cachemodel)
#endif
free( *cachemodel);
}
bool is_allsent( cachemodel_param_t cachemodel)
{
target_param_t *target;
Byte8_t TPnum; // num of tile parts in each tile
Byte8_t Pmax; // max num of packets per tile
int i, j, k, n;
target = cachemodel.target;
if( !cachemodel.mhead_model)
return false;
TPnum = get_nmax( target->codeidx->tilepart);
if( cachemodel.jppstream){
for( i=0; i<target->codeidx->SIZ.XTnum*target->codeidx->SIZ.YTnum; i++){
if( !cachemodel.th_model[i])
return false;
for( j=0; j<target->codeidx->SIZ.Csiz; j++){
Pmax = get_nmax( target->codeidx->precpacket[j]);
for( k=0; k<Pmax; k++)
if( !cachemodel.pp_model[j][i*Pmax+k])
return false;
}
}
return true;
}
else{
for( i=0, n=0; i<target->codeidx->SIZ.YTnum; i++)
for( j=0; j<target->codeidx->SIZ.XTnum; j++)
for( k=0; k<TPnum; k++)
if( !cachemodel.tp_model[n++])
return false;
return true;
}
}

View File

@ -88,6 +88,15 @@ void print_cachemodel( cachemodel_param_t cachemodel);
cachemodel_param_t * search_cachemodel( target_param_t *target, cachemodellist_param_t *cachemodellist);
/**
* check if all data has been sent
*
* @param[in] cachemodel cache model
* @return true if sent all, false otherwise
*/
bool is_allsent( cachemodel_param_t cachemodel);
/**
* delete a cache model
*

View File

@ -54,9 +54,10 @@ channellist_param_t * gene_channellist()
return channellist;
}
channel_param_t * gene_channel( query_param_t query_param, cachemodel_param_t *cachemodel, channellist_param_t *channellist)
channel_param_t * gene_channel( query_param_t query_param, auxtrans_param_t auxtrans, cachemodel_param_t *cachemodel, channellist_param_t *channellist)
{
channel_param_t *channel;
char transport[4][10] = { "non", "http", "http-tcp", "http-udp"};
if( !cachemodel){
fprintf( FCGI_stdout, "Status: 404\r\n");
@ -70,6 +71,12 @@ channel_param_t * gene_channel( query_param_t query_param, cachemodel_param_t *c
// set channel ID and get present time
snprintf( channel->cid, MAX_LENOFCID, "%x%x", (unsigned int)time( &channel->start_tm), (unsigned int)rand());
channel->aux = query_param.cnew;
// only tcp implemented for now
if( channel->aux == udp)
channel->aux = tcp;
channel->next=NULL;
set_channel_variable_param( query_param, channel);
@ -81,8 +88,12 @@ channel_param_t * gene_channel( query_param_t query_param, cachemodel_param_t *c
channellist->last = channel;
fprintf( FCGI_stdout, "JPIP-cnew: cid=%s", channel->cid);
// only http implemented for now
fprintf( FCGI_stdout, ",transport=http\r\n");
fprintf( FCGI_stdout, ",transport=%s", transport[channel->aux]);
if( channel->aux == tcp || channel->aux == udp)
fprintf( FCGI_stdout, ",auxport=%d", channel->aux==tcp ? auxtrans.tcpauxport : auxtrans.udpauxport);
fprintf( FCGI_stdout, "\r\n");
return channel;
}

View File

@ -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

View File

@ -14,7 +14,7 @@ $(LIBNAME): openjpip.o target_manager.o byte_manager.o box_manager.o boxheader_m
mhixbox_manager.o marker_manager.o codestream_manager.o faixbox_manager.o index_manager.o \
msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o \
cachemodel_manager.o j2kheader_manager.o jp2k_encoder.o query_parser.o channel_manager.o \
session_manager.o jpip_parser.o
session_manager.o jpip_parser.o sock_manager.o auxtrans_manager.o
ar r $@ $^
else
$(LIBNAME): openjpip.o target_manager.o byte_manager.o box_manager.o boxheader_manager.o manfbox_manager.o \
@ -22,7 +22,7 @@ $(LIBNAME): openjpip.o target_manager.o byte_manager.o box_manager.o boxheader_m
msgqueue_manager.o metadata_manager.o placeholder_manager.o ihdrbox_manager.o imgreg_manager.o \
cachemodel_manager.o j2kheader_manager.o jp2k_encoder.o query_parser.o channel_manager.o \
session_manager.o jpip_parser.o jp2k_decoder.o imgsock_manager.o jpipstream_manager.o cache_manager.o \
dec_clientmsg_handler.o
dec_clientmsg_handler.o sock_manager.o auxtrans_manager.o
ar r $@ $^
endif
clean:

View File

@ -48,6 +48,8 @@ void handle_JPIPstreamMSG( SOCKET connected_socket, cachelist_param_t *cachelist
newjpipstream = receive_JPIPstream( connected_socket, &target, &tid, &cid, &newstreamlen);
fprintf( stderr, "newjpipstream length: %d\n", newstreamlen);
parse_JPIPstream( newjpipstream, newstreamlen, *streamlen, msgqueue);
*jpipstream = update_JPIPstream( newjpipstream, newstreamlen, *jpipstream, streamlen);

View File

@ -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);
}

View File

@ -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

View 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)

View File

@ -68,6 +68,7 @@ bool associate_channel( query_param_t query_param,
*
* @param[in] query_param structured query
* @param[in] sessionlist session list pointer
* @param[in] auxtrans auxiliary transport
* @param[in] target requested target pointer
* @param[in,out] cursession address of the associated/opened session pointer
* @param[in,out] curchannel address of the associated/opened channel pointer
@ -75,6 +76,7 @@ bool associate_channel( query_param_t query_param,
*/
bool open_channel( query_param_t query_param,
sessionlist_param_t *sessionlist,
auxtrans_param_t auxtrans,
target_param_t *target,
session_param_t **cursession,
channel_param_t **curchannel);

View File

@ -383,13 +383,12 @@ void enqueue_message( message_param_t *msg, msgqueue_param_t *msgqueue)
msgqueue->last = msg;
}
void add_bin_id_vbas_stream( Byte_t bb, Byte_t c, Byte8_t in_class_id, int tmpfd);
void add_vbas_stream( Byte8_t code, int tmpfd);
void add_body_stream( message_param_t *msg, int fd, int tmpfd);
void add_placeholder_stream( placeholder_param_t *phld, int tmpfd);
void emit_bin_id_vbas( Byte_t bb, Byte_t c, Byte8_t in_class_id);
void emit_vbas( Byte8_t code);
void emit_body( message_param_t *msg, int fd);
void emit_placeholder( placeholder_param_t *phld);
void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue)
void recons_stream_from_msgqueue( msgqueue_param_t *msgqueue, int tmpfd)
{
message_param_t *msg;
Byte8_t class_id, csn;
@ -417,33 +416,33 @@ void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue)
}
c = msg->last_byte ? 1 : 0;
emit_bin_id_vbas( bb, c, msg->in_class_id);
add_bin_id_vbas_stream( bb, c, msg->in_class_id, tmpfd);
if( bb >= 2)
emit_vbas( class_id);
add_vbas_stream( class_id, tmpfd);
if (bb == 3)
emit_vbas( csn);
add_vbas_stream( csn, tmpfd);
emit_vbas( msg->bin_offset);
emit_vbas (msg->length);
add_vbas_stream( msg->bin_offset, tmpfd);
add_vbas_stream (msg->length, tmpfd);
if( msg->class_id%2) // Aux is present only if the id is odd
emit_vbas( msg->aux);
add_vbas_stream( msg->aux, tmpfd);
if( msg->phld)
emit_placeholder( msg->phld);
add_placeholder_stream( msg->phld, tmpfd);
else
emit_body( msg, msgqueue->cachemodel->target->fd);
add_body_stream( msg, msgqueue->cachemodel->target->fd, tmpfd);
msg = msg->next;
}
}
void emit_vbas_with_bytelen( Byte8_t code, int bytelength);
void add_vbas_with_bytelen_stream( Byte8_t code, int bytelength, int tmpfd);
void print_binarycode( Byte8_t n, int segmentlen);
void emit_bin_id_vbas( Byte_t bb, Byte_t c, Byte8_t in_class_id)
void add_bin_id_vbas_stream( Byte_t bb, Byte_t c, Byte8_t in_class_id, int tmpfd)
{
int bytelength;
Byte8_t tmp;
@ -459,10 +458,10 @@ void emit_bin_id_vbas( Byte_t bb, Byte_t c, Byte8_t in_class_id)
in_class_id |= (((bb & 3) << 5) | (c & 1) << 4) << ((bytelength-1)*7);
emit_vbas_with_bytelen( in_class_id, bytelength);
add_vbas_with_bytelen_stream( in_class_id, bytelength, tmpfd);
}
void emit_vbas( Byte8_t code)
void add_vbas_stream( Byte8_t code, int tmpfd)
{
int bytelength;
Byte8_t tmp;
@ -472,10 +471,10 @@ void emit_vbas( Byte8_t code)
while( tmp >>= 7)
bytelength ++;
emit_vbas_with_bytelen( code, bytelength);
add_vbas_with_bytelen_stream( code, bytelength, tmpfd);
}
void emit_vbas_with_bytelen( Byte8_t code, int bytelength)
void add_vbas_with_bytelen_stream( Byte8_t code, int bytelength, int tmpfd)
{
int n;
Byte8_t seg;
@ -485,47 +484,47 @@ void emit_vbas_with_bytelen( Byte8_t code, int bytelength)
seg = ( code >> (n*7)) & 0x7f;
if( n)
seg |= 0x80;
fputc(( Byte4_t)seg, FCGI_stdout);
write( tmpfd, ( Byte4_t *)&seg, 1);
n--;
}
}
void emit_body( message_param_t *msg, int fd)
void add_body_stream( message_param_t *msg, int fd, int tmpfd)
{
Byte_t *data;
if( !(data = fetch_bytes( fd, msg->res_offset, msg->length))){
fprintf( FCGI_stderr, "Error: fetch_bytes in emit_body()\n");
fprintf( FCGI_stderr, "Error: fetch_bytes in add_body_stream()\n");
return;
}
if( fwrite( data, msg->length, 1, FCGI_stdout) < 1){
if( write( tmpfd, data, msg->length) < 1){
free( data);
fprintf( FCGI_stderr, "Error: fwrite in emit_body()\n");
fprintf( FCGI_stderr, "Error: fwrite in add_body_stream()\n");
return;
}
free(data);
}
void emit_bigendian_bytes( Byte8_t code, int bytelength);
void add_bigendian_bytestream( Byte8_t code, int bytelength, int tmpfd);
void emit_placeholder( placeholder_param_t *phld)
void add_placeholder_stream( placeholder_param_t *phld, int tmpfd)
{
emit_bigendian_bytes( phld->LBox, 4);
if( fwrite( phld->TBox, 4, 1, FCGI_stdout) < 1){
fprintf( FCGI_stderr, "Error: fwrite in emit_placeholder()\n");
add_bigendian_bytestream( phld->LBox, 4, tmpfd);
if( write( tmpfd, phld->TBox, 4) < 1){
fprintf( FCGI_stderr, "Error: fwrite in add_placeholder_stream()\n");
return;
}
emit_bigendian_bytes( phld->Flags, 4);
emit_bigendian_bytes( phld->OrigID, 8);
add_bigendian_bytestream( phld->Flags, 4, tmpfd);
add_bigendian_bytestream( phld->OrigID, 8, tmpfd);
if( fwrite( phld->OrigBH, phld->OrigBHlen, 1, FCGI_stdout) < 1){
fprintf( FCGI_stderr, "Error: fwrite in emit_placeholder()\n");
if( write( tmpfd, phld->OrigBH, phld->OrigBHlen) < 1){
fprintf( FCGI_stderr, "Error: fwrite in add_placeholder_stream()\n");
return;
}
}
void emit_bigendian_bytes( Byte8_t code, int bytelength)
void add_bigendian_bytestream( Byte8_t code, int bytelength, int tmpfd)
{
int n;
Byte8_t seg;
@ -533,7 +532,7 @@ void emit_bigendian_bytes( Byte8_t code, int bytelength)
n = bytelength - 1;
while( n >= 0) {
seg = ( code >> (n*8)) & 0xff;
fputc(( Byte4_t)seg, FCGI_stdout);
write( tmpfd, ( Byte4_t *)&seg, 1);
n--;
}
}

View File

@ -145,11 +145,12 @@ void enqueue_metadata( int meta_id, msgqueue_param_t *msgqueue);
/**
* emit stream from message queue
* reconstruct JPT/JPP-stream from message queue
*
* @param[in] msgqueue message queue pointer
* @param[in] tmpfd file discriptor to write JPT/JPP-stream
*/
void emit_stream_from_msgqueue( msgqueue_param_t *msgqueue);
void recons_stream_from_msgqueue( msgqueue_param_t *msgqueue, int tmpfd);
/**

View File

@ -32,6 +32,8 @@
#include "openjpip.h"
#include "jpip_parser.h"
#include "channel_manager.h"
#include "byte_manager.h"
#include "auxtrans_manager.h"
#include <stdio.h>
#include "dec_clientmsg_handler.h"
@ -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;

View File

@ -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. 4915265535)
* @param[in] udp_auxport opening udp auxiliary port ( 0 not to open, valid No. 4915265535)
* @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. 4915265535)
* @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

View File

@ -69,14 +69,7 @@ query_param_t * get_initquery();
*/
char * get_fieldparam( char *stringptr, char *fieldname, char *fieldval);
/**
* parse string to string array
*
* @param[in] src src string
* @param[out] cclose parsed string array
*/
void str2cclose( char *src, char cclose[][MAX_LENOFCID]);
void parse_cclose( char *src, query_param_t *query_param);
void parse_metareq( char *field, query_param_t *query_param);
// parse the requested components (parses forms like:a; a,b; a-b; a-b,c; a,b-c)
@ -104,10 +97,10 @@ query_param_t * parse_query( char *query_string)
if( fieldname[0] != '\0'){
if( strcasecmp( fieldname, "target") == 0)
strcpy( query_param->target,fieldval);
query_param->target = strdup( fieldval);
else if( strcasecmp( fieldname, "tid") == 0)
strcpy( query_param->tid, fieldval);
query_param->tid = strdup( fieldval);
else if( strcasecmp( fieldname, "fsiz") == 0)
sscanf( fieldval, "%d,%d", &query_param->fx, &query_param->fy);
@ -122,13 +115,17 @@ query_param_t * parse_query( char *query_string)
sscanf( fieldval, "%d", &query_param->layers);
else if( strcasecmp( fieldname, "cid") == 0)
strcpy( query_param->cid, fieldval);
query_param->cid = strdup( fieldval);
else if( strcasecmp( fieldname, "cnew") == 0)
query_param->cnew = true;
else if( strcasecmp( fieldname, "cnew") == 0){
if( strncasecmp( fieldval, "http-tcp", 8) == 0)
query_param->cnew = tcp;
else if( strncasecmp( fieldval, "http", 4) == 0)
query_param->cnew = http;
}
else if( strcasecmp( fieldname, "cclose") == 0)
str2cclose( fieldval, query_param->cclose);
parse_cclose( fieldval, query_param);
else if( strcasecmp( fieldname, "metareq") == 0)
parse_metareq( fieldval, query_param);
@ -157,8 +154,8 @@ query_param_t * get_initquery()
query = (query_param_t *)malloc( sizeof(query_param_t));
query->target[0] = '\0';
query->tid[0] = '\0';
query->target = NULL;
query->tid = NULL;
query->fx = -1;
query->fy = -1;
query->rx = -1;
@ -168,9 +165,10 @@ query_param_t * get_initquery()
query->layers = -1;
query->lastcomp = -1;
query->comps = NULL;
query->cid[0] = '\0';
query->cnew = false;
memset( query->cclose, 0, MAX_NUMOFCCLOSE*MAX_LENOFCID);
query->cid = NULL;
query->cnew = non;
query->cclose = NULL;
query->numOfcclose = 0;
memset( query->box_type, 0, MAX_NUMOFBOX*4);
memset( query->limit, 0, MAX_NUMOFBOX*sizeof(int));
for( i=0; i<MAX_NUMOFBOX; i++){
@ -218,14 +216,21 @@ char * get_fieldparam( char *stringptr, char *fieldname, char *fieldval)
void print_queryparam( query_param_t query_param)
{
int i;
char *cclose;
fprintf( logstream, "query parameters:\n");
fprintf( logstream, "\t target: %s\n", query_param.target);
fprintf( logstream, "\t tid: %s\n", query_param.tid);
if( query_param.target)
fprintf( logstream, "\t target: %s\n", query_param.target);
if( query_param.tid)
fprintf( logstream, "\t tid: %s\n", query_param.tid);
fprintf( logstream, "\t fx,fy: %d, %d\n", query_param.fx, query_param.fy);
fprintf( logstream, "\t rx,ry: %d, %d \t rw,rh: %d, %d\n", query_param.rx, query_param.ry, query_param.rw, query_param.rh);
fprintf( logstream, "\t layers: %d\n", query_param.layers);
fprintf( logstream, "\t components: ");
if( query_param.lastcomp == -1)
fprintf( logstream, "ALL\n");
else{
@ -235,13 +240,20 @@ void print_queryparam( query_param_t query_param)
fprintf( logstream, "\n");
}
fprintf( logstream, "\t cnew: %d\n", query_param.cnew);
fprintf( logstream, "\t cid: %s\n", query_param.cid);
fprintf( logstream, "\t cclose: ");
for( i=0; query_param.cclose[i][0]!=0 && i<MAX_NUMOFCCLOSE; i++)
fprintf( logstream, "%s ", query_param.cclose[i]);
fprintf(logstream, "\n");
if( query_param.cid)
fprintf( logstream, "\t cid: %s\n", query_param.cid);
if( query_param.cclose){
fprintf( logstream, "\t cclose: ");
for( i=0, cclose=query_param.cclose; i<query_param.numOfcclose; i++){
fprintf( logstream, "%s ", cclose);
cclose += (strlen(cclose)+1);
}
fprintf(logstream, "\n");
}
fprintf( logstream, "\t req-box-prop\n");
for( i=0; query_param.box_type[i][0]!=0 && i<MAX_NUMOFBOX; i++){
fprintf( logstream, "\t\t box_type: %.4s limit: %d w:%d s:%d g:%d a:%d priority:%d\n", query_param.box_type[i], query_param.limit[i], query_param.w[i], query_param.s[i], query_param.g[i], query_param.a[i], query_param.priority[i]);
@ -254,20 +266,21 @@ void print_queryparam( query_param_t query_param)
fprintf( logstream, "\t len: %d\n", query_param.len);
}
void str2cclose( char *src, char cclose[][MAX_LENOFCID])
void parse_cclose( char *src, query_param_t *query_param)
{
int i, u, v;
size_t len = strlen( src);
int i;
size_t len;
for( i=0, u=0, v=0; i<len; i++){
if( src[i]==','){
u++;
v=0;
len = strlen( src);
query_param->cclose = strdup( src);
for( i=0; i<len; i++)
if( query_param->cclose[i] == ','){
query_param->cclose[i] = '\0';
query_param->numOfcclose ++;
}
else
cclose[u][v++] = src[i];
}
query_param->numOfcclose ++;
}
void parse_req_box_prop( char *req_box_prop, int idx, query_param_t *query_param);
@ -386,6 +399,20 @@ void parse_comps( char *field, query_param_t *query_param)
void delete_query( query_param_t **query)
{
free((*query)->comps);
if( (*query)->target)
free( (*query)->target);
if( (*query)->tid)
free( (*query)->tid);
if( (*query)->comps)
free((*query)->comps);
if( (*query)->cid)
free( (*query)->cid);
if( (*query)->cclose)
free( (*query)->cclose);
free( *query);
}

View File

@ -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

View File

@ -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
}

View File

@ -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_ */

View File

@ -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

View File

@ -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

View File

@ -2,13 +2,13 @@ JPIPLIBDIR = ../libopenjpip
SLIBFNAME = $(JPIPLIBDIR)/libopenjpip_server.a
SCFLAGS = -O3 -Wall -m32 -I$(JPIPLIBDIR) -DSERVER -DQUIT_SIGNAL=\"quitJPIP\"
SLDFLAGS = -L$(JPIPLIBDIR) -lm -lfcgi -lcurl -lopenjpip_server
SLDFLAGS = -L$(JPIPLIBDIR) -lm -lfcgi -lcurl -lpthread -lopenjpip_server
J2KINCDIR = ../../../libopenjpeg
J2KLIBDIR = $(J2KINCDIR)/.libs
LIBFNAME = $(JPIPLIBDIR)/libopenjpip_local.a $(J2KLIBDIR)/libopenjpeg.a
CFLAGS = -O3 -Wall -I$(JPIPLIBDIR)
LDFLAGS = -L$(JPIPLIBDIR) -L$(J2KLIBDIR) -lm -lcurl -lopenjpip_local
LDFLAGS = -L$(JPIPLIBDIR) -L$(J2KLIBDIR) -lm -lpthread -lopenjpip_local
ALL = opj_server opj_dec_server jpip_to_jp2 jpip_to_j2k test_index addXMLinJP2

View File

@ -64,7 +64,7 @@ int main(int argc, char *argv[]){
printf( "Initialisation Winsock\n");
#endif //_WIN32
server_record = init_dec_server();
server_record = init_dec_server( 50000);
while(( client = accept_connection( server_record)) != -1 )
if(!handle_clientreq( client, server_record))

View File

@ -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.

View File

@ -1 +1 @@
opj_viewer-20111116.jar
opj_viewer-20111130.jar

View File

@ -60,7 +60,7 @@ public class ImageManager extends JPIPHttpClient
}
public int getOrigHeight(){ return origheight;}
public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew, boolean reqJPP, boolean reqJPT)
public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
{
System.err.println();
@ -69,17 +69,17 @@ public class ImageManager extends JPIPHttpClient
// Todo: check if the cid is for the same stream type
if( reqcnew)
refcid = ImgdecClient.query_cid( j2kfilename);
refcid = ImgdecClient.query_cid( j2kfilename);
if( refcid == null){
String reftid = ImgdecClient.query_tid( j2kfilename);
if( reftid == null)
jpipstream = super.requestViewWindow( j2kfilename, reqfw, reqfh, reqcnew, reqJPP, reqJPT);
jpipstream = super.requestViewWindow( j2kfilename, reqfw, reqfh, reqcnew, reqaux, reqJPP, reqJPT);
else
jpipstream = super.requestViewWindow( j2kfilename, reftid, reqfw, reqfh, reqcnew, reqJPP, reqJPT);
jpipstream = super.requestViewWindow( j2kfilename, reftid, reqfw, reqfh, reqcnew, reqaux, reqJPP, reqJPT);
}
else
jpipstream = super.requestViewWindow( reqfw, reqfh, refcid, reqcnew, reqJPP, reqJPT);
jpipstream = super.requestViewWindow( reqfw, reqfh, refcid, reqcnew, reqaux, reqJPP, reqJPT);
System.err.println( "decoding to PNM image");
if((pnmimage = ImgdecClient.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh))!=null){

View File

@ -53,7 +53,7 @@ public class ImageViewer extends JPanel
private Rectangle roirect[] = null;
private String roiname[] = null;
public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream)
public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream, int aux)
{
String str;
MML myMML;
@ -69,8 +69,8 @@ public class ImageViewer extends JPanel
imgmanager = manager;
img = imgmanager.getImage( j2kfilename, vw, vh, session, jppstream, !jppstream);
img = imgmanager.getImage( j2kfilename, vw, vh, session, aux, jppstream, !jppstream);
addMouseListener(myMML);
addMouseMotionListener(myMML);
addComponentListener( new ResizeListener(this));

View File

@ -37,13 +37,13 @@ public class ImageWindow extends JFrame
private ImageViewer imgviewer;
private ImageManager imgmanager;
public ImageWindow( String uri, String j2kfilename, boolean session, boolean jppstream)
public ImageWindow( String uri, String j2kfilename, boolean session, boolean jppstream, int aux)
{
super( j2kfilename);
imgmanager = new ImageManager( uri);
imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream);
imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream, aux);
imgviewer.setOpaque(true); //content panes must be opaque
JPanel panel = new JPanel();
@ -68,6 +68,7 @@ public class ImageWindow extends JFrame
{
String j2kfilename, uri;
boolean session, jppstream;
int aux; // 0: none, 1: tcp, 2: udp
if(s.length >= 2){
uri = s[0];
@ -81,12 +82,21 @@ public class ImageWindow extends JFrame
jppstream = !s[3].equalsIgnoreCase( "JPT");
else
jppstream = true;
if( s.length > 4){
if( s[4].equalsIgnoreCase("udp"))
aux = 2;
else
aux = 1;
}
else
aux = 0;
}
else{
System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2 [stateless/session] [JPT/JPP]");
System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2 [stateless/session] [JPT/JPP] [tcp/udp]");
return;
}
ImageWindow frame = new ImageWindow( uri, j2kfilename, session, jppstream);
ImageWindow frame = new ImageWindow( uri, j2kfilename, session, jppstream, aux);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

View File

@ -49,7 +49,7 @@ public class ImgdecClient{
public static void send_JPIPstream( byte[] jpipstream)
{
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
Socket imgdecSocket = new Socket( "localhost", 50000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
@ -74,7 +74,7 @@ public class ImgdecClient{
public static void send_JPIPstream( byte[] jpipstream, String j2kfilename, String tid, String cid)
{
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
Socket imgdecSocket = new Socket( "localhost", 50000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
int length = 0;
@ -114,7 +114,7 @@ public class ImgdecClient{
PnmImage pnmstream = null;
try {
Socket imgdecSocket = new Socket( "localhost", 5000);
Socket imgdecSocket = new Socket( "localhost", 50000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
byte []header = new byte[7];
@ -171,7 +171,7 @@ public class ImgdecClient{
byte []xmldata = null;
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
Socket imgdecSocket = new Socket( "localhost", 50000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
byte []header = new byte[5];
@ -222,7 +222,7 @@ public class ImgdecClient{
String id = null;
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
Socket imgdecSocket = new Socket( "localhost", 50000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
byte []header = new byte[4];
@ -259,7 +259,7 @@ public class ImgdecClient{
java.awt.Dimension dim = null;
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
Socket imgdecSocket = new Socket( "localhost", 50000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
byte []header = new byte[3];
@ -321,7 +321,7 @@ public class ImgdecClient{
public static void destroy_cid( String cid)
{
try{
Socket imgdecSocket = new Socket( "localhost", 5000);
Socket imgdecSocket = new Socket( "localhost", 50000);
DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());

View File

@ -43,6 +43,9 @@ public class JPIPHttpClient
protected String tid;
private boolean JPTstream;
private boolean JPPstream;
private boolean aux;
private boolean tcp; // true: tcp, false: udp
private int port;
public JPIPHttpClient( String URI)
{
@ -52,8 +55,8 @@ public class JPIPHttpClient
rw = rh = -1;
cid = null;
tid = null;
JPTstream = false;
JPPstream = false;
JPTstream = JPPstream = aux = false;
port = 0;
}
public int getFw(){ return fw;}
@ -77,51 +80,50 @@ public class JPIPHttpClient
return requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh, cid);
else
if( tid != null)
return requestViewWindow( null, tid, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false, false, false);
return requestViewWindow( null, tid, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false, 0, false, false);
else
return null;
}
public byte[] requestViewWindow( int reqfw, int reqfh, String reqcid)
{
return requestViewWindow( null, null, reqfw, reqfh, -1, -1, -1, -1, reqcid, false, false, false);
return requestViewWindow( null, null, reqfw, reqfh, -1, -1, -1, -1, reqcid, false, 0, false, false);
}
public byte[] requestViewWindow( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh, String reqcid)
{
return requestViewWindow( null, null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, false, false, false);
return requestViewWindow( null, null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, false, 0, false, false);
}
public byte[] requestViewWindow( String target, int reqfw, int reqfh)
{
return requestViewWindow( target, null, reqfw, reqfh, -1, -1, -1, -1, null, false, false, false);
return requestViewWindow( target, null, reqfw, reqfh, -1, -1, -1, -1, null, false, 0, false, false);
}
public byte[] requestViewWindow( String target, int reqfw, int reqfh, boolean reqcnew, boolean reqJPP, boolean reqJPT)
public byte[] requestViewWindow( String target, int reqfw, int reqfh, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
{
if( cid == null) // 1 channel allocation only
return requestViewWindow( target, null, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew, reqJPP, reqJPT);
return requestViewWindow( target, null, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew, reqaux, reqJPP, reqJPT);
else
return null;
}
public byte[] requestViewWindow( String target, String reqtid, int reqfw, int reqfh, boolean reqcnew, boolean reqJPP, boolean reqJPT)
public byte[] requestViewWindow( String target, String reqtid, int reqfw, int reqfh, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
{
if( cid == null) // 1 channel allocation only
return requestViewWindow( target, reqtid, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew, reqJPP, reqJPT);
return requestViewWindow( target, reqtid, reqfw, reqfh, -1, -1, -1, -1, null, reqcnew, reqaux, reqJPP, reqJPT);
else
return null;
}
public byte[] requestViewWindow( String target, int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
{
return requestViewWindow( target, null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false, false, false);
return requestViewWindow( target, null, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, null, false, 0, false, false);
}
public byte[] requestViewWindow( int reqfw, int reqfh, String reqcid, boolean reqcnew, boolean reqJPP, boolean reqJPT)
public byte[] requestViewWindow( int reqfw, int reqfh, String reqcid, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
{
return requestViewWindow( null, null, reqfw, reqfh, -1, -1, -1, -1, reqcid, reqcnew, reqJPP, reqJPT);
return requestViewWindow( null, null, reqfw, reqfh, -1, -1, -1, -1, reqcid, reqcnew, reqaux, reqJPP, reqJPT);
}
public byte[] requestViewWindow( String target,
@ -129,12 +131,12 @@ public class JPIPHttpClient
int reqfw, int reqfh,
int reqrx, int reqry,
int reqrw, int reqrh,
String reqcid, boolean reqcnew, boolean reqJPP, boolean reqJPT)
String reqcid, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
{
if( reqtid != null)
tid = reqtid;
String urlstring = const_urlstring( target, reqtid, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, reqcnew, reqJPP, reqJPT);
String urlstring = const_urlstring( target, reqtid, reqfw, reqfh, reqrx, reqry, reqrw, reqrh, reqcid, reqcnew, reqaux, reqJPP, reqJPT);
return GETrequest( urlstring);
}
@ -153,7 +155,6 @@ public class JPIPHttpClient
private byte[] GETrequest( String urlstring)
{
int buflen = 0;
URL url = null;
HttpURLConnection urlconn = null;
byte[] jpipstream = null;
@ -167,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( "&");

View File

@ -1 +1 @@
opj_viewer_xerces-20111116.jar
opj_viewer_xerces-20111130.jar

View File

@ -53,7 +53,7 @@ public class ImageViewer extends JPanel
private Rectangle roirect[] = null;
private String roiname[] = null;
public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream)
public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream, int aux)
{
String str;
MML myMML;
@ -69,7 +69,7 @@ public class ImageViewer extends JPanel
imgmanager = manager;
img = imgmanager.getImage( j2kfilename, vw, vh, session, jppstream, !jppstream);
img = imgmanager.getImage( j2kfilename, vw, vh, session, aux, jppstream, !jppstream);
addMouseListener(myMML);
addMouseMotionListener(myMML);

View File

@ -38,13 +38,13 @@ public class ImageWindow extends JFrame
private OptionPanel optpanel;
private ImageManager imgmanager;
public ImageWindow( String uri, String j2kfilename, boolean session, boolean jppstream)
public ImageWindow( String uri, String j2kfilename, boolean session, boolean jppstream, int aux)
{
super( j2kfilename);
imgmanager = new ImageManager( uri);
imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream);
imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream, aux);
imgviewer.setOpaque(true); //content panes must be opaque
optpanel = new OptionPanel( imgmanager, imgviewer);
@ -72,6 +72,7 @@ public class ImageWindow extends JFrame
{
String j2kfilename, uri;
boolean session, jppstream;
int aux; // 0: none, 1: tcp, 2: udp
if(s.length >= 2){
uri = s[0];
@ -85,12 +86,21 @@ public class ImageWindow extends JFrame
jppstream = !s[3].equalsIgnoreCase( "JPT");
else
jppstream = true;
if( s.length > 4){
if( s[4].equalsIgnoreCase("udp"))
aux = 2;
else
aux = 1;
}
else
aux = 0;
}
else{
System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2 [stateless/session] [JPT/JPP]");
System.out.println("Usage: java -jar opj_viewer.jar HTTP_server_URI imagefile.jp2 [stateless/session] [JPT/JPP] [tcp/udp]");
return;
}
ImageWindow frame = new ImageWindow( uri, j2kfilename, session, jppstream);
ImageWindow frame = new ImageWindow( uri, j2kfilename, session, jppstream, aux);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);