diff options
| author | Mathieu Malaterre <mathieu.malaterre@gmail.com> | 2012-09-28 08:11:41 +0000 |
|---|---|---|
| committer | Mathieu Malaterre <mathieu.malaterre@gmail.com> | 2012-09-28 08:11:41 +0000 |
| commit | d518970039a19a2a9b6d2bdd592cc88a43897bbb (patch) | |
| tree | 57bac2cf7e63e9352228231062763baac627563c /src/bin/jpip | |
| parent | 8363a6ab1e031bb4b2e40a92e56efd40fdab1aa1 (diff) | |
[trunk] Start FolderReorgProposal task
Update issue 177
Diffstat (limited to 'src/bin/jpip')
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 */ |
