summaryrefslogtreecommitdiff
path: root/src/bin/jpip
diff options
context:
space:
mode:
authorMathieu Malaterre <mathieu.malaterre@gmail.com>2012-09-28 08:11:41 +0000
committerMathieu Malaterre <mathieu.malaterre@gmail.com>2012-09-28 08:11:41 +0000
commitd518970039a19a2a9b6d2bdd592cc88a43897bbb (patch)
tree57bac2cf7e63e9352228231062763baac627563c /src/bin/jpip
parent8363a6ab1e031bb4b2e40a92e56efd40fdab1aa1 (diff)
[trunk] Start FolderReorgProposal task
Update issue 177
Diffstat (limited to 'src/bin/jpip')
-rw-r--r--src/bin/jpip/CMakeLists.txt150
-rw-r--r--src/bin/jpip/Makefile.am85
-rw-r--r--src/bin/jpip/addXMLinJP2.c181
-rw-r--r--src/bin/jpip/jpip_to_j2k.c72
-rw-r--r--src/bin/jpip/jpip_to_jp2.c72
-rw-r--r--src/bin/jpip/opj_dec_server.c92
-rw-r--r--src/bin/jpip/opj_server.c127
-rw-r--r--src/bin/jpip/opj_viewer/dist/manifest.txt4
-rw-r--r--src/bin/jpip/opj_viewer/src/ImageManager.java136
-rw-r--r--src/bin/jpip/opj_viewer/src/ImageViewer.java266
-rw-r--r--src/bin/jpip/opj_viewer/src/ImageWindow.java120
-rw-r--r--src/bin/jpip/opj_viewer/src/ImgdecClient.java350
-rw-r--r--src/bin/jpip/opj_viewer/src/JPIPHttpClient.java503
-rw-r--r--src/bin/jpip/opj_viewer/src/MML.java116
-rw-r--r--src/bin/jpip/opj_viewer/src/PnmImage.java154
-rw-r--r--src/bin/jpip/opj_viewer/src/RegimViewer.java114
-rw-r--r--src/bin/jpip/opj_viewer/src/ResizeListener.java67
-rw-r--r--src/bin/jpip/opj_viewer_xerces/dist/manifest.txt.in5
-rw-r--r--src/bin/jpip/opj_viewer_xerces/src/ImageViewer.java266
-rw-r--r--src/bin/jpip/opj_viewer_xerces/src/ImageWindow.java124
-rw-r--r--src/bin/jpip/opj_viewer_xerces/src/JP2XMLparser.java122
-rw-r--r--src/bin/jpip/opj_viewer_xerces/src/OptionPanel.java98
-rw-r--r--src/bin/jpip/test_index.c73
23 files changed, 3297 insertions, 0 deletions
diff --git a/src/bin/jpip/CMakeLists.txt b/src/bin/jpip/CMakeLists.txt
new file mode 100644
index 00000000..5a3fc0ff
--- /dev/null
+++ b/src/bin/jpip/CMakeLists.txt
@@ -0,0 +1,150 @@
+# Headers file are located here:
+include_directories(
+ ${OPENJPEG_SOURCE_DIR}/src/lib/openjp2 # opj_stdint.h
+ ${OPENJPEG_SOURCE_DIR}/src/lib/openjpip
+ ${FCGI_INCLUDE_DIRS}
+)
+
+# Tool to embed metadata into JP2 file
+add_executable(addXMLinJP2 addXMLinJP2.c)
+# Install exe
+install(TARGETS addXMLinJP2
+ EXPORT OpenJPEGTargets
+ DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
+ )
+
+if(BUILD_JPIP_SERVER)
+
+ set(OPJ_SERVER_SRCS
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_server.c
+ )
+
+ # Build executable
+ add_executable(opj_server ${OPJ_SERVER_SRCS})
+ target_link_libraries(opj_server openjpip_server)
+ set_property(
+ TARGET opj_server
+ APPEND PROPERTY
+ COMPILE_DEFINITIONS SERVER QUIT_SIGNAL="quitJPIP"
+ )
+
+ # On unix you need to link to the math library:
+ if(UNIX)
+ target_link_libraries(opj_server m)
+ endif()
+
+ # Install exe
+ install(TARGETS opj_server
+ EXPORT OpenJPEGTargets
+ DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
+ )
+endif()
+
+set(EXES
+ opj_dec_server
+ jpip_to_jp2
+ jpip_to_j2k
+ test_index
+ )
+foreach(exe ${EXES})
+ add_executable(${exe} ${exe}.c)
+ target_link_libraries(${exe} openjpip_local)
+ install(TARGETS ${exe}
+ EXPORT OpenJPEGTargets
+ DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications
+ )
+endforeach()
+
+# Build the two java clients:
+find_package(Java 1.5 COMPONENTS Development) # javac, jar
+
+# Only build the java viewer if dev is found:
+if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE)
+ set(jflags $ENV{JFLAGS})
+ # 1. opj_viewer
+ # build dep list:
+ file(GLOB java1_srcs "opj_viewer/src/*.java")
+
+ # make sure target javac dir exists:
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/classes1)
+ # Build java
+ add_custom_command(
+ OUTPUT ${LIBRARY_OUTPUT_PATH}/opj_viewer.jar
+ COMMAND ${Java_JAVAC_EXECUTABLE} ${jflags}
+ ${java1_srcs} -d ${CMAKE_CURRENT_BINARY_DIR}/classes1
+ COMMAND ${Java_JAR_EXECUTABLE} cfm ${LIBRARY_OUTPUT_PATH}/opj_viewer.jar
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/dist/manifest.txt -C
+ ${CMAKE_CURRENT_BINARY_DIR}/classes1 .
+ DEPENDS ${java1_srcs}
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/dist/manifest.txt
+ COMMENT "javac *.java; jar cvf -> opj_viewer.jar"
+ )
+
+ # name the target
+ add_custom_target(OPJViewerJar ALL
+ DEPENDS ${LIBRARY_OUTPUT_PATH}/opj_viewer.jar
+ COMMENT "building opj_viewer.jar"
+ )
+
+ install(FILES ${LIBRARY_OUTPUT_PATH}/opj_viewer.jar
+ DESTINATION ${OPENJPEG_INSTALL_SHARE_DIR} COMPONENT JavaModule
+ )
+
+ # 2. opj_viewer_xerces
+ # search for package org.apache.xerces.parsers
+ find_file(APACHE_XERCES_JAR
+ NAMES xerces-j2.jar xercesImpl.jar
+ PATHS /usr/share/java/
+ NO_DEFAULT_PATH
+ )
+ mark_as_advanced(APACHE_XERCES_JAR)
+
+ if(EXISTS ${APACHE_XERCES_JAR})
+ configure_file(
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer_xerces/dist/manifest.txt.in
+ ${CMAKE_CURRENT_BINARY_DIR}/opj_viewer_xerces/dist/manifest.txt
+ @ONLY
+ )
+ # build dep list:
+ file(GLOB java2_srcs "opj_viewer_xerces/src/*.java")
+
+ # Need some common files:
+ list(APPEND java2_srcs
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/src/ImageManager.java
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/src/ImgdecClient.java
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/src/JPIPHttpClient.java
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/src/MML.java
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/src/PnmImage.java
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/src/RegimViewer.java
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer/src/ResizeListener.java
+ )
+
+ # make sure target javac dir exists:
+ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/classes2)
+ # Build java
+ add_custom_command(
+ OUTPUT ${LIBRARY_OUTPUT_PATH}/opj_viewer_xerces.jar
+ COMMAND ${Java_JAVAC_EXECUTABLE} ${jflags}
+ -classpath ${APACHE_XERCES_JAR}
+ ${java2_srcs} -d ${CMAKE_CURRENT_BINARY_DIR}/classes2
+ COMMAND ${Java_JAR_EXECUTABLE} cfm ${LIBRARY_OUTPUT_PATH}/opj_viewer_xerces.jar
+ ${CMAKE_CURRENT_BINARY_DIR}/opj_viewer_xerces/dist/manifest.txt
+ -C ${CMAKE_CURRENT_BINARY_DIR}/classes2 .
+ DEPENDS ${java2_srcs}
+ ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer_xerces/dist/manifest.txt.in
+ COMMENT "javac *.java; jar cvf -> opj_viewer_xerces.jar"
+ )
+
+ # name the target
+ add_custom_target(OPJViewerXercesJar ALL
+ DEPENDS ${LIBRARY_OUTPUT_PATH}/opj_viewer_xerces.jar
+ COMMENT "building opj_viewer_xerces.jar"
+ )
+
+ install(FILES ${LIBRARY_OUTPUT_PATH}/opj_viewer_xerces.jar
+ DESTINATION ${OPENJPEG_INSTALL_SHARE_DIR} COMPONENT JavaModule
+ )
+ endif()
+else()
+ message(WARNING "No java compiler found. Wont be able to build java viewer")
+endif()
diff --git a/src/bin/jpip/Makefile.am b/src/bin/jpip/Makefile.am
new file mode 100644
index 00000000..0e98b71e
--- /dev/null
+++ b/src/bin/jpip/Makefile.am
@@ -0,0 +1,85 @@
+MAINTAINERCLEANFILES = Makefile.in
+
+bin_PROGRAMS =
+
+if WANT_JPIP
+bin_PROGRAMS += opj_dec_server test_index jpip_to_j2k jpip_to_jp2
+endif
+
+if WANT_JPIP_SERVER
+bin_PROGRAMS += opj_server
+endif
+
+opj_server_CPPFLAGS = \
+@FCGI_CFLAGS@ \
+-I. \
+-I$(top_srcdir)/libopenjpeg \
+-I$(top_builddir)/libopenjpeg \
+-I$(top_srcdir)/applications/jpip/libopenjpip \
+-I$(top_builddir)/applications/jpip/libopenjpip \
+-DSERVER \
+-DQUIT_SIGNAL=\"quitJPIP\"
+#
+opj_server_LDADD = $(top_builddir)/applications/jpip/libopenjpip/libopenjpip_server.la @FCGI_LIBS@ -lm
+#
+opj_server_SOURCES = opj_server.c
+
+#-------------
+opj_dec_server_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/libopenjpeg \
+-I$(top_builddir)/libopenjpeg \
+-I$(top_srcdir)/applications/jpip/libopenjpip \
+-I$(top_builddir)/applications/jpip/libopenjpip
+#
+opj_dec_server_CFLAGS =
+opj_dec_server_LDADD = $(top_builddir)/applications/jpip/libopenjpip/libopenjpip_local.la
+opj_dec_server_SOURCES = opj_dec_server.c
+
+#-------------
+jpip_to_jp2_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/libopenjpeg \
+-I$(top_builddir)/libopenjpeg \
+-I$(top_srcdir)/applications/jpip/libopenjpip \
+-I$(top_builddir)/applications/jpip/libopenjpip
+#
+jpip_to_jp2_CFLAGS =
+jpip_to_jp2_LDADD = $(top_builddir)/applications/jpip/libopenjpip/libopenjpip_local.la
+jpip_to_jp2_SOURCES = jpip_to_jp2.c
+
+#-------------
+jpip_to_j2k_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/libopenjpeg \
+-I$(top_builddir)/libopenjpeg \
+-I$(top_srcdir)/applications/jpip/libopenjpip \
+-I$(top_builddir)/applications/jpip/libopenjpip
+#
+jpip_to_j2k_CFLAGS =
+jpip_to_j2k_LDADD = $(top_builddir)/applications/jpip/libopenjpip/libopenjpip_local.la
+jpip_to_j2k_SOURCES = jpip_to_j2k.c
+
+#-------------
+test_index_CPPFLAGS = \
+-I. \
+-I$(top_srcdir)/libopenjpeg \
+-I$(top_builddir)/libopenjpeg \
+-I$(top_srcdir)/applications/jpip/libopenjpip \
+-I$(top_builddir)/applications/jpip/libopenjpip
+#
+test_index_CFLAGS =
+test_index_LDADD = $(top_builddir)/applications/jpip/libopenjpip/libopenjpip_local.la
+test_index_SOURCES = test_index.c
+
+#-------------
+install-data-hook:
+if WANT_JPIP_SERVER
+ @echo -e " (B)\t$(bindir)/opj_server$(EXEEXT)" >> $(top_builddir)/report.txt
+endif
+if WANT_JPIP
+ @echo -e " (B)\t$(bindir)/opj_dec_server$(EXEEXT)" >> $(top_builddir)/report.txt
+ @echo -e " (B)\t$(bindir)/jpip_to_jp2$(EXEEXT)" >> $(top_builddir)/report.txt
+ @echo -e " (B)\t$(bindir)/jpip_to_j2k$(EXEEXT)" >> $(top_builddir)/report.txt
+ @echo -e " (B)\t$(bindir)/test_index$(EXEEXT)" >> $(top_builddir)/report.txt
+endif
diff --git a/src/bin/jpip/addXMLinJP2.c b/src/bin/jpip/addXMLinJP2.c
new file mode 100644
index 00000000..f136e913
--- /dev/null
+++ b/src/bin/jpip/addXMLinJP2.c
@@ -0,0 +1,181 @@
+/*
+ * $Id: addXMLinJP2.c 46 2011-02-17 14:50:55Z kaori $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*! \file
+ * \brief addXMLinJP2 is a program to embed metadata into JP2 file
+ *
+ * \section impinst Implementing instructions
+ * This program takes two arguments. \n
+ * -# Input/output image file in JP2 format, this JP2 file is being modified
+ * -# Input XML file with metadata contents\n
+ * % ./addXMLinJP2 image.jp2 metadata.xml\n
+ *
+ * Currently, this program does not parse XML file, and the XML file contents is directly embedded as a XML Box.\n
+ * The following is an example of XML file contents specifying Region Of Interests with target names.\n
+ * <xmlbox>\n
+ * <roi name="island" x="1890" y="1950" w="770" h="310"/>\n
+ * <roi name="ship" x="750" y="330" w="100" h="60"/>\n
+ * <roi name="airport" x="650" y="1800" w="650" h="800"/>\n
+ * <roi name="harbor" x="4200" y="1650" w="130" h="130"/>\n
+ * </xmlbox>
+ */
+
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+
+/**
+ * Open JP2 file with the check of JP2 header
+ *
+ * @param[in] filename file name string
+ * @return file descriptor
+ */
+FILE * open_jp2file( const char filename[]);
+
+
+/**
+ * read xml file without any format check for the moment
+ *
+ * @param[in] filename file name string
+ * @param[out] fsize file byte size
+ * @return pointer to the xml file content buffer
+ */
+char * read_xmlfile( const char filename[], long *fsize);
+
+int main(int argc, char *argv[])
+{
+ FILE *fp;
+ char *xmldata, type[]="xml ";
+ long fsize, boxsize;
+
+ if( argc<3){
+ fprintf( stderr, "USAGE: ./addXMLinJP2 modifing.jp2 adding.xml\n");
+ return -1;
+ }
+
+ fp = open_jp2file( argv[1]);
+ if( !fp)
+ return -1;
+
+ xmldata = read_xmlfile( argv[2], &fsize);
+ boxsize = fsize + 8;
+
+ fputc( (boxsize>>24)&0xff, fp);
+ fputc( (boxsize>>16)&0xff, fp);
+ fputc( (boxsize>>8)&0xff, fp);
+ fputc( boxsize&0xff, fp);
+ fwrite( type, 4, 1, fp);
+ fwrite( xmldata, fsize, 1, fp);
+
+ free( xmldata);
+ fclose(fp);
+
+ return 0;
+}
+
+FILE * open_jp2file( const char filename[])
+{
+ FILE *fp;
+ char *data;
+
+ if( !(fp = fopen( filename, "a+b"))){
+ fprintf( stderr, "Original JP2 %s not found\n", filename);
+ return NULL;
+ }
+ /* Check resource is a JP family file. */
+ if( fseek( fp, 0, SEEK_SET)==-1){
+ fclose(fp);
+ fprintf( stderr, "Original JP2 %s broken (fseek error)\n", filename);
+ return NULL;
+ }
+
+ data = (char *)malloc( 12); /* size of header */
+ if( fread( data, 12, 1, fp) != 1){
+ free( data);
+ fclose(fp);
+ fprintf( stderr, "Original JP2 %s broken (read error)\n", filename);
+ return NULL;
+ }
+
+ if( *data || *(data + 1) || *(data + 2) ||
+ *(data + 3) != 12 || strncmp (data + 4, "jP \r\n\x87\n", 8)){
+ free( data);
+ fclose(fp);
+ fprintf( stderr, "No JPEG 2000 Signature box in target %s\n", filename);
+ return NULL;
+ }
+ free( data);
+ return fp;
+}
+
+char * read_xmlfile( const char filename[], long *fsize)
+{
+ FILE *fp;
+ char *data;
+
+ /* fprintf( stderr, "open %s\n", filename);*/
+ if(!(fp = fopen( filename, "r"))){
+ fprintf( stderr, "XML file %s not found\n", filename);
+ return NULL;
+ }
+
+ if( fseek( fp, 0, SEEK_END) == -1){
+ fprintf( stderr, "XML file %s broken (seek error)\n", filename);
+ fclose( fp);
+ return NULL;
+ }
+
+ if( (*fsize = ftell( fp)) == -1){
+ fprintf( stderr, "XML file %s broken (seek error)\n", filename);
+ fclose( fp);
+ return NULL;
+ }
+
+ if( fseek( fp, 0, SEEK_SET) == -1){
+ fprintf( stderr, "XML file %s broken (seek error)\n", filename);
+ fclose( fp);
+ return NULL;
+ }
+
+ data = (char *)malloc( *fsize);
+
+ if( fread( data, *fsize, 1, fp) != 1){
+ fprintf( stderr, "XML file %s broken (read error)\n", filename);
+ free( data);
+ fclose(fp);
+ return NULL;
+ }
+
+ fclose( fp);
+
+ return data;
+}
diff --git a/src/bin/jpip/jpip_to_j2k.c b/src/bin/jpip/jpip_to_j2k.c
new file mode 100644
index 00000000..d8b2e2b0
--- /dev/null
+++ b/src/bin/jpip/jpip_to_j2k.c
@@ -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.
+ */
+
+/*! \file
+ * \brief jpip_to_j2k is a program to convert JPT- JPP- stream to J2K file
+ *
+ * \section impinst Implementing instructions
+ * This program takes two arguments. \n
+ * -# Input JPT or JPP file
+ * -# Output J2K file\n
+ * % ./jpip_to_j2k input.jpt output.j2k
+ * or
+ * % ./jpip_to_j2k input.jpp output.j2k
+ */
+
+#include <stdio.h>
+#include "openjpip.h"
+
+int main(int argc,char *argv[])
+{
+ jpip_dec_param_t *dec;
+
+ if( argc < 3){
+ fprintf( stderr, "Too few arguments:\n");
+ fprintf( stderr, " - input jpt or jpp file\n");
+ fprintf( stderr, " - output j2k file\n");
+ return -1;
+ }
+
+ dec = init_jpipdecoder( false);
+
+ if(!( fread_jpip( argv[1], dec)))
+ return -1;
+
+ decode_jpip( dec);
+
+ if(!( fwrite_jp2k( argv[2], dec)))
+ return -1;
+
+ /* output_log( true, false, false, dec); */
+
+ destroy_jpipdecoder( &dec);
+
+ return 0;
+}
diff --git a/src/bin/jpip/jpip_to_jp2.c b/src/bin/jpip/jpip_to_jp2.c
new file mode 100644
index 00000000..d667ed9d
--- /dev/null
+++ b/src/bin/jpip/jpip_to_jp2.c
@@ -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.
+ */
+
+/*! \file
+ * \brief jpip_to_jp2 is a program to convert JPT- JPP- stream to JP2 file
+ *
+ * \section impinst Implementing instructions
+ * This program takes two arguments. \n
+ * -# Input JPT or JPP file
+ * -# Output JP2 file\n
+ * % ./jpip_to_jp2 input.jpt output.jp2
+ * or
+ * % ./jpip_to_jp2 input.jpp output.jp2
+ */
+
+#include <stdio.h>
+#include "openjpip.h"
+
+int main(int argc,char *argv[])
+{
+ jpip_dec_param_t *dec;
+
+ if( argc < 3){
+ fprintf( stderr, "Too few arguments:\n");
+ fprintf( stderr, " - input jpt or jpp file\n");
+ fprintf( stderr, " - output jp2 file\n");
+ return -1;
+ }
+
+ dec = init_jpipdecoder( true);
+
+ if(!( fread_jpip( argv[1], dec)))
+ return -1;
+
+ decode_jpip( dec);
+
+ if(!(fwrite_jp2k( argv[2], dec)))
+ return -1;
+
+ output_log( true, false, true, dec);
+
+ destroy_jpipdecoder( &dec);
+
+ return 0;
+}
diff --git a/src/bin/jpip/opj_dec_server.c b/src/bin/jpip/opj_dec_server.c
new file mode 100644
index 00000000..b41ef0c9
--- /dev/null
+++ b/src/bin/jpip/opj_dec_server.c
@@ -0,0 +1,92 @@
+/*
+ * $Id: opj_dec_server.c 54 2011-05-10 13:22:47Z kaori $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*! \file
+ * \brief opj_dec_server is a server to decode JPT-stream and communicate locally with JPIP client, which is coded in java.
+ *
+ * \section impinst Implementing instructions
+ * Launch opj_dec_server from a terminal in the same machine as JPIP client image viewers. \n
+ * % ./opj_dec_server [portnumber]\n
+ * ( portnumber=50000 by default)\n
+ * Keep it alive as long as image viewers are open.\n
+ *
+ * To quite the opj_dec_server, send a message "quit" through the telnet.\n
+ * % telnet localhost 50000\n
+ * quit\n
+ * Be sure all image viewers are closed.\n
+ * Cache file in JPT format is stored in the working directly before it quites.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include "openjpip.h"
+
+#ifdef _WIN32
+WSADATA initialisation_win32;
+#endif
+
+int main(int argc, char *argv[]){
+
+ dec_server_record_t *server_record;
+ client_t client;
+ int port = 50000;
+ int erreur;
+ (void)erreur;
+
+ if( argc > 1)
+ port = atoi( argv[1]);
+
+#ifdef _WIN32
+ erreur = WSAStartup(MAKEWORD(2,2),&initialisation_win32);
+ if( erreur!=0)
+ fprintf( stderr, "Erreur initialisation Winsock error : %d %d\n",erreur,WSAGetLastError());
+ else
+ printf( "Initialisation Winsock\n");
+#endif /*_WIN32*/
+
+ server_record = init_dec_server( port);
+
+ while(( client = accept_connection( server_record)) != -1 )
+ if(!handle_clientreq( client, server_record))
+ break;
+
+ terminate_dec_server( &server_record);
+
+#ifdef _WIN32
+ if( WSACleanup() != 0){
+ printf("\nError in WSACleanup : %d %d",erreur,WSAGetLastError());
+ }else{
+ printf("\nWSACleanup OK\n");
+ }
+#endif
+
+ return 0;
+}
diff --git a/src/bin/jpip/opj_server.c b/src/bin/jpip/opj_server.c
new file mode 100644
index 00000000..1666a94f
--- /dev/null
+++ b/src/bin/jpip/opj_server.c
@@ -0,0 +1,127 @@
+/*
+ * $Id: opj_server.c 53 2011-05-09 16:55:39Z kaori $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * Copyright (c) 2011, Lucian Corlaciu, GSoC
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*! \file
+ * \brief opj_server is a JPIP server program, which supports HTTP connection, JPT-stream, session, channels, and cache model managements.
+ *
+ * \section req Requirements
+ * FastCGI development kit (http://www.fastcgi.com).
+ *
+ * \section impinst Implementing instructions
+ * Launch opj_server from the server terminal:\n
+ * % spawn-fcgi -f ./opj_server -p 3000 -n
+ *
+ * Note: JP2 files are stored in the working directory of opj_server\n
+ * Check README for the JP2 Encoding\n
+ *
+ * We tested this software with a virtual server running on the same Linux machine as the clients.
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include "openjpip.h"
+
+#ifndef QUIT_SIGNAL
+#define QUIT_SIGNAL "quitJPIP"
+#endif
+
+#ifdef _WIN32
+WSADATA initialisation_win32;
+#endif /*_WIN32*/
+
+int main(void)
+{
+ server_record_t *server_record;
+#ifdef SERVER
+ char *query_string;
+#endif
+
+#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
+ while(FCGI_Accept() >= 0)
+#else
+
+ char query_string[128];
+ while( fgets( query_string, 128, stdin) && query_string[0]!='\n')
+#endif
+ {
+ QR_t *qr;
+ bool parse_status;
+
+#ifdef SERVER
+ query_string = getenv("QUERY_STRING");
+#endif /*SERVER*/
+
+ if( strcmp( query_string, QUIT_SIGNAL) == 0)
+ break;
+
+ qr = parse_querystring( query_string);
+
+ parse_status = process_JPIPrequest( server_record, qr);
+
+#ifndef SERVER
+ local_log( true, true, parse_status, false, qr, server_record);
+#endif
+
+ if( parse_status)
+ send_responsedata( server_record, qr);
+ else{
+ fprintf( FCGI_stderr, "Error: JPIP request failed\n");
+ fprintf( FCGI_stdout, "\r\n");
+ }
+
+ end_QRprocess( server_record, &qr);
+ }
+
+ fprintf( FCGI_stderr, "JPIP server terminated by a client request\n");
+
+ terminate_JPIPserver( &server_record);
+
+#ifdef _WIN32
+ if( WSACleanup() != 0){
+ fprintf( stderr, "\nError in WSACleanup : %d %d",erreur,WSAGetLastError());
+ }else{
+ fprintf( stderr, "\nWSACleanup OK\n");
+ }
+#endif
+
+ return 0;
+}
diff --git a/src/bin/jpip/opj_viewer/dist/manifest.txt b/src/bin/jpip/opj_viewer/dist/manifest.txt
new file mode 100644
index 00000000..537c33dd
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/dist/manifest.txt
@@ -0,0 +1,4 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.7.0
+Created-By: Kaori Hagihara
+Main-Class: ImageWindow
diff --git a/src/bin/jpip/opj_viewer/src/ImageManager.java b/src/bin/jpip/opj_viewer/src/ImageManager.java
new file mode 100644
index 00000000..aad3ffaa
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/ImageManager.java
@@ -0,0 +1,136 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.awt.Image;
+
+public class ImageManager extends JPIPHttpClient
+{
+ private PnmImage pnmimage;
+ private int origwidth;
+ private int origheight;
+ private ImgdecClient imgdecoder;
+
+ public ImageManager( String uri, String host, int port)
+ {
+ super( uri);
+ imgdecoder = new ImgdecClient( host, port);
+ pnmimage = null;
+ origwidth = 0;
+ origheight = 0;
+ }
+
+ public int getOrigWidth(){
+ if( origwidth == 0){
+ if( cid != null || tid != null){
+ java.awt.Dimension dim = imgdecoder.query_imagesize( cid, tid);
+ if( dim != null){
+ origwidth = dim.width;
+ origheight = dim.height;
+ }
+ }
+ else
+ System.err.println("Neither cid or tid obtained before to get Original Image Dimension");
+ }
+ return origwidth;
+ }
+ public int getOrigHeight(){ return origheight;}
+
+ public Image getImage( String j2kfilename, int reqfw, int reqfh, boolean reqcnew, int reqaux, boolean reqJPP, boolean reqJPT)
+ {
+ System.err.println();
+
+ String refcid = null;
+ byte[] jpipstream;
+
+ // Todo: check if the cid is for the same stream type
+ if( reqcnew)
+ refcid = imgdecoder.query_cid( j2kfilename);
+
+ if( refcid == null){
+ String reftid = imgdecoder.query_tid( j2kfilename);
+ if( reftid == null)
+ jpipstream = super.requestViewWindow( j2kfilename, reqfw, reqfh, reqcnew, reqaux, reqJPP, reqJPT);
+ else
+ jpipstream = super.requestViewWindow( j2kfilename, reftid, reqfw, reqfh, reqcnew, reqaux, reqJPP, reqJPT);
+ }
+ else
+ jpipstream = super.requestViewWindow( reqfw, reqfh, refcid, reqcnew, reqaux, reqJPP, reqJPT);
+
+ System.err.println( "decoding to PNM image");
+ if((pnmimage = imgdecoder.decode_jpipstream( jpipstream, j2kfilename, tid, cid, fw, fh))!=null){
+ System.err.println( " done");
+ return pnmimage.createROIImage( rx, ry, rw, rh);
+ }
+ else{
+ System.err.println( " failed");
+ return null;
+ }
+ }
+
+ public Image getImage( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
+ {
+ System.err.println();
+
+ byte[] jpipstream = super.requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh);
+
+ System.err.println( "decoding to PNM image");
+ if((pnmimage = imgdecoder.decode_jpipstream( jpipstream, tid, cid, fw, fh)) != null){
+ System.err.println( " done");
+ return pnmimage.createROIImage( rx, ry, rw, rh);
+ }
+ else{
+ System.err.println( " failed");
+ return null;
+ }
+ }
+
+ public byte[] getXML()
+ {
+ System.err.println();
+
+ byte []xmldata = null;
+ byte[] jpipstream = super.requestXML();
+
+ if( jpipstream != null){
+ imgdecoder.send_JPIPstream( jpipstream);
+
+ xmldata = imgdecoder.get_XMLstream( cid);
+ }
+ return xmldata;
+ }
+
+ public void closeChannel()
+ {
+ if( cid != null){
+ imgdecoder.destroy_cid( cid);
+ super.closeChannel();
+ }
+ }
+}
diff --git a/src/bin/jpip/opj_viewer/src/ImageViewer.java b/src/bin/jpip/opj_viewer/src/ImageViewer.java
new file mode 100644
index 00000000..163193b9
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/ImageViewer.java
@@ -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.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.awt.image.*;
+import java.awt.geom.*;
+import java.net.URL;
+import javax.swing.border.*;
+import java.util.*;
+import java.io.*;
+
+public class ImageViewer extends JPanel
+{
+ private ImageManager imgmanager;
+ private int vw, vh;
+ private int iw, ih;
+ private int selected = 0;
+ private Image img;
+
+ private String cmdline = new String();
+ private boolean fullRefresh = false;
+ private Point offset = new Point(0,0);
+ private Rectangle rect = new Rectangle();
+ private Rectangle roirect[] = null;
+ private String roiname[] = null;
+
+ public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream, int aux)
+ {
+ String str;
+ MML myMML;
+
+ this.setSize( 170, 170);
+ Dimension asz = this.getSize();
+
+ vw = asz.width;
+ vh = asz.height;
+
+ setBackground(Color.black);
+ myMML = new MML(this);
+
+ imgmanager = manager;
+
+ img = imgmanager.getImage( j2kfilename, vw, vh, session, aux, jppstream, !jppstream);
+
+ addMouseListener(myMML);
+ addMouseMotionListener(myMML);
+ addComponentListener( new ResizeListener(this));
+ }
+
+ public Image getImage()
+ {
+ return img;
+ }
+
+ public void zoomIn()
+ {
+ roirect = null;
+ roiname = null;
+
+ double scalex = (double)vw/(double)rect.width;
+ double scaley = (double)vh/(double)rect.height;
+
+ int fw = (int)(imgmanager.getFw()*scalex);
+ int fh = (int)(imgmanager.getFh()*scaley);
+ int rx = (int)((imgmanager.getRx()+rect.x)*scalex);
+ int ry = (int)((imgmanager.getRy()+rect.y)*scaley);
+
+ img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
+
+ rect.x = rect.y = rect.width = rect.height = 0;
+
+ selected = 0;
+ fullRefresh = true;
+ repaint();
+ }
+
+ public void enlarge()
+ {
+ roirect = null;
+ roiname = null;
+
+ Dimension asz = this.getSize();
+
+ vw = asz.width;
+ vh = asz.height;
+
+ double scalex = vw/(double)imgmanager.getRw();
+ double scaley = vh/(double)imgmanager.getRh();
+
+ int fw = (int)(imgmanager.getFw()*scalex);
+ int fh = (int)(imgmanager.getFh()*scaley);
+ int rx = (int)(imgmanager.getRx()*scalex);
+ int ry = (int)(imgmanager.getRy()*scaley);
+
+ img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
+
+ fullRefresh = true;
+ repaint();
+ }
+
+ public void setSelected(int state)
+ {
+ roirect = null;
+ roiname = null;
+
+ if (state != selected) {
+
+ selected = state;
+ repaint();
+ }
+ }
+
+ public boolean isInsideRect(int x, int y)
+ {
+ return rect.contains(x - offset.x, y - offset.y);
+ }
+
+ public void setRGeom(int x1, int y1, int x2, int y2)
+ {
+ rect.x = Math.min(x1,x2) - offset.x;
+ rect.y = Math.min(y1,y2) - offset.y;
+ rect.width = Math.abs(x2-x1);
+ rect.height = Math.abs(y2-y1);
+ }
+
+ // public void annotate( JP2XMLparser.ROIparams roi[])
+ // {
+ // int numofroi = roi.length;
+
+ // roirect = new Rectangle [numofroi];
+ // roiname = new String [numofroi];
+
+ // double scale_x = imgmanager.getFw()/(double)imgmanager.getOrigWidth();
+ // double scale_y = imgmanager.getFh()/(double)imgmanager.getOrigHeight();
+ // int rx = imgmanager.getRx();
+ // int ry = imgmanager.getRy();
+ // int rw = imgmanager.getRw();
+ // int rh = imgmanager.getRh();
+
+ // for( int i=0; i<numofroi ; i++){
+ // int x = (int)(roi[i].x*scale_x) - rx;
+ // int y = (int)(roi[i].y*scale_y) - ry;
+ // int w = (int)(roi[i].w*scale_x);
+ // int h = (int)(roi[i].h*scale_y);
+ // if( 0<=x && 0<=y && x+w<=rw && y+h<=rh){ // can be optimized
+ // roirect[i] = new Rectangle( x, y, w, h);
+ // roiname[i] = new String( roi[i].name);
+ // }
+ // else{
+ // roirect[i] = null;
+ // roiname[i] = null;
+ // }
+ // }
+ // repaint();
+ // }
+
+ public boolean hasAnnotation()
+ {
+ if( roirect == null)
+ return false;
+ else
+ return true;
+ }
+
+ public boolean isInsideROIRect(int x, int y)
+ {
+ for( int i=0; i<roirect.length; i++)
+ if( roirect[i] != null)
+ if( roirect[i].contains(x - offset.x, y - offset.y)){
+ rect = roirect[i];
+ return true;
+ }
+ return false;
+ }
+
+ public void paint(Graphics g)
+ {
+ BufferedImage bi;
+ Graphics2D big;
+ Graphics2D g2 = (Graphics2D) g;
+
+ if (fullRefresh) {
+ g2.clearRect(0, 0, vw, vh);
+ fullRefresh = false;
+ }
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_QUALITY);
+
+ offset.x = 0;
+ offset.y = 0;
+
+ iw = img.getWidth(this);
+ ih = img.getHeight(this);
+
+ bi = new BufferedImage( iw, ih, BufferedImage.TYPE_INT_RGB);
+ big = bi.createGraphics();
+
+ big.drawImage(img, 0, 0, this);
+ big.setPaint(Color.red);
+ if ((rect.width > 0) && (rect.height > 0))
+ big.draw(rect);
+
+ if( roirect != null){
+ for( int i=0; i<roirect.length; i++)
+ if( roirect[i] != null){
+ big.draw( roirect[i]);
+ big.drawString( roiname[i], roirect[i].x+3, roirect[i].y+roirect[i].height*2/3);
+ }
+ }
+ if (selected == 1)
+ shadeExt(big, 0, 0, 0, 64);
+ else if (selected == 2) {
+ shadeExt(big, 0, 0, 0, 255);
+ selected = 1;
+ }
+ g2.drawImage(bi, offset.x, offset.y, this);
+ }
+
+ private void shadeRect(Graphics2D g2, int r, int g, int b, int a)
+ {
+ g2.setPaint(new Color(r, g, b, a));
+ g2.fillRect(rect.x + 1, rect.y + 1, rect.width - 1, rect.height - 1);
+ }
+
+ private void shadeExt(Graphics2D g2, int r, int g, int b, int a)
+ {
+ g2.setPaint(new Color(r, g, b, a));
+ g2.fillRect(0, 0, iw, rect.y); /* _N_ */
+ g2.fillRect(rect.x + rect.width + 1, rect.y,
+ iw - rect.x - rect.width - 1, rect.height + 1); /* E */
+ g2.fillRect(0, rect.y, rect.x, rect.height + 1); /* W */
+ g2.fillRect(0, rect.y + rect.height + 1,
+ iw, ih - rect.y - rect.height - 1); /* _S_ */
+ }
+}
diff --git a/src/bin/jpip/opj_viewer/src/ImageWindow.java b/src/bin/jpip/opj_viewer/src/ImageWindow.java
new file mode 100644
index 00000000..9a236e4a
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/ImageWindow.java
@@ -0,0 +1,120 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+
+public class ImageWindow extends JFrame
+{
+ private ImageViewer imgviewer;
+ private ImageManager imgmanager;
+
+ public ImageWindow( String uri, String j2kfilename, String host, int port, boolean session, boolean jppstream, int aux)
+ {
+ super( j2kfilename);
+
+ imgmanager = new ImageManager( uri, host, port);
+
+ imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream, aux);
+ imgviewer.setOpaque(true); //content panes must be opaque
+
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ panel.add( imgviewer, BorderLayout.CENTER);
+
+ setContentPane( panel);
+
+ addWindowListener(new WindowMyAdapter());
+ }
+
+ class WindowMyAdapter extends WindowAdapter
+ {
+ public void windowClosing(WindowEvent arg)
+ {
+ imgmanager.closeChannel();
+ System.exit(0);
+ }
+ }
+
+ public static void main(String s[])
+ {
+ String j2kfilename, uri, host;
+ boolean session, jppstream;
+ int port, aux; // 0: none, 1: tcp, 2: udp
+
+ if(s.length >= 2){
+ uri = s[0];
+ j2kfilename = s[1];
+
+ if( s.length > 2)
+ host = s[2];
+ else
+ host = "localhost";
+
+ if( s.length > 3)
+ port = Integer.valueOf( s[3]).intValue();
+ else
+ port = 50000;
+
+ if( s.length > 4)
+ session = !s[4].equalsIgnoreCase( "stateless");
+ else
+ session = true;
+
+ if( s.length > 5)
+ jppstream = !s[5].equalsIgnoreCase( "JPT");
+ else
+ jppstream = true;
+
+ if( s.length > 6){
+ if( s[6].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 [hostname] [portnumber] [stateless/session] [JPT/JPP] [tcp/udp]");
+ return;
+ }
+ ImageWindow frame = new ImageWindow( uri, j2kfilename, host, port, session, jppstream, aux);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ //Display the window.
+ frame.pack();
+ frame.setSize(new Dimension(400,200));
+ frame.setLocation( 0, 50);
+ frame.setVisible(true);
+ }
+}
diff --git a/src/bin/jpip/opj_viewer/src/ImgdecClient.java b/src/bin/jpip/opj_viewer/src/ImgdecClient.java
new file mode 100644
index 00000000..edb64ded
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/ImgdecClient.java
@@ -0,0 +1,350 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.io.*;
+import java.net.*;
+
+public class ImgdecClient{
+
+ private String hostname;
+ private int portNo;
+
+ public ImgdecClient( String host, int port)
+ {
+ hostname = host;
+ portNo = port;
+ }
+
+ public PnmImage decode_jpipstream( byte[] jpipstream, String tid, String cid, int fw, int fh)
+ {
+ if( jpipstream != null)
+ send_JPIPstream( jpipstream);
+ return get_PNMstream( cid, tid, fw, fh);
+ }
+
+ public PnmImage decode_jpipstream( byte[] jpipstream, String j2kfilename, String tid, String cid, int fw, int fh)
+ {
+ send_JPIPstream( jpipstream, j2kfilename, tid, cid);
+ return get_PNMstream( cid, tid, fw, fh);
+ }
+
+ public void send_JPIPstream( byte[] jpipstream)
+ {
+ try{
+ Socket imgdecSocket = new Socket( hostname, portNo);
+ DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
+ DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
+
+ System.err.println("Sending " + jpipstream.length + "Data Bytes to decodingServer");
+
+ os.writeBytes("JPIP-stream\n");
+ os.writeBytes("version 1.2\n");
+ os.writeBytes( jpipstream.length + "\n");
+ os.write( jpipstream, 0, jpipstream.length);
+
+ byte signal = is.readByte();
+
+ if( signal == 0)
+ System.err.println(" failed");
+ } catch (UnknownHostException e) {
+ System.err.println("Trying to connect to unknown host: " + e);
+ } catch (IOException e) {
+ System.err.println("IOException: " + e);
+ }
+ }
+
+ public void send_JPIPstream( byte[] jpipstream, String j2kfilename, String tid, String cid)
+ {
+ try{
+ Socket imgdecSocket = new Socket( hostname, portNo);
+ DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
+ DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
+ int length = 0;
+
+ if( jpipstream != null)
+ length = jpipstream.length;
+
+ System.err.println("Sending " + length + "Data Bytes to decodingServer");
+
+ os.writeBytes("JPIP-stream\n");
+ os.writeBytes("version 1.2\n");
+ os.writeBytes( j2kfilename + "\n");
+ if( tid == null)
+ os.writeBytes( "0\n");
+ else
+ os.writeBytes( tid + "\n");
+ if( cid == null)
+ os.writeBytes( "0\n");
+ else
+ os.writeBytes( cid + "\n");
+ os.writeBytes( length + "\n");
+ os.write( jpipstream, 0, length);
+
+ byte signal = is.readByte();
+
+ if( signal == 0)
+ System.err.println(" failed");
+ } catch (UnknownHostException e) {
+ System.err.println("Trying to connect to unknown host: " + e);
+ } catch (IOException e) {
+ System.err.println("IOException: " + e);
+ }
+ }
+
+ public PnmImage get_PNMstream( String cid, String tid, int fw, int fh)
+ {
+ PnmImage pnmstream = null;
+
+ try {
+ Socket imgdecSocket = new Socket( hostname, portNo);
+ DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
+ DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
+ byte []header = new byte[7];
+
+ os.writeBytes("PNM request\n");
+ if( cid != null)
+ os.writeBytes( cid + "\n");
+ else
+ if( tid != null)
+ os.writeBytes( tid + "\n");
+ else
+ os.writeBytes( "0\n");
+ os.writeBytes( fw + "\n");
+ os.writeBytes( fh + "\n");
+
+ read_stream( is, header, 7);
+
+ if( header[0] == 80){
+ // P5: gray, P6: color
+ byte magicknum = header[1];
+ if( magicknum == 5 || magicknum == 6){
+ int c = magicknum==6 ? 3: 1;
+ int w = (header[2]&0xff)<<8 | (header[3]&0xff);
+ int h = (header[4]&0xff)<<8 | (header[5]&0xff);
+ int maxval = header[6]&0xff;
+ int length = w*h*c;
+
+ if( maxval == 255 && length != 0){
+ pnmstream = new PnmImage( c, w, h);
+ read_stream( is, pnmstream.get_data(), length);
+ }
+ else
+ System.err.println("Error in get_PNMstream(), only 255 is accepted");
+ }
+ else
+ System.err.println("Error in get_PNMstream(), wrong magick number" + header[1]);
+ }
+ else
+ System.err.println("Error in get_PNMstream(), Not starting with P");
+
+ os.close();
+ is.close();
+ imgdecSocket.close();
+ } catch (UnknownHostException e) {
+ System.err.println("Trying to connect to unknown host: " + e);
+ } catch (IOException e) {
+ System.err.println("IOException: " + e);
+ }
+ return pnmstream;
+ }
+
+ public byte [] get_XMLstream( String cid)
+ {
+ byte []xmldata = null;
+
+ try{
+ Socket imgdecSocket = new Socket( hostname, portNo);
+ DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
+ DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
+ byte []header = new byte[5];
+
+ os.writeBytes("XML request\n");
+ os.writeBytes( cid + "\n");
+
+ read_stream( is, header, 5);
+
+ if( header[0] == 88 && header[1] == 77 && header[2] == 76){
+ int length = (header[3]&0xff)<<8 | (header[4]&0xff);
+
+ xmldata = new byte[ length];
+ read_stream( is, xmldata, length);
+ }
+ else
+ System.err.println("Error in get_XMLstream(), not starting with XML");
+ } catch (UnknownHostException e) {
+ System.err.println("Trying to connect to unknown host: " + e);
+ } catch (IOException e) {
+ System.err.println("IOException: " + e);
+ }
+ return xmldata;
+ }
+
+ public String query_cid( String j2kfilename)
+ {
+ int []retmsglabel = new int[3];
+ retmsglabel[0] = 67;
+ retmsglabel[1] = 73;
+ retmsglabel[2] = 68;
+
+ return query_id( "CID request", j2kfilename, retmsglabel);
+ }
+
+ public String query_tid( String j2kfilename)
+ {
+ int []retmsglabel = new int[3];
+ retmsglabel[0] = 84;
+ retmsglabel[1] = 73;
+ retmsglabel[2] = 68;
+
+ return query_id( "TID request", j2kfilename, retmsglabel);
+ }
+
+ public String query_id( String reqmsghead, String j2kfilename, int[] retmsglabel)
+ {
+ String id = null;
+
+ try{
+ Socket imgdecSocket = new Socket( hostname, portNo);
+ DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
+ DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
+ byte []header = new byte[4];
+
+ os.writeBytes( reqmsghead + "\n");
+ os.writeBytes( j2kfilename + "\n");
+
+ read_stream( is, header, 4);
+
+ if( header[0] == retmsglabel[0] && header[1] == retmsglabel[1] && header[2] == retmsglabel[2]){
+ int length = header[3]&0xff;
+
+ if( length > 0){
+
+ byte []iddata = new byte[ length];
+ read_stream( is, iddata, length);
+ id = new String( iddata);
+ }
+ }
+ else
+ System.err.println("Error in query_id("+ reqmsghead + "), wrong to start with " + header);
+ }
+ catch (UnknownHostException e) {
+ System.err.println("Trying to connect to unknown host: " + e);
+ } catch (IOException e) {
+ System.err.println("IOException: " + e);
+ }
+
+ return id;
+ }
+
+ public java.awt.Dimension query_imagesize( String cid, String tid)
+ {
+ java.awt.Dimension dim = null;
+
+ try{
+ Socket imgdecSocket = new Socket( hostname, portNo);
+ DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
+ DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
+ byte []header = new byte[3];
+
+ os.writeBytes( "SIZ request\n");
+ if( tid == null)
+ os.writeBytes( "0\n");
+ else
+ os.writeBytes( tid + "\n");
+ if( cid == null)
+ os.writeBytes( "0\n");
+ else
+ os.writeBytes( cid + "\n");
+
+ read_stream( is, header, 3);
+
+ if( header[0] == 83 && header[1] == 73 && header[2] == 90){
+
+ byte []data = new byte[ 3];
+ read_stream( is, data, 3);
+ int w = (data[0]&0xff)<<16 | (data[1]&0xff)<<8 | (data[2]&0xff);
+ read_stream( is, data, 3);
+ int h = (data[0]&0xff)<<16 | (data[1]&0xff)<<8 | (data[2]&0xff);
+ dim = new java.awt.Dimension( w, h);
+ }
+ else
+ System.err.println("Error in query_imagesize("+ cid + ", " + tid + "), wrong to start with " + header);
+ }
+ catch (UnknownHostException e) {
+ System.err.println("Trying to connect to unknown host: " + e);
+ } catch (IOException e) {
+ System.err.println("IOException: " + e);
+ }
+
+ return dim;
+ }
+
+ private static void read_stream( DataInputStream is, byte []stream, int length)
+ {
+ int remlen = length;
+ int off = 0;
+
+ try{
+ while( remlen > 0){
+ int redlen = is.read( stream, off, remlen);
+
+ if( redlen == -1){
+ System.err.println(" failed to read_stream()");
+ break;
+ }
+ off += redlen;
+ remlen -= redlen;
+ }
+ } catch (IOException e) {
+ System.err.println("IOException: " + e);
+ }
+ }
+
+ public void destroy_cid( String cid)
+ {
+ try{
+ Socket imgdecSocket = new Socket( hostname, portNo);
+ DataOutputStream os = new DataOutputStream( imgdecSocket.getOutputStream());
+ DataInputStream is = new DataInputStream( imgdecSocket.getInputStream());
+
+ os.writeBytes("CID destroy\n");
+ os.writeBytes( cid + "\n");
+
+ byte signal = is.readByte();
+
+ if( signal == 0)
+ System.err.println(" failed");
+ } catch (UnknownHostException e) {
+ System.err.println("Trying to connect to unknown host: " + e);
+ } catch (IOException e) {
+ System.err.println("IOException: " + e);
+ }
+ }
+}
diff --git a/src/bin/jpip/opj_viewer/src/JPIPHttpClient.java b/src/bin/jpip/opj_viewer/src/JPIPHttpClient.java
new file mode 100644
index 00000000..ce9a301d
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/JPIPHttpClient.java
@@ -0,0 +1,503 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.net.*;
+import java.io.*;
+import java.util.*;
+
+
+public class JPIPHttpClient
+{
+ private String comURL;
+ protected int fw, fh;
+ protected int rx, ry;
+ protected int rw, rh;
+ protected String cid;
+ 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)
+ {
+ comURL = URI + "?";
+ fw = fh = -1;
+ rx = ry = -1;
+ rw = rh = -1;
+ cid = null;
+ tid = null;
+ JPTstream = JPPstream = aux = false;
+ port = 0;
+ }
+
+ public int getFw(){ return fw;}
+ public int getFh(){ return fh;}
+ public int getRx(){ return rx;}
+ public int getRy(){ return ry;}
+ public int getRw(){ return rw;}
+ public int getRh(){ return rh;}
+
+ public byte[] requestViewWindow( int reqfw, int reqfh)
+ {
+ if( cid != null)
+ return requestViewWindow( reqfw, reqfh, cid);
+ else
+ return null;
+ }
+
+ public byte[] requestViewWindow( int reqfw, int reqfh, int reqrx, int reqry, int reqrw, int reqrh)
+ {
+ if( cid != null)
+ return requestViewWindow( reqfw, reqfh, reqrx, reqry, reqrw, reqrh, cid);
+ else
+ if( tid != null)
+ 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, 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, 0, false, false);
+ }
+
+ public byte[] requestViewWindow( String target, int reqfw, int reqfh)
+ {
+ 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, 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, reqaux, reqJPP, reqJPT);
+ else
+ return null;
+ }
+
+ 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, 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, 0, false, false);
+ }
+
+ 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, reqaux, reqJPP, reqJPT);
+ }
+
+ public byte[] requestViewWindow( String target,
+ String reqtid,
+ int reqfw, int reqfh,
+ int reqrx, int reqry,
+ int reqrw, int reqrh,
+ 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, reqaux, reqJPP, reqJPT);
+ return GETrequest( urlstring);
+ }
+
+ public byte[] requestXML()
+ {
+ String urlstring = comURL;
+
+ if( cid == null)
+ return null;
+
+ urlstring = urlstring.concat( "cid=" + cid);
+ urlstring = urlstring.concat( "&metareq=[xml_]");
+
+ return GETrequest( urlstring);
+ }
+
+ private byte[] GETrequest( String urlstring)
+ {
+ URL url = null;
+ HttpURLConnection urlconn = null;
+ byte[] jpipstream = null;
+
+ try{
+ url = new URL( urlstring);
+
+ System.err.println("Requesting: " + url);
+
+ urlconn = (HttpURLConnection)url.openConnection();
+ urlconn.setRequestMethod("GET");
+ urlconn.setInstanceFollowRedirects(false);
+ urlconn.connect();
+
+ set_responseheader( urlconn);
+
+ if( !aux){
+ jpipstream = receive_httpchunk( urlconn);
+ urlconn.disconnect();
+ }
+ else{
+ urlconn.disconnect();
+ jpipstream = receive_tcpaux( comURL.substring( 7, comURL.indexOf('/', 7)), port, cid);
+ }
+ }
+ catch ( MalformedURLException e){
+ e.printStackTrace();
+ }
+ catch ( ProtocolException e){
+ e.printStackTrace();
+ }
+ catch( ClassCastException e){
+ e.printStackTrace();
+ }
+ catch( NullPointerException e){
+ e.printStackTrace();
+ }
+ catch( UnknownServiceException e){
+ e.printStackTrace();
+ }
+ catch ( IOException e){
+ e.printStackTrace();
+ }
+
+ return jpipstream;
+ }
+
+ private void set_responseheader( HttpURLConnection urlconn)
+ {
+ Map<String,java.util.List<String>> headers = urlconn.getHeaderFields();
+ java.util.List<String> hvaluelist;
+ String hvalueline;
+
+ String status = headers.get(null).get(0);
+
+ System.err.println( status);
+ if( !status.contains("OK"))
+ System.err.println( headers.get("Reason"));
+
+ 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, int reqaux, boolean reqJPP, boolean reqJPT)
+ {
+ String urlstring = comURL;
+
+ // C.7.3 Image Return Type
+ // add type=jpp-stream(;ptype=ext) or type=jpt-stream;ttype=ext
+
+ if( target != null){
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ urlstring = urlstring.concat( "target=" + target);
+ }
+ if( reqtid != null){
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ urlstring = urlstring.concat( "tid=" + reqtid);
+ }
+ if( reqfw != -1 && reqfh != -1){
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ urlstring = urlstring.concat( "fsiz=" + reqfw + "," + reqfh);
+ }
+ if( reqrx != -1 && reqry != -1){
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ urlstring = urlstring.concat( "roff=" + reqrx + "," + reqry);
+ }
+ if( reqrw != -1 && reqrh != -1){
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ urlstring = urlstring.concat( "rsiz=" + reqrw + "," + reqrh);
+ }
+ if( reqcid != null){
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ urlstring = urlstring.concat( "cid=" + reqcid);
+ }
+ if( reqcnew){
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ 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( "&");
+ urlstring = urlstring.concat( "type=jpp-stream");
+ }
+ else if( reqJPT && !JPPstream){
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ urlstring = urlstring.concat( "type=jpt-stream");
+ }
+ else{ // remove this option later
+ if( !urlstring.endsWith("?"))
+ urlstring = urlstring.concat( "&");
+ if( JPTstream)
+ urlstring = urlstring.concat( "type=jpt-stream");
+ else if( JPPstream)
+ urlstring = urlstring.concat( "type=jpp-stream");
+ }
+
+ return urlstring;
+ }
+
+ public void closeChannel()
+ {
+ if( cid == null)
+ return;
+
+ try{
+ URL url = new URL( comURL + "cclose=" + cid);
+ System.err.println( "closing cid: " + cid);
+
+ HttpURLConnection urlconn = (HttpURLConnection)url.openConnection();
+ urlconn.setRequestMethod("GET");
+ urlconn.setInstanceFollowRedirects(false);
+ urlconn.connect();
+
+ Map headers = urlconn.getHeaderFields();
+
+ urlconn.disconnect();
+ } catch ( MalformedURLException e){
+ e.printStackTrace();
+ } catch ( IOException e){
+ e.printStackTrace();
+ }
+ }
+}
diff --git a/src/bin/jpip/opj_viewer/src/MML.java b/src/bin/jpip/opj_viewer/src/MML.java
new file mode 100644
index 00000000..983ff200
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/MML.java
@@ -0,0 +1,116 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.awt.event.*;
+
+class MML implements MouseMotionListener, MouseListener
+{
+ public void mouseExited(MouseEvent e) {}
+ public void mouseEntered(MouseEvent e) {}
+ public void mouseClicked(MouseEvent e) {}
+
+ private ImageViewer iv;
+ private int x1, y1, x2, y2, zf, btn;
+ private boolean zoomrq;
+
+ public MML(ImageViewer imageviewer)
+ {
+ x1 = y1 = -1;
+ iv = imageviewer;
+ zoomrq = false;
+ zf = 0;
+ }
+
+ private boolean isInside(int x, int y)
+ {
+ x -= iv.getX();
+ y -= iv.getY();
+ return (x >= 0) && (x < iv.getWidth())
+ && (y >= 0) && (y < iv.getHeight());
+ }
+
+ public void mousePressed(MouseEvent e)
+ {
+ btn = e.getButton();
+
+ if( iv.hasAnnotation()){
+ if( iv.isInsideROIRect(e.getX(), e.getY())){
+ iv.zoomIn();
+ System.out.println("annotation click");
+ return;
+ }
+ }
+ if (iv.isInsideRect(e.getX(), e.getY())) {
+ iv.setSelected(2);
+ iv.repaint();
+ zoomrq = true;
+ } else {
+ iv.setRGeom(0, 0, 0, 0);
+ iv.setSelected(0);
+ iv.repaint();
+ x1 = y1 = -1;
+ }
+ }
+
+ public void mouseReleased(MouseEvent e)
+ {
+ if(e.getButton() == 1) {
+ if (zoomrq) {
+ iv.zoomIn();
+ zoomrq = false;
+ }
+ }
+ }
+
+ public void mouseMoved(MouseEvent e)
+ {
+ }
+
+ public void mouseDragged(MouseEvent e)
+ {
+ if (btn == 1) {
+ x2 = e.getX();
+ y2 = e.getY();
+
+ iv.setSelected(0);
+ zoomrq = false;
+
+ if (isInside(x2, y2)) {
+ if (x1 == -1) {
+ x1 = x2;
+ y1 = y2;
+ } else {
+ iv.setRGeom(x1, y1, x2, y2);
+ iv.repaint();
+ }
+ }
+ }
+ }
+}
diff --git a/src/bin/jpip/opj_viewer/src/PnmImage.java b/src/bin/jpip/opj_viewer/src/PnmImage.java
new file mode 100644
index 00000000..092acecb
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/PnmImage.java
@@ -0,0 +1,154 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.awt.*;
+import java.awt.image.*;
+import java.io.*;
+import java.util.regex.*;
+
+public class PnmImage extends Component
+{
+ private byte[] data = null;
+ private int width = 0;
+ private int height = 0;
+ private int channel = 0;
+
+ public PnmImage( int c, int w, int h)
+ {
+ channel = c;
+ width = w;
+ height = h;
+ data = new byte [ w*h*c];
+ }
+
+ public PnmImage( String filename)
+ {
+ String str;
+ Pattern pat;
+ Matcher mat;
+ int bytes;
+ int r, offset = 0;
+
+ try {
+ FileInputStream fis = new FileInputStream( new File(filename));
+ DataInputStream is = new DataInputStream( fis);
+
+ pat = Pattern.compile("^P([56])$");
+ mat = pat.matcher(str = is.readLine());
+ if( !mat.matches()){
+ System.out.println("PNM header format error");
+ return;
+ }
+
+ if( (mat.group(1)).compareTo("5") == 0)
+ channel = 1;
+ else
+ channel = 3;
+
+ pat = Pattern.compile("^(\\d+) (\\d+)$");
+ mat = pat.matcher(str = is.readLine());
+ if( !mat.matches()){
+ System.out.println("PNM header format error");
+ return;
+ }
+ width = Integer.parseInt( mat.group(1));
+ height = Integer.parseInt( mat.group(2));
+
+ str = is.readLine(); // 255
+
+ bytes = width*height*channel;
+ data = new byte[bytes];
+
+ while( bytes > 0){
+ try {
+ r = is.read(data, offset, bytes);
+ if( r == -1){
+ System.err.println(" failed to read()");
+ break;
+ }
+ offset += r;
+ bytes -= r;
+ }
+ catch (IOException e) { e.printStackTrace(); }
+ }
+ fis.close();
+ } catch (IOException e) { e.printStackTrace(); }
+ }
+
+ public byte [] get_data(){ return data;}
+ public int get_width() { return width;}
+ public int get_height(){ return height;}
+
+ public Image createROIImage( int rx, int ry, int rw, int rh)
+ {
+ int []pix = new int[ rw*rh];
+
+ for( int i=0; i<rh; i++)
+ for( int j=0; j<rw; j++){
+ pix[i*rw+j] = 0xFF << 24; // transparency
+ if( channel == 1){
+ Byte lum = data[(ry+i)*width+rx+j];
+ short slum;
+
+ if( lum < 0)
+ slum = (short)(2*128+lum);
+ else
+ slum = (short)lum;
+
+ for( int c=0; c<3; c++){
+ pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
+ }
+ }
+ else
+ for( int c=0; c<3; c++){
+ Byte lum = data[ ((ry+i)*width+rx+j)*channel+(2-c)];
+ short slum;
+
+ if( lum < 0)
+ slum = (short)(2*128+lum);
+ else
+ slum = (short)lum;
+
+ pix[i*rw+j] = pix[i*rw+j] | slum << (8*c);
+ }
+ }
+
+ return createImage(new MemoryImageSource( rw, rh, pix, 0, rw));
+ }
+
+ public Image createScaleImage( double scale)
+ {
+ Image src = createROIImage( 0, 0, width, height);
+ ImageFilter replicate = new ReplicateScaleFilter( (int)(width*scale), (int)(height*scale));
+ ImageProducer prod = new FilteredImageSource( src.getSource(), replicate);
+
+ return createImage(prod);
+ }
+}
diff --git a/src/bin/jpip/opj_viewer/src/RegimViewer.java b/src/bin/jpip/opj_viewer/src/RegimViewer.java
new file mode 100644
index 00000000..57c54c57
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/RegimViewer.java
@@ -0,0 +1,114 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.image.*;
+import java.awt.geom.AffineTransform;
+
+public class RegimViewer extends JPanel
+{
+ private PnmImage refpnm;
+ private int vw, vh;
+ private Image refimg;
+ private Image jpipImg;
+ private double[] affine_matrix;
+ private AffineTransform affine;
+
+ public RegimViewer( String refname, double[] mat)
+ {
+ refpnm = new PnmImage( refname.replaceFirst("jp2", "pgm")); // decoding not realized
+ affine_matrix = new double[6];
+
+ affine_matrix[0] = mat[0];
+ affine_matrix[1] = mat[3];
+ affine_matrix[2] = mat[1];
+ affine_matrix[3] = mat[4];
+ affine_matrix[4] = mat[2];
+ affine_matrix[5] = mat[5];
+
+ affine = new AffineTransform();
+
+ for( int i=0; i<3; i++){
+ for( int j=0; j<3; j++)
+ System.out.print( mat[i*3+j] + " ");
+ System.out.println();
+ }
+ }
+
+ public void projection( Image jpipimg, double scale)
+ {
+ jpipImg = jpipimg;
+ refimg = refpnm.createScaleImage( scale);
+ vw = refimg.getWidth(this);
+ vh = refimg.getHeight(this);
+ this.setSize( vw, vh);
+
+ affine.setTransform( affine_matrix[0], affine_matrix[1], affine_matrix[2], affine_matrix[3], affine_matrix[4], affine_matrix[5]);
+ repaint();
+ }
+
+ public void paint(Graphics g)
+ {
+ int iw, ih;
+ BufferedImage bi, bi2;
+ Graphics2D big, big2;
+ Graphics2D g2 = (Graphics2D) g;
+
+ g2.clearRect(0, 0, vw, vh);
+
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_QUALITY);
+
+ iw = refimg.getWidth(this);
+ ih = refimg.getHeight(this);
+
+ bi = new BufferedImage( iw, ih, BufferedImage.TYPE_INT_RGB);
+ big = bi.createGraphics();
+ big.drawImage(refimg, 0, 0, this);
+
+ g2.drawImage(bi, 0, 0, this);
+
+ bi2 = new BufferedImage( jpipImg.getWidth(this), jpipImg.getHeight(this), BufferedImage.TYPE_INT_RGB);
+ big2 = bi2.createGraphics();
+ big2.drawImage( jpipImg, 0, 0, this);
+
+ g2.setTransform(affine);
+
+ g2.drawImage(bi2, 0, 0, this);
+ }
+
+ public Dimension get_imsize()
+ {
+ return (new Dimension( vw, vh));
+ }
+}
diff --git a/src/bin/jpip/opj_viewer/src/ResizeListener.java b/src/bin/jpip/opj_viewer/src/ResizeListener.java
new file mode 100644
index 00000000..fce8a4ff
--- /dev/null
+++ b/src/bin/jpip/opj_viewer/src/ResizeListener.java
@@ -0,0 +1,67 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+class ResizeListener implements ComponentListener
+{
+ private ImageViewer iv;
+ private Dimension largest;
+
+ public ResizeListener( ImageViewer _iv)
+ {
+ iv = _iv;
+ largest = iv.getSize();
+ }
+
+ public void componentHidden(ComponentEvent e) {}
+
+ public void componentMoved(ComponentEvent e) {}
+
+ public void componentResized(ComponentEvent e) {
+ Dimension cursize = iv.getSize();
+ if( largest.getWidth() < cursize.getWidth() || largest.getHeight() < cursize.getHeight()){
+ update_largest( cursize);
+ iv.enlarge();
+ }
+ }
+
+ private void update_largest( Dimension cursize)
+ {
+ if( largest.getWidth() < cursize.getWidth())
+ largest.setSize( cursize.getWidth(), largest.getHeight());
+ if( largest.getHeight() < cursize.getHeight())
+ largest.setSize( largest.getWidth(), cursize.getHeight());
+ }
+
+ public void componentShown(ComponentEvent e) {}
+}
diff --git a/src/bin/jpip/opj_viewer_xerces/dist/manifest.txt.in b/src/bin/jpip/opj_viewer_xerces/dist/manifest.txt.in
new file mode 100644
index 00000000..c7ba9f36
--- /dev/null
+++ b/src/bin/jpip/opj_viewer_xerces/dist/manifest.txt.in
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Ant-Version: Apache Ant 1.7.0
+Created-By: Kaori Hagihara
+Main-Class: ImageWindow
+Class-Path: @APACHE_XERCES_JAR@
diff --git a/src/bin/jpip/opj_viewer_xerces/src/ImageViewer.java b/src/bin/jpip/opj_viewer_xerces/src/ImageViewer.java
new file mode 100644
index 00000000..52f0522a
--- /dev/null
+++ b/src/bin/jpip/opj_viewer_xerces/src/ImageViewer.java
@@ -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.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+import java.awt.image.*;
+import java.awt.geom.*;
+import java.net.URL;
+import javax.swing.border.*;
+import java.util.*;
+import java.io.*;
+
+public class ImageViewer extends JPanel
+{
+ private ImageManager imgmanager;
+ private int vw, vh;
+ private int iw, ih;
+ private int selected = 0;
+ private Image img;
+
+ private String cmdline = new String();
+ private boolean fullRefresh = false;
+ private Point offset = new Point(0,0);
+ private Rectangle rect = new Rectangle();
+ private Rectangle roirect[] = null;
+ private String roiname[] = null;
+
+ public ImageViewer( String j2kfilename, ImageManager manager, boolean session, boolean jppstream, int aux)
+ {
+ String str;
+ MML myMML;
+
+ this.setSize( 170, 170);
+ Dimension asz = this.getSize();
+
+ vw = asz.width;
+ vh = asz.height;
+
+ setBackground(Color.black);
+ myMML = new MML(this);
+
+ imgmanager = manager;
+
+ img = imgmanager.getImage( j2kfilename, vw, vh, session, aux, jppstream, !jppstream);
+
+ addMouseListener(myMML);
+ addMouseMotionListener(myMML);
+ addComponentListener( new ResizeListener(this));
+ }
+
+ public Image getImage()
+ {
+ return img;
+ }
+
+ public void zoomIn()
+ {
+ roirect = null;
+ roiname = null;
+
+ double scalex = (double)vw/(double)rect.width;
+ double scaley = (double)vh/(double)rect.height;
+
+ int fw = (int)(imgmanager.getFw()*scalex);
+ int fh = (int)(imgmanager.getFh()*scaley);
+ int rx = (int)((imgmanager.getRx()+rect.x)*scalex);
+ int ry = (int)((imgmanager.getRy()+rect.y)*scaley);
+
+ img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
+
+ rect.x = rect.y = rect.width = rect.height = 0;
+
+ selected = 0;
+ fullRefresh = true;
+ repaint();
+ }
+
+ public void enlarge()
+ {
+ roirect = null;
+ roiname = null;
+
+ Dimension asz = this.getSize();
+
+ vw = asz.width;
+ vh = asz.height;
+
+ double scalex = vw/(double)imgmanager.getRw();
+ double scaley = vh/(double)imgmanager.getRh();
+
+ int fw = (int)(imgmanager.getFw()*scalex);
+ int fh = (int)(imgmanager.getFh()*scaley);
+ int rx = (int)(imgmanager.getRx()*scalex);
+ int ry = (int)(imgmanager.getRy()*scaley);
+
+ img = imgmanager.getImage( fw, fh, rx, ry, vw, vh);
+
+ fullRefresh = true;
+ repaint();
+ }
+
+ public void setSelected(int state)
+ {
+ roirect = null;
+ roiname = null;
+
+ if (state != selected) {
+
+ selected = state;
+ repaint();
+ }
+ }
+
+ public boolean isInsideRect(int x, int y)
+ {
+ return rect.contains(x - offset.x, y - offset.y);
+ }
+
+ public void setRGeom(int x1, int y1, int x2, int y2)
+ {
+ rect.x = Math.min(x1,x2) - offset.x;
+ rect.y = Math.min(y1,y2) - offset.y;
+ rect.width = Math.abs(x2-x1);
+ rect.height = Math.abs(y2-y1);
+ }
+
+ public void annotate( JP2XMLparser.ROIparams roi[])
+ {
+ int numofroi = roi.length;
+
+ roirect = new Rectangle [numofroi];
+ roiname = new String [numofroi];
+
+ double scale_x = imgmanager.getFw()/(double)imgmanager.getOrigWidth();
+ double scale_y = imgmanager.getFh()/(double)imgmanager.getOrigHeight();
+ int rx = imgmanager.getRx();
+ int ry = imgmanager.getRy();
+ int rw = imgmanager.getRw();
+ int rh = imgmanager.getRh();
+
+ for( int i=0; i<numofroi ; i++){
+ int x = (int)(roi[i].x*scale_x) - rx;
+ int y = (int)(roi[i].y*scale_y) - ry;
+ int w = (int)(roi[i].w*scale_x);
+ int h = (int)(roi[i].h*scale_y);
+ if( 0<=x && 0<=y && x+w<=rw && y+h<=rh){ // can be optimized
+ roirect[i] = new Rectangle( x, y, w, h);
+ roiname[i] = new String( roi[i].name);
+ }
+ else{
+ roirect[i] = null;
+ roiname[i] = null;
+ }
+ }
+ repaint();
+ }
+
+ public boolean hasAnnotation()
+ {
+ if( roirect == null)
+ return false;
+ else
+ return true;
+ }
+
+ public boolean isInsideROIRect(int x, int y)
+ {
+ for( int i=0; i<roirect.length; i++)
+ if( roirect[i] != null)
+ if( roirect[i].contains(x - offset.x, y - offset.y)){
+ rect = roirect[i];
+ return true;
+ }
+ return false;
+ }
+
+ public void paint(Graphics g)
+ {
+ BufferedImage bi;
+ Graphics2D big;
+ Graphics2D g2 = (Graphics2D) g;
+
+ if (fullRefresh) {
+ g2.clearRect(0, 0, vw, vh);
+ fullRefresh = false;
+ }
+ g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
+ RenderingHints.VALUE_ANTIALIAS_ON);
+ g2.setRenderingHint(RenderingHints.KEY_RENDERING,
+ RenderingHints.VALUE_RENDER_QUALITY);
+
+ offset.x = 0;
+ offset.y = 0;
+
+ iw = img.getWidth(this);
+ ih = img.getHeight(this);
+
+ bi = new BufferedImage( iw, ih, BufferedImage.TYPE_INT_RGB);
+ big = bi.createGraphics();
+
+ big.drawImage(img, 0, 0, this);
+ big.setPaint(Color.red);
+ if ((rect.width > 0) && (rect.height > 0))
+ big.draw(rect);
+
+ if( roirect != null){
+ for( int i=0; i<roirect.length; i++)
+ if( roirect[i] != null){
+ big.draw( roirect[i]);
+ big.drawString( roiname[i], roirect[i].x+3, roirect[i].y+roirect[i].height*2/3);
+ }
+ }
+ if (selected == 1)
+ shadeExt(big, 0, 0, 0, 64);
+ else if (selected == 2) {
+ shadeExt(big, 0, 0, 0, 255);
+ selected = 1;
+ }
+ g2.drawImage(bi, offset.x, offset.y, this);
+ }
+
+ private void shadeRect(Graphics2D g2, int r, int g, int b, int a)
+ {
+ g2.setPaint(new Color(r, g, b, a));
+ g2.fillRect(rect.x + 1, rect.y + 1, rect.width - 1, rect.height - 1);
+ }
+
+ private void shadeExt(Graphics2D g2, int r, int g, int b, int a)
+ {
+ g2.setPaint(new Color(r, g, b, a));
+ g2.fillRect(0, 0, iw, rect.y); /* _N_ */
+ g2.fillRect(rect.x + rect.width + 1, rect.y,
+ iw - rect.x - rect.width - 1, rect.height + 1); /* E */
+ g2.fillRect(0, rect.y, rect.x, rect.height + 1); /* W */
+ g2.fillRect(0, rect.y + rect.height + 1,
+ iw, ih - rect.y - rect.height - 1); /* _S_ */
+ }
+}
diff --git a/src/bin/jpip/opj_viewer_xerces/src/ImageWindow.java b/src/bin/jpip/opj_viewer_xerces/src/ImageWindow.java
new file mode 100644
index 00000000..ae3f54c5
--- /dev/null
+++ b/src/bin/jpip/opj_viewer_xerces/src/ImageWindow.java
@@ -0,0 +1,124 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import javax.swing.*;
+import java.awt.event.*;
+import java.awt.*;
+
+public class ImageWindow extends JFrame
+{
+ private ImageViewer imgviewer;
+ private OptionPanel optpanel;
+ private ImageManager imgmanager;
+
+ public ImageWindow( String uri, String j2kfilename, String host, int port, boolean session, boolean jppstream, int aux)
+ {
+ super( j2kfilename);
+
+ imgmanager = new ImageManager( uri, host, port);
+
+ imgviewer = new ImageViewer( j2kfilename, imgmanager, session, jppstream, aux);
+ imgviewer.setOpaque(true); //content panes must be opaque
+
+ optpanel = new OptionPanel( imgmanager, imgviewer);
+
+ JPanel panel = new JPanel();
+ panel.setLayout(new BorderLayout());
+ panel.add( imgviewer, BorderLayout.CENTER);
+ panel.add( optpanel, BorderLayout.EAST);
+
+ setContentPane( panel);
+
+ addWindowListener(new WindowMyAdapter());
+ }
+
+ class WindowMyAdapter extends WindowAdapter
+ {
+ public void windowClosing(WindowEvent arg)
+ {
+ imgmanager.closeChannel();
+ System.exit(0);
+ }
+ }
+
+ public static void main(String s[])
+ {
+ String j2kfilename, uri, host;
+ boolean session, jppstream;
+ int port, aux; // 0: none, 1: tcp, 2: udp
+
+ if(s.length >= 2){
+ uri = s[0];
+ j2kfilename = s[1];
+
+ if( s.length > 2)
+ host = s[2];
+ else
+ host = "localhost";
+
+ if( s.length > 3)
+ port = Integer.valueOf( s[3]).intValue();
+ else
+ port = 50000;
+
+ if( s.length > 4)
+ session = !s[4].equalsIgnoreCase( "stateless");
+ else
+ session = true;
+
+ if( s.length > 5)
+ jppstream = !s[5].equalsIgnoreCase( "JPT");
+ else
+ jppstream = true;
+
+ if( s.length > 6){
+ if( s[6].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 [hostname] [portnumber] [stateless/session] [JPT/JPP] [tcp/udp]");
+ return;
+ }
+ ImageWindow frame = new ImageWindow( uri, j2kfilename, host, port, session, jppstream, aux);
+
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ //Display the window.
+ frame.pack();
+ frame.setSize(new Dimension(400,200));
+ frame.setLocation( 0, 50);
+ frame.setVisible(true);
+ }
+}
diff --git a/src/bin/jpip/opj_viewer_xerces/src/JP2XMLparser.java b/src/bin/jpip/opj_viewer_xerces/src/JP2XMLparser.java
new file mode 100644
index 00000000..bec1d4db
--- /dev/null
+++ b/src/bin/jpip/opj_viewer_xerces/src/JP2XMLparser.java
@@ -0,0 +1,122 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import org.w3c.dom.Attr;
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.NodeList;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.ErrorHandler;
+import org.apache.xerces.parsers.DOMParser;
+import org.xml.sax.InputSource;
+import java.io.*;
+import java.lang.Integer;
+
+public class JP2XMLparser
+{
+ Document document;
+
+ public static class ROIparams{
+ public String name = null;
+ public int x = 0;
+ public int y = 0;
+ public int w = 0;
+ public int h = 0;
+ }
+
+ public static class IRTparams{
+ public String refimg = null;
+ public double []mat = { 0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0};
+ }
+
+ public JP2XMLparser( byte[] buf)
+ {
+ try{
+ InputSource source = new InputSource( new ByteArrayInputStream( buf));
+ DOMParser parser = new DOMParser();
+ parser.setErrorHandler(new MyHandler());
+ parser.parse( source);
+ document = parser.getDocument();
+ }
+ catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public ROIparams [] getROIparams()
+ {
+ ROIparams roi[];
+ NodeList elements = document.getElementsByTagName("roi");
+ int elementCount = elements.getLength();
+
+ roi = new ROIparams [elementCount];
+
+ for( int i = 0; i < elementCount; i++) {
+ Element element = (Element)elements.item(i);
+
+ roi[i] = new ROIparams();
+ roi[i].name = element.getAttribute( "name");
+ roi[i].x = Integer.parseInt( element.getAttribute( "x")) ;
+ roi[i].y = Integer.parseInt( element.getAttribute( "y")) ;
+ roi[i].w = Integer.parseInt( element.getAttribute( "w")) ;
+ roi[i].h = Integer.parseInt( element.getAttribute( "h")) ;
+ }
+ return roi;
+ }
+
+ public IRTparams getIRTparams()
+ {
+ IRTparams irt = new IRTparams();
+ NodeList elements = document.getElementsByTagName("irt");
+ int elementCount = elements.getLength();
+
+ Element element = (Element)elements.item(0);
+ irt.refimg = element.getAttribute( "refimg");
+ for( int i=1; i<=9; i++)
+ irt.mat[i-1] = Double.parseDouble( element.getAttribute("m" + i));
+
+ return irt;
+ }
+}
+
+class MyHandler implements ErrorHandler {
+ public void warning(SAXParseException e) {
+ System.out.println("Warning: line" + e.getLineNumber());
+ System.out.println(e.getMessage());
+ }
+ public void error(SAXParseException e) {
+ System.out.println("Error: line" + e.getLineNumber());
+ System.out.println(e.getMessage());
+ }
+ public void fatalError(SAXParseException e) {
+ System.out.println("Critical error: line" + e.getLineNumber());
+ System.out.println(e.getMessage());
+ }
+} \ No newline at end of file
diff --git a/src/bin/jpip/opj_viewer_xerces/src/OptionPanel.java b/src/bin/jpip/opj_viewer_xerces/src/OptionPanel.java
new file mode 100644
index 00000000..822e2dd8
--- /dev/null
+++ b/src/bin/jpip/opj_viewer_xerces/src/OptionPanel.java
@@ -0,0 +1,98 @@
+/*
+ * $Id$
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.awt.*;
+import java.awt.event.*;
+import javax.swing.*;
+
+public class OptionPanel extends JPanel implements ActionListener
+{
+ private JButton roibutton;
+ private JButton imregbutton;
+ private ImageManager imgmanager;
+ private ImageViewer iv;
+ private JP2XMLparser xmlparser;
+ private JFrame regimwindow;
+ private RegimViewer regimgviewer;
+
+ public OptionPanel( ImageManager manager, ImageViewer imgviewer)
+ {
+ this.setLayout(new BoxLayout( this, BoxLayout.Y_AXIS));
+
+ roibutton = new JButton("Region Of Interest");
+ imregbutton = new JButton("Image Registration");
+
+ roibutton.setAlignmentX( Component.CENTER_ALIGNMENT);
+ imregbutton.setAlignmentX( Component.CENTER_ALIGNMENT);
+
+ add( roibutton);
+ add( imregbutton);
+ roibutton.addActionListener(this);
+ imregbutton.addActionListener(this);
+
+ imgmanager = manager;
+ iv = imgviewer;
+ xmlparser = null;
+ }
+
+ public void actionPerformed(ActionEvent e)
+ {
+ if( xmlparser == null){
+ byte []xmldata = imgmanager.getXML();
+ if( xmldata != null)
+ xmlparser = new JP2XMLparser( xmldata);
+ }
+ if( e.getSource() == roibutton){
+ if( xmlparser != null){
+ JP2XMLparser.ROIparams roi[] = xmlparser.getROIparams();
+ iv.annotate( roi);
+ }
+ }
+ if( e.getSource() == imregbutton){
+ if( xmlparser != null){
+ if( regimwindow == null){
+ JP2XMLparser.IRTparams irt = xmlparser.getIRTparams();
+
+ regimgviewer = new RegimViewer( irt.refimg, irt.mat);
+ regimgviewer.setOpaque(false);
+
+ regimwindow = new JFrame("Registered Image");
+ regimwindow.getContentPane().add("Center", regimgviewer);
+ regimwindow.pack();
+ regimwindow.setLocation( 500, 50);
+ regimwindow.setVisible(true);
+ }
+ regimgviewer.projection( iv.getImage(), (double)imgmanager.getRw()/(double)imgmanager.getOrigWidth());
+ regimwindow.setSize( regimgviewer.get_imsize());
+ regimwindow.show();
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/src/bin/jpip/test_index.c b/src/bin/jpip/test_index.c
new file mode 100644
index 00000000..1a22c1eb
--- /dev/null
+++ b/src/bin/jpip/test_index.c
@@ -0,0 +1,73 @@
+/*
+ * $Id: test_index.c 46 2011-02-17 14:50:55Z kaori $
+ *
+ * Copyright (c) 2002-2011, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium
+ * Copyright (c) 2002-2011, Professor Benoit Macq
+ * Copyright (c) 2010-2011, Kaori Hagihara
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS'
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*! \file
+ * \brief test_index is a program to test the index code format of a JP2 file
+ *
+ * \section impinst Implementing instructions
+ * This program takes one argument, and print out text type index information to the terminal. \n
+ * -# Input JP2 file\n
+ * % ./test_index input.jp2\n
+ */
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#ifdef _WIN32
+#include <io.h>
+#else
+#include <unistd.h>
+#endif
+#include "openjpip.h"
+
+int
+main(int argc, char *argv[])
+{
+ int fd;
+ index_t *jp2idx;
+ if( argc < 2 ) return 1;
+
+ if( (fd = open( argv[1], O_RDONLY)) == -1){
+ fprintf( stderr, "Error: Target %s not found\n", argv[1]);
+ return -1;
+ }
+
+ if( !(jp2idx = get_index_from_JP2file( fd))){
+ fprintf( stderr, "JP2 file broken\n");
+ return -1;
+ }
+
+ output_index( jp2idx);
+ destroy_index( &jp2idx);
+ close(fd);
+
+ return 0;
+} /* main */