From d84b16caf98efb94cf85247f78ed91350d6e1e69 Mon Sep 17 00:00:00 2001 From: Mathieu Malaterre Date: Fri, 28 Sep 2012 09:52:57 +0000 Subject: [trunk] FolderReorgProposal task: rename MJ2/JPIP CLI tools Update issue 177 --- src/bin/jpip/CMakeLists.txt | 88 ++-- src/bin/jpip/addXMLinJP2.c | 181 -------- src/bin/jpip/jpip_to_j2k.c | 2 +- src/bin/jpip/jpip_to_jp2.c | 2 +- src/bin/jpip/opj_jpip_addxml.c | 181 ++++++++ src/bin/jpip/opj_jpip_test.c | 73 ++++ src/bin/jpip/opj_jpip_transcode.c | 49 +++ src/bin/jpip/test_index.c | 73 ---- src/bin/mj2/CMakeLists.txt | 61 +-- src/bin/mj2/extract_j2k_from_mj2.c | 150 ------- src/bin/mj2/frames_to_mj2.c | 843 ------------------------------------ src/bin/mj2/mj2_convert.c | 372 ---------------- src/bin/mj2/mj2_convert.h | 45 -- src/bin/mj2/mj2_to_frames.c | 252 ----------- src/bin/mj2/opj_mj2_compress.c | 845 +++++++++++++++++++++++++++++++++++++ src/bin/mj2/opj_mj2_decompress.c | 254 +++++++++++ src/bin/mj2/opj_mj2_extract.c | 150 +++++++ src/bin/mj2/opj_mj2_wrap.c | 525 +++++++++++++++++++++++ src/bin/mj2/wrap_j2k_in_mj2.c | 523 ----------------------- src/lib/openmj2/CMakeLists.txt | 1 + src/lib/openmj2/mj2_convert.c | 372 ++++++++++++++++ src/lib/openmj2/mj2_convert.h | 45 ++ 22 files changed, 2561 insertions(+), 2526 deletions(-) delete mode 100644 src/bin/jpip/addXMLinJP2.c create mode 100644 src/bin/jpip/opj_jpip_addxml.c create mode 100644 src/bin/jpip/opj_jpip_test.c create mode 100644 src/bin/jpip/opj_jpip_transcode.c delete mode 100644 src/bin/jpip/test_index.c delete mode 100644 src/bin/mj2/extract_j2k_from_mj2.c delete mode 100644 src/bin/mj2/frames_to_mj2.c delete mode 100644 src/bin/mj2/mj2_convert.c delete mode 100644 src/bin/mj2/mj2_convert.h delete mode 100644 src/bin/mj2/mj2_to_frames.c create mode 100644 src/bin/mj2/opj_mj2_compress.c create mode 100644 src/bin/mj2/opj_mj2_decompress.c create mode 100644 src/bin/mj2/opj_mj2_extract.c create mode 100644 src/bin/mj2/opj_mj2_wrap.c delete mode 100644 src/bin/mj2/wrap_j2k_in_mj2.c create mode 100644 src/lib/openmj2/mj2_convert.c create mode 100644 src/lib/openmj2/mj2_convert.h (limited to 'src') diff --git a/src/bin/jpip/CMakeLists.txt b/src/bin/jpip/CMakeLists.txt index 5a3fc0ff..d887aa7a 100644 --- a/src/bin/jpip/CMakeLists.txt +++ b/src/bin/jpip/CMakeLists.txt @@ -6,9 +6,9 @@ include_directories( ) # Tool to embed metadata into JP2 file -add_executable(addXMLinJP2 addXMLinJP2.c) +add_executable(opj_jpip_addxml opj_jpip_addxml.c) # Install exe -install(TARGETS addXMLinJP2 +install(TARGETS opj_jpip_addxml EXPORT OpenJPEGTargets DESTINATION ${OPENJPEG_INSTALL_BIN_DIR} COMPONENT Applications ) @@ -42,12 +42,18 @@ endif() set(EXES opj_dec_server - jpip_to_jp2 - jpip_to_j2k - test_index + opj_jpip_transcode + opj_jpip_test ) foreach(exe ${EXES}) - add_executable(${exe} ${exe}.c) + if(${exe} STREQUAL "opj_jpip_transcode") + add_executable(${exe} ${exe}.c + jpip_to_jp2.c + jpip_to_j2k.c + ) + else() + add_executable(${exe} ${exe}.c) + endif() target_link_libraries(${exe} openjpip_local) install(TARGETS ${exe} EXPORT OpenJPEGTargets @@ -61,36 +67,6 @@ 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 @@ -99,6 +75,7 @@ if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE) ) mark_as_advanced(APACHE_XERCES_JAR) + # Decide to build the simple viewer or the xerces one: if(EXISTS ${APACHE_XERCES_JAR}) configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/opj_viewer_xerces/dist/manifest.txt.in @@ -123,11 +100,11 @@ if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE) file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/classes2) # Build java add_custom_command( - OUTPUT ${LIBRARY_OUTPUT_PATH}/opj_viewer_xerces.jar + OUTPUT ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.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 + COMMAND ${Java_JAR_EXECUTABLE} cfm ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar ${CMAKE_CURRENT_BINARY_DIR}/opj_viewer_xerces/dist/manifest.txt -C ${CMAKE_CURRENT_BINARY_DIR}/classes2 . DEPENDS ${java2_srcs} @@ -137,11 +114,40 @@ if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE) # name the target add_custom_target(OPJViewerXercesJar ALL - DEPENDS ${LIBRARY_OUTPUT_PATH}/opj_viewer_xerces.jar - COMMENT "building opj_viewer_xerces.jar" + DEPENDS ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar + COMMENT "building opj_jpip_viewer.jar (xerces)" + ) + + install(FILES ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar + DESTINATION ${OPENJPEG_INSTALL_SHARE_DIR} COMPONENT JavaModule + ) + else() + # opj_viewer (simple, no xerces) + # 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_jpip_viewer.jar + COMMAND ${Java_JAVAC_EXECUTABLE} ${jflags} + ${java1_srcs} -d ${CMAKE_CURRENT_BINARY_DIR}/classes1 + COMMAND ${Java_JAR_EXECUTABLE} cfm ${LIBRARY_OUTPUT_PATH}/opj_jpip_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_jpip_viewer.jar" + ) + + # name the target + add_custom_target(OPJViewerJar ALL + DEPENDS ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar + COMMENT "building opj_jpip_viewer.jar (no xerces found)" ) - install(FILES ${LIBRARY_OUTPUT_PATH}/opj_viewer_xerces.jar + install(FILES ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar DESTINATION ${OPENJPEG_INSTALL_SHARE_DIR} COMPONENT JavaModule ) endif() diff --git a/src/bin/jpip/addXMLinJP2.c b/src/bin/jpip/addXMLinJP2.c deleted file mode 100644 index f136e913..00000000 --- a/src/bin/jpip/addXMLinJP2.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * $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 - * \n - * \n - * \n - * \n - * \n - * - */ - - -#include -#include -#include - - -/** - * 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 index d8b2e2b0..0f64715e 100644 --- a/src/bin/jpip/jpip_to_j2k.c +++ b/src/bin/jpip/jpip_to_j2k.c @@ -43,7 +43,7 @@ #include #include "openjpip.h" -int main(int argc,char *argv[]) +int jpip_to_j2k(int argc,char *argv[]) { jpip_dec_param_t *dec; diff --git a/src/bin/jpip/jpip_to_jp2.c b/src/bin/jpip/jpip_to_jp2.c index d667ed9d..138fc8ac 100644 --- a/src/bin/jpip/jpip_to_jp2.c +++ b/src/bin/jpip/jpip_to_jp2.c @@ -43,7 +43,7 @@ #include #include "openjpip.h" -int main(int argc,char *argv[]) +int jpip_to_jp2(int argc,char *argv[]) { jpip_dec_param_t *dec; diff --git a/src/bin/jpip/opj_jpip_addxml.c b/src/bin/jpip/opj_jpip_addxml.c new file mode 100644 index 00000000..f136e913 --- /dev/null +++ b/src/bin/jpip/opj_jpip_addxml.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 + * \n + * \n + * \n + * \n + * \n + * + */ + + +#include +#include +#include + + +/** + * 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/opj_jpip_test.c b/src/bin/jpip/opj_jpip_test.c new file mode 100644 index 00000000..1a22c1eb --- /dev/null +++ b/src/bin/jpip/opj_jpip_test.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 +#include +#include +#include +#ifdef _WIN32 +#include +#else +#include +#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 */ diff --git a/src/bin/jpip/opj_jpip_transcode.c b/src/bin/jpip/opj_jpip_transcode.c new file mode 100644 index 00000000..4bb8b354 --- /dev/null +++ b/src/bin/jpip/opj_jpip_transcode.c @@ -0,0 +1,49 @@ +/* + * $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) 2012, Mathieu Malaterre + * 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_jpip_transcode is a program to convert JPT- JPP- stream to J2K/JP2 file + * + * \section impinst Implementing instructions + * This program takes two arguments. \n + * -# Input JPT or JPP file + * -# Output J2K file\n + * % ./opj_jpip_transcode input.jpt output.j2k + * or + * % ./jpip_to_j2k input.jpp output.j2k + */ +extern int jpip_to_j2k(int argc,char *argv[]); +extern int jpip_to_jp2(int argc,char *argv[]); + +int main(int argc,char *argv[]) +{ + /* MM: FIXME */ + return jpip_to_jp2(argc,argv); +} diff --git a/src/bin/jpip/test_index.c b/src/bin/jpip/test_index.c deleted file mode 100644 index 1a22c1eb..00000000 --- a/src/bin/jpip/test_index.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * $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 -#include -#include -#include -#ifdef _WIN32 -#include -#else -#include -#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 */ diff --git a/src/bin/mj2/CMakeLists.txt b/src/bin/mj2/CMakeLists.txt index 601f3bd9..e27fc50e 100644 --- a/src/bin/mj2/CMakeLists.txt +++ b/src/bin/mj2/CMakeLists.txt @@ -44,52 +44,25 @@ include_directories( ${LCMS_INCLUDE_DIRNAME} ) -add_executable(frames_to_mj2 - frames_to_mj2.c - ${common_SRCS} - ${OPJ_SRCS} - ${MJ2_SRCS} - ) -target_link_libraries(frames_to_mj2 ${LCMS_LIBNAME} openmj2) - -if(UNIX) - target_link_libraries(frames_to_mj2 m) -endif() - -add_executable(mj2_to_frames - mj2_to_frames.c +foreach(exe + opj_mj2_wrap + opj_mj2_extract + opj_mj2_decompress + opj_mj2_compress +) + add_executable(${exe} + ${exe}.c ${common_SRCS} ${OPJ_SRCS} ${MJ2_SRCS} ${OPENJPEG_SOURCE_DIR}/src/bin/common/color.c ) -target_link_libraries(mj2_to_frames ${LCMS_LIBNAME}) - -if(UNIX) - target_link_libraries(mj2_to_frames m) -endif() - -add_executable(extract_j2k_from_mj2 - extract_j2k_from_mj2.c - ${OPJ_SRCS} - ${MJ2_SRCS} - ) -target_link_libraries(extract_j2k_from_mj2 ${LCMS_LIBNAME} openmj2) - -if(UNIX) - target_link_libraries(extract_j2k_from_mj2 m) -endif() - -add_executable(wrap_j2k_in_mj2 - wrap_j2k_in_mj2.c - ${OPJ_SRCS} - ${MJ2_SRCS} - ) -target_link_libraries(wrap_j2k_in_mj2 ${LCMS_LIBNAME}) - -if(UNIX) - target_link_libraries(wrap_j2k_in_mj2 m) -endif() - -install(TARGETS frames_to_mj2 mj2_to_frames extract_j2k_from_mj2 wrap_j2k_in_mj2 - DESTINATION ${OPENJPEG_INSTALL_BIN_DIR}) + target_link_libraries(${exe} ${LCMS_LIBNAME} openmj2) + + if(UNIX) + target_link_libraries(${exe} m) + endif() + + install(TARGETS ${exe} + DESTINATION ${OPENJPEG_INSTALL_BIN_DIR}) +endforeach() diff --git a/src/bin/mj2/extract_j2k_from_mj2.c b/src/bin/mj2/extract_j2k_from_mj2.c deleted file mode 100644 index f694d531..00000000 --- a/src/bin/mj2/extract_j2k_from_mj2.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium - * Copyright (c) 2002-2007, Professor Benoit Macq - * Copyright (c) 2003-2007, Francois-Olivier Devaux - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include "openjpeg.h" -#include "cio.h" -#include "j2k.h" -#include "jp2.h" -#include "mj2.h" - -/* -------------------------------------------------------------------------- */ - -/** -sample error callback expecting a FILE* client object -*/ -void error_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** -sample warning callback expecting a FILE* client object -*/ -void warning_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[WARNING] %s", msg); -} -/** -sample debug callback expecting a FILE* client object -*/ -void info_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[INFO] %s", msg); -} - -/* -------------------------------------------------------------------------- */ - - -int main(int argc, char *argv[]) { - opj_dinfo_t* dinfo; - opj_event_mgr_t event_mgr; /* event manager */ - int tnum; - unsigned int snum; - opj_mj2_t *movie; - mj2_tk_t *track; - mj2_sample_t *sample; - unsigned char* frame_codestream; - FILE *file, *outfile; - char outfilename[50]; - mj2_dparameters_t parameters; - - if (argc != 3) { - printf("Usage: %s mj2filename output_location\n",argv[0]); - printf("Example: %s foreman.mj2 output/foreman\n",argv[0]); - return 1; - } - - file = fopen(argv[1], "rb"); - - if (!file) { - fprintf(stderr, "failed to open %s for reading\n", argv[1]); - return 1; - } - - /* - configure the event callbacks (not required) - setting of each callback is optionnal - */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; - - /* get a MJ2 decompressor handle */ - dinfo = mj2_create_decompress(); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - memset(¶meters, 0, sizeof(mj2_dparameters_t)); - movie = (opj_mj2_t*) dinfo->mj2_handle; - mj2_setup_decoder(movie, ¶meters); - - if (mj2_read_struct(file, movie)) /* Creating the movie structure*/ - return 1; - - /* Decode first video track */ - tnum = 0; - while (movie->tk[tnum].track_type != 0) - tnum ++; - - track = &movie->tk[tnum]; - - fprintf(stdout,"Extracting %d frames from file...\n",track->num_samples); - - for (snum=0; snum < track->num_samples; snum++) - { - sample = &track->sample[snum]; - frame_codestream = (unsigned char*) malloc (sample->sample_size-8); /* Skipping JP2C marker*/ - fseek(file,sample->offset+8,SEEK_SET); - fread(frame_codestream,sample->sample_size-8,1, file); /* Assuming that jp and ftyp markers size do*/ - - sprintf(outfilename,"%s_%05d.j2k",argv[2],snum); - outfile = fopen(outfilename, "wb"); - if (!outfile) { - fprintf(stderr, "failed to open %s for writing\n",outfilename); - return 1; - } - fwrite(frame_codestream,sample->sample_size-8,1,outfile); - fclose(outfile); - free(frame_codestream); - } - fclose(file); - fprintf(stdout, "%d frames correctly extracted\n", snum); - - /* free remaining structures */ - if(dinfo) { - mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle); - } - - return 0; -} diff --git a/src/bin/mj2/frames_to_mj2.c b/src/bin/mj2/frames_to_mj2.c deleted file mode 100644 index dff34ab7..00000000 --- a/src/bin/mj2/frames_to_mj2.c +++ /dev/null @@ -1,843 +0,0 @@ -/* -* Copyright (c) 2003-2004, Francois-Olivier Devaux -* Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include - -#include "openjpeg.h" -#include "j2k_lib.h" -#include "cio.h" -#include "j2k.h" -#include "jp2.h" -#include "mj2.h" -#include "mj2_convert.h" -#include "opj_getopt.h" - -/** -Size of memory first allocated for MOOV box -*/ -#define TEMP_BUF 10000 - -#define ENUMCS_GRAY 16 -#define ENUMCS_SRGB 17 -#define ENUMCS_SYCC 18 - -/* -------------------------------------------------------------------------- */ - -/** -sample error callback expecting a FILE* client object -*/ -void error_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** -sample warning callback expecting a FILE* client object -*/ -void warning_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[WARNING] %s", msg); -} -/** -sample debug callback expecting a FILE* client object -*/ -void info_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[INFO] %s", msg); -} - -/* -------------------------------------------------------------------------- */ - - -void help_display() -{ - fprintf(stdout,"HELP for frames_to_mj2\n----\n\n"); - fprintf(stdout,"- the -h option displays this help information on screen\n\n"); - - - fprintf(stdout,"List of parameters for the MJ2 encoder:\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"REMARKS:\n"); - fprintf(stdout,"---------\n"); - fprintf(stdout,"\n"); - fprintf - (stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n"); - fprintf - (stdout,"COD and QCD never appear in the tile_header.\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"By default:\n"); - fprintf(stdout,"------------\n"); - fprintf(stdout,"\n"); - fprintf(stdout," * Lossless\n"); - fprintf(stdout," * 1 tile\n"); - fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n"); - fprintf(stdout," * Size of code-block : 64 x 64\n"); - fprintf(stdout," * Number of resolutions: 6\n"); - fprintf(stdout," * No SOP marker in the codestream\n"); - fprintf(stdout," * No EPH marker in the codestream\n"); - fprintf(stdout," * No sub-sampling in x or y direction\n"); - fprintf(stdout," * No mode switch activated\n"); - fprintf(stdout," * Progression order: LRCP\n"); - fprintf(stdout," * No index file\n"); - fprintf(stdout," * No ROI upshifted\n"); - fprintf(stdout," * No offset of the origin of the image\n"); - fprintf(stdout," * No offset of the origin of the tiles\n"); - fprintf(stdout," * Reversible DWT 5-3\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"Parameters:\n"); - fprintf(stdout,"------------\n"); - fprintf(stdout,"\n"); - fprintf - (stdout,"Required Parameters (except with -h):\n"); - fprintf - (stdout,"-i : source file (-i source.yuv) \n"); - fprintf - (stdout,"-o : destination file (-o dest.mj2) \n"); - fprintf - (stdout,"Optional Parameters:\n"); - fprintf(stdout,"-h : display the help information \n"); - fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n"); - fprintf(stdout," - The rate specified for each quality level is the desired \n"); - fprintf(stdout," compression factor.\n"); - fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n"); - fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n"); - fprintf(stdout," (options -r and -q cannot be used together)\n"); - - fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n"); - fprintf(stdout," (options -r and -q cannot be used together)\n"); - - fprintf(stdout,"-n : number of resolutions (-n 3) \n"); - fprintf(stdout,"-b : size of code block (-b 32,32) \n"); - fprintf(stdout,"-c : size of precinct (-c 128,128) \n"); - fprintf(stdout,"-t : size of tile (-t 512,512) \n"); - fprintf - (stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n"); - fprintf - (stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n"); - fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n"); - fprintf - (stdout,"-S : write SOP marker before each packet \n"); - fprintf - (stdout,"-E : write EPH marker after each header packet \n"); - fprintf - (stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n"); - fprintf - (stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n"); - fprintf - (stdout," Indicate multiple modes by adding their values. \n"); - fprintf - (stdout," Example: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n"); - fprintf - (stdout,"-R : c=%%d,U=%%d : quantization indices upshifted \n"); - fprintf - (stdout," for component c=%%d [%%d = 0,1,2]\n"); - fprintf - (stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n"); - fprintf - (stdout,"-d : offset of the origin of the image (-d 150,300) \n"); - fprintf - (stdout,"-T : offset of the origin of the tiles (-T 100,75) \n"); - fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n"); - fprintf(stdout,"-W : image width, height and the dx and dy subsampling \n"); - fprintf(stdout," of the Cb and Cr components for YUV files \n"); - fprintf(stdout," (default is '352,288,2,2' for CIF format's 352x288 and 4:2:0)\n"); - fprintf(stdout,"-F : video frame rate (set to 25 by default)\n"); - fprintf(stdout,"-D : depth, precision in bits [8 .. 16]; default:8\n"); - fprintf(stdout,"-C : comment\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"IMPORTANT:\n"); - fprintf(stdout,"-----------\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"The index file has the structure below:\n"); - fprintf(stdout,"---------------------------------------\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"Image_height Image_width\n"); - fprintf(stdout,"progression order\n"); - fprintf(stdout,"Tiles_size_X Tiles_size_Y\n"); - fprintf(stdout,"Components_nb\n"); - fprintf(stdout,"Layers_nb\n"); - fprintf(stdout,"decomposition_levels\n"); - fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n"); - fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n"); - fprintf(stdout,"Main_header_end_position\n"); - fprintf(stdout,"Codestream_size\n"); - fprintf(stdout,"Tile_0 start_pos end_Theader end_pos TotalDisto NumPix MaxMSE\n"); - fprintf(stdout,"Tile_1 '' '' '' '' '' ''\n"); - fprintf(stdout,"...\n"); - fprintf(stdout,"Tile_Nt '' '' '' '' '' ''\n"); - fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n"); - fprintf(stdout,"...\n"); - fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n"); - - fprintf(stdout,"MaxDisto\n"); - - fprintf(stdout,"TotalDisto\n\n"); -} - -OPJ_PROG_ORDER give_progression(char progression[5]) -{ - if (progression[0] == 'L' && progression[1] == 'R' - && progression[2] == 'C' && progression[3] == 'P') { - return LRCP; - } else { - if (progression[0] == 'R' && progression[1] == 'L' - && progression[2] == 'C' && progression[3] == 'P') { - return RLCP; - } else { - if (progression[0] == 'R' && progression[1] == 'P' - && progression[2] == 'C' && progression[3] == 'L') { - return RPCL; - } else { - if (progression[0] == 'P' && progression[1] == 'C' - && progression[2] == 'R' && progression[3] == 'L') { - return PCRL; - } else { - if (progression[0] == 'C' && progression[1] == 'P' - && progression[2] == 'R' && progression[3] == 'L') { - return CPRL; - } else { - return PROG_UNKNOWN; - } - } - } - } - } -} - - - - -int main(int argc, char **argv) -{ - mj2_cparameters_t mj2_parameters; /* MJ2 compression parameters */ - opj_cparameters_t *j2k_parameters; /* J2K compression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - opj_cio_t *cio; - int value; - opj_mj2_t *movie; - opj_image_t *img; - int i, j; - char *s, S1, S2, S3; - unsigned char *buf; - int x1, y1, len; - long mdat_initpos, offset; - FILE *mj2file; - int sampleno; - opj_cinfo_t* cinfo; - opj_bool bSuccess; - int numframes; - int prec = 8;/* DEFAULT */ - double total_time = 0; - - memset(&mj2_parameters, 0, sizeof(mj2_cparameters_t)); - /* default value */ - /* ------------- */ - mj2_parameters.w = 352; // CIF default value - mj2_parameters.h = 288; // CIF default value - mj2_parameters.CbCr_subsampling_dx = 2; // CIF default value - mj2_parameters.CbCr_subsampling_dy = 2; // CIF default value - mj2_parameters.frame_rate = 25; - mj2_parameters.prec = 8; /* DEFAULT */ - mj2_parameters.enumcs = ENUMCS_SYCC; /* FIXME: ENUMCS_YUV420 */ - mj2_parameters.meth = 1; /* enumerated color space */ - -/* - configure the event callbacks (not required) - setting of each callback is optionnal -*/ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = NULL; - - /* set J2K encoding parameters to default values */ - opj_set_default_encoder_parameters(&mj2_parameters.j2k_parameters); - j2k_parameters = &mj2_parameters.j2k_parameters; - - /* Create comment for codestream */ - if(j2k_parameters->cp_comment == NULL) { - const char comment[] = "Created by OpenJPEG version "; - const size_t clen = strlen(comment); - const char *version = opj_version(); - j2k_parameters->cp_comment = (char*)malloc(clen+strlen(version)+1); - sprintf(j2k_parameters->cp_comment,"%s%s", comment, version); - } - - while (1) { - int c = opj_getopt(argc, argv, - "i:o:r:q:f:t:n:c:b:p:s:d:P:S:E:M:R:T:C:I:W:F:D:h"); - if (c == -1) - break; - switch (c) { - case 'i': /* IN fill */ - { - char *infile = opj_optarg; - s = opj_optarg; - while (*s) { - s++; - } - s--; - S3 = *s; - s--; - S2 = *s; - s--; - S1 = *s; - - if ((S1 == 'y' && S2 == 'u' && S3 == 'v') - || (S1 == 'Y' && S2 == 'U' && S3 == 'V')) { - mj2_parameters.decod_format = YUV_DFMT; - } - else { - fprintf(stderr, - "!! Unrecognized format for infile : %c%c%c [accept only *.yuv] !!\n\n", - S1, S2, S3); - return 1; - } - strncpy(mj2_parameters.infile, infile, sizeof(mj2_parameters.infile)-1); - } - break; - /* ----------------------------------------------------- */ - case 'o': /* OUT fill */ - { - char *outfile = opj_optarg; - while (*outfile) { - outfile++; - } - outfile--; - S3 = *outfile; - outfile--; - S2 = *outfile; - outfile--; - S1 = *outfile; - - outfile = opj_optarg; - - if ((S1 == 'm' && S2 == 'j' && S3 == '2') - || (S1 == 'M' && S2 == 'J' && S3 == '2')) - mj2_parameters.cod_format = MJ2_CFMT; - else { - fprintf(stderr, - "Unknown output format image *.%c%c%c [only *.mj2]!! \n", - S1, S2, S3); - return 1; - } - strncpy(mj2_parameters.outfile, outfile, sizeof(mj2_parameters.outfile)-1); - } - break; - /* ----------------------------------------------------- */ - case 'r': /* rates rates/distorsion */ - { - float rate; - s = opj_optarg; - while (sscanf(s, "%f", &rate) == 1) { - j2k_parameters->tcp_rates[j2k_parameters->tcp_numlayers] = rate * 2; - j2k_parameters->tcp_numlayers++; - while (*s && *s != ',') { - s++; - } - if (!*s) - break; - s++; - } - j2k_parameters->cp_disto_alloc = 1; - } - break; - /* ----------------------------------------------------- */ - case 'q': /* add fixed_quality */ - s = opj_optarg; - while (sscanf(s, "%f", &j2k_parameters->tcp_distoratio[j2k_parameters->tcp_numlayers]) == 1) { - j2k_parameters->tcp_numlayers++; - while (*s && *s != ',') { - s++; - } - if (!*s) - break; - s++; - } - j2k_parameters->cp_fixed_quality = 1; - break; - /* dda */ - /* ----------------------------------------------------- */ - case 'f': /* mod fixed_quality (before : -q) */ - { - int *row = NULL, *col = NULL; - int numlayers = 0, numresolution = 0, matrix_width = 0; - - s = opj_optarg; - sscanf(s, "%d", &numlayers); - s++; - if (numlayers > 9) - s++; - - j2k_parameters->tcp_numlayers = numlayers; - numresolution = j2k_parameters->numresolution; - matrix_width = numresolution * 3; - j2k_parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int)); - s = s + 2; - - for (i = 0; i < numlayers; i++) { - row = &j2k_parameters->cp_matrice[i * matrix_width]; - col = row; - j2k_parameters->tcp_rates[i] = 1; - sscanf(s, "%d,", &col[0]); - s += 2; - if (col[0] > 9) - s++; - col[1] = 0; - col[2] = 0; - for (j = 1; j < numresolution; j++) { - col += 3; - sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]); - s += 6; - if (col[0] > 9) - s++; - if (col[1] > 9) - s++; - if (col[2] > 9) - s++; - } - if (i < numlayers - 1) - s++; - } - j2k_parameters->cp_fixed_alloc = 1; - } - break; - /* ----------------------------------------------------- */ - case 't': /* tiles */ - sscanf(opj_optarg, "%d,%d", &j2k_parameters->cp_tdx, &j2k_parameters->cp_tdy); - j2k_parameters->tile_size_on = OPJ_TRUE; - break; - /* ----------------------------------------------------- */ - case 'n': /* resolution */ - sscanf(opj_optarg, "%d", &j2k_parameters->numresolution); - break; - /* ----------------------------------------------------- */ - case 'c': /* precinct dimension */ - { - char sep; - int res_spec = 0; - - char *s = opj_optarg; - do { - sep = 0; - sscanf(s, "[%d,%d]%c", &j2k_parameters->prcw_init[res_spec], - &j2k_parameters->prch_init[res_spec], &sep); - j2k_parameters->csty |= 0x01; - res_spec++; - s = strpbrk(s, "]") + 2; - } - while (sep == ','); - j2k_parameters->res_spec = res_spec; - } - break; - - /* ----------------------------------------------------- */ - case 'b': /* code-block dimension */ - { - int cblockw_init = 0, cblockh_init = 0; - sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init); - if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024 - || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) { - fprintf(stderr, - "!! Size of code_block error (option -b) !!\n\nRestriction :\n" - " * width*height<=4096\n * 4<=width,height<= 1024\n\n"); - return 1; - } - j2k_parameters->cblockw_init = cblockw_init; - j2k_parameters->cblockh_init = cblockh_init; - } - break; - /* ----------------------------------------------------- */ - case 'p': /* progression order */ - { - char progression[5]; - - strncpy(progression, opj_optarg, 5); - j2k_parameters->prog_order = give_progression(progression); - if (j2k_parameters->prog_order == -1) { - fprintf(stderr, "Unrecognized progression order " - "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n"); - return 1; - } - } - break; - /* ----------------------------------------------------- */ - case 's': /* subsampling factor */ - { - if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->subsampling_dx, - &j2k_parameters->subsampling_dy) != 2) { - fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n"); - return 1; - } - } - break; - /* ----------------------------------------------------- */ - case 'd': /* coordonnate of the reference grid */ - { - if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->image_offset_x0, - &j2k_parameters->image_offset_y0) != 2) { - fprintf(stderr, "-d 'coordonnate of the reference grid' argument " - "error !! [-d x0,y0]\n"); - return 1; - } - } - break; - /* ----------------------------------------------------- */ - case 'h': /* Display an help description */ - help_display(); - return 0; - break; - /* ----------------------------------------------------- */ - case 'P': /* POC */ - { - int numpocs = 0; /* number of progression order change (POC) default 0 */ - opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */ - - char *s = opj_optarg; - POC = j2k_parameters->POC; - - while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile, - &POC[numpocs].resno0, &POC[numpocs].compno0, - &POC[numpocs].layno1, &POC[numpocs].resno1, - &POC[numpocs].compno1, POC[numpocs].progorder) == 7) { - POC[numpocs].prg1 = give_progression(POC[numpocs].progorder); - numpocs++; - while (*s && *s != '/') { - s++; - } - if (!*s) { - break; - } - s++; - } - j2k_parameters->numpocs = numpocs; - } - break; - /* ------------------------------------------------------ */ - case 'S': /* SOP marker */ - j2k_parameters->csty |= 0x02; - break; - /* ------------------------------------------------------ */ - case 'E': /* EPH marker */ - j2k_parameters->csty |= 0x04; - break; - /* ------------------------------------------------------ */ - case 'M': /* Mode switch pas tous au point !! */ - if (sscanf(opj_optarg, "%d", &value) == 1) { - for (i = 0; i <= 5; i++) { - int cache = value & (1 << i); - if (cache) - j2k_parameters->mode |= (1 << i); - } - } - break; - /* ------------------------------------------------------ */ - case 'R': /* ROI */ - { - if (sscanf(opj_optarg, "OI:c=%d,U=%d", &j2k_parameters->roi_compno, - &j2k_parameters->roi_shift) != 2) { - fprintf(stderr, "ROI error !! [-ROI:c='compno',U='shift']\n"); - return 1; - } - } - break; - /* ------------------------------------------------------ */ - case 'T': /* Tile offset */ - { - if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->cp_tx0, &j2k_parameters->cp_ty0) != 2) { - fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]"); - return 1; - } - } - break; - /* ------------------------------------------------------ */ - case 'C': /* Add a comment */ - { - j2k_parameters->cp_comment = (char*)malloc(strlen(opj_optarg) + 1); - if(j2k_parameters->cp_comment) { - strcpy(j2k_parameters->cp_comment, opj_optarg); - } - } - break; - /* ------------------------------------------------------ */ - case 'I': /* reversible or not */ - { - j2k_parameters->irreversible = 1; - } - break; - /* ------------------------------------------------------ */ - case 'W': /* Width and Height and Cb and Cr subsampling in case of YUV format files */ - if (sscanf - (opj_optarg, "%d,%d,%d,%d", &mj2_parameters.w, &mj2_parameters.h, &mj2_parameters.CbCr_subsampling_dx, - &mj2_parameters.CbCr_subsampling_dy) != 4) { - fprintf(stderr, "-W argument error"); - return 1; - } - break; - /* ------------------------------------------------------ */ - case 'F': /* Video frame rate */ - if (sscanf(opj_optarg, "%d", &mj2_parameters.frame_rate) != 1) { - fprintf(stderr, "-F argument error"); - return 1; - } - break; - /* ------------------------------------------------------ */ - case 'D': /* Depth: the precision */ - if(sscanf(opj_optarg, "%d", &prec) != 1) prec = 0; - break; - - default: - return 1; - } - } - - /* Error messages */ - /* -------------- */ - if (!mj2_parameters.cod_format || !mj2_parameters.decod_format) { - fprintf(stderr, - "Usage: %s -i yuv-file -o mj2-file (+ options)\n",argv[0]); - return 1; - } - if(prec < 1 || prec > 16) - { - fprintf(stderr, "Error: Depth %d must be in the range 8 .. 16\n",prec); - return 1; - } - if ((j2k_parameters->cp_disto_alloc || j2k_parameters->cp_fixed_alloc || j2k_parameters->cp_fixed_quality) - && (!(j2k_parameters->cp_disto_alloc ^ j2k_parameters->cp_fixed_alloc ^ j2k_parameters->cp_fixed_quality))) { - fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n"); - return 1; - } /* mod fixed_quality */ - - /* if no rate entered, lossless by default */ - if (j2k_parameters->tcp_numlayers == 0) { - j2k_parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */ - j2k_parameters->tcp_numlayers++; - j2k_parameters->cp_disto_alloc = 1; - } - - if((j2k_parameters->cp_tx0 > j2k_parameters->image_offset_x0) || (j2k_parameters->cp_ty0 > j2k_parameters->image_offset_y0)) { - fprintf(stderr, - "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", - j2k_parameters->cp_tx0, j2k_parameters->image_offset_x0, j2k_parameters->cp_ty0, j2k_parameters->image_offset_y0); - return 1; - } - - for (i = 0; i < j2k_parameters->numpocs; i++) { - if (j2k_parameters->POC[i].prg == -1) { - fprintf(stderr, - "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n", - i + 1); - } - } - - if (j2k_parameters->cp_tdx > mj2_parameters.Dim[0] || j2k_parameters->cp_tdy > mj2_parameters.Dim[1]) { - fprintf(stderr, - "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", - j2k_parameters->cp_tdx, mj2_parameters.Dim[0], j2k_parameters->cp_tdy, mj2_parameters.Dim[1]); - return 1; - } - - /* to respect profile - 0 */ - /* ---------------------- */ - - x1 = !mj2_parameters.Dim[0] ? (mj2_parameters.w - 1) * j2k_parameters->subsampling_dx - + 1 : mj2_parameters.Dim[0] + (mj2_parameters.w - 1) * j2k_parameters->subsampling_dx + 1; - y1 = !mj2_parameters.Dim[1] ? (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy - + 1 : mj2_parameters.Dim[1] + (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy + 1; - mj2_parameters.numcomps = 3; /* YUV files only have 3 components */ - - mj2_parameters.prec = prec; - - j2k_parameters->tcp_mct = 0; - - mj2file = fopen(mj2_parameters.outfile, "wb"); - - if (!mj2file) { - fprintf(stderr, "failed to open %s for writing\n", argv[2]); - return 1; - } - - /* get a MJ2 decompressor handle */ - cinfo = mj2_create_compress(); - movie = (opj_mj2_t*)cinfo->mj2_handle; - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); - - /* setup encoder parameters */ - mj2_setup_encoder(movie, &mj2_parameters); - - movie->tk[0].num_samples = - yuv_num_frames(&movie->tk[0],mj2_parameters.infile); - - if (movie->tk[0].num_samples == 0) { - return 1; - } - - // One sample per chunk - movie->tk[0].chunk = (mj2_chunk_t*) - malloc(movie->tk[0].num_samples * sizeof(mj2_chunk_t)); - movie->tk[0].sample = (mj2_sample_t*) - malloc(movie->tk[0].num_samples * sizeof(mj2_sample_t)); - - if (mj2_init_stdmovie(movie)) { - fprintf(stderr, "Error with movie initialization"); - return 1; - } - -// Writing JP, FTYP and MDAT boxes -// Assuming that the JP and FTYP boxes won't be longer than 300 bytes: - buf = (unsigned char*) - malloc (300 * sizeof(unsigned char)); - - cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, 300); - - mj2_write_jp(cio); - mj2_write_ftyp(movie, cio); - - mdat_initpos = cio_tell(cio); - cio_skip(cio, 4); - - cio_write(cio, MJ2_MDAT, 4); - - fwrite(buf,cio_tell(cio),1,mj2file); - - offset = cio_tell(cio); - opj_cio_close(cio); - free(buf); - - for(i = 0; i < movie->num_stk + movie->num_htk + movie->num_vtk; i++) - { - if(movie->tk[i].track_type != 0) - { - fprintf(stderr, "Unable to write sound or hint tracks\n"); - } - else - { - mj2_tk_t *tk; - int buflen = 0; - - tk = &movie->tk[i]; - tk->num_chunks = tk->num_samples; - numframes = tk->num_samples; - tk->depth = prec; - - fprintf(stderr, "Video Track number %d\n", i); - - img = mj2_image_create(tk, j2k_parameters); - - buflen = 2 * (tk->w * tk->h * 8); - buf = (unsigned char *) malloc(buflen*sizeof(unsigned char)); - - for(sampleno = 0; sampleno < numframes; sampleno++) - { - double init_time = opj_clock(); - double elapsed_time; - - if(yuvtoimage(tk, img, sampleno, j2k_parameters, - mj2_parameters.infile)) - { - fprintf(stderr, "Error with frame number %d in YUV file\n", sampleno); - return 1; - } - -/* setup the encoder parameters using the current image and user parameters */ - opj_setup_encoder(cinfo, j2k_parameters, img); - - cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, buflen); - - cio_skip(cio, 4); - cio_write(cio, JP2_JP2C, 4); // JP2C - -/* encode the image */ - bSuccess = opj_encode(cinfo, cio, img, NULL); - - if (!bSuccess) { - opj_cio_close(cio); - fprintf(stderr, "failed to encode image\n"); - return 1; - } - - len = cio_tell(cio) - 8; - cio_seek(cio, 0); - cio_write(cio, len+8,4); - opj_cio_close(cio); - - tk->sample[sampleno].sample_size = len+8; - tk->sample[sampleno].offset = offset; - tk->chunk[sampleno].offset = offset; // There is one sample per chunk - fwrite(buf, 1, len+8, mj2file); - offset += len+8; - - elapsed_time = opj_clock()-init_time; - fprintf(stderr, "Frame number %d/%d encoded in %.2f mseconds\n", - sampleno + 1, numframes, elapsed_time*1000); - total_time += elapsed_time; - } /* for(sampleno */ - - free(buf); - opj_image_destroy(img); - } - }/* for(i */ - - fseek(mj2file, mdat_initpos, SEEK_SET); - - buf = (unsigned char*) malloc(4*sizeof(unsigned char)); - -// Init a cio to write box length variable in a little endian way - cio = opj_cio_open(NULL, buf, 4); - cio_write(cio, offset - mdat_initpos, 4); - fwrite(buf, 4, 1, mj2file); - fseek(mj2file,0,SEEK_END); - free(buf); - -// Writing MOOV box - buf = (unsigned char*) - malloc ((TEMP_BUF+numframes*20) * sizeof(unsigned char)); - cio = opj_cio_open(movie->cinfo, buf, (TEMP_BUF+numframes*20)); - mj2_write_moov(movie, cio); - fwrite(buf,cio_tell(cio),1,mj2file); - free(buf); - - fprintf(stdout,"Total encoding time: %.2f s for %d frames (%.1f fps)\n", - total_time, numframes, (float)numframes/total_time); - - // Ending program - - fclose(mj2file); -/* free remaining compression structures */ - mj2_destroy_compress(movie); - free(cinfo); - - if(j2k_parameters->cp_comment) free(j2k_parameters->cp_comment); - if(j2k_parameters->cp_matrice) free(j2k_parameters->cp_matrice); - opj_cio_close(cio); - - return 0; -} diff --git a/src/bin/mj2/mj2_convert.c b/src/bin/mj2/mj2_convert.c deleted file mode 100644 index ed823f8b..00000000 --- a/src/bin/mj2/mj2_convert.c +++ /dev/null @@ -1,372 +0,0 @@ -/* -* Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium -* Copyright (c) 2002-2007, Professor Benoit Macq -* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*/ - -#include "opj_includes.h" -#include "mj2.h" - -/* ----------------------- */ -/* */ -/* */ -/* Count the number of frames */ -/* in a YUV file */ -/* */ -/* ----------------------- */ - -unsigned int yuv_num_frames(mj2_tk_t * tk, char *infile) -{ - unsigned int prec_size; - long end_of_f, frame_size; - FILE *f; - - f = fopen(infile,"rb"); - if (!f) { - fprintf(stderr, "failed to open %s for reading\n",infile); - return 0; - } - prec_size = (tk->depth + 7)/8;/* bytes of precision */ - - frame_size = (long) (tk->w * tk->h * (1.0 + (double) 2 / (double) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy))); /* Calculate frame size */ - frame_size *= prec_size; - - fseek(f, 0, SEEK_END); - end_of_f = ftell(f); /* Calculate file size */ - - if (end_of_f < frame_size) { - fprintf(stderr, - "YUV does not contains any frame of %d x %d size\n", tk->w, - tk->h); - return 0; - } - fclose(f); - - return (unsigned int)(end_of_f / frame_size); -} - -/* ----------------------- */ -/* */ -/* */ -/* YUV to IMAGE */ -/* */ -/* ----------------------- */ - -opj_image_t *mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters) -{ - opj_image_cmptparm_t cmptparm[3]; - opj_image_t * img; - int i; - int numcomps = 3; - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; - - /* initialize image components */ - memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); - for(i = 0; i < numcomps; i++) { - cmptparm[i].prec = tk->depth; - cmptparm[i].bpp = tk->depth; - cmptparm[i].sgnd = 0; - cmptparm[i].dx = i ? subsampling_dx * tk->CbCr_subsampling_dx : subsampling_dx; - cmptparm[i].dy = i ? subsampling_dy * tk->CbCr_subsampling_dy : subsampling_dy; - cmptparm[i].w = tk->w; - cmptparm[i].h = tk->h; - } - /* create the image */ - img = opj_image_create(numcomps, cmptparm, CLRSPC_SRGB); - return img; -} - -char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters_t *parameters, char* infile) -{ - int i, compno; - int offset, size, max, prec_bytes, is_16, v; - long end_of_f, position; - int numcomps = 3; - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; - FILE *yuvfile; - int *data; - unsigned char uc; - - yuvfile = fopen(infile,"rb"); - if (!yuvfile) { - fprintf(stderr, "failed to open %s for readings\n",parameters->infile); - return 1; - } - is_16 = (tk->depth > 8); - prec_bytes = (is_16?2:1); - - offset = (int) ((double) (frame_num * tk->w * tk->h) * (1.0 + - 1.0 * (double) 2 / (double) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy))); - offset *= prec_bytes; - - fseek(yuvfile, 0, SEEK_END); - end_of_f = ftell(yuvfile); - fseek(yuvfile, sizeof(unsigned char) * offset, SEEK_SET); - position = ftell(yuvfile); - if (position >= end_of_f) { - fprintf(stderr, "Cannot reach frame number %d in yuv file !!\n", - frame_num); - fclose(yuvfile); - return 1; - } - - img->x0 = tk->Dim[0]; - img->y0 = tk->Dim[1]; - img->x1 = !tk->Dim[0] ? (tk->w - 1) * subsampling_dx + 1 : tk->Dim[0] + - (tk->w - 1) * subsampling_dx + 1; - img->y1 = !tk->Dim[1] ? (tk->h - 1) * subsampling_dy + 1 : tk->Dim[1] + - (tk->h - 1) * subsampling_dy + 1; - - size = tk->w * tk->h * prec_bytes; - - for(compno = 0; compno < numcomps; compno++) - { - max = size/(img->comps[compno].dx * img->comps[compno].dy); - data = img->comps[compno].data; - - for (i = 0; i < max && !feof(yuvfile); i++) - { - v = 0; - fread(&uc, 1, 1, yuvfile); - v = uc; - - if(is_16) - { - fread(&uc, 1, 1, yuvfile); - v |= (uc<<8); - } - *data++ = v; - } - } - fclose(yuvfile); - - return 0; -} - - - -/* ----------------------- */ -/* */ -/* */ -/* IMAGE to YUV */ -/* */ -/* ----------------------- */ - - -opj_bool imagetoyuv(opj_image_t * img, char *outfile) -{ - FILE *f; - int *data; - int i, v, is_16, prec_bytes; - unsigned char buf[2]; - - if (img->numcomps == 3) { - if (img->comps[0].dx != img->comps[1].dx / 2 - || img->comps[1].dx != img->comps[2].dx) { - fprintf(stderr, - "Error with the input image components size: cannot create yuv file)\n"); - return OPJ_FALSE; - } - } else if (!(img->numcomps == 1)) { - fprintf(stderr, - "Error with the number of image components(must be one or three)\n"); - return OPJ_FALSE; - } - - f = fopen(outfile, "a+b"); - if (!f) { - fprintf(stderr, "failed to open %s for writing\n", outfile); - return OPJ_FALSE; - } - is_16 = (img->comps[0].prec > 8); - prec_bytes = (is_16?2:1); - data = img->comps[0].data; - - for (i = 0; i < (img->comps[0].w * img->comps[0].h); i++) { - v = *data++; - buf[0] = (unsigned char)v; - - if(is_16) buf[1] = (unsigned char)(v>>8); - - fwrite(buf, 1, prec_bytes, f); - } - - - if (img->numcomps == 3) { - data = img->comps[1].data; - - for (i = 0; i < (img->comps[1].w * img->comps[1].h); i++) { - v = *data++; - buf[0] = (unsigned char)v; - - if(is_16) buf[1] = (unsigned char)(v>>8); - - fwrite(buf, 1, prec_bytes, f); - } - data = img->comps[2].data; - - for (i = 0; i < (img->comps[2].w * img->comps[2].h); i++) { - v = *data++; - buf[0] = (unsigned char)v; - - if(is_16) buf[1] = (unsigned char)(v>>8); - - fwrite(buf, 1, prec_bytes, f); - } - } else if (img->numcomps == 1) { -/* fake CbCr values */ - if(is_16) - { - buf[0] = 255; - if(img->comps[0].prec == 10) buf[1] = 1; - else - if(img->comps[0].prec == 12) buf[1] = 3; - else - buf[1] = 125; - } - else buf[0] = 125; - - for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) { - fwrite(buf, 1, prec_bytes, f); - } - - - for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) { - fwrite(buf, 1, prec_bytes, f); - } - } - fclose(f); - return OPJ_TRUE; -} - -/* ----------------------- */ -/* */ -/* */ -/* IMAGE to BMP */ -/* */ -/* ----------------------- */ - -int imagetobmp(opj_image_t * img, char *outfile) { - int w,wr,h,hr,i,pad; - FILE *f; - - if (img->numcomps == 3 && img->comps[0].dx == img->comps[1].dx - && img->comps[1].dx == img->comps[2].dx - && img->comps[0].dy == img->comps[1].dy - && img->comps[1].dy == img->comps[2].dy - && img->comps[0].prec == img->comps[1].prec - && img->comps[1].prec == img->comps[2].prec) { - /* -->> -->> -->> -->> - - 24 bits color - - <<-- <<-- <<-- <<-- */ - - f = fopen(outfile, "wb"); - if (!f) { - fprintf(stderr, "failed to open %s for writing\n", outfile); - return 1; - } - - w = img->comps[0].w; - wr = int_ceildivpow2(img->comps[0].w, img->comps[0].factor); - - h = img->comps[0].h; - hr = int_ceildivpow2(img->comps[0].h, img->comps[0].factor); - - fprintf(f, "BM"); - - /* FILE HEADER */ - /* ------------- */ - fprintf(f, "%c%c%c%c", - (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + - 54) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) - >> 8) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) - >> 16) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) - >> 24) & 0xff); - fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(f, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff, - ((54) >> 16) & 0xff, ((54) >> 24) & 0xff); - - /* INFO HEADER */ - /* ------------- */ - fprintf(f, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, - ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); - fprintf(f, "%c%c%c%c", (unsigned char) ((wr) & 0xff), - (unsigned char) ((wr) >> 8) & 0xff, - (unsigned char) ((wr) >> 16) & 0xff, - (unsigned char) ((wr) >> 24) & 0xff); - fprintf(f, "%c%c%c%c", (unsigned char) ((hr) & 0xff), - (unsigned char) ((hr) >> 8) & 0xff, - (unsigned char) ((hr) >> 16) & 0xff, - (unsigned char) ((hr) >> 24) & 0xff); - fprintf(f, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); - fprintf(f, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); - fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(f, "%c%c%c%c", - (unsigned char) (3 * hr * wr + - 3 * hr * (wr % 2)) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> - 8) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> - 16) & 0xff, - (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> - 24) & 0xff); - fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, - ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, - ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, - ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - - for (i = 0; i < wr * hr; i++) { - unsigned char R, G, B; - /* a modifier */ - /* R = img->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/ - R = img->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; - /* G = img->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/ - G = img->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; - /* B = img->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/ - B = img->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; - fprintf(f, "%c%c%c", B, G, R); - - if ((i + 1) % wr == 0) { - for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */ - fprintf(f, "%c", 0); - } - } - fclose(f); - } - return 0; -} diff --git a/src/bin/mj2/mj2_convert.h b/src/bin/mj2/mj2_convert.h deleted file mode 100644 index 736ef80c..00000000 --- a/src/bin/mj2/mj2_convert.h +++ /dev/null @@ -1,45 +0,0 @@ -/* -* Copyright (c) 2003-2004, Francois-Olivier Devaux -* Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*/ - - -#include "mj2.h" - -#ifndef __MJ2_CONVERT_H -#define __MJ2_CONVERT_H - -int imagetoyuv(opj_image_t * img, char *outfile); - -int imagetobmp(opj_image_t * img, char *outfile); - -opj_image_t *mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters); - -char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters_t *parameters, char* infile); - -unsigned int yuv_num_frames(mj2_tk_t * tk, char *infile); - - -#endif diff --git a/src/bin/mj2/mj2_to_frames.c b/src/bin/mj2/mj2_to_frames.c deleted file mode 100644 index 32679198..00000000 --- a/src/bin/mj2/mj2_to_frames.c +++ /dev/null @@ -1,252 +0,0 @@ -/* -* Copyright (c) 2003-2004, Francois-Olivier Devaux -* Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium -* All rights reserved. -* -* Redistribution and use in source and binary forms, with or without -* modification, are permitted provided that the following conditions -* are met: -* 1. Redistributions of source code must retain the above copyright -* notice, this list of conditions and the following disclaimer. -* 2. Redistributions in binary form must reproduce the above copyright -* notice, this list of conditions and the following disclaimer in the -* documentation and/or other materials provided with the distribution. -* -* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' -* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE -* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -* POSSIBILITY OF SUCH DAMAGE. -*/ - -#include -#include -#include - -#include "opj_config.h" -#include "openjpeg.h" -#include "j2k_lib.h" -#include "cio.h" -#include "j2k.h" -#include "jp2.h" -#include "mj2.h" -#include "mj2_convert.h" - -#ifdef HAVE_LIBLCMS2 -#include -#endif -#ifdef HAVE_LIBLCMS1 -#include -#endif -#include "color.h" -/* -------------------------------------------------------------------------- */ - -/** -sample error callback expecting a FILE* client object -*/ -void error_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** -sample warning callback expecting a FILE* client object -*/ -void warning_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[WARNING] %s", msg); -} -/** -sample debug callback expecting a FILE* client object -*/ -void info_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[INFO] %s", msg); -} - -/* -------------------------------------------------------------------------- */ - - -int main(int argc, char *argv[]) { - mj2_dparameters_t mj2_parameters; /* decompression parameters */ - opj_dinfo_t* dinfo; - opj_event_mgr_t event_mgr; /* event manager */ - opj_cio_t *cio = NULL; - unsigned int tnum, snum; - opj_mj2_t *movie; - mj2_tk_t *track; - mj2_sample_t *sample; - unsigned char* frame_codestream; - FILE *file, *outfile; - char outfilename[50]; - opj_image_t *img = NULL; - unsigned int max_codstrm_size = 0; - double total_time = 0; - unsigned int numframes = 0; - - if (argc != 3) { - printf("Usage: %s inputfile.mj2 outputfile.yuv\n",argv[0]); - return 1; - } - - file = fopen(argv[1], "rb"); - - if (!file) { - fprintf(stderr, "failed to open %s for reading\n", argv[1]); - return 1; - } - - // Checking output file - outfile = fopen(argv[2], "w"); - if (!file) { - fprintf(stderr, "failed to open %s for writing\n", argv[2]); - return 1; - } - fclose(outfile); - - /* - configure the event callbacks (not required) - setting of each callback is optionnal - */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = NULL; - - /* get a MJ2 decompressor handle */ - dinfo = mj2_create_decompress(); - movie = (opj_mj2_t*)dinfo->mj2_handle; - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - memset(&mj2_parameters, 0, sizeof(mj2_dparameters_t)); - /* set J2K decoding parameters to default values */ - opj_set_default_decoder_parameters(&mj2_parameters.j2k_parameters); - - /* setup the decoder decoding parameters using user parameters */ - mj2_setup_decoder(movie, &mj2_parameters); - - if (mj2_read_struct(file, movie)) // Creating the movie structure - return 1; - - // Decode first video track - for (tnum=0; tnum < (unsigned int)(movie->num_htk + movie->num_stk + movie->num_vtk); tnum++) { - if (movie->tk[tnum].track_type == 0) - break; - } - - if (movie->tk[tnum].track_type != 0) { - printf("Error. Movie does not contain any video track\n"); - return 1; - } - - track = &movie->tk[tnum]; - - // Output info on first video tracl - fprintf(stdout,"The first video track contains %d frames.\nWidth: %d, Height: %d \n\n", - track->num_samples, track->w, track->h); - - max_codstrm_size = track->sample[0].sample_size-8; - frame_codestream = (unsigned char*) malloc(max_codstrm_size * sizeof(unsigned char)); - - numframes = track->num_samples; - - for (snum=0; snum < numframes; snum++) - { - double init_time = opj_clock(); - double elapsed_time; - - sample = &track->sample[snum]; - if (sample->sample_size-8 > max_codstrm_size) { - max_codstrm_size = sample->sample_size-8; - if ((frame_codestream = (unsigned char*) - realloc(frame_codestream, max_codstrm_size)) == NULL) { - printf("Error reallocation memory\n"); - return 1; - }; - } - fseek(file,sample->offset+8,SEEK_SET); - fread(frame_codestream, sample->sample_size-8, 1, file); // Assuming that jp and ftyp markers size do - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, frame_codestream, sample->sample_size-8); - - img = opj_decode(dinfo, cio); // Decode J2K to image - -#ifdef WANT_SYCC_TO_RGB - if(img->color_space == CLRSPC_SYCC) - { - color_sycc_to_rgb(img); - } -#endif - - if(img->icc_profile_buf) - { -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) - color_apply_icc_profile(img); -#endif - - free(img->icc_profile_buf); - img->icc_profile_buf = NULL; img->icc_profile_len = 0; - } - - if (((img->numcomps == 3) && (img->comps[0].dx == img->comps[1].dx / 2) - && (img->comps[0].dx == img->comps[2].dx / 2 ) && (img->comps[0].dx == 1)) - || (img->numcomps == 1)) { - - if (!imagetoyuv(img, argv[2])) // Convert image to YUV - return 1; - } - else if ((img->numcomps == 3) && - (img->comps[0].dx == 1) && (img->comps[1].dx == 1)&& - (img->comps[2].dx == 1))// If YUV 4:4:4 input --> to bmp - { - fprintf(stdout,"The frames will be output in a bmp format (output_1.bmp, ...)\n"); - sprintf(outfilename,"output_%d.bmp",snum); - if (imagetobmp(img, outfilename)) // Convert image to BMP - return 1; - - } - else { - fprintf(stdout,"Image component dimensions are unknown. Unable to output image\n"); - fprintf(stdout,"The frames will be output in a j2k file (output_1.j2k, ...)\n"); - - sprintf(outfilename,"output_%d.j2k",snum); - outfile = fopen(outfilename, "wb"); - if (!outfile) { - fprintf(stderr, "failed to open %s for writing\n",outfilename); - return 1; - } - fwrite(frame_codestream,sample->sample_size-8,1,outfile); - fclose(outfile); - } - /* close the byte stream */ - opj_cio_close(cio); - /* free image data structure */ - opj_image_destroy(img); - elapsed_time = opj_clock()-init_time; - fprintf(stderr, "Frame number %d/%d decoded in %.2f mseconds\n", snum + 1, numframes, elapsed_time*1000); - total_time += elapsed_time; - - } - - free(frame_codestream); - fclose(file); - - /* free remaining structures */ - if(dinfo) { - mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle); - } - free(dinfo); - - fprintf(stdout, "%d frame(s) correctly decompressed\n", snum); - fprintf(stdout,"Total decoding time: %.2f seconds (%.1f fps)\n", total_time, (float)numframes/total_time); - - return 0; -} diff --git a/src/bin/mj2/opj_mj2_compress.c b/src/bin/mj2/opj_mj2_compress.c new file mode 100644 index 00000000..d05204bf --- /dev/null +++ b/src/bin/mj2/opj_mj2_compress.c @@ -0,0 +1,845 @@ +/* +* Copyright (c) 2003-2004, Francois-Olivier Devaux +* Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "openjpeg.h" +#include "j2k_lib.h" +#include "cio.h" +#include "j2k.h" +#include "jp2.h" +#include "mj2.h" +#include "mj2_convert.h" +#include "opj_getopt.h" + +/** +Size of memory first allocated for MOOV box +*/ +#define TEMP_BUF 10000 + +#define ENUMCS_GRAY 16 +#define ENUMCS_SRGB 17 +#define ENUMCS_SYCC 18 + +/* -------------------------------------------------------------------------- */ + +/** +sample error callback expecting a FILE* client object +*/ +void error_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[ERROR] %s", msg); +} +/** +sample warning callback expecting a FILE* client object +*/ +void warning_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[WARNING] %s", msg); +} +/** +sample debug callback expecting a FILE* client object +*/ +void info_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[INFO] %s", msg); +} + +/* -------------------------------------------------------------------------- */ + + +void help_display() +{ + fprintf(stdout,"HELP for frames_to_mj2\n----\n\n"); + fprintf(stdout,"- the -h option displays this help information on screen\n\n"); + + + fprintf(stdout,"List of parameters for the MJ2 encoder:\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"REMARKS:\n"); + fprintf(stdout,"---------\n"); + fprintf(stdout,"\n"); + fprintf + (stdout,"The markers written to the main_header are : SOC SIZ COD QCD COM.\n"); + fprintf + (stdout,"COD and QCD never appear in the tile_header.\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"By default:\n"); + fprintf(stdout,"------------\n"); + fprintf(stdout,"\n"); + fprintf(stdout," * Lossless\n"); + fprintf(stdout," * 1 tile\n"); + fprintf(stdout," * Size of precinct : 2^15 x 2^15 (means 1 precinct)\n"); + fprintf(stdout," * Size of code-block : 64 x 64\n"); + fprintf(stdout," * Number of resolutions: 6\n"); + fprintf(stdout," * No SOP marker in the codestream\n"); + fprintf(stdout," * No EPH marker in the codestream\n"); + fprintf(stdout," * No sub-sampling in x or y direction\n"); + fprintf(stdout," * No mode switch activated\n"); + fprintf(stdout," * Progression order: LRCP\n"); + fprintf(stdout," * No index file\n"); + fprintf(stdout," * No ROI upshifted\n"); + fprintf(stdout," * No offset of the origin of the image\n"); + fprintf(stdout," * No offset of the origin of the tiles\n"); + fprintf(stdout," * Reversible DWT 5-3\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"Parameters:\n"); + fprintf(stdout,"------------\n"); + fprintf(stdout,"\n"); + fprintf + (stdout,"Required Parameters (except with -h):\n"); + fprintf + (stdout,"-i : source file (-i source.yuv) \n"); + fprintf + (stdout,"-o : destination file (-o dest.mj2) \n"); + fprintf + (stdout,"Optional Parameters:\n"); + fprintf(stdout,"-h : display the help information \n"); + fprintf(stdout,"-r : different compression ratios for successive layers (-r 20,10,5)\n"); + fprintf(stdout," - The rate specified for each quality level is the desired \n"); + fprintf(stdout," compression factor.\n"); + fprintf(stdout," Example: -r 20,10,1 means quality 1: compress 20x, \n"); + fprintf(stdout," quality 2: compress 10x and quality 3: compress lossless\n"); + fprintf(stdout," (options -r and -q cannot be used together)\n"); + + fprintf(stdout,"-q : different psnr for successive layers (-q 30,40,50) \n"); + fprintf(stdout," (options -r and -q cannot be used together)\n"); + + fprintf(stdout,"-n : number of resolutions (-n 3) \n"); + fprintf(stdout,"-b : size of code block (-b 32,32) \n"); + fprintf(stdout,"-c : size of precinct (-c 128,128) \n"); + fprintf(stdout,"-t : size of tile (-t 512,512) \n"); + fprintf + (stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n"); + fprintf + (stdout,"-s : subsampling factor (-s 2,2) [-s X,Y] \n"); + fprintf(stdout," Remark: subsampling bigger than 2 can produce error\n"); + fprintf + (stdout,"-S : write SOP marker before each packet \n"); + fprintf + (stdout,"-E : write EPH marker after each header packet \n"); + fprintf + (stdout,"-M : mode switch (-M 3) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n"); + fprintf + (stdout," 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)] \n"); + fprintf + (stdout," Indicate multiple modes by adding their values. \n"); + fprintf + (stdout," Example: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n"); + fprintf + (stdout,"-R : c=%%d,U=%%d : quantization indices upshifted \n"); + fprintf + (stdout," for component c=%%d [%%d = 0,1,2]\n"); + fprintf + (stdout," with a value of U=%%d [0 <= %%d <= 37] (i.e. -ROI:c=0,U=25) \n"); + fprintf + (stdout,"-d : offset of the origin of the image (-d 150,300) \n"); + fprintf + (stdout,"-T : offset of the origin of the tiles (-T 100,75) \n"); + fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n"); + fprintf(stdout,"-W : image width, height and the dx and dy subsampling \n"); + fprintf(stdout," of the Cb and Cr components for YUV files \n"); + fprintf(stdout," (default is '352,288,2,2' for CIF format's 352x288 and 4:2:0)\n"); + fprintf(stdout,"-F : video frame rate (set to 25 by default)\n"); + fprintf(stdout,"-D : depth, precision in bits [8 .. 16]; default:8\n"); + fprintf(stdout,"-C : comment\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"IMPORTANT:\n"); + fprintf(stdout,"-----------\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"The index file has the structure below:\n"); + fprintf(stdout,"---------------------------------------\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"Image_height Image_width\n"); + fprintf(stdout,"progression order\n"); + fprintf(stdout,"Tiles_size_X Tiles_size_Y\n"); + fprintf(stdout,"Components_nb\n"); + fprintf(stdout,"Layers_nb\n"); + fprintf(stdout,"decomposition_levels\n"); + fprintf(stdout,"[Precincts_size_X_res_Nr Precincts_size_Y_res_Nr]...\n"); + fprintf(stdout," [Precincts_size_X_res_0 Precincts_size_Y_res_0]\n"); + fprintf(stdout,"Main_header_end_position\n"); + fprintf(stdout,"Codestream_size\n"); + fprintf(stdout,"Tile_0 start_pos end_Theader end_pos TotalDisto NumPix MaxMSE\n"); + fprintf(stdout,"Tile_1 '' '' '' '' '' ''\n"); + fprintf(stdout,"...\n"); + fprintf(stdout,"Tile_Nt '' '' '' '' '' ''\n"); + fprintf(stdout,"Tpacket_0 Tile layer res. comp. prec. start_pos end_pos disto\n"); + fprintf(stdout,"...\n"); + fprintf(stdout,"Tpacket_Np '' '' '' '' '' '' '' ''\n"); + + fprintf(stdout,"MaxDisto\n"); + + fprintf(stdout,"TotalDisto\n\n"); +} + +OPJ_PROG_ORDER give_progression(char progression[5]) +{ + if (progression[0] == 'L' && progression[1] == 'R' + && progression[2] == 'C' && progression[3] == 'P') { + return LRCP; + } else { + if (progression[0] == 'R' && progression[1] == 'L' + && progression[2] == 'C' && progression[3] == 'P') { + return RLCP; + } else { + if (progression[0] == 'R' && progression[1] == 'P' + && progression[2] == 'C' && progression[3] == 'L') { + return RPCL; + } else { + if (progression[0] == 'P' && progression[1] == 'C' + && progression[2] == 'R' && progression[3] == 'L') { + return PCRL; + } else { + if (progression[0] == 'C' && progression[1] == 'P' + && progression[2] == 'R' && progression[3] == 'L') { + return CPRL; + } else { + return PROG_UNKNOWN; + } + } + } + } + } +} + + + + +int main(int argc, char **argv) +{ + mj2_cparameters_t mj2_parameters; /* MJ2 compression parameters */ + opj_cparameters_t *j2k_parameters; /* J2K compression parameters */ + opj_event_mgr_t event_mgr; /* event manager */ + opj_cio_t *cio; + int value; + opj_mj2_t *movie; + opj_image_t *img; + int i, j; + char *s, S1, S2, S3; + unsigned char *buf; + int x1, y1, len; + long mdat_initpos, offset; + FILE *mj2file; + int sampleno; + opj_cinfo_t* cinfo; + opj_bool bSuccess; + int numframes; + int prec = 8;/* DEFAULT */ + double total_time = 0; + + memset(&mj2_parameters, 0, sizeof(mj2_cparameters_t)); + /* default value */ + /* ------------- */ + mj2_parameters.w = 352; // CIF default value + mj2_parameters.h = 288; // CIF default value + mj2_parameters.CbCr_subsampling_dx = 2; // CIF default value + mj2_parameters.CbCr_subsampling_dy = 2; // CIF default value + mj2_parameters.frame_rate = 25; + mj2_parameters.prec = 8; /* DEFAULT */ + mj2_parameters.enumcs = ENUMCS_SYCC; /* FIXME: ENUMCS_YUV420 */ + mj2_parameters.meth = 1; /* enumerated color space */ + +/* + configure the event callbacks (not required) + setting of each callback is optionnal +*/ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = NULL; + + /* set J2K encoding parameters to default values */ + opj_set_default_encoder_parameters(&mj2_parameters.j2k_parameters); + j2k_parameters = &mj2_parameters.j2k_parameters; + + /* Create comment for codestream */ + if(j2k_parameters->cp_comment == NULL) { + const char comment[] = "Created by OpenJPEG version "; + const size_t clen = strlen(comment); + const char *version = opj_version(); + j2k_parameters->cp_comment = (char*)malloc(clen+strlen(version)+1); + sprintf(j2k_parameters->cp_comment,"%s%s", comment, version); + } + + while (1) { + int c = opj_getopt(argc, argv, + "i:o:r:q:f:t:n:c:b:p:s:d:P:S:E:M:R:T:C:I:W:F:D:h"); + if (c == -1) + break; + switch (c) { + case 'i': /* IN fill */ + { + char *infile = opj_optarg; + s = opj_optarg; + while (*s) { + s++; + } + s--; + S3 = *s; + s--; + S2 = *s; + s--; + S1 = *s; + + if ((S1 == 'y' && S2 == 'u' && S3 == 'v') + || (S1 == 'Y' && S2 == 'U' && S3 == 'V')) { + mj2_parameters.decod_format = YUV_DFMT; + } + else { + fprintf(stderr, + "!! Unrecognized format for infile : %c%c%c [accept only *.yuv] !!\n\n", + S1, S2, S3); + return 1; + } + strncpy(mj2_parameters.infile, infile, sizeof(mj2_parameters.infile)-1); + } + break; + /* ----------------------------------------------------- */ + case 'o': /* OUT fill */ + { + char *outfile = opj_optarg; + while (*outfile) { + outfile++; + } + outfile--; + S3 = *outfile; + outfile--; + S2 = *outfile; + outfile--; + S1 = *outfile; + + outfile = opj_optarg; + + if ((S1 == 'm' && S2 == 'j' && S3 == '2') + || (S1 == 'M' && S2 == 'J' && S3 == '2')) + mj2_parameters.cod_format = MJ2_CFMT; + else { + fprintf(stderr, + "Unknown output format image *.%c%c%c [only *.mj2]!! \n", + S1, S2, S3); + return 1; + } + strncpy(mj2_parameters.outfile, outfile, sizeof(mj2_parameters.outfile)-1); + } + break; + /* ----------------------------------------------------- */ + case 'r': /* rates rates/distorsion */ + { + float rate; + s = opj_optarg; + while (sscanf(s, "%f", &rate) == 1) { + j2k_parameters->tcp_rates[j2k_parameters->tcp_numlayers] = rate * 2; + j2k_parameters->tcp_numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + j2k_parameters->cp_disto_alloc = 1; + } + break; + /* ----------------------------------------------------- */ + case 'q': /* add fixed_quality */ + s = opj_optarg; + while (sscanf(s, "%f", &j2k_parameters->tcp_distoratio[j2k_parameters->tcp_numlayers]) == 1) { + j2k_parameters->tcp_numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + j2k_parameters->cp_fixed_quality = 1; + break; + /* dda */ + /* ----------------------------------------------------- */ + case 'f': /* mod fixed_quality (before : -q) */ + { + int *row = NULL, *col = NULL; + int numlayers = 0, numresolution = 0, matrix_width = 0; + + s = opj_optarg; + sscanf(s, "%d", &numlayers); + s++; + if (numlayers > 9) + s++; + + j2k_parameters->tcp_numlayers = numlayers; + numresolution = j2k_parameters->numresolution; + matrix_width = numresolution * 3; + j2k_parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int)); + s = s + 2; + + for (i = 0; i < numlayers; i++) { + row = &j2k_parameters->cp_matrice[i * matrix_width]; + col = row; + j2k_parameters->tcp_rates[i] = 1; + sscanf(s, "%d,", &col[0]); + s += 2; + if (col[0] > 9) + s++; + col[1] = 0; + col[2] = 0; + for (j = 1; j < numresolution; j++) { + col += 3; + sscanf(s, "%d,%d,%d", &col[0], &col[1], &col[2]); + s += 6; + if (col[0] > 9) + s++; + if (col[1] > 9) + s++; + if (col[2] > 9) + s++; + } + if (i < numlayers - 1) + s++; + } + j2k_parameters->cp_fixed_alloc = 1; + } + break; + /* ----------------------------------------------------- */ + case 't': /* tiles */ + sscanf(opj_optarg, "%d,%d", &j2k_parameters->cp_tdx, &j2k_parameters->cp_tdy); + j2k_parameters->tile_size_on = OPJ_TRUE; + break; + /* ----------------------------------------------------- */ + case 'n': /* resolution */ + sscanf(opj_optarg, "%d", &j2k_parameters->numresolution); + break; + /* ----------------------------------------------------- */ + case 'c': /* precinct dimension */ + { + char sep; + int res_spec = 0; + + char *s = opj_optarg; + do { + sep = 0; + sscanf(s, "[%d,%d]%c", &j2k_parameters->prcw_init[res_spec], + &j2k_parameters->prch_init[res_spec], &sep); + j2k_parameters->csty |= 0x01; + res_spec++; + s = strpbrk(s, "]") + 2; + } + while (sep == ','); + j2k_parameters->res_spec = res_spec; + } + break; + + /* ----------------------------------------------------- */ + case 'b': /* code-block dimension */ + { + int cblockw_init = 0, cblockh_init = 0; + sscanf(opj_optarg, "%d,%d", &cblockw_init, &cblockh_init); + if (cblockw_init * cblockh_init > 4096 || cblockw_init > 1024 + || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4) { + fprintf(stderr, + "!! Size of code_block error (option -b) !!\n\nRestriction :\n" + " * width*height<=4096\n * 4<=width,height<= 1024\n\n"); + return 1; + } + j2k_parameters->cblockw_init = cblockw_init; + j2k_parameters->cblockh_init = cblockh_init; + } + break; + /* ----------------------------------------------------- */ + case 'p': /* progression order */ + { + char progression[5]; + + strncpy(progression, opj_optarg, 5); + j2k_parameters->prog_order = give_progression(progression); + if (j2k_parameters->prog_order == -1) { + fprintf(stderr, "Unrecognized progression order " + "[LRCP, RLCP, RPCL, PCRL, CPRL] !!\n"); + return 1; + } + } + break; + /* ----------------------------------------------------- */ + case 's': /* subsampling factor */ + { + if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->subsampling_dx, + &j2k_parameters->subsampling_dy) != 2) { + fprintf(stderr, "'-s' sub-sampling argument error ! [-s dx,dy]\n"); + return 1; + } + } + break; + /* ----------------------------------------------------- */ + case 'd': /* coordonnate of the reference grid */ + { + if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->image_offset_x0, + &j2k_parameters->image_offset_y0) != 2) { + fprintf(stderr, "-d 'coordonnate of the reference grid' argument " + "error !! [-d x0,y0]\n"); + return 1; + } + } + break; + /* ----------------------------------------------------- */ + case 'h': /* Display an help description */ + help_display(); + return 0; + break; + /* ----------------------------------------------------- */ + case 'P': /* POC */ + { + int numpocs = 0; /* number of progression order change (POC) default 0 */ + opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */ + + char *s = opj_optarg; + POC = j2k_parameters->POC; + + while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%4s", &POC[numpocs].tile, + &POC[numpocs].resno0, &POC[numpocs].compno0, + &POC[numpocs].layno1, &POC[numpocs].resno1, + &POC[numpocs].compno1, POC[numpocs].progorder) == 7) { + POC[numpocs].prg1 = give_progression(POC[numpocs].progorder); + numpocs++; + while (*s && *s != '/') { + s++; + } + if (!*s) { + break; + } + s++; + } + j2k_parameters->numpocs = numpocs; + } + break; + /* ------------------------------------------------------ */ + case 'S': /* SOP marker */ + j2k_parameters->csty |= 0x02; + break; + /* ------------------------------------------------------ */ + case 'E': /* EPH marker */ + j2k_parameters->csty |= 0x04; + break; + /* ------------------------------------------------------ */ + case 'M': /* Mode switch pas tous au point !! */ + if (sscanf(opj_optarg, "%d", &value) == 1) { + for (i = 0; i <= 5; i++) { + int cache = value & (1 << i); + if (cache) + j2k_parameters->mode |= (1 << i); + } + } + break; + /* ------------------------------------------------------ */ + case 'R': /* ROI */ + { + if (sscanf(opj_optarg, "OI:c=%d,U=%d", &j2k_parameters->roi_compno, + &j2k_parameters->roi_shift) != 2) { + fprintf(stderr, "ROI error !! [-ROI:c='compno',U='shift']\n"); + return 1; + } + } + break; + /* ------------------------------------------------------ */ + case 'T': /* Tile offset */ + { + if (sscanf(opj_optarg, "%d,%d", &j2k_parameters->cp_tx0, &j2k_parameters->cp_ty0) != 2) { + fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]"); + return 1; + } + } + break; + /* ------------------------------------------------------ */ + case 'C': /* Add a comment */ + { + j2k_parameters->cp_comment = (char*)malloc(strlen(opj_optarg) + 1); + if(j2k_parameters->cp_comment) { + strcpy(j2k_parameters->cp_comment, opj_optarg); + } + } + break; + /* ------------------------------------------------------ */ + case 'I': /* reversible or not */ + { + j2k_parameters->irreversible = 1; + } + break; + /* ------------------------------------------------------ */ + case 'W': /* Width and Height and Cb and Cr subsampling in case of YUV format files */ + if (sscanf + (opj_optarg, "%d,%d,%d,%d", &mj2_parameters.w, &mj2_parameters.h, &mj2_parameters.CbCr_subsampling_dx, + &mj2_parameters.CbCr_subsampling_dy) != 4) { + fprintf(stderr, "-W argument error"); + return 1; + } + break; + /* ------------------------------------------------------ */ + case 'F': /* Video frame rate */ + if (sscanf(opj_optarg, "%d", &mj2_parameters.frame_rate) != 1) { + fprintf(stderr, "-F argument error"); + return 1; + } + break; + /* ------------------------------------------------------ */ + case 'D': /* Depth: the precision */ + if(sscanf(opj_optarg, "%d", &prec) != 1) prec = 0; + break; + + default: + return 1; + } + } + + /* Error messages */ + /* -------------- */ + if (!mj2_parameters.cod_format || !mj2_parameters.decod_format) { + fprintf(stderr, + "Usage: %s -i yuv-file -o mj2-file (+ options)\n",argv[0]); + return 1; + } + if(prec < 1 || prec > 16) + { + fprintf(stderr, "Error: Depth %d must be in the range 8 .. 16\n",prec); + return 1; + } + if ((j2k_parameters->cp_disto_alloc || j2k_parameters->cp_fixed_alloc || j2k_parameters->cp_fixed_quality) + && (!(j2k_parameters->cp_disto_alloc ^ j2k_parameters->cp_fixed_alloc ^ j2k_parameters->cp_fixed_quality))) { + fprintf(stderr, "Error: options -r -q and -f cannot be used together !!\n"); + return 1; + } /* mod fixed_quality */ + + /* if no rate entered, lossless by default */ + if (j2k_parameters->tcp_numlayers == 0) { + j2k_parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */ + j2k_parameters->tcp_numlayers++; + j2k_parameters->cp_disto_alloc = 1; + } + + if((j2k_parameters->cp_tx0 > j2k_parameters->image_offset_x0) || (j2k_parameters->cp_ty0 > j2k_parameters->image_offset_y0)) { + fprintf(stderr, + "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", + j2k_parameters->cp_tx0, j2k_parameters->image_offset_x0, j2k_parameters->cp_ty0, j2k_parameters->image_offset_y0); + return 1; + } + + for (i = 0; i < j2k_parameters->numpocs; i++) { + if (j2k_parameters->POC[i].prg == -1) { + fprintf(stderr, + "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n", + i + 1); + } + } + + if (j2k_parameters->cp_tdx > mj2_parameters.Dim[0] || j2k_parameters->cp_tdy > mj2_parameters.Dim[1]) { + fprintf(stderr, + "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", + j2k_parameters->cp_tdx, mj2_parameters.Dim[0], j2k_parameters->cp_tdy, mj2_parameters.Dim[1]); + return 1; + } + + /* to respect profile - 0 */ + /* ---------------------- */ + + x1 = !mj2_parameters.Dim[0] ? (mj2_parameters.w - 1) * j2k_parameters->subsampling_dx + + 1 : mj2_parameters.Dim[0] + (mj2_parameters.w - 1) * j2k_parameters->subsampling_dx + 1; + y1 = !mj2_parameters.Dim[1] ? (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy + + 1 : mj2_parameters.Dim[1] + (mj2_parameters.h - 1) * j2k_parameters->subsampling_dy + 1; + mj2_parameters.numcomps = 3; /* YUV files only have 3 components */ + + mj2_parameters.prec = prec; + + j2k_parameters->tcp_mct = 0; + + mj2file = fopen(mj2_parameters.outfile, "wb"); + + if (!mj2file) { + fprintf(stderr, "failed to open %s for writing\n", argv[2]); + return 1; + } + + /* get a MJ2 decompressor handle */ + cinfo = mj2_create_compress(); + movie = (opj_mj2_t*)cinfo->mj2_handle; + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); + + /* setup encoder parameters */ + mj2_setup_encoder(movie, &mj2_parameters); + + movie->tk[0].num_samples = + yuv_num_frames(&movie->tk[0],mj2_parameters.infile); + + if (movie->tk[0].num_samples == 0) { + return 1; + } + + // One sample per chunk + movie->tk[0].chunk = (mj2_chunk_t*) + malloc(movie->tk[0].num_samples * sizeof(mj2_chunk_t)); + movie->tk[0].sample = (mj2_sample_t*) + malloc(movie->tk[0].num_samples * sizeof(mj2_sample_t)); + + if (mj2_init_stdmovie(movie)) { + fprintf(stderr, "Error with movie initialization"); + return 1; + } + +// Writing JP, FTYP and MDAT boxes +// Assuming that the JP and FTYP boxes won't be longer than 300 bytes: + buf = (unsigned char*) + malloc (300 * sizeof(unsigned char)); + + cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, 300); + + mj2_write_jp(cio); + mj2_write_ftyp(movie, cio); + + mdat_initpos = cio_tell(cio); + cio_skip(cio, 4); + + cio_write(cio, MJ2_MDAT, 4); + + fwrite(buf,cio_tell(cio),1,mj2file); + + offset = cio_tell(cio); + opj_cio_close(cio); + free(buf); + + for(i = 0; i < movie->num_stk + movie->num_htk + movie->num_vtk; i++) + { + if(movie->tk[i].track_type != 0) + { + fprintf(stderr, "Unable to write sound or hint tracks\n"); + } + else + { + mj2_tk_t *tk; + int buflen = 0; + + tk = &movie->tk[i]; + tk->num_chunks = tk->num_samples; + numframes = tk->num_samples; + tk->depth = prec; + + fprintf(stderr, "Video Track number %d\n", i); + + img = mj2_image_create(tk, j2k_parameters); + + buflen = 2 * (tk->w * tk->h * 8); + buf = (unsigned char *) malloc(buflen*sizeof(unsigned char)); + + for(sampleno = 0; sampleno < numframes; sampleno++) + { + double init_time = opj_clock(); + double elapsed_time; + + if(yuvtoimage(tk, img, sampleno, j2k_parameters, + mj2_parameters.infile)) + { + fprintf(stderr, "Error with frame number %d in YUV file\n", sampleno); + return 1; + } + +/* setup the encoder parameters using the current image and user parameters */ + opj_setup_encoder(cinfo, j2k_parameters, img); + + cio = opj_cio_open((opj_common_ptr)movie->cinfo, buf, buflen); + + cio_skip(cio, 4); + cio_write(cio, JP2_JP2C, 4); // JP2C + +/* encode the image */ +#if 0 /* MM: FIXME */ + bSuccess = opj_encode(cinfo, cio, img, NULL); +#endif + + if (!bSuccess) { + opj_cio_close(cio); + fprintf(stderr, "failed to encode image\n"); + return 1; + } + + len = cio_tell(cio) - 8; + cio_seek(cio, 0); + cio_write(cio, len+8,4); + opj_cio_close(cio); + + tk->sample[sampleno].sample_size = len+8; + tk->sample[sampleno].offset = offset; + tk->chunk[sampleno].offset = offset; // There is one sample per chunk + fwrite(buf, 1, len+8, mj2file); + offset += len+8; + + elapsed_time = opj_clock()-init_time; + fprintf(stderr, "Frame number %d/%d encoded in %.2f mseconds\n", + sampleno + 1, numframes, elapsed_time*1000); + total_time += elapsed_time; + } /* for(sampleno */ + + free(buf); + opj_image_destroy(img); + } + }/* for(i */ + + fseek(mj2file, mdat_initpos, SEEK_SET); + + buf = (unsigned char*) malloc(4*sizeof(unsigned char)); + +// Init a cio to write box length variable in a little endian way + cio = opj_cio_open(NULL, buf, 4); + cio_write(cio, offset - mdat_initpos, 4); + fwrite(buf, 4, 1, mj2file); + fseek(mj2file,0,SEEK_END); + free(buf); + +// Writing MOOV box + buf = (unsigned char*) + malloc ((TEMP_BUF+numframes*20) * sizeof(unsigned char)); + cio = opj_cio_open(movie->cinfo, buf, (TEMP_BUF+numframes*20)); + mj2_write_moov(movie, cio); + fwrite(buf,cio_tell(cio),1,mj2file); + free(buf); + + fprintf(stdout,"Total encoding time: %.2f s for %d frames (%.1f fps)\n", + total_time, numframes, (float)numframes/total_time); + + // Ending program + + fclose(mj2file); +/* free remaining compression structures */ + mj2_destroy_compress(movie); + free(cinfo); + + if(j2k_parameters->cp_comment) free(j2k_parameters->cp_comment); + if(j2k_parameters->cp_matrice) free(j2k_parameters->cp_matrice); + opj_cio_close(cio); + + return 0; +} diff --git a/src/bin/mj2/opj_mj2_decompress.c b/src/bin/mj2/opj_mj2_decompress.c new file mode 100644 index 00000000..1cf05555 --- /dev/null +++ b/src/bin/mj2/opj_mj2_decompress.c @@ -0,0 +1,254 @@ +/* +* Copyright (c) 2003-2004, Francois-Olivier Devaux +* Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include +#include +#include + +#include "opj_config.h" +#include "openjpeg.h" +#include "j2k_lib.h" +#include "cio.h" +#include "j2k.h" +#include "jp2.h" +#include "mj2.h" +#include "mj2_convert.h" + +#ifdef HAVE_LIBLCMS2 +#include +#endif +#ifdef HAVE_LIBLCMS1 +#include +#endif +#include "color.h" +/* -------------------------------------------------------------------------- */ + +/** +sample error callback expecting a FILE* client object +*/ +void error_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[ERROR] %s", msg); +} +/** +sample warning callback expecting a FILE* client object +*/ +void warning_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[WARNING] %s", msg); +} +/** +sample debug callback expecting a FILE* client object +*/ +void info_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[INFO] %s", msg); +} + +/* -------------------------------------------------------------------------- */ + + +int main(int argc, char *argv[]) { + mj2_dparameters_t mj2_parameters; /* decompression parameters */ + opj_dinfo_t* dinfo; + opj_event_mgr_t event_mgr; /* event manager */ + opj_cio_t *cio = NULL; + unsigned int tnum, snum; + opj_mj2_t *movie; + mj2_tk_t *track; + mj2_sample_t *sample; + unsigned char* frame_codestream; + FILE *file, *outfile; + char outfilename[50]; + opj_image_t *img = NULL; + unsigned int max_codstrm_size = 0; + double total_time = 0; + unsigned int numframes = 0; + + if (argc != 3) { + printf("Usage: %s inputfile.mj2 outputfile.yuv\n",argv[0]); + return 1; + } + + file = fopen(argv[1], "rb"); + + if (!file) { + fprintf(stderr, "failed to open %s for reading\n", argv[1]); + return 1; + } + + // Checking output file + outfile = fopen(argv[2], "w"); + if (!file) { + fprintf(stderr, "failed to open %s for writing\n", argv[2]); + return 1; + } + fclose(outfile); + + /* + configure the event callbacks (not required) + setting of each callback is optionnal + */ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = NULL; + + /* get a MJ2 decompressor handle */ + dinfo = mj2_create_decompress(); + movie = (opj_mj2_t*)dinfo->mj2_handle; + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); + + memset(&mj2_parameters, 0, sizeof(mj2_dparameters_t)); + /* set J2K decoding parameters to default values */ + opj_set_default_decoder_parameters(&mj2_parameters.j2k_parameters); + + /* setup the decoder decoding parameters using user parameters */ + mj2_setup_decoder(movie, &mj2_parameters); + + if (mj2_read_struct(file, movie)) // Creating the movie structure + return 1; + + // Decode first video track + for (tnum=0; tnum < (unsigned int)(movie->num_htk + movie->num_stk + movie->num_vtk); tnum++) { + if (movie->tk[tnum].track_type == 0) + break; + } + + if (movie->tk[tnum].track_type != 0) { + printf("Error. Movie does not contain any video track\n"); + return 1; + } + + track = &movie->tk[tnum]; + + // Output info on first video tracl + fprintf(stdout,"The first video track contains %d frames.\nWidth: %d, Height: %d \n\n", + track->num_samples, track->w, track->h); + + max_codstrm_size = track->sample[0].sample_size-8; + frame_codestream = (unsigned char*) malloc(max_codstrm_size * sizeof(unsigned char)); + + numframes = track->num_samples; + + for (snum=0; snum < numframes; snum++) + { + double init_time = opj_clock(); + double elapsed_time; + + sample = &track->sample[snum]; + if (sample->sample_size-8 > max_codstrm_size) { + max_codstrm_size = sample->sample_size-8; + if ((frame_codestream = (unsigned char*) + realloc(frame_codestream, max_codstrm_size)) == NULL) { + printf("Error reallocation memory\n"); + return 1; + }; + } + fseek(file,sample->offset+8,SEEK_SET); + fread(frame_codestream, sample->sample_size-8, 1, file); // Assuming that jp and ftyp markers size do + + /* open a byte stream */ + cio = opj_cio_open((opj_common_ptr)dinfo, frame_codestream, sample->sample_size-8); + +#if 0 /* MM: FIXME */ + img = opj_decode(dinfo, cio); // Decode J2K to image +#endif + +#ifdef WANT_SYCC_TO_RGB + if(img->color_space == CLRSPC_SYCC) + { + color_sycc_to_rgb(img); + } +#endif + + if(img->icc_profile_buf) + { +#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) + color_apply_icc_profile(img); +#endif + + free(img->icc_profile_buf); + img->icc_profile_buf = NULL; img->icc_profile_len = 0; + } + + if (((img->numcomps == 3) && (img->comps[0].dx == img->comps[1].dx / 2) + && (img->comps[0].dx == img->comps[2].dx / 2 ) && (img->comps[0].dx == 1)) + || (img->numcomps == 1)) { + + if (!imagetoyuv(img, argv[2])) // Convert image to YUV + return 1; + } + else if ((img->numcomps == 3) && + (img->comps[0].dx == 1) && (img->comps[1].dx == 1)&& + (img->comps[2].dx == 1))// If YUV 4:4:4 input --> to bmp + { + fprintf(stdout,"The frames will be output in a bmp format (output_1.bmp, ...)\n"); + sprintf(outfilename,"output_%d.bmp",snum); + if (imagetobmp(img, outfilename)) // Convert image to BMP + return 1; + + } + else { + fprintf(stdout,"Image component dimensions are unknown. Unable to output image\n"); + fprintf(stdout,"The frames will be output in a j2k file (output_1.j2k, ...)\n"); + + sprintf(outfilename,"output_%d.j2k",snum); + outfile = fopen(outfilename, "wb"); + if (!outfile) { + fprintf(stderr, "failed to open %s for writing\n",outfilename); + return 1; + } + fwrite(frame_codestream,sample->sample_size-8,1,outfile); + fclose(outfile); + } + /* close the byte stream */ + opj_cio_close(cio); + /* free image data structure */ + opj_image_destroy(img); + elapsed_time = opj_clock()-init_time; + fprintf(stderr, "Frame number %d/%d decoded in %.2f mseconds\n", snum + 1, numframes, elapsed_time*1000); + total_time += elapsed_time; + + } + + free(frame_codestream); + fclose(file); + + /* free remaining structures */ + if(dinfo) { + mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle); + } + free(dinfo); + + fprintf(stdout, "%d frame(s) correctly decompressed\n", snum); + fprintf(stdout,"Total decoding time: %.2f seconds (%.1f fps)\n", total_time, (float)numframes/total_time); + + return 0; +} diff --git a/src/bin/mj2/opj_mj2_extract.c b/src/bin/mj2/opj_mj2_extract.c new file mode 100644 index 00000000..f694d531 --- /dev/null +++ b/src/bin/mj2/opj_mj2_extract.c @@ -0,0 +1,150 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2003-2007, Francois-Olivier Devaux + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "openjpeg.h" +#include "cio.h" +#include "j2k.h" +#include "jp2.h" +#include "mj2.h" + +/* -------------------------------------------------------------------------- */ + +/** +sample error callback expecting a FILE* client object +*/ +void error_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[ERROR] %s", msg); +} +/** +sample warning callback expecting a FILE* client object +*/ +void warning_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[WARNING] %s", msg); +} +/** +sample debug callback expecting a FILE* client object +*/ +void info_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[INFO] %s", msg); +} + +/* -------------------------------------------------------------------------- */ + + +int main(int argc, char *argv[]) { + opj_dinfo_t* dinfo; + opj_event_mgr_t event_mgr; /* event manager */ + int tnum; + unsigned int snum; + opj_mj2_t *movie; + mj2_tk_t *track; + mj2_sample_t *sample; + unsigned char* frame_codestream; + FILE *file, *outfile; + char outfilename[50]; + mj2_dparameters_t parameters; + + if (argc != 3) { + printf("Usage: %s mj2filename output_location\n",argv[0]); + printf("Example: %s foreman.mj2 output/foreman\n",argv[0]); + return 1; + } + + file = fopen(argv[1], "rb"); + + if (!file) { + fprintf(stderr, "failed to open %s for reading\n", argv[1]); + return 1; + } + + /* + configure the event callbacks (not required) + setting of each callback is optionnal + */ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = info_callback; + + /* get a MJ2 decompressor handle */ + dinfo = mj2_create_decompress(); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); + + /* setup the decoder decoding parameters using user parameters */ + memset(¶meters, 0, sizeof(mj2_dparameters_t)); + movie = (opj_mj2_t*) dinfo->mj2_handle; + mj2_setup_decoder(movie, ¶meters); + + if (mj2_read_struct(file, movie)) /* Creating the movie structure*/ + return 1; + + /* Decode first video track */ + tnum = 0; + while (movie->tk[tnum].track_type != 0) + tnum ++; + + track = &movie->tk[tnum]; + + fprintf(stdout,"Extracting %d frames from file...\n",track->num_samples); + + for (snum=0; snum < track->num_samples; snum++) + { + sample = &track->sample[snum]; + frame_codestream = (unsigned char*) malloc (sample->sample_size-8); /* Skipping JP2C marker*/ + fseek(file,sample->offset+8,SEEK_SET); + fread(frame_codestream,sample->sample_size-8,1, file); /* Assuming that jp and ftyp markers size do*/ + + sprintf(outfilename,"%s_%05d.j2k",argv[2],snum); + outfile = fopen(outfilename, "wb"); + if (!outfile) { + fprintf(stderr, "failed to open %s for writing\n",outfilename); + return 1; + } + fwrite(frame_codestream,sample->sample_size-8,1,outfile); + fclose(outfile); + free(frame_codestream); + } + fclose(file); + fprintf(stdout, "%d frames correctly extracted\n", snum); + + /* free remaining structures */ + if(dinfo) { + mj2_destroy_decompress((opj_mj2_t*)dinfo->mj2_handle); + } + + return 0; +} diff --git a/src/bin/mj2/opj_mj2_wrap.c b/src/bin/mj2/opj_mj2_wrap.c new file mode 100644 index 00000000..5d37cd7b --- /dev/null +++ b/src/bin/mj2/opj_mj2_wrap.c @@ -0,0 +1,525 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * Copyright (c) 2003-2007, Francois-Olivier Devaux + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include + +#include "openjpeg.h" +#include "cio.h" +#include "j2k.h" +#include "jp2.h" +#include "mj2.h" + +static int int_ceildiv(int a, int b) { + return (a + b - 1) / b; +} + +/** +Size of memory first allocated for MOOV box +*/ +#define TEMP_BUF 10000 + +#define ENUMCS_GRAY 16 +#define ENUMCS_SRGB 17 +#define ENUMCS_SYCC 18 + +#define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51" + +/* -------------------------------------------------------------------------- */ + +static int test_image(const char *fname, mj2_cparameters_t *cp) +{ + FILE *reader; + opj_image_t *image; + unsigned char *src; + opj_dinfo_t *dinfo; + opj_cio_t *cio; + opj_dparameters_t dparameters; + int success; + long src_len; + + success = 0; + + if((reader = fopen(fname, "rb")) == NULL) return success; + + fseek(reader, 0, SEEK_END); + src_len = ftell(reader); + fseek(reader, 0, SEEK_SET); + src = (unsigned char*) malloc(src_len); + fread(src, 1, src_len, reader); + fclose(reader); + + if(memcmp(src, J2K_CODESTREAM_MAGIC, 4) != 0) + { + free(src); return success; + } + memset(&dparameters, 0, sizeof(opj_dparameters_t)); + + opj_set_default_decoder_parameters(&dparameters); + + dinfo = opj_create_decompress(CODEC_J2K); + + opj_setup_decoder(dinfo, &dparameters); + + cio = opj_cio_open((opj_common_ptr)dinfo, src, src_len); + +#if 0 /* MM: FIXME */ + image = opj_decode(dinfo, cio); +#endif + + free(src); cio->buffer = NULL; + opj_cio_close(cio); + + if(image == NULL) goto fin; + + cp->numcomps = image->numcomps; + cp->w = image->comps[0].w; + cp->h = image->comps[0].h; + cp->prec = image->comps[0].prec; + + if(image->numcomps > 2 ) + { + if((image->comps[0].dx == 1) + && (image->comps[1].dx == 2) + && (image->comps[2].dx == 2) + && (image->comps[0].dy == 1) + && (image->comps[1].dy == 2) + && (image->comps[2].dy == 2))// horizontal and vertical + { +// Y420 + cp->enumcs = ENUMCS_SYCC; + cp->CbCr_subsampling_dx = 2; + cp->CbCr_subsampling_dy = 2; + } + else + if((image->comps[0].dx == 1) + && (image->comps[1].dx == 2) + && (image->comps[2].dx == 2) + && (image->comps[0].dy == 1) + && (image->comps[1].dy == 1) + && (image->comps[2].dy == 1))// horizontal only + { +// Y422 + cp->enumcs = ENUMCS_SYCC; + cp->CbCr_subsampling_dx = 2; + cp->CbCr_subsampling_dy = 1; + } + else + if((image->comps[0].dx == 1) + && (image->comps[1].dx == 1) + && (image->comps[2].dx == 1) + && (image->comps[0].dy == 1) + && (image->comps[1].dy == 1) + && (image->comps[2].dy == 1)) + { +// Y444 or RGB + + if(image->color_space == CLRSPC_SRGB) + { + cp->enumcs = ENUMCS_SRGB; + +// cp->CbCr_subsampling_dx = 0; +// cp->CbCr_subsampling_dy = 0; + } + else + { + cp->enumcs = ENUMCS_SYCC; + + cp->CbCr_subsampling_dx = 1; + cp->CbCr_subsampling_dy = 1; + } + } + else + { + goto fin; + } + } + else + { + cp->enumcs = ENUMCS_GRAY; +// cp->CbCr_subsampling_dx = 0; +// cp->CbCr_subsampling_dy = 0; + } + if(image->icc_profile_buf) + { + cp->meth = 2; + free(image->icc_profile_buf); image->icc_profile_buf = NULL; + } + else cp->meth = 1; + + success = 1; +fin: + if(dinfo) + opj_destroy_decompress(dinfo); + + if(image) + opj_image_destroy(image); + + return success; +} + +/** +sample error callback expecting a FILE* client object +*/ +void error_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[ERROR] %s", msg); +} +/** +sample warning callback expecting a FILE* client object +*/ +void warning_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[WARNING] %s", msg); +} +/** +sample debug callback expecting a FILE* client object +*/ +void info_callback(const char *msg, void *client_data) { + FILE *stream = (FILE*)client_data; + fprintf(stream, "[INFO] %s", msg); +} + +/* -------------------------------------------------------------------------- */ + + + +static void read_siz_marker(FILE *file, opj_image_t *image) +{ + int len,i; + char buf, buf2[2]; + unsigned char *siz_buffer; + opj_cio_t *cio; + + fseek(file, 0, SEEK_SET); + do { + fread(&buf,1,1, file); + if (buf==(char)0xff) + fread(&buf,1,1, file); + } + while (!(buf==(char)0x51)); + + fread(buf2,2,1,file); /* Lsiz */ + len = ((buf2[0])<<8) + buf2[1]; + + siz_buffer = (unsigned char*) malloc(len * sizeof(unsigned char)); + fread(siz_buffer,len, 1, file); + cio = opj_cio_open(NULL, siz_buffer, len); + + cio_read(cio, 2); /* Rsiz (capabilities) */ + image->x1 = cio_read(cio, 4); /* Xsiz */ + image->y1 = cio_read(cio, 4); /* Ysiz */ + image->x0 = cio_read(cio, 4); /* X0siz */ + image->y0 = cio_read(cio, 4); /* Y0siz */ + cio_skip(cio, 16); /* XTsiz, YTsiz, XT0siz, YT0siz */ + + image->numcomps = cio_read(cio,2); /* Csiz */ + image->comps = + (opj_image_comp_t *) malloc(image->numcomps * sizeof(opj_image_comp_t)); + + for (i = 0; i < image->numcomps; i++) { + int tmp; + tmp = cio_read(cio,1); /* Ssiz_i */ + image->comps[i].prec = (tmp & 0x7f) + 1; + image->comps[i].sgnd = tmp >> 7; + image->comps[i].dx = cio_read(cio,1); /* XRsiz_i */ + image->comps[i].dy = cio_read(cio,1); /* YRsiz_i */ + image->comps[i].resno_decoded = 0; /* number of resolution decoded */ + image->comps[i].factor = 0; /* reducing factor by component */ + } + fseek(file, 0, SEEK_SET); + opj_cio_close(cio); + free(siz_buffer); +} + +static void setparams(opj_mj2_t *movie, opj_image_t *image) { + int i, depth_0, depth, sign; + + movie->tk[0].w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); + movie->tk[0].h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); + mj2_init_stdmovie(movie); + + movie->tk[0].depth = image->comps[0].prec; + + if (image->numcomps==3) { + if ((image->comps[0].dx == 1) + && (image->comps[1].dx == 1) + && (image->comps[2].dx == 1)) + movie->tk[0].CbCr_subsampling_dx = 1; + else + if ((image->comps[0].dx == 1) + && (image->comps[1].dx == 2) + && (image->comps[2].dx == 2)) + movie->tk[0].CbCr_subsampling_dx = 2; + else + fprintf(stderr,"Image component sizes are incoherent\n"); + + if ((image->comps[0].dy == 1) + && (image->comps[1].dy == 1) + && (image->comps[2].dy == 1)) + movie->tk[0].CbCr_subsampling_dy = 1; + else + if ((image->comps[0].dy == 1) + && (image->comps[1].dy == 2) + && (image->comps[2].dy == 2)) + movie->tk[0].CbCr_subsampling_dy = 2; + else + fprintf(stderr,"Image component sizes are incoherent\n"); + } + + movie->tk[0].sample_rate = 25; + + movie->tk[0].jp2_struct.numcomps = image->numcomps; // NC + + /* Init Standard jp2 structure */ + + movie->tk[0].jp2_struct.comps = + (opj_jp2_comps_t *) malloc(movie->tk[0].jp2_struct.numcomps * sizeof(opj_jp2_comps_t)); + movie->tk[0].jp2_struct.precedence = 0; /* PRECEDENCE*/ + movie->tk[0].jp2_struct.approx = 0; /* APPROX*/ + movie->tk[0].jp2_struct.brand = JP2_JP2; /* BR */ + movie->tk[0].jp2_struct.minversion = 0; /* MinV */ + movie->tk[0].jp2_struct.numcl = 1; + movie->tk[0].jp2_struct.cl = (unsigned int *) malloc(movie->tk[0].jp2_struct.numcl * sizeof(int)); + movie->tk[0].jp2_struct.cl[0] = JP2_JP2; /* CL0 : JP2 */ + movie->tk[0].jp2_struct.C = 7; /* C : Always 7*/ + movie->tk[0].jp2_struct.UnkC = 0; /* UnkC, colorspace specified in colr box*/ + movie->tk[0].jp2_struct.IPR = 0; /* IPR, no intellectual property*/ + movie->tk[0].jp2_struct.w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); + movie->tk[0].jp2_struct.h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); + + depth_0 = image->comps[0].prec - 1; + sign = image->comps[0].sgnd; + movie->tk[0].jp2_struct.bpc = depth_0 + (sign << 7); + + for (i = 1; i < image->numcomps; i++) { + depth = image->comps[i].prec - 1; + sign = image->comps[i].sgnd; + if (depth_0 != depth) + movie->tk[0].jp2_struct.bpc = 255; + } + + for (i = 0; i < image->numcomps; i++) + movie->tk[0].jp2_struct.comps[i].bpcc = + image->comps[i].prec - 1 + (image->comps[i].sgnd << 7); + + if ((image->numcomps == 1 || image->numcomps == 3) + && (movie->tk[0].jp2_struct.bpc != 255)) + movie->tk[0].jp2_struct.meth = 1; + else + movie->tk[0].jp2_struct.meth = 2; + + if (image->numcomps == 1) + movie->tk[0].jp2_struct.enumcs = 17; // Grayscale + + else + if ((image->comps[0].dx == 1) + && (image->comps[1].dx == 1) + && (image->comps[2].dx == 1) + && (image->comps[0].dy == 1) + && (image->comps[1].dy == 1) + && (image->comps[2].dy == 1)) + movie->tk[0].jp2_struct.enumcs = 16; // RGB + + else + if ((image->comps[0].dx == 1) + && (image->comps[1].dx == 2) + && (image->comps[2].dx == 2) + && (image->comps[0].dy == 1) + && (image->comps[1].dy == 2) + && (image->comps[2].dy == 2)) + movie->tk[0].jp2_struct.enumcs = 18; // YUV + + else + movie->tk[0].jp2_struct.enumcs = 0; // Unkown profile */ +} + +int main(int argc, char *argv[]) { + opj_cinfo_t* cinfo; + opj_event_mgr_t event_mgr; /* event manager */ + unsigned int snum; + opj_mj2_t *movie; + mj2_sample_t *sample; + unsigned char* frame_codestream; + FILE *mj2file, *j2kfile; + char *j2kfilename; + unsigned char *buf; + int offset, mdat_initpos; + opj_image_t img; + opj_cio_t *cio; + mj2_cparameters_t parameters; + + if (argc != 3) { + printf("Usage: %s source_location mj2_filename\n",argv[0]); + printf("Example: %s input/input output.mj2\n",argv[0]); + return 1; + } + + mj2file = fopen(argv[2], "wb"); + + if (!mj2file) { + fprintf(stderr, "failed to open %s for writing\n", argv[2]); + return 1; + } + memset(&img, 0, sizeof(opj_image_t)); + /* + configure the event callbacks (not required) + setting of each callback is optionnal + */ + memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); + event_mgr.error_handler = error_callback; + event_mgr.warning_handler = warning_callback; + event_mgr.info_handler = info_callback; + + /* get a MJ2 decompressor handle */ + cinfo = mj2_create_compress(); + + /* catch events using our callbacks and give a local context */ + opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); + + /* setup the decoder encoding parameters using user parameters */ + memset(¶meters, 0, sizeof(mj2_cparameters_t)); + movie = (opj_mj2_t*) cinfo->mj2_handle; + + j2kfilename = (char*)malloc(strlen(argv[1]) + 12);/* max. '%6d' */ + sprintf(j2kfilename, "%s_00001.j2k",argv[1]); + + if(test_image(j2kfilename, ¶meters) == 0) goto fin; + + parameters.frame_rate = 25; /* DEFAULT */ + + mj2_setup_encoder(movie, ¶meters); + + + /* Writing JP, FTYP and MDAT boxes + Assuming that the JP and FTYP boxes won't be longer than 300 bytes */ + + buf = (unsigned char*) malloc (300 * sizeof(unsigned char)); + cio = opj_cio_open(movie->cinfo, buf, 300); + mj2_write_jp(cio); + mj2_write_ftyp(movie, cio); + mdat_initpos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio,MJ2_MDAT, 4); + fwrite(buf,cio_tell(cio),1,mj2file); + free(buf); + + // Insert each j2k codestream in a JP2C box + snum=0; + offset = 0; + while(1) + { + sample = &movie->tk[0].sample[snum]; + sprintf(j2kfilename,"%s_%05d.j2k",argv[1],snum); + j2kfile = fopen(j2kfilename, "rb"); + if (!j2kfile) { + if (snum==0) { // Could not open a single codestream + fprintf(stderr, "failed to open %s for reading\n",j2kfilename); + return 1; + } + else { // Tried to open a inexistant codestream + fprintf(stdout,"%d frames are being added to the MJ2 file\n",snum); + break; + } + } + + // Calculating offset for samples and chunks + offset += cio_tell(cio); + sample->offset = offset; + movie->tk[0].chunk[snum].offset = offset; // There will be one sample per chunk + + // Calculating sample size + fseek(j2kfile,0,SEEK_END); + sample->sample_size = ftell(j2kfile) + 8; // Sample size is codestream + JP2C box header + fseek(j2kfile,0,SEEK_SET); + + // Reading siz marker of j2k image for the first codestream + if (snum==0) + read_siz_marker(j2kfile, &img); + + // Writing JP2C box header + frame_codestream = (unsigned char*) malloc (sample->sample_size+8); + cio = opj_cio_open(movie->cinfo, frame_codestream, sample->sample_size); + cio_write(cio,sample->sample_size, 4); // Sample size + cio_write(cio,JP2_JP2C, 4); // JP2C + + // Writing codestream from J2K file to MJ2 file + fread(frame_codestream+8,sample->sample_size-8,1,j2kfile); + fwrite(frame_codestream,sample->sample_size,1,mj2file); + cio_skip(cio, sample->sample_size-8); + + // Ending loop + fclose(j2kfile); + snum++; + mj2_sample_t * new_sample = (mj2_sample_t*) + realloc(movie->tk[0].sample, (snum+1) * sizeof(mj2_sample_t)); + mj2_chunk_t * new_chunk = (mj2_chunk_t*) + realloc(movie->tk[0].chunk, (snum+1) * sizeof(mj2_chunk_t)); + if (new_sample && new_chunk) { + movie->tk[0].sample = new_sample; + movie->tk[0].chunk = new_chunk; + } else { + fprintf(stderr, "Failed to allocate enough memory to read %s\n", j2kfilename); + return 1; + } + free(frame_codestream); + } + + // Writing the MDAT box length in header + offset += cio_tell(cio); + buf = (unsigned char*) malloc (4 * sizeof(unsigned char)); + cio = opj_cio_open(movie->cinfo, buf, 4); + cio_write(cio,offset-mdat_initpos,4); + fseek(mj2file,(long)mdat_initpos,SEEK_SET); + fwrite(buf,4,1,mj2file); + fseek(mj2file,0,SEEK_END); + free(buf); + + // Setting movie parameters + movie->tk[0].num_samples=snum; + movie->tk[0].num_chunks=snum; + setparams(movie, &img); + + // Writing MOOV box + buf = (unsigned char*) malloc ((TEMP_BUF+snum*20) * sizeof(unsigned char)); + cio = opj_cio_open(movie->cinfo, buf, (TEMP_BUF+snum*20)); + mj2_write_moov(movie, cio); + fwrite(buf,cio_tell(cio),1,mj2file); + + // Ending program + free(img.comps); + opj_cio_close(cio); + +fin: + fclose(mj2file); + mj2_destroy_compress(movie); + free(j2kfilename); + + return 0; +} diff --git a/src/bin/mj2/wrap_j2k_in_mj2.c b/src/bin/mj2/wrap_j2k_in_mj2.c deleted file mode 100644 index 7ce88677..00000000 --- a/src/bin/mj2/wrap_j2k_in_mj2.c +++ /dev/null @@ -1,523 +0,0 @@ -/* - * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium - * Copyright (c) 2002-2007, Professor Benoit Macq - * Copyright (c) 2003-2007, Francois-Olivier Devaux - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include "openjpeg.h" -#include "cio.h" -#include "j2k.h" -#include "jp2.h" -#include "mj2.h" - -static int int_ceildiv(int a, int b) { - return (a + b - 1) / b; -} - -/** -Size of memory first allocated for MOOV box -*/ -#define TEMP_BUF 10000 - -#define ENUMCS_GRAY 16 -#define ENUMCS_SRGB 17 -#define ENUMCS_SYCC 18 - -#define J2K_CODESTREAM_MAGIC "\xff\x4f\xff\x51" - -/* -------------------------------------------------------------------------- */ - -static int test_image(const char *fname, mj2_cparameters_t *cp) -{ - FILE *reader; - opj_image_t *image; - unsigned char *src; - opj_dinfo_t *dinfo; - opj_cio_t *cio; - opj_dparameters_t dparameters; - int success; - long src_len; - - success = 0; - - if((reader = fopen(fname, "rb")) == NULL) return success; - - fseek(reader, 0, SEEK_END); - src_len = ftell(reader); - fseek(reader, 0, SEEK_SET); - src = (unsigned char*) malloc(src_len); - fread(src, 1, src_len, reader); - fclose(reader); - - if(memcmp(src, J2K_CODESTREAM_MAGIC, 4) != 0) - { - free(src); return success; - } - memset(&dparameters, 0, sizeof(opj_dparameters_t)); - - opj_set_default_decoder_parameters(&dparameters); - - dinfo = opj_create_decompress(CODEC_J2K); - - opj_setup_decoder(dinfo, &dparameters); - - cio = opj_cio_open((opj_common_ptr)dinfo, src, src_len); - - image = opj_decode(dinfo, cio); - - free(src); cio->buffer = NULL; - opj_cio_close(cio); - - if(image == NULL) goto fin; - - cp->numcomps = image->numcomps; - cp->w = image->comps[0].w; - cp->h = image->comps[0].h; - cp->prec = image->comps[0].prec; - - if(image->numcomps > 2 ) - { - if((image->comps[0].dx == 1) - && (image->comps[1].dx == 2) - && (image->comps[2].dx == 2) - && (image->comps[0].dy == 1) - && (image->comps[1].dy == 2) - && (image->comps[2].dy == 2))// horizontal and vertical - { -// Y420 - cp->enumcs = ENUMCS_SYCC; - cp->CbCr_subsampling_dx = 2; - cp->CbCr_subsampling_dy = 2; - } - else - if((image->comps[0].dx == 1) - && (image->comps[1].dx == 2) - && (image->comps[2].dx == 2) - && (image->comps[0].dy == 1) - && (image->comps[1].dy == 1) - && (image->comps[2].dy == 1))// horizontal only - { -// Y422 - cp->enumcs = ENUMCS_SYCC; - cp->CbCr_subsampling_dx = 2; - cp->CbCr_subsampling_dy = 1; - } - else - if((image->comps[0].dx == 1) - && (image->comps[1].dx == 1) - && (image->comps[2].dx == 1) - && (image->comps[0].dy == 1) - && (image->comps[1].dy == 1) - && (image->comps[2].dy == 1)) - { -// Y444 or RGB - - if(image->color_space == CLRSPC_SRGB) - { - cp->enumcs = ENUMCS_SRGB; - -// cp->CbCr_subsampling_dx = 0; -// cp->CbCr_subsampling_dy = 0; - } - else - { - cp->enumcs = ENUMCS_SYCC; - - cp->CbCr_subsampling_dx = 1; - cp->CbCr_subsampling_dy = 1; - } - } - else - { - goto fin; - } - } - else - { - cp->enumcs = ENUMCS_GRAY; -// cp->CbCr_subsampling_dx = 0; -// cp->CbCr_subsampling_dy = 0; - } - if(image->icc_profile_buf) - { - cp->meth = 2; - free(image->icc_profile_buf); image->icc_profile_buf = NULL; - } - else cp->meth = 1; - - success = 1; -fin: - if(dinfo) - opj_destroy_decompress(dinfo); - - if(image) - opj_image_destroy(image); - - return success; -} - -/** -sample error callback expecting a FILE* client object -*/ -void error_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** -sample warning callback expecting a FILE* client object -*/ -void warning_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[WARNING] %s", msg); -} -/** -sample debug callback expecting a FILE* client object -*/ -void info_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[INFO] %s", msg); -} - -/* -------------------------------------------------------------------------- */ - - - -static void read_siz_marker(FILE *file, opj_image_t *image) -{ - int len,i; - char buf, buf2[2]; - unsigned char *siz_buffer; - opj_cio_t *cio; - - fseek(file, 0, SEEK_SET); - do { - fread(&buf,1,1, file); - if (buf==(char)0xff) - fread(&buf,1,1, file); - } - while (!(buf==(char)0x51)); - - fread(buf2,2,1,file); /* Lsiz */ - len = ((buf2[0])<<8) + buf2[1]; - - siz_buffer = (unsigned char*) malloc(len * sizeof(unsigned char)); - fread(siz_buffer,len, 1, file); - cio = opj_cio_open(NULL, siz_buffer, len); - - cio_read(cio, 2); /* Rsiz (capabilities) */ - image->x1 = cio_read(cio, 4); /* Xsiz */ - image->y1 = cio_read(cio, 4); /* Ysiz */ - image->x0 = cio_read(cio, 4); /* X0siz */ - image->y0 = cio_read(cio, 4); /* Y0siz */ - cio_skip(cio, 16); /* XTsiz, YTsiz, XT0siz, YT0siz */ - - image->numcomps = cio_read(cio,2); /* Csiz */ - image->comps = - (opj_image_comp_t *) malloc(image->numcomps * sizeof(opj_image_comp_t)); - - for (i = 0; i < image->numcomps; i++) { - int tmp; - tmp = cio_read(cio,1); /* Ssiz_i */ - image->comps[i].prec = (tmp & 0x7f) + 1; - image->comps[i].sgnd = tmp >> 7; - image->comps[i].dx = cio_read(cio,1); /* XRsiz_i */ - image->comps[i].dy = cio_read(cio,1); /* YRsiz_i */ - image->comps[i].resno_decoded = 0; /* number of resolution decoded */ - image->comps[i].factor = 0; /* reducing factor by component */ - } - fseek(file, 0, SEEK_SET); - opj_cio_close(cio); - free(siz_buffer); -} - -static void setparams(opj_mj2_t *movie, opj_image_t *image) { - int i, depth_0, depth, sign; - - movie->tk[0].w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); - movie->tk[0].h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); - mj2_init_stdmovie(movie); - - movie->tk[0].depth = image->comps[0].prec; - - if (image->numcomps==3) { - if ((image->comps[0].dx == 1) - && (image->comps[1].dx == 1) - && (image->comps[2].dx == 1)) - movie->tk[0].CbCr_subsampling_dx = 1; - else - if ((image->comps[0].dx == 1) - && (image->comps[1].dx == 2) - && (image->comps[2].dx == 2)) - movie->tk[0].CbCr_subsampling_dx = 2; - else - fprintf(stderr,"Image component sizes are incoherent\n"); - - if ((image->comps[0].dy == 1) - && (image->comps[1].dy == 1) - && (image->comps[2].dy == 1)) - movie->tk[0].CbCr_subsampling_dy = 1; - else - if ((image->comps[0].dy == 1) - && (image->comps[1].dy == 2) - && (image->comps[2].dy == 2)) - movie->tk[0].CbCr_subsampling_dy = 2; - else - fprintf(stderr,"Image component sizes are incoherent\n"); - } - - movie->tk[0].sample_rate = 25; - - movie->tk[0].jp2_struct.numcomps = image->numcomps; // NC - - /* Init Standard jp2 structure */ - - movie->tk[0].jp2_struct.comps = - (opj_jp2_comps_t *) malloc(movie->tk[0].jp2_struct.numcomps * sizeof(opj_jp2_comps_t)); - movie->tk[0].jp2_struct.precedence = 0; /* PRECEDENCE*/ - movie->tk[0].jp2_struct.approx = 0; /* APPROX*/ - movie->tk[0].jp2_struct.brand = JP2_JP2; /* BR */ - movie->tk[0].jp2_struct.minversion = 0; /* MinV */ - movie->tk[0].jp2_struct.numcl = 1; - movie->tk[0].jp2_struct.cl = (unsigned int *) malloc(movie->tk[0].jp2_struct.numcl * sizeof(int)); - movie->tk[0].jp2_struct.cl[0] = JP2_JP2; /* CL0 : JP2 */ - movie->tk[0].jp2_struct.C = 7; /* C : Always 7*/ - movie->tk[0].jp2_struct.UnkC = 0; /* UnkC, colorspace specified in colr box*/ - movie->tk[0].jp2_struct.IPR = 0; /* IPR, no intellectual property*/ - movie->tk[0].jp2_struct.w = int_ceildiv(image->x1 - image->x0, image->comps[0].dx); - movie->tk[0].jp2_struct.h = int_ceildiv(image->y1 - image->y0, image->comps[0].dy); - - depth_0 = image->comps[0].prec - 1; - sign = image->comps[0].sgnd; - movie->tk[0].jp2_struct.bpc = depth_0 + (sign << 7); - - for (i = 1; i < image->numcomps; i++) { - depth = image->comps[i].prec - 1; - sign = image->comps[i].sgnd; - if (depth_0 != depth) - movie->tk[0].jp2_struct.bpc = 255; - } - - for (i = 0; i < image->numcomps; i++) - movie->tk[0].jp2_struct.comps[i].bpcc = - image->comps[i].prec - 1 + (image->comps[i].sgnd << 7); - - if ((image->numcomps == 1 || image->numcomps == 3) - && (movie->tk[0].jp2_struct.bpc != 255)) - movie->tk[0].jp2_struct.meth = 1; - else - movie->tk[0].jp2_struct.meth = 2; - - if (image->numcomps == 1) - movie->tk[0].jp2_struct.enumcs = 17; // Grayscale - - else - if ((image->comps[0].dx == 1) - && (image->comps[1].dx == 1) - && (image->comps[2].dx == 1) - && (image->comps[0].dy == 1) - && (image->comps[1].dy == 1) - && (image->comps[2].dy == 1)) - movie->tk[0].jp2_struct.enumcs = 16; // RGB - - else - if ((image->comps[0].dx == 1) - && (image->comps[1].dx == 2) - && (image->comps[2].dx == 2) - && (image->comps[0].dy == 1) - && (image->comps[1].dy == 2) - && (image->comps[2].dy == 2)) - movie->tk[0].jp2_struct.enumcs = 18; // YUV - - else - movie->tk[0].jp2_struct.enumcs = 0; // Unkown profile */ -} - -int main(int argc, char *argv[]) { - opj_cinfo_t* cinfo; - opj_event_mgr_t event_mgr; /* event manager */ - unsigned int snum; - opj_mj2_t *movie; - mj2_sample_t *sample; - unsigned char* frame_codestream; - FILE *mj2file, *j2kfile; - char *j2kfilename; - unsigned char *buf; - int offset, mdat_initpos; - opj_image_t img; - opj_cio_t *cio; - mj2_cparameters_t parameters; - - if (argc != 3) { - printf("Usage: %s source_location mj2_filename\n",argv[0]); - printf("Example: %s input/input output.mj2\n",argv[0]); - return 1; - } - - mj2file = fopen(argv[2], "wb"); - - if (!mj2file) { - fprintf(stderr, "failed to open %s for writing\n", argv[2]); - return 1; - } - memset(&img, 0, sizeof(opj_image_t)); - /* - configure the event callbacks (not required) - setting of each callback is optionnal - */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; - - /* get a MJ2 decompressor handle */ - cinfo = mj2_create_compress(); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); - - /* setup the decoder encoding parameters using user parameters */ - memset(¶meters, 0, sizeof(mj2_cparameters_t)); - movie = (opj_mj2_t*) cinfo->mj2_handle; - - j2kfilename = (char*)malloc(strlen(argv[1]) + 12);/* max. '%6d' */ - sprintf(j2kfilename, "%s_00001.j2k",argv[1]); - - if(test_image(j2kfilename, ¶meters) == 0) goto fin; - - parameters.frame_rate = 25; /* DEFAULT */ - - mj2_setup_encoder(movie, ¶meters); - - - /* Writing JP, FTYP and MDAT boxes - Assuming that the JP and FTYP boxes won't be longer than 300 bytes */ - - buf = (unsigned char*) malloc (300 * sizeof(unsigned char)); - cio = opj_cio_open(movie->cinfo, buf, 300); - mj2_write_jp(cio); - mj2_write_ftyp(movie, cio); - mdat_initpos = cio_tell(cio); - cio_skip(cio, 4); - cio_write(cio,MJ2_MDAT, 4); - fwrite(buf,cio_tell(cio),1,mj2file); - free(buf); - - // Insert each j2k codestream in a JP2C box - snum=0; - offset = 0; - while(1) - { - sample = &movie->tk[0].sample[snum]; - sprintf(j2kfilename,"%s_%05d.j2k",argv[1],snum); - j2kfile = fopen(j2kfilename, "rb"); - if (!j2kfile) { - if (snum==0) { // Could not open a single codestream - fprintf(stderr, "failed to open %s for reading\n",j2kfilename); - return 1; - } - else { // Tried to open a inexistant codestream - fprintf(stdout,"%d frames are being added to the MJ2 file\n",snum); - break; - } - } - - // Calculating offset for samples and chunks - offset += cio_tell(cio); - sample->offset = offset; - movie->tk[0].chunk[snum].offset = offset; // There will be one sample per chunk - - // Calculating sample size - fseek(j2kfile,0,SEEK_END); - sample->sample_size = ftell(j2kfile) + 8; // Sample size is codestream + JP2C box header - fseek(j2kfile,0,SEEK_SET); - - // Reading siz marker of j2k image for the first codestream - if (snum==0) - read_siz_marker(j2kfile, &img); - - // Writing JP2C box header - frame_codestream = (unsigned char*) malloc (sample->sample_size+8); - cio = opj_cio_open(movie->cinfo, frame_codestream, sample->sample_size); - cio_write(cio,sample->sample_size, 4); // Sample size - cio_write(cio,JP2_JP2C, 4); // JP2C - - // Writing codestream from J2K file to MJ2 file - fread(frame_codestream+8,sample->sample_size-8,1,j2kfile); - fwrite(frame_codestream,sample->sample_size,1,mj2file); - cio_skip(cio, sample->sample_size-8); - - // Ending loop - fclose(j2kfile); - snum++; - mj2_sample_t * new_sample = (mj2_sample_t*) - realloc(movie->tk[0].sample, (snum+1) * sizeof(mj2_sample_t)); - mj2_chunk_t * new_chunk = (mj2_chunk_t*) - realloc(movie->tk[0].chunk, (snum+1) * sizeof(mj2_chunk_t)); - if (new_sample && new_chunk) { - movie->tk[0].sample = new_sample; - movie->tk[0].chunk = new_chunk; - } else { - fprintf(stderr, "Failed to allocate enough memory to read %s\n", j2kfilename); - return 1; - } - free(frame_codestream); - } - - // Writing the MDAT box length in header - offset += cio_tell(cio); - buf = (unsigned char*) malloc (4 * sizeof(unsigned char)); - cio = opj_cio_open(movie->cinfo, buf, 4); - cio_write(cio,offset-mdat_initpos,4); - fseek(mj2file,(long)mdat_initpos,SEEK_SET); - fwrite(buf,4,1,mj2file); - fseek(mj2file,0,SEEK_END); - free(buf); - - // Setting movie parameters - movie->tk[0].num_samples=snum; - movie->tk[0].num_chunks=snum; - setparams(movie, &img); - - // Writing MOOV box - buf = (unsigned char*) malloc ((TEMP_BUF+snum*20) * sizeof(unsigned char)); - cio = opj_cio_open(movie->cinfo, buf, (TEMP_BUF+snum*20)); - mj2_write_moov(movie, cio); - fwrite(buf,cio_tell(cio),1,mj2file); - - // Ending program - free(img.comps); - opj_cio_close(cio); - -fin: - fclose(mj2file); - mj2_destroy_compress(movie); - free(j2kfilename); - - return 0; -} diff --git a/src/lib/openmj2/CMakeLists.txt b/src/lib/openmj2/CMakeLists.txt index b3ba90bd..59e2143b 100644 --- a/src/lib/openmj2/CMakeLists.txt +++ b/src/lib/openmj2/CMakeLists.txt @@ -1,6 +1,7 @@ set(OPENMJ2_LIBRARY_NAME openmj2) set(OPENMJ2_SRCS mj2.c + mj2_convert.c ) # Build the library diff --git a/src/lib/openmj2/mj2_convert.c b/src/lib/openmj2/mj2_convert.c new file mode 100644 index 00000000..ed823f8b --- /dev/null +++ b/src/lib/openmj2/mj2_convert.c @@ -0,0 +1,372 @@ +/* +* Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium +* Copyright (c) 2002-2007, Professor Benoit Macq +* Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "opj_includes.h" +#include "mj2.h" + +/* ----------------------- */ +/* */ +/* */ +/* Count the number of frames */ +/* in a YUV file */ +/* */ +/* ----------------------- */ + +unsigned int yuv_num_frames(mj2_tk_t * tk, char *infile) +{ + unsigned int prec_size; + long end_of_f, frame_size; + FILE *f; + + f = fopen(infile,"rb"); + if (!f) { + fprintf(stderr, "failed to open %s for reading\n",infile); + return 0; + } + prec_size = (tk->depth + 7)/8;/* bytes of precision */ + + frame_size = (long) (tk->w * tk->h * (1.0 + (double) 2 / (double) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy))); /* Calculate frame size */ + frame_size *= prec_size; + + fseek(f, 0, SEEK_END); + end_of_f = ftell(f); /* Calculate file size */ + + if (end_of_f < frame_size) { + fprintf(stderr, + "YUV does not contains any frame of %d x %d size\n", tk->w, + tk->h); + return 0; + } + fclose(f); + + return (unsigned int)(end_of_f / frame_size); +} + +/* ----------------------- */ +/* */ +/* */ +/* YUV to IMAGE */ +/* */ +/* ----------------------- */ + +opj_image_t *mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters) +{ + opj_image_cmptparm_t cmptparm[3]; + opj_image_t * img; + int i; + int numcomps = 3; + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; + + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) { + cmptparm[i].prec = tk->depth; + cmptparm[i].bpp = tk->depth; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = i ? subsampling_dx * tk->CbCr_subsampling_dx : subsampling_dx; + cmptparm[i].dy = i ? subsampling_dy * tk->CbCr_subsampling_dy : subsampling_dy; + cmptparm[i].w = tk->w; + cmptparm[i].h = tk->h; + } + /* create the image */ + img = opj_image_create(numcomps, cmptparm, CLRSPC_SRGB); + return img; +} + +char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters_t *parameters, char* infile) +{ + int i, compno; + int offset, size, max, prec_bytes, is_16, v; + long end_of_f, position; + int numcomps = 3; + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; + FILE *yuvfile; + int *data; + unsigned char uc; + + yuvfile = fopen(infile,"rb"); + if (!yuvfile) { + fprintf(stderr, "failed to open %s for readings\n",parameters->infile); + return 1; + } + is_16 = (tk->depth > 8); + prec_bytes = (is_16?2:1); + + offset = (int) ((double) (frame_num * tk->w * tk->h) * (1.0 + + 1.0 * (double) 2 / (double) (tk->CbCr_subsampling_dx * tk->CbCr_subsampling_dy))); + offset *= prec_bytes; + + fseek(yuvfile, 0, SEEK_END); + end_of_f = ftell(yuvfile); + fseek(yuvfile, sizeof(unsigned char) * offset, SEEK_SET); + position = ftell(yuvfile); + if (position >= end_of_f) { + fprintf(stderr, "Cannot reach frame number %d in yuv file !!\n", + frame_num); + fclose(yuvfile); + return 1; + } + + img->x0 = tk->Dim[0]; + img->y0 = tk->Dim[1]; + img->x1 = !tk->Dim[0] ? (tk->w - 1) * subsampling_dx + 1 : tk->Dim[0] + + (tk->w - 1) * subsampling_dx + 1; + img->y1 = !tk->Dim[1] ? (tk->h - 1) * subsampling_dy + 1 : tk->Dim[1] + + (tk->h - 1) * subsampling_dy + 1; + + size = tk->w * tk->h * prec_bytes; + + for(compno = 0; compno < numcomps; compno++) + { + max = size/(img->comps[compno].dx * img->comps[compno].dy); + data = img->comps[compno].data; + + for (i = 0; i < max && !feof(yuvfile); i++) + { + v = 0; + fread(&uc, 1, 1, yuvfile); + v = uc; + + if(is_16) + { + fread(&uc, 1, 1, yuvfile); + v |= (uc<<8); + } + *data++ = v; + } + } + fclose(yuvfile); + + return 0; +} + + + +/* ----------------------- */ +/* */ +/* */ +/* IMAGE to YUV */ +/* */ +/* ----------------------- */ + + +opj_bool imagetoyuv(opj_image_t * img, char *outfile) +{ + FILE *f; + int *data; + int i, v, is_16, prec_bytes; + unsigned char buf[2]; + + if (img->numcomps == 3) { + if (img->comps[0].dx != img->comps[1].dx / 2 + || img->comps[1].dx != img->comps[2].dx) { + fprintf(stderr, + "Error with the input image components size: cannot create yuv file)\n"); + return OPJ_FALSE; + } + } else if (!(img->numcomps == 1)) { + fprintf(stderr, + "Error with the number of image components(must be one or three)\n"); + return OPJ_FALSE; + } + + f = fopen(outfile, "a+b"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", outfile); + return OPJ_FALSE; + } + is_16 = (img->comps[0].prec > 8); + prec_bytes = (is_16?2:1); + data = img->comps[0].data; + + for (i = 0; i < (img->comps[0].w * img->comps[0].h); i++) { + v = *data++; + buf[0] = (unsigned char)v; + + if(is_16) buf[1] = (unsigned char)(v>>8); + + fwrite(buf, 1, prec_bytes, f); + } + + + if (img->numcomps == 3) { + data = img->comps[1].data; + + for (i = 0; i < (img->comps[1].w * img->comps[1].h); i++) { + v = *data++; + buf[0] = (unsigned char)v; + + if(is_16) buf[1] = (unsigned char)(v>>8); + + fwrite(buf, 1, prec_bytes, f); + } + data = img->comps[2].data; + + for (i = 0; i < (img->comps[2].w * img->comps[2].h); i++) { + v = *data++; + buf[0] = (unsigned char)v; + + if(is_16) buf[1] = (unsigned char)(v>>8); + + fwrite(buf, 1, prec_bytes, f); + } + } else if (img->numcomps == 1) { +/* fake CbCr values */ + if(is_16) + { + buf[0] = 255; + if(img->comps[0].prec == 10) buf[1] = 1; + else + if(img->comps[0].prec == 12) buf[1] = 3; + else + buf[1] = 125; + } + else buf[0] = 125; + + for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) { + fwrite(buf, 1, prec_bytes, f); + } + + + for (i = 0; i < (img->comps[0].w * img->comps[0].h * 0.25); i++) { + fwrite(buf, 1, prec_bytes, f); + } + } + fclose(f); + return OPJ_TRUE; +} + +/* ----------------------- */ +/* */ +/* */ +/* IMAGE to BMP */ +/* */ +/* ----------------------- */ + +int imagetobmp(opj_image_t * img, char *outfile) { + int w,wr,h,hr,i,pad; + FILE *f; + + if (img->numcomps == 3 && img->comps[0].dx == img->comps[1].dx + && img->comps[1].dx == img->comps[2].dx + && img->comps[0].dy == img->comps[1].dy + && img->comps[1].dy == img->comps[2].dy + && img->comps[0].prec == img->comps[1].prec + && img->comps[1].prec == img->comps[2].prec) { + /* -->> -->> -->> -->> + + 24 bits color + + <<-- <<-- <<-- <<-- */ + + f = fopen(outfile, "wb"); + if (!f) { + fprintf(stderr, "failed to open %s for writing\n", outfile); + return 1; + } + + w = img->comps[0].w; + wr = int_ceildivpow2(img->comps[0].w, img->comps[0].factor); + + h = img->comps[0].h; + hr = int_ceildivpow2(img->comps[0].h, img->comps[0].factor); + + fprintf(f, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", + (unsigned char) (hr * wr * 3 + 3 * hr * (wr % 2) + + 54) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 8) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 16) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2) + 54) + >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff, + ((54) >> 16) & 0xff, ((54) >> 24) & 0xff); + + /* INFO HEADER */ + /* ------------- */ + fprintf(f, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, + ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((wr) & 0xff), + (unsigned char) ((wr) >> 8) & 0xff, + (unsigned char) ((wr) >> 16) & 0xff, + (unsigned char) ((wr) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (unsigned char) ((hr) & 0xff), + (unsigned char) ((hr) >> 8) & 0xff, + (unsigned char) ((hr) >> 16) & 0xff, + (unsigned char) ((hr) >> 24) & 0xff); + fprintf(f, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(f, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", + (unsigned char) (3 * hr * wr + + 3 * hr * (wr % 2)) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 8) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 16) & 0xff, + (unsigned char) ((hr * wr * 3 + 3 * hr * (wr % 2)) >> + 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, + ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(f, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, + ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + + for (i = 0; i < wr * hr; i++) { + unsigned char R, G, B; + /* a modifier */ + /* R = img->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/ + R = img->comps[0].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + /* G = img->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/ + G = img->comps[1].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + /* B = img->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)];*/ + B = img->comps[2].data[w * hr - ((i) / (wr) + 1) * w + (i) % (wr)]; + fprintf(f, "%c%c%c", B, G, R); + + if ((i + 1) % wr == 0) { + for (pad = (3 * wr) % 4 ? 4 - (3 * wr) % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(f, "%c", 0); + } + } + fclose(f); + } + return 0; +} diff --git a/src/lib/openmj2/mj2_convert.h b/src/lib/openmj2/mj2_convert.h new file mode 100644 index 00000000..736ef80c --- /dev/null +++ b/src/lib/openmj2/mj2_convert.h @@ -0,0 +1,45 @@ +/* +* Copyright (c) 2003-2004, Francois-Olivier Devaux +* Copyright (c) 2002-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium +* All rights reserved. +* +* Redistribution and use in source and binary forms, with or without +* modification, are permitted provided that the following conditions +* are met: +* 1. Redistributions of source code must retain the above copyright +* notice, this list of conditions and the following disclaimer. +* 2. Redistributions in binary form must reproduce the above copyright +* notice, this list of conditions and the following disclaimer in the +* documentation and/or other materials provided with the distribution. +* +* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' +* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +* POSSIBILITY OF SUCH DAMAGE. +*/ + + +#include "mj2.h" + +#ifndef __MJ2_CONVERT_H +#define __MJ2_CONVERT_H + +int imagetoyuv(opj_image_t * img, char *outfile); + +int imagetobmp(opj_image_t * img, char *outfile); + +opj_image_t *mj2_image_create(mj2_tk_t * tk, opj_cparameters_t *parameters); + +char yuvtoimage(mj2_tk_t * tk, opj_image_t * img, int frame_num, opj_cparameters_t *parameters, char* infile); + +unsigned int yuv_num_frames(mj2_tk_t * tk, char *infile); + + +#endif -- cgit v1.2.3