diff --git a/CMakeLists.txt b/CMakeLists.txt index c689843c..dee84dbc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -30,7 +30,7 @@ include_regular_expression("^.*$") # OPENJPEG version number, useful for packaging and doxygen doc: set(OPENJPEG_VERSION_MAJOR 2) set(OPENJPEG_VERSION_MINOR 0) -set(OPENJPEG_VERSION_BUILD 0) +set(OPENJPEG_VERSION_BUILD 1) set(OPENJPEG_VERSION "${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}") set(PACKAGE_VERSION @@ -47,11 +47,12 @@ set(PACKAGE_VERSION # 1.5 | 5 # 1.5.1 | 5 # 2.0 | 6 +# 2.0.1 | 6 # above is the recommendation by the OPJ team. If you really need to override this default, # you can specify your own OPENJPEG_SOVERSION at cmake configuration time: # cmake -DOPENJPEG_SOVERSION:STRING=42 /path/to/openjpeg if(NOT OPENJPEG_SOVERSION) - SET(OPENJPEG_SOVERSION 6) + SET(OPENJPEG_SOVERSION 7) endif(NOT OPENJPEG_SOVERSION) set(OPENJPEG_LIBRARY_PROPERTIES VERSION "${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}" @@ -181,14 +182,28 @@ endif() #----------------------------------------------------------------------------- # opj_config.h generation (1/2) + +# Check if some include files are provided by the system +include(EnsureFileInclude) +# These files are mandatory +ensure_file_include("string.h" HAVE_STRING_H YES) +ensure_file_include("memory.h" HAVE_MEMORY_H YES) +ensure_file_include("stdlib.h" HAVE_STDLIB_H YES) +ensure_file_include("stdio.h" HAVE_STDIO_H YES) +ensure_file_include("math.h" HAVE_MATH_H YES) +ensure_file_include("float.h" HAVE_FLOAT_H YES) +ensure_file_include("time.h" HAVE_TIME_H YES) +ensure_file_include("stdarg.h" HAVE_STDARG_H YES) +ensure_file_include("ctype.h" HAVE_CTYPE_H YES) +ensure_file_include("assert.h" HAVE_ASSERT_H YES) + +# For the following files, we provide an alternative, they are not mandatory +ensure_file_include("stdint.h" OPJ_HAVE_STDINT_H NO) +ensure_file_include("inttypes.h" OPJ_HAVE_INTTYPES_H NO) + +# why check this one ? for openjpip ? include (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) CHECK_INCLUDE_FILE("strings.h" HAVE_STRINGS_H) -CHECK_INCLUDE_FILE("inttypes.h" HAVE_INTTYPES_H) -CHECK_INCLUDE_FILE("memory.h" HAVE_MEMORY_H) -CHECK_INCLUDE_FILE("stdint.h" HAVE_STDINT_H) -CHECK_INCLUDE_FILE("stdlib.h" HAVE_STDLIB_H) -CHECK_INCLUDE_FILE("stdio.h" HAVE_STDIO_H) -CHECK_INCLUDE_FILE("string.h" HAVE_STRING_H) CHECK_INCLUDE_FILE("sys/stat.h" HAVE_SYS_STAT_H) CHECK_INCLUDE_FILE("sys/types.h" HAVE_SYS_TYPES_H) CHECK_INCLUDE_FILE("unistd.h" HAVE_UNISTD_H) @@ -199,7 +214,15 @@ OPJ_TEST_LARGE_FILES(OPJ_HAVE_LARGEFILES) #----------------------------------------------------------------------------- # Build Library -add_subdirectory(src) +if(BUILD_JPIP_SERVER) + find_package(CURL REQUIRED) + find_package(FCGI REQUIRED) + find_package(Threads REQUIRED) + if(NOT CMAKE_USE_PTHREADS_INIT) + message(FATAL_ERROR "Only pthread are supported") + endif() +endif() +add_subdirectory(src/lib) #----------------------------------------------------------------------------- # Build Applications @@ -233,6 +256,12 @@ configure_file( ${CMAKE_CURRENT_BINARY_DIR}/src/lib/openjp2/opj_config.h @ONLY ) + + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/src/lib/openjp2/opj_config_private.h.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/src/lib/openjp2/opj_config_private.h + @ONLY + ) #----------------------------------------------------------------------------- # Build DOCUMENTATION (not in ALL target and only if Doxygen is found) @@ -253,9 +282,8 @@ if(BUILD_TESTING) # They could be found via svn on the OpenJPEG google code project # svn checkout http://openjpeg.googlecode.com/svn/data (about 70 Mo) find_path(OPJ_DATA_ROOT README-OPJ-Data - PATHS - $ENV{OPJ_DATA_ROOT} - ${CMAKE_SOURCE_DIR}/../data + PATHS $ENV{OPJ_DATA_ROOT} ${CMAKE_SOURCE_DIR}/../../data + NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH ) # Add repository where to find tests @@ -319,4 +347,5 @@ if(UNIX) ${OPENJPEG_INSTALL_LIB_DIR}/pkgconfig ) endif() endif() + #----------------------------------------------------------------------------- diff --git a/cmake/CTestCustom.cmake.in b/cmake/CTestCustom.cmake.in index cdde4a7e..a8cb57ae 100644 --- a/cmake/CTestCustom.cmake.in +++ b/cmake/CTestCustom.cmake.in @@ -27,6 +27,9 @@ set(CTEST_CUSTOM_WARNING_EXCEPTION # Suppress warning caused by intentional messages about deprecation ".*warning,.* is deprecated" + # java also warns about deprecated API + ".*java.*deprecation" + ".*deprecation.*" # supress warnings caused by 3rd party libs: ".*thirdparty.*" "libtiff.*has no symbols" diff --git a/cmake/EnsureFileInclude.cmake b/cmake/EnsureFileInclude.cmake new file mode 100644 index 00000000..e173ea1a --- /dev/null +++ b/cmake/EnsureFileInclude.cmake @@ -0,0 +1,26 @@ +# Ensure that an include file is provided by the system +# Add the check about the mandatory status to the check_include_file macro +# provided by cmake + +include (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) + +macro(ensure_file_include INCLUDE_FILENAME VARIABLE_NAME MANDATORY_STATUS) + +#message(WARNING "INCLUDE_FILENAME=${INCLUDE_FILENAME} \n" +# "VARIABLE_NAME=${VARIABLE_NAME} \n" +# "MANDATORY_STATUS=${MANDATORY_STATUS}") + +CHECK_INCLUDE_FILE(${INCLUDE_FILENAME} ${VARIABLE_NAME}) + +#message(WARNING "INCLUDE_FILENAME=${INCLUDE_FILENAME} \n" +# "VARIABLE_NAME=${VARIABLE_NAME} \n" +# "VARIABLE_NAME_VALUE=${${VARIABLE_NAME}} \n" +# "MANDATORY_STATUS=${MANDATORY_STATUS}") + +if (NOT ${${VARIABLE_NAME}}) + if (${MANDATORY_STATUS}) + message(FATAL_ERROR "The file ${INCLUDE_FILENAME} is mandatory but not found on your system") + endif() +endif() + +endmacro() \ No newline at end of file diff --git a/cmake/FindKAKADU.cmake b/cmake/FindKAKADU.cmake index 3e0409df..0564a0e6 100644 --- a/cmake/FindKAKADU.cmake +++ b/cmake/FindKAKADU.cmake @@ -1,9 +1,9 @@ # -# this module looks for KAKADu +# this module looks for KAKADU # http://www.kakadusoftware.com/ # # -# Copyright (c) 2006-2011 Mathieu Malaterre +# Copyright (c) 2006-2014 Mathieu Malaterre # # Redistribution and use is allowed according to the terms of the New # BSD license. @@ -14,6 +14,11 @@ find_program(KDU_EXPAND_EXECUTABLE kdu_expand ) +find_program(KDU_COMPRESS_EXECUTABLE + kdu_compress + ) + mark_as_advanced( KDU_EXPAND_EXECUTABLE + KDU_COMPRESS_EXECUTABLE ) diff --git a/cmake/TestLargeFiles.cmake b/cmake/TestLargeFiles.cmake index ffef84f5..7960e52c 100644 --- a/cmake/TestLargeFiles.cmake +++ b/cmake/TestLargeFiles.cmake @@ -7,7 +7,7 @@ # _LARGE_FILES # _LARGEFILE_SOURCE # _FILE_OFFSET_BITS 64 -# HAVE_FSEEKO +# OPJ_HAVE_FSEEKO # # However, it is YOUR job to make sure these defines are set in a #cmakedefine so they # end up in a config.h file that is included in your source if necessary! @@ -113,10 +113,10 @@ macro(OPJ_TEST_LARGE_FILES VARIABLE) endif() if(FSEEKO_COMPILE_OK) - set(HAVE_FSEEKO ON CACHE INTERNAL "Result of test for fseeko/ftello") + set(OPJ_HAVE_FSEEKO ON CACHE INTERNAL "Result of test for fseeko/ftello") else() message(STATUS "Checking for fseeko/ftello - not found") - set(HAVE_FSEEKO OFF CACHE INTERNAL "Result of test for fseeko/ftello") + set(OPJ_HAVE_FSEEKO OFF CACHE INTERNAL "Result of test for fseeko/ftello") endif() if(FILE64_OK AND FSEEKO_COMPILE_OK) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 673843ec..87526cfc 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,12 +1,12 @@ # required dep for server: -if(BUILD_JPIP_SERVER) - find_package(CURL REQUIRED) - find_package(FCGI REQUIRED) - find_package(Threads REQUIRED) - if(NOT CMAKE_USE_PTHREADS_INIT) - message(FATAL_ERROR "Only pthread are supported") - endif() -endif() +#if(BUILD_JPIP_SERVER) +# find_package(CURL REQUIRED) +# find_package(FCGI REQUIRED) +# find_package(Threads REQUIRED) +# if(NOT CMAKE_USE_PTHREADS_INIT) +# message(FATAL_ERROR "Only pthread are supported") +# endif() +#endif() -add_subdirectory(lib) +#add_subdirectory(lib) #add_subdirectory(bin) diff --git a/src/bin/common/CMakeLists.txt b/src/bin/common/CMakeLists.txt index e69de29b..bb07ba7c 100644 --- a/src/bin/common/CMakeLists.txt +++ b/src/bin/common/CMakeLists.txt @@ -0,0 +1,7 @@ +#----------------------------------------------------------------------------- +# opj_apps_config.h generation +configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/opj_apps_config.h.cmake.in + ${CMAKE_CURRENT_BINARY_DIR}/opj_apps_config.h + @ONLY + ) \ No newline at end of file diff --git a/src/bin/common/color.c b/src/bin/common/color.c index a71b7410..47eefa0b 100644 --- a/src/bin/common/color.c +++ b/src/bin/common/color.c @@ -33,15 +33,16 @@ #include #include #include +#include -#include "opj_config.h" +#include "opj_apps_config.h" #include "openjpeg.h" #include "color.h" -#ifdef HAVE_LIBLCMS2 +#ifdef OPJ_HAVE_LIBLCMS2 #include #endif -#ifdef HAVE_LIBLCMS1 +#ifdef OPJ_HAVE_LIBLCMS1 #include #endif @@ -86,19 +87,19 @@ static void sycc444_to_rgb(opj_image_t *img) const int *y, *cb, *cr; int maxw, maxh, max, i, offset, upb; - i = img->comps[0].prec; + i = (int)img->comps[0].prec; offset = 1<<(i - 1); upb = (1<comps[0].w; maxh = img->comps[0].h; + maxw = (int)img->comps[0].w; maxh = (int)img->comps[0].h; max = maxw * maxh; y = img->comps[0].data; cb = img->comps[1].data; cr = img->comps[2].data; - d0 = r = (int*)malloc(sizeof(int) * max); - d1 = g = (int*)malloc(sizeof(int) * max); - d2 = b = (int*)malloc(sizeof(int) * max); + d0 = r = (int*)malloc(sizeof(int) * (size_t)max); + d1 = g = (int*)malloc(sizeof(int) * (size_t)max); + d2 = b = (int*)malloc(sizeof(int) * (size_t)max); for(i = 0; i < max; ++i) { @@ -119,19 +120,19 @@ static void sycc422_to_rgb(opj_image_t *img) int maxw, maxh, max, offset, upb; int i, j; - i = img->comps[0].prec; + i = (int)img->comps[0].prec; offset = 1<<(i - 1); upb = (1<comps[0].w; maxh = img->comps[0].h; + maxw = (int)img->comps[0].w; maxh = (int)img->comps[0].h; max = maxw * maxh; y = img->comps[0].data; cb = img->comps[1].data; cr = img->comps[2].data; - d0 = r = (int*)malloc(sizeof(int) * max); - d1 = g = (int*)malloc(sizeof(int) * max); - d2 = b = (int*)malloc(sizeof(int) * max); + d0 = r = (int*)malloc(sizeof(int) * (size_t)max); + d1 = g = (int*)malloc(sizeof(int) * (size_t)max); + d2 = b = (int*)malloc(sizeof(int) * (size_t)max); for(i=0; i < maxh; ++i) { @@ -150,8 +151,13 @@ static void sycc422_to_rgb(opj_image_t *img) free(img->comps[1].data); img->comps[1].data = d1; free(img->comps[2].data); img->comps[2].data = d2; +#if defined(USE_JPWL) || defined(USE_MJ2) img->comps[1].w = maxw; img->comps[1].h = maxh; img->comps[2].w = maxw; img->comps[2].h = maxh; +#else + img->comps[1].w = (OPJ_UINT32)maxw; img->comps[1].h = (OPJ_UINT32)maxh; + img->comps[2].w = (OPJ_UINT32)maxw; img->comps[2].h = (OPJ_UINT32)maxh; +#endif img->comps[1].dx = img->comps[0].dx; img->comps[2].dx = img->comps[0].dx; img->comps[1].dy = img->comps[0].dy; @@ -166,19 +172,19 @@ static void sycc420_to_rgb(opj_image_t *img) int maxw, maxh, max, offset, upb; int i, j; - i = img->comps[0].prec; + i = (int)img->comps[0].prec; offset = 1<<(i - 1); upb = (1<comps[0].w; maxh = img->comps[0].h; + maxw = (int)img->comps[0].w; maxh = (int)img->comps[0].h; max = maxw * maxh; y = img->comps[0].data; cb = img->comps[1].data; cr = img->comps[2].data; - d0 = r = (int*)malloc(sizeof(int) * max); - d1 = g = (int*)malloc(sizeof(int) * max); - d2 = b = (int*)malloc(sizeof(int) * max); + d0 = r = (int*)malloc(sizeof(int) * (size_t)max); + d1 = g = (int*)malloc(sizeof(int) * (size_t)max); + d2 = b = (int*)malloc(sizeof(int) * (size_t)max); for(i=0; i < maxh; i += 2) { @@ -209,8 +215,13 @@ static void sycc420_to_rgb(opj_image_t *img) free(img->comps[1].data); img->comps[1].data = d1; free(img->comps[2].data); img->comps[2].data = d2; +#if defined(USE_JPWL) || defined(USE_MJ2) img->comps[1].w = maxw; img->comps[1].h = maxh; img->comps[2].w = maxw; img->comps[2].h = maxh; +#else + img->comps[1].w = (OPJ_UINT32)maxw; img->comps[1].h = (OPJ_UINT32)maxh; + img->comps[2].w = (OPJ_UINT32)maxw; img->comps[2].h = (OPJ_UINT32)maxh; +#endif img->comps[1].dx = img->comps[0].dx; img->comps[2].dx = img->comps[0].dx; img->comps[1].dy = img->comps[0].dy; @@ -265,8 +276,8 @@ void color_sycc_to_rgb(opj_image_t *img) }/* color_sycc_to_rgb() */ -#if defined(HAVE_LIBLCMS2) || defined(HAVE_LIBLCMS1) -#ifdef HAVE_LIBLCMS1 +#if defined(OPJ_HAVE_LIBLCMS2) || defined(OPJ_HAVE_LIBLCMS1) +#ifdef OPJ_HAVE_LIBLCMS1 /* Bob Friesenhahn proposed:*/ #define cmsSigXYZData icSigXYZData #define cmsSigLabData icSigLabData @@ -280,8 +291,9 @@ void color_sycc_to_rgb(opj_image_t *img) #define cmsColorSpaceSignature icColorSpaceSignature #define cmsGetHeaderRenderingIntent cmsTakeRenderingIntent -#endif /* HAVE_LIBLCMS1 */ +#endif /* OPJ_HAVE_LIBLCMS1 */ +/*#define DEBUG_PROFILE*/ void color_apply_icc_profile(opj_image_t *image) { cmsHPROFILE in_prof, out_prof; @@ -294,6 +306,11 @@ void color_apply_icc_profile(opj_image_t *image) in_prof = cmsOpenProfileFromMem(image->icc_profile_buf, image->icc_profile_len); +#ifdef DEBUG_PROFILE + FILE *icm = fopen("debug.icm","wb"); + fwrite( image->icc_profile_buf,1, image->icc_profile_len,icm); + fclose(icm); +#endif if(in_prof == NULL) return; @@ -302,14 +319,23 @@ void color_apply_icc_profile(opj_image_t *image) intent = cmsGetHeaderRenderingIntent(in_prof); - max_w = image->comps[0].w; max_h = image->comps[0].h; - prec = image->comps[0].prec; + max_w = (int)image->comps[0].w; + max_h = (int)image->comps[0].h; + prec = (int)image->comps[0].prec; oldspace = image->color_space; if(out_space == cmsSigRgbData) /* enumCS 16 */ { + if( prec <= 8 ) +{ + in_type = TYPE_RGB_8; + out_type = TYPE_RGB_8; +} +else +{ in_type = TYPE_RGB_16; out_type = TYPE_RGB_16; +} out_prof = cmsCreate_sRGBProfile(); image->color_space = OPJ_CLRSPC_SRGB; } @@ -360,12 +386,15 @@ out_space, in_type,out_type ); +#else + (void)prec; + (void)in_space; #endif /* DEBUG_PROFILE */ transform = cmsCreateTransform(in_prof, in_type, out_prof, out_type, intent, 0); -#ifdef HAVE_LIBLCMS2 +#ifdef OPJ_HAVE_LIBLCMS2 /* Possible for: LCMS_VERSION >= 2000 :*/ cmsCloseProfile(in_prof); cmsCloseProfile(out_prof); @@ -378,7 +407,7 @@ fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. " "ICC Profile ignored.\n",__FILE__,__LINE__); #endif image->color_space = oldspace; -#ifdef HAVE_LIBLCMS1 +#ifdef OPJ_HAVE_LIBLCMS1 cmsCloseProfile(in_prof); cmsCloseProfile(out_prof); #endif @@ -387,8 +416,44 @@ fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. " if(image->numcomps > 2)/* RGB, RGBA */ { + if( prec <= 8 ) +{ + unsigned char *inbuf, *outbuf, *in, *out; + max = max_w * max_h; + nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned char); + in = inbuf = (unsigned char*)malloc(nr_samples); + out = outbuf = (unsigned char*)malloc(nr_samples); + + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + + for(i = 0; i < max; ++i) + { + *in++ = (unsigned char)*r++; + *in++ = (unsigned char)*g++; + *in++ = (unsigned char)*b++; + } + + cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); + + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + + for(i = 0; i < max; ++i) + { + *r++ = (int)*out++; + *g++ = (int)*out++; + *b++ = (int)*out++; + } + free(inbuf); free(outbuf); +} +else +{ unsigned short *inbuf, *outbuf, *in, *out; - max = max_w * max_h; nr_samples = max * 3 * sizeof(unsigned short); + max = max_w * max_h; + nr_samples = (cmsUInt32Number)max * 3 * (cmsUInt32Number)sizeof(unsigned short); in = inbuf = (unsigned short*)malloc(nr_samples); out = outbuf = (unsigned short*)malloc(nr_samples); @@ -403,7 +468,7 @@ fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. " *in++ = (unsigned short)*b++; } - cmsDoTransform(transform, inbuf, outbuf, max); + cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); r = image->comps[0].data; g = image->comps[1].data; @@ -416,12 +481,13 @@ fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. " *b++ = (int)*out++; } free(inbuf); free(outbuf); +} } else /* GRAY, GRAYA */ { unsigned char *in, *inbuf, *out, *outbuf; - - max = max_w * max_h; nr_samples = max * 3 * sizeof(unsigned char); + max = max_w * max_h; + nr_samples = (cmsUInt32Number)max * 3 * sizeof(unsigned char); in = inbuf = (unsigned char*)malloc(nr_samples); out = outbuf = (unsigned char*)malloc(nr_samples); @@ -434,8 +500,8 @@ fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. " image->comps[1] = image->comps[0]; image->comps[2] = image->comps[0]; - image->comps[1].data = (int*)calloc(max, sizeof(int)); - image->comps[2].data = (int*)calloc(max, sizeof(int)); + image->comps[1].data = (int*)calloc((size_t)max, sizeof(int)); + image->comps[2].data = (int*)calloc((size_t)max, sizeof(int)); image->numcomps += 2; @@ -445,7 +511,7 @@ fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. " { *in++ = (unsigned char)*r++; } - cmsDoTransform(transform, inbuf, outbuf, max); + cmsDoTransform(transform, inbuf, outbuf, (cmsUInt32Number)max); r = image->comps[0].data; g = image->comps[1].data; @@ -461,11 +527,11 @@ fprintf(stderr,"%s:%d:color_apply_icc_profile\n\tcmsCreateTransform failed. " cmsDeleteTransform(transform); -#ifdef HAVE_LIBLCMS1 +#ifdef OPJ_HAVE_LIBLCMS1 cmsCloseProfile(in_prof); cmsCloseProfile(out_prof); #endif }/* color_apply_icc_profile() */ -#endif /* HAVE_LIBLCMS2 || HAVE_LIBLCMS1 */ +#endif /* OPJ_HAVE_LIBLCMS2 || OPJ_HAVE_LIBLCMS1 */ diff --git a/src/bin/common/format_defs.h b/src/bin/common/format_defs.h index e82986cc..386f21dc 100644 --- a/src/bin/common/format_defs.h +++ b/src/bin/common/format_defs.h @@ -41,9 +41,9 @@ #define BMP_DFMT 12 #define YUV_DFMT 13 #define TIF_DFMT 14 -#define RAW_DFMT 15 +#define RAW_DFMT 15 /* MSB / Big Endian */ #define TGA_DFMT 16 #define PNG_DFMT 17 -#define RAWL_DFMT 18 +#define RAWL_DFMT 18 /* LSB / Little Endian */ #endif /* _OPJ_FORMAT_DEFS_H_ */ diff --git a/src/bin/common/opj_apps_config.h.cmake.in b/src/bin/common/opj_apps_config.h.cmake.in new file mode 100644 index 00000000..4ea1efa3 --- /dev/null +++ b/src/bin/common/opj_apps_config.h.cmake.in @@ -0,0 +1,13 @@ +/* create opj_apps_config.h for CMake */ + +#cmakedefine OPJ_HAVE_LIBPNG @HAVE_LIBPNG@ +#cmakedefine OPJ_HAVE_PNG_H @HAVE_PNG_H@ +#cmakedefine OPJ_HAVE_LIBTIFF @HAVE_LIBTIFF@ +#cmakedefine OPJ_HAVE_TIFF_H @HAVE_TIFF_H@ + +#cmakedefine OPJ_HAVE_LIBLCMS1 +#cmakedefine OPJ_HAVE_LIBLCMS2 +#cmakedefine OPJ_HAVE_LCMS1_H +#cmakedefine OPJ_HAVE_LCMS2_H + + diff --git a/src/bin/common/opj_getopt.c b/src/bin/common/opj_getopt.c index 252d8359..6fcead46 100644 --- a/src/bin/common/opj_getopt.c +++ b/src/bin/common/opj_getopt.c @@ -10,11 +10,7 @@ * 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. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors + * 3. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * diff --git a/src/bin/jp2/CMakeLists.txt b/src/bin/jp2/CMakeLists.txt index aee330a5..43746317 100644 --- a/src/bin/jp2/CMakeLists.txt +++ b/src/bin/jp2/CMakeLists.txt @@ -11,6 +11,7 @@ set(common_SRCS # Headers file are located here: include_directories( ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h + ${OPENJPEG_BINARY_DIR}/src/bin/common # opj_apps_config.h ${OPENJPEG_SOURCE_DIR}/src/lib/openjp2 ${OPENJPEG_SOURCE_DIR}/src/bin/common ${LCMS_INCLUDE_DIRNAME} diff --git a/src/bin/jp2/convert.c b/src/bin/jp2/convert.c index 98d900ad..d3e9773c 100644 --- a/src/bin/jp2/convert.c +++ b/src/bin/jp2/convert.c @@ -29,21 +29,21 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#include "opj_config.h" +#include "opj_apps_config.h" #include #include #include #include -#ifdef HAVE_LIBTIFF +#ifdef OPJ_HAVE_LIBTIFF #include -#endif /* HAVE_LIBTIFF */ +#endif /* OPJ_HAVE_LIBTIFF */ -#ifdef HAVE_LIBPNG +#ifdef OPJ_HAVE_LIBPNG #include #include -#endif /* HAVE_LIBPNG */ +#endif /* OPJ_HAVE_LIBPNG */ #include "openjpeg.h" #include "convert.h" @@ -54,11 +54,11 @@ * log2(a) */ static int int_floorlog2(int a) { - int l; - for (l = 0; a > 1; l++) { - a >>= 1; - } - return l; + int l; + for (l = 0; a > 1; l++) { + a >>= 1; + } + return l; } /* -->> -->> -->> -->> @@ -94,8 +94,8 @@ struct tga_header static unsigned short get_ushort(unsigned short val) { -#ifdef WORDS_BIGENDIAN - return( ((val & 0xff) << 8) + (val >> 8) ); +#ifdef OPJ_BIG_ENDIAN + return( ((val & 0xff) << 8) + (val >> 8) ); #else return( val ); #endif @@ -105,399 +105,422 @@ static unsigned short get_ushort(unsigned short val) { #define TGA_HEADER_SIZE 18 static int tga_readheader(FILE *fp, unsigned int *bits_per_pixel, - unsigned int *width, unsigned int *height, int *flip_image) + unsigned int *width, unsigned int *height, int *flip_image) { - int palette_size; - unsigned char *tga ; - unsigned char id_len, cmap_type, image_type; - unsigned char pixel_depth, image_desc; - unsigned short cmap_index, cmap_len, cmap_entry_size; - unsigned short x_origin, y_origin, image_w, image_h; + int palette_size; + unsigned char *tga ; + unsigned char id_len, /*cmap_type,*/ image_type; + unsigned char pixel_depth, image_desc; + unsigned short /*cmap_index,*/ cmap_len, cmap_entry_size; + unsigned short /*x_origin, y_origin,*/ image_w, image_h; - if (!bits_per_pixel || !width || !height || !flip_image) - return 0; - tga = (unsigned char*)malloc(18); + if (!bits_per_pixel || !width || !height || !flip_image) + return 0; + tga = (unsigned char*)malloc(18); - if ( fread(tga, TGA_HEADER_SIZE, 1, fp) != 1 ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return 0 ; - } - id_len = (unsigned char)tga[0]; - cmap_type = (unsigned char)tga[1]; - image_type = (unsigned char)tga[2]; - cmap_index = get_ushort(*(unsigned short*)(&tga[3])); - cmap_len = get_ushort(*(unsigned short*)(&tga[5])); - cmap_entry_size = (unsigned char)tga[7]; + if ( fread(tga, TGA_HEADER_SIZE, 1, fp) != 1 ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return 0 ; + } + id_len = (unsigned char)tga[0]; + /*cmap_type = (unsigned char)tga[1];*/ + image_type = (unsigned char)tga[2]; + /*cmap_index = get_ushort(*(unsigned short*)(&tga[3]));*/ + cmap_len = get_ushort(*(unsigned short*)(&tga[5])); + cmap_entry_size = (unsigned char)tga[7]; - x_origin = get_ushort(*(unsigned short*)(&tga[8])); - y_origin = get_ushort(*(unsigned short*)(&tga[10])); - image_w = get_ushort(*(unsigned short*)(&tga[12])); - image_h = get_ushort(*(unsigned short*)(&tga[14])); - pixel_depth = (unsigned char)tga[16]; - image_desc = (unsigned char)tga[17]; +#if 0 + x_origin = get_ushort(*(unsigned short*)(&tga[8])); + y_origin = get_ushort(*(unsigned short*)(&tga[10])); +#endif + image_w = get_ushort(*(unsigned short*)(&tga[12])); + image_h = get_ushort(*(unsigned short*)(&tga[14])); + pixel_depth = (unsigned char)tga[16]; + image_desc = (unsigned char)tga[17]; - free(tga); + free(tga); - *bits_per_pixel = (unsigned int)pixel_depth; - *width = (unsigned int)image_w; - *height = (unsigned int)image_h; + *bits_per_pixel = (unsigned int)pixel_depth; + *width = (unsigned int)image_w; + *height = (unsigned int)image_h; - /* Ignore tga identifier, if present ... */ - if (id_len) - { - unsigned char *id = (unsigned char *) malloc(id_len); - if ( !fread(id, id_len, 1, fp) ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - free(id); - return 0 ; - } - free(id); - } + /* Ignore tga identifier, if present ... */ + if (id_len) + { + unsigned char *id = (unsigned char *) malloc(id_len); + if ( !fread(id, id_len, 1, fp) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + free(id); + return 0 ; + } + free(id); + } - /* Test for compressed formats ... not yet supported ... - // Note :- 9 - RLE encoded palettized. - // 10 - RLE encoded RGB. */ - if (image_type > 8) - { - fprintf(stderr, "Sorry, compressed tga files are not currently supported.\n"); - return 0 ; - } + /* Test for compressed formats ... not yet supported ... + // Note :- 9 - RLE encoded palettized. + // 10 - RLE encoded RGB. */ + if (image_type > 8) + { + fprintf(stderr, "Sorry, compressed tga files are not currently supported.\n"); + return 0 ; + } - *flip_image = !(image_desc & 32); + *flip_image = !(image_desc & 32); - /* Palettized formats are not yet supported, skip over the palette, if present ... */ - palette_size = cmap_len * (cmap_entry_size/8); - - if (palette_size>0) - { - fprintf(stderr, "File contains a palette - not yet supported."); - fseek(fp, palette_size, SEEK_CUR); - } - return 1; + /* Palettized formats are not yet supported, skip over the palette, if present ... */ + palette_size = cmap_len * (cmap_entry_size/8); + + if (palette_size>0) + { + fprintf(stderr, "File contains a palette - not yet supported."); + fseek(fp, palette_size, SEEK_CUR); + } + return 1; } -#if WORDS_BIGENDIAN == 1 +#ifdef OPJ_BIG_ENDIAN -static inline int16_t swap16(int16_t x) +static INLINE int16_t swap16(int16_t x) { - return((((u_int16_t)x & 0x00ffU) << 8) | - (((u_int16_t)x & 0xff00U) >> 8)); + return((((u_int16_t)x & 0x00ffU) << 8) | + (((u_int16_t)x & 0xff00U) >> 8)); } #endif static int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height, - OPJ_BOOL flip_image) + OPJ_BOOL flip_image) { - unsigned short image_w, image_h, us0; - unsigned char uc0, image_type; - unsigned char pixel_depth, image_desc; + unsigned short image_w, image_h, us0; + unsigned char uc0, image_type; + unsigned char pixel_depth, image_desc; - if (!bits_per_pixel || !width || !height) - return 0; + if (!bits_per_pixel || !width || !height) + return 0; - pixel_depth = 0; + pixel_depth = 0; - if ( bits_per_pixel < 256 ) - pixel_depth = (unsigned char)bits_per_pixel; - else{ - fprintf(stderr,"ERROR: Wrong bits per pixel inside tga_header"); - return 0; - } - uc0 = 0; + if ( bits_per_pixel < 256 ) + pixel_depth = (unsigned char)bits_per_pixel; + else{ + fprintf(stderr,"ERROR: Wrong bits per pixel inside tga_header"); + return 0; + } + uc0 = 0; - if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* id_length */ - if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* colour_map_type */ + if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* id_length */ + if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* colour_map_type */ - image_type = 2; /* Uncompressed. */ - if(fwrite(&image_type, 1, 1, fp) != 1) goto fails; + image_type = 2; /* Uncompressed. */ + if(fwrite(&image_type, 1, 1, fp) != 1) goto fails; - us0 = 0; - if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* colour_map_index */ - if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* colour_map_length */ - if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* colour_map_entry_size */ + us0 = 0; + if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* colour_map_index */ + if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* colour_map_length */ + if(fwrite(&uc0, 1, 1, fp) != 1) goto fails; /* colour_map_entry_size */ - if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* x_origin */ - if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* y_origin */ + if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* x_origin */ + if(fwrite(&us0, 2, 1, fp) != 1) goto fails; /* y_origin */ - image_w = (unsigned short)width; - image_h = (unsigned short) height; + image_w = (unsigned short)width; + image_h = (unsigned short) height; -#if WORDS_BIGENDIAN == 0 - if(fwrite(&image_w, 2, 1, fp) != 1) goto fails; - if(fwrite(&image_h, 2, 1, fp) != 1) goto fails; +#ifndef OPJ_BIG_ENDIAN + if(fwrite(&image_w, 2, 1, fp) != 1) goto fails; + if(fwrite(&image_h, 2, 1, fp) != 1) goto fails; #else - image_w = swap16(image_w); - image_h = swap16(image_h); - if(fwrite(&image_w, 2, 1, fp) != 1) goto fails; - if(fwrite(&image_h, 2, 1, fp) != 1) goto fails; + image_w = swap16(image_w); + image_h = swap16(image_h); + if(fwrite(&image_w, 2, 1, fp) != 1) goto fails; + if(fwrite(&image_h, 2, 1, fp) != 1) goto fails; #endif - if(fwrite(&pixel_depth, 1, 1, fp) != 1) goto fails; + if(fwrite(&pixel_depth, 1, 1, fp) != 1) goto fails; - image_desc = 8; /* 8 bits per component. */ + image_desc = 8; /* 8 bits per component. */ - if (flip_image) - image_desc |= 32; - if(fwrite(&image_desc, 1, 1, fp) != 1) goto fails; + if (flip_image) + image_desc |= 32; + if(fwrite(&image_desc, 1, 1, fp) != 1) goto fails; - return 1; + return 1; fails: - fputs("\nwrite_tgaheader: write ERROR\n", stderr); - return 0; + fputs("\nwrite_tgaheader: write ERROR\n", stderr); + return 0; } opj_image_t* tgatoimage(const char *filename, opj_cparameters_t *parameters) { - FILE *f; - opj_image_t *image; - unsigned int image_width, image_height, pixel_bit_depth; - unsigned int x, y; - int flip_image=0; - opj_image_cmptparm_t cmptparm[4]; /* maximum 4 components */ - int numcomps; - OPJ_COLOR_SPACE color_space; - OPJ_BOOL mono ; - OPJ_BOOL save_alpha; - int subsampling_dx, subsampling_dy; - int i; + FILE *f; + opj_image_t *image; + unsigned int image_width, image_height, pixel_bit_depth; + unsigned int x, y; + int flip_image=0; + opj_image_cmptparm_t cmptparm[4]; /* maximum 4 components */ + int numcomps; + OPJ_COLOR_SPACE color_space; + OPJ_BOOL mono ; + OPJ_BOOL save_alpha; + int subsampling_dx, subsampling_dy; + int i; - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "Failed to open %s for reading !!\n", filename); - return 0; - } + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !!\n", filename); + return 0; + } - if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, &flip_image)) - return NULL; + if (!tga_readheader(f, &pixel_bit_depth, &image_width, &image_height, &flip_image)) + return NULL; - /* We currently only support 24 & 32 bit tga's ... */ - if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32))) - return NULL; + /* We currently only support 24 & 32 bit tga's ... */ + if (!((pixel_bit_depth == 24) || (pixel_bit_depth == 32))) + return NULL; - /* initialize image components */ - memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); + /* initialize image components */ + memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); - mono = (pixel_bit_depth == 8) || (pixel_bit_depth == 16); /* Mono with & without alpha. */ - save_alpha = (pixel_bit_depth == 16) || (pixel_bit_depth == 32); /* Mono with alpha, or RGB with alpha */ + mono = (pixel_bit_depth == 8) || (pixel_bit_depth == 16); /* Mono with & without alpha. */ + save_alpha = (pixel_bit_depth == 16) || (pixel_bit_depth == 32); /* Mono with alpha, or RGB with alpha */ - if (mono) { - color_space = OPJ_CLRSPC_GRAY; - numcomps = save_alpha ? 2 : 1; - } - else { - numcomps = save_alpha ? 4 : 3; - color_space = OPJ_CLRSPC_SRGB; - } + if (mono) { + color_space = OPJ_CLRSPC_GRAY; + numcomps = save_alpha ? 2 : 1; + } + else { + numcomps = save_alpha ? 4 : 3; + color_space = OPJ_CLRSPC_SRGB; + } - subsampling_dx = parameters->subsampling_dx; - subsampling_dy = parameters->subsampling_dy; + subsampling_dx = parameters->subsampling_dx; + subsampling_dy = parameters->subsampling_dy; - for (i = 0; i < numcomps; i++) { - cmptparm[i].prec = 8; - cmptparm[i].bpp = 8; - cmptparm[i].sgnd = 0; - cmptparm[i].dx = subsampling_dx; - cmptparm[i].dy = subsampling_dy; - cmptparm[i].w = image_width; - cmptparm[i].h = image_height; - } + for (i = 0; i < numcomps; i++) { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = (OPJ_UINT32)subsampling_dx; + cmptparm[i].dy = (OPJ_UINT32)subsampling_dy; + cmptparm[i].w = image_width; + cmptparm[i].h = image_height; + } - /* create the image */ - image = opj_image_create(numcomps, &cmptparm[0], color_space); + /* create the image */ + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); - if (!image) - return NULL; + if (!image) + return NULL; - /* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = !image->x0 ? (image_width - 1) * subsampling_dx + 1 : image->x0 + (image_width - 1) * subsampling_dx + 1; - image->y1 = !image->y0 ? (image_height - 1) * subsampling_dy + 1 : image->y0 + (image_height - 1) * subsampling_dy + 1; + /* set image offset and reference grid */ + image->x0 = (OPJ_UINT32)parameters->image_offset_x0; + image->y0 = (OPJ_UINT32)parameters->image_offset_y0; + image->x1 = !image->x0 ? (OPJ_UINT32)(image_width - 1) * (OPJ_UINT32)subsampling_dx + 1 : image->x0 + (OPJ_UINT32)(image_width - 1) * (OPJ_UINT32)subsampling_dx + 1; + image->y1 = !image->y0 ? (OPJ_UINT32)(image_height - 1) * (OPJ_UINT32)subsampling_dy + 1 : image->y0 + (OPJ_UINT32)(image_height - 1) * (OPJ_UINT32)subsampling_dy + 1; - /* set image data */ - for (y=0; y < image_height; y++) - { - int index; + /* set image data */ + for (y=0; y < image_height; y++) + { + int index; - if (flip_image) - index = (image_height-y-1)*image_width; - else - index = y*image_width; + if (flip_image) + index = (int)((image_height-y-1)*image_width); + else + index = (int)(y*image_width); - if (numcomps==3) - { - for (x=0;xcomps[0].data[index]=r; - image->comps[1].data[index]=g; - image->comps[2].data[index]=b; - index++; - } - } - else if (numcomps==4) - { - for (x=0;xcomps[0].data[index]=r; + image->comps[1].data[index]=g; + image->comps[2].data[index]=b; + index++; + } + } + else if (numcomps==4) + { + for (x=0;xcomps[0].data[index]=r; - image->comps[1].data[index]=g; - image->comps[2].data[index]=b; - image->comps[3].data[index]=a; - index++; - } - } - else { - fprintf(stderr, "Currently unsupported bit depth : %s\n", filename); - } - } - return image; + image->comps[0].data[index]=r; + image->comps[1].data[index]=g; + image->comps[2].data[index]=b; + image->comps[3].data[index]=a; + index++; + } + } + else { + fprintf(stderr, "Currently unsupported bit depth : %s\n", filename); + } + } + return image; } int imagetotga(opj_image_t * image, const char *outfile) { - int width, height, bpp, x, y; - OPJ_BOOL write_alpha; - int i, adjustR, adjustG, adjustB; - unsigned int alpha_channel; - float r,g,b,a; - unsigned char value; - float scale; - FILE *fdest; - size_t res; + int width, height, bpp, x, y; + OPJ_BOOL write_alpha; + unsigned int i; + int adjustR, adjustG, adjustB, fails; + unsigned int alpha_channel; + float r,g,b,a; + unsigned char value; + float scale; + FILE *fdest; + size_t res; + fails = 1; - fdest = fopen(outfile, "wb"); - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); - return 1; - } - - for (i = 0; i < image->numcomps-1; i++) { - if ((image->comps[0].dx != image->comps[i+1].dx) - ||(image->comps[0].dy != image->comps[i+1].dy) - ||(image->comps[0].prec != image->comps[i+1].prec)) { - fprintf(stderr, "Unable to create a tga file with such J2K image charateristics."); - return 1; - } - } - - width = image->comps[0].w; - height = image->comps[0].h; - - /* Mono with alpha, or RGB with alpha. */ - write_alpha = (image->numcomps==2) || (image->numcomps==4); - - /* Write TGA header */ - bpp = write_alpha ? 32 : 24; - if (!tga_writeheader(fdest, bpp, width , height, OPJ_TRUE)) - return 1; - - alpha_channel = image->numcomps-1; - - scale = 255.0f / (float)((1<comps[0].prec)-1); - - adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); - adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); - adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); - - for (y=0; y < height; y++) { - unsigned int index=y*width; - - for (x=0; x < width; x++, index++) { - r = (float)(image->comps[0].data[index] + adjustR); - - if (image->numcomps>2) { - g = (float)(image->comps[1].data[index] + adjustG); - b = (float)(image->comps[2].data[index] + adjustB); - } - else {/* Greyscale ... */ - g = r; - b = r; - } - - /* TGA format writes BGR ... */ - value = (unsigned char)(b*scale); - res = fwrite(&value,1,1,fdest); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); + fdest = fopen(outfile, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); return 1; - } + } - value = (unsigned char)(g*scale); - res = fwrite(&value,1,1,fdest); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; - } - - value = (unsigned char)(r*scale); - res = fwrite(&value,1,1,fdest); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; - } - - if (write_alpha) { - a = (float)(image->comps[alpha_channel].data[index]); - value = (unsigned char)(a*scale); - res = fwrite(&value,1,1,fdest); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; + for (i = 0; i < image->numcomps-1; i++) { + if ((image->comps[0].dx != image->comps[i+1].dx) + ||(image->comps[0].dy != image->comps[i+1].dy) + ||(image->comps[0].prec != image->comps[i+1].prec)) { + fprintf(stderr, "Unable to create a tga file with such J2K image charateristics."); + return 1; } - } - } - } + } - return 0; + width = (int)image->comps[0].w; + height = (int)image->comps[0].h; + + /* Mono with alpha, or RGB with alpha. */ + write_alpha = (image->numcomps==2) || (image->numcomps==4); + + /* Write TGA header */ + bpp = write_alpha ? 32 : 24; + + if (!tga_writeheader(fdest, bpp, width , height, OPJ_TRUE)) + goto fin; + + alpha_channel = image->numcomps-1; + + scale = 255.0f / (float)((1<comps[0].prec)-1); + + adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); + adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); + + for (y=0; y < height; y++) + { + unsigned int index= (unsigned int)(y*width); + + for (x=0; x < width; x++, index++) + { + r = (float)(image->comps[0].data[index] + adjustR); + + if (image->numcomps > 2) + { + g = (float)(image->comps[1].data[index] + adjustG); + b = (float)(image->comps[2].data[index] + adjustB); + } + else + {/* Greyscale ... */ + g = r; + b = r; + } + +/* TGA format writes BGR ... */ + if(b > 255.) b = 255.; else if(b < 0.) b = 0.; + value = (unsigned char)(b*scale); + res = fwrite(&value,1,1,fdest); + + if( res < 1 ) + { + fprintf(stderr, "failed to write 1 byte for %s\n", outfile); + goto fin; + } + if(g > 255.) g = 255.; else if(g < 0.) g = 0.; + value = (unsigned char)(g*scale); + res = fwrite(&value,1,1,fdest); + + if( res < 1 ) + { + fprintf(stderr, "failed to write 1 byte for %s\n", outfile); + goto fin; + } + if(r > 255.) r = 255.; else if(r < 0.) r = 0.; + value = (unsigned char)(r*scale); + res = fwrite(&value,1,1,fdest); + + if( res < 1 ) + { + fprintf(stderr, "failed to write 1 byte for %s\n", outfile); + goto fin; + } + + if (write_alpha) + { + a = (float)(image->comps[alpha_channel].data[index]); + if(a > 255.) a = 255.; else if(a < 0.) a = 0.; + value = (unsigned char)(a*scale); + res = fwrite(&value,1,1,fdest); + + if( res < 1 ) + { + fprintf(stderr, "failed to write 1 byte for %s\n", outfile); + goto fin; + } + } + } + } + fails = 0; +fin: + fclose(fdest); + + return fails; } /* -->> -->> -->> -->> @@ -513,686 +536,685 @@ typedef unsigned short int WORD; typedef unsigned int DWORD; typedef struct { - WORD bfType; /* 'BM' for Bitmap (19776) */ - DWORD bfSize; /* Size of the file */ - WORD bfReserved1; /* Reserved : 0 */ - WORD bfReserved2; /* Reserved : 0 */ - DWORD bfOffBits; /* Offset */ + WORD bfType; /* 'BM' for Bitmap (19776) */ + DWORD bfSize; /* Size of the file */ + WORD bfReserved1; /* Reserved : 0 */ + WORD bfReserved2; /* Reserved : 0 */ + DWORD bfOffBits; /* Offset */ } BITMAPFILEHEADER_t; typedef struct { - DWORD biSize; /* Size of the structure in bytes */ - DWORD biWidth; /* Width of the image in pixels */ - DWORD biHeight; /* Heigth of the image in pixels */ - WORD biPlanes; /* 1 */ - WORD biBitCount; /* Number of color bits by pixels */ - DWORD biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */ - DWORD biSizeImage; /* Size of the image in bytes */ - DWORD biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */ - DWORD biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */ - DWORD biClrUsed; /* Number of color used in the image (0: ALL) */ - DWORD biClrImportant; /* Number of important color (0: ALL) */ + DWORD biSize; /* Size of the structure in bytes */ + DWORD biWidth; /* Width of the image in pixels */ + DWORD biHeight; /* Heigth of the image in pixels */ + WORD biPlanes; /* 1 */ + WORD biBitCount; /* Number of color bits by pixels */ + DWORD biCompression; /* Type of encoding 0: none 1: RLE8 2: RLE4 */ + DWORD biSizeImage; /* Size of the image in bytes */ + DWORD biXpelsPerMeter; /* Horizontal (X) resolution in pixels/meter */ + DWORD biYpelsPerMeter; /* Vertical (Y) resolution in pixels/meter */ + DWORD biClrUsed; /* Number of color used in the image (0: ALL) */ + DWORD biClrImportant; /* Number of important color (0: ALL) */ } BITMAPINFOHEADER_t; opj_image_t* bmptoimage(const char *filename, opj_cparameters_t *parameters) { - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; - int i, numcomps, w, h; - OPJ_COLOR_SPACE color_space; - opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */ - opj_image_t * image = NULL; + int i, numcomps, w, h; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm[3]; /* maximum of 3 components */ + opj_image_t * image = NULL; - FILE *IN; - BITMAPFILEHEADER_t File_h; - BITMAPINFOHEADER_t Info_h; - unsigned char *RGB; - unsigned char *table_R, *table_G, *table_B; - unsigned int j, PAD = 0; + FILE *IN; + BITMAPFILEHEADER_t File_h; + BITMAPINFOHEADER_t Info_h; + unsigned char *RGB; + unsigned char *table_R, *table_G, *table_B; + unsigned int j, PAD = 0; - int x, y, index; - int gray_scale = 1; - int has_color; - DWORD W, H; - - IN = fopen(filename, "rb"); - if (!IN) - { - fprintf(stderr, "Failed to open %s for reading !!\n", filename); - return NULL; - } - - File_h.bfType = getc(IN); - File_h.bfType = (getc(IN) << 8) + File_h.bfType; - - if (File_h.bfType != 19778) - { - fprintf(stderr,"Error, not a BMP file!\n"); - fclose(IN); - return NULL; - } - /* FILE HEADER */ - /* ------------- */ - File_h.bfSize = getc(IN); - File_h.bfSize = (getc(IN) << 8) + File_h.bfSize; - File_h.bfSize = (getc(IN) << 16) + File_h.bfSize; - File_h.bfSize = (getc(IN) << 24) + File_h.bfSize; + unsigned int x, y; + int index; + int gray_scale = 1; + int has_color; + DWORD W, H; - File_h.bfReserved1 = getc(IN); - File_h.bfReserved1 = (getc(IN) << 8) + File_h.bfReserved1; + IN = fopen(filename, "rb"); + if (!IN) + { + fprintf(stderr, "Failed to open %s for reading !!\n", filename); + return NULL; + } - File_h.bfReserved2 = getc(IN); - File_h.bfReserved2 = (getc(IN) << 8) + File_h.bfReserved2; + File_h.bfType = (WORD)getc(IN); + File_h.bfType = (WORD)((getc(IN) << 8) + File_h.bfType); - File_h.bfOffBits = getc(IN); - File_h.bfOffBits = (getc(IN) << 8) + File_h.bfOffBits; - File_h.bfOffBits = (getc(IN) << 16) + File_h.bfOffBits; - File_h.bfOffBits = (getc(IN) << 24) + File_h.bfOffBits; + if (File_h.bfType != 19778) + { + fprintf(stderr,"Error, not a BMP file!\n"); + fclose(IN); + return NULL; + } + /* FILE HEADER */ + /* ------------- */ + File_h.bfSize = (DWORD)getc(IN); + File_h.bfSize = (DWORD)(getc(IN) << 8) + File_h.bfSize; + File_h.bfSize = (DWORD)(getc(IN) << 16) + File_h.bfSize; + File_h.bfSize = (DWORD)(getc(IN) << 24) + File_h.bfSize; - /* INFO HEADER */ - /* ------------- */ + File_h.bfReserved1 = (WORD)getc(IN); + File_h.bfReserved1 = (WORD)((getc(IN) << 8) + File_h.bfReserved1); - Info_h.biSize = getc(IN); - Info_h.biSize = (getc(IN) << 8) + Info_h.biSize; - Info_h.biSize = (getc(IN) << 16) + Info_h.biSize; - Info_h.biSize = (getc(IN) << 24) + Info_h.biSize; + File_h.bfReserved2 = (WORD)getc(IN); + File_h.bfReserved2 = (WORD)((getc(IN) << 8) + File_h.bfReserved2); - if(Info_h.biSize != 40) - { - fprintf(stderr,"Error, unknown BMP header size %d\n", Info_h.biSize); - fclose(IN); - return NULL; - } - Info_h.biWidth = getc(IN); - Info_h.biWidth = (getc(IN) << 8) + Info_h.biWidth; - Info_h.biWidth = (getc(IN) << 16) + Info_h.biWidth; - Info_h.biWidth = (getc(IN) << 24) + Info_h.biWidth; - w = Info_h.biWidth; + File_h.bfOffBits = (DWORD)getc(IN); + File_h.bfOffBits = (DWORD)(getc(IN) << 8) + File_h.bfOffBits; + File_h.bfOffBits = (DWORD)(getc(IN) << 16) + File_h.bfOffBits; + File_h.bfOffBits = (DWORD)(getc(IN) << 24) + File_h.bfOffBits; - Info_h.biHeight = getc(IN); - Info_h.biHeight = (getc(IN) << 8) + Info_h.biHeight; - Info_h.biHeight = (getc(IN) << 16) + Info_h.biHeight; - Info_h.biHeight = (getc(IN) << 24) + Info_h.biHeight; - h = Info_h.biHeight; + /* INFO HEADER */ + /* ------------- */ - Info_h.biPlanes = getc(IN); - Info_h.biPlanes = (getc(IN) << 8) + Info_h.biPlanes; + Info_h.biSize = (DWORD)getc(IN); + Info_h.biSize = (DWORD)(getc(IN) << 8) + Info_h.biSize; + Info_h.biSize = (DWORD)(getc(IN) << 16) + Info_h.biSize; + Info_h.biSize = (DWORD)(getc(IN) << 24) + Info_h.biSize; - Info_h.biBitCount = getc(IN); - Info_h.biBitCount = (getc(IN) << 8) + Info_h.biBitCount; + if(Info_h.biSize != 40) + { + fprintf(stderr,"Error, unknown BMP header size %d\n", Info_h.biSize); + fclose(IN); + return NULL; + } + Info_h.biWidth = (DWORD)getc(IN); + Info_h.biWidth = (DWORD)(getc(IN) << 8) + Info_h.biWidth; + Info_h.biWidth = (DWORD)(getc(IN) << 16) + Info_h.biWidth; + Info_h.biWidth = (DWORD)(getc(IN) << 24) + Info_h.biWidth; + w = (int)Info_h.biWidth; - Info_h.biCompression = getc(IN); - Info_h.biCompression = (getc(IN) << 8) + Info_h.biCompression; - Info_h.biCompression = (getc(IN) << 16) + Info_h.biCompression; - Info_h.biCompression = (getc(IN) << 24) + Info_h.biCompression; + Info_h.biHeight = (DWORD)getc(IN); + Info_h.biHeight = (DWORD)(getc(IN) << 8) + Info_h.biHeight; + Info_h.biHeight = (DWORD)(getc(IN) << 16) + Info_h.biHeight; + Info_h.biHeight = (DWORD)(getc(IN) << 24) + Info_h.biHeight; + h = (int)Info_h.biHeight; - Info_h.biSizeImage = getc(IN); - Info_h.biSizeImage = (getc(IN) << 8) + Info_h.biSizeImage; - Info_h.biSizeImage = (getc(IN) << 16) + Info_h.biSizeImage; - Info_h.biSizeImage = (getc(IN) << 24) + Info_h.biSizeImage; + Info_h.biPlanes = (WORD)getc(IN); + Info_h.biPlanes = (WORD)((getc(IN) << 8) + Info_h.biPlanes); - Info_h.biXpelsPerMeter = getc(IN); - Info_h.biXpelsPerMeter = (getc(IN) << 8) + Info_h.biXpelsPerMeter; - Info_h.biXpelsPerMeter = (getc(IN) << 16) + Info_h.biXpelsPerMeter; - Info_h.biXpelsPerMeter = (getc(IN) << 24) + Info_h.biXpelsPerMeter; + Info_h.biBitCount = (WORD)getc(IN); + Info_h.biBitCount = (WORD)((getc(IN) << 8) + Info_h.biBitCount); - Info_h.biYpelsPerMeter = getc(IN); - Info_h.biYpelsPerMeter = (getc(IN) << 8) + Info_h.biYpelsPerMeter; - Info_h.biYpelsPerMeter = (getc(IN) << 16) + Info_h.biYpelsPerMeter; - Info_h.biYpelsPerMeter = (getc(IN) << 24) + Info_h.biYpelsPerMeter; + Info_h.biCompression = (DWORD)getc(IN); + Info_h.biCompression = (DWORD)(getc(IN) << 8) + Info_h.biCompression; + Info_h.biCompression = (DWORD)(getc(IN) << 16) + Info_h.biCompression; + Info_h.biCompression = (DWORD)(getc(IN) << 24) + Info_h.biCompression; - Info_h.biClrUsed = getc(IN); - Info_h.biClrUsed = (getc(IN) << 8) + Info_h.biClrUsed; - Info_h.biClrUsed = (getc(IN) << 16) + Info_h.biClrUsed; - Info_h.biClrUsed = (getc(IN) << 24) + Info_h.biClrUsed; + Info_h.biSizeImage = (DWORD)getc(IN); + Info_h.biSizeImage = (DWORD)(getc(IN) << 8) + Info_h.biSizeImage; + Info_h.biSizeImage = (DWORD)(getc(IN) << 16) + Info_h.biSizeImage; + Info_h.biSizeImage = (DWORD)(getc(IN) << 24) + Info_h.biSizeImage; - Info_h.biClrImportant = getc(IN); - Info_h.biClrImportant = (getc(IN) << 8) + Info_h.biClrImportant; - Info_h.biClrImportant = (getc(IN) << 16) + Info_h.biClrImportant; - Info_h.biClrImportant = (getc(IN) << 24) + Info_h.biClrImportant; + Info_h.biXpelsPerMeter = (DWORD)getc(IN); + Info_h.biXpelsPerMeter = (DWORD)(getc(IN) << 8) + Info_h.biXpelsPerMeter; + Info_h.biXpelsPerMeter = (DWORD)(getc(IN) << 16) + Info_h.biXpelsPerMeter; + Info_h.biXpelsPerMeter = (DWORD)(getc(IN) << 24) + Info_h.biXpelsPerMeter; - /* Read the data and store them in the OUT file */ + Info_h.biYpelsPerMeter = (DWORD)getc(IN); + Info_h.biYpelsPerMeter = (DWORD)(getc(IN) << 8) + Info_h.biYpelsPerMeter; + Info_h.biYpelsPerMeter = (DWORD)(getc(IN) << 16) + Info_h.biYpelsPerMeter; + Info_h.biYpelsPerMeter = (DWORD)(getc(IN) << 24) + Info_h.biYpelsPerMeter; - if (Info_h.biBitCount == 24) - { - numcomps = 3; - color_space = OPJ_CLRSPC_SRGB; - /* initialize image components */ - memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); - for(i = 0; i < numcomps; i++) - { - cmptparm[i].prec = 8; - cmptparm[i].bpp = 8; - cmptparm[i].sgnd = 0; - cmptparm[i].dx = subsampling_dx; - cmptparm[i].dy = subsampling_dy; - cmptparm[i].w = w; - cmptparm[i].h = h; - } - /* create the image */ - image = opj_image_create(numcomps, &cmptparm[0], color_space); - if(!image) - { - fclose(IN); - return NULL; - } + Info_h.biClrUsed = (DWORD)getc(IN); + Info_h.biClrUsed = (DWORD)(getc(IN) << 8) + Info_h.biClrUsed; + Info_h.biClrUsed = (DWORD)(getc(IN) << 16) + Info_h.biClrUsed; + Info_h.biClrUsed = (DWORD)(getc(IN) << 24) + Info_h.biClrUsed; - /* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; - image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; + Info_h.biClrImportant = (DWORD)getc(IN); + Info_h.biClrImportant = (DWORD)(getc(IN) << 8) + Info_h.biClrImportant; + Info_h.biClrImportant = (DWORD)(getc(IN) << 16) + Info_h.biClrImportant; + Info_h.biClrImportant = (DWORD)(getc(IN) << 24) + Info_h.biClrImportant; - /* set image data */ + /* Read the data and store them in the OUT file */ - /* Place the cursor at the beginning of the image information */ - fseek(IN, 0, SEEK_SET); - fseek(IN, File_h.bfOffBits, SEEK_SET); - - W = Info_h.biWidth; - H = Info_h.biHeight; + if (Info_h.biBitCount == 24) + { + numcomps = 3; + color_space = OPJ_CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) + { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = (OPJ_UINT32)subsampling_dx; + cmptparm[i].dy = (OPJ_UINT32)subsampling_dy; + cmptparm[i].w = (OPJ_UINT32)w; + cmptparm[i].h = (OPJ_UINT32)h; + } + /* create the image */ + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); + if(!image) + { + fclose(IN); + return NULL; + } - /* PAD = 4 - (3 * W) % 4; */ - /* PAD = (PAD == 4) ? 0 : PAD; */ - PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0; - - RGB = (unsigned char *) - malloc((3 * W + PAD) * H * sizeof(unsigned char)); - - if ( fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN) != (3 * W + PAD) * H ) - { - free(RGB); - opj_image_destroy(image); - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return NULL; - } - - index = 0; + /* set image offset and reference grid */ + image->x0 = (OPJ_UINT32)parameters->image_offset_x0; + image->y0 = (OPJ_UINT32)parameters->image_offset_y0; + image->x1 = !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 : image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1; + image->y1 = !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 : image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1; - for(y = 0; y < (int)H; y++) - { - unsigned char *scanline = RGB + (3 * W + PAD) * (H - 1 - y); - for(x = 0; x < (int)W; x++) - { - unsigned char *pixel = &scanline[3 * x]; - image->comps[0].data[index] = pixel[2]; /* R */ - image->comps[1].data[index] = pixel[1]; /* G */ - image->comps[2].data[index] = pixel[0]; /* B */ - index++; - } - } - free(RGB); - }/* if (Info_h.biBitCount == 24) */ - else - if (Info_h.biBitCount == 8 && Info_h.biCompression == 0)/*RGB */ - { - if(Info_h.biClrUsed == 0) Info_h.biClrUsed = 256; - else - if(Info_h.biClrUsed > 256) Info_h.biClrUsed = 256; + /* set image data */ - table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); - table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); - table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); - - has_color = 0; - for (j = 0; j < Info_h.biClrUsed; j++) - { - table_B[j] = (unsigned char)getc(IN); - table_G[j] = (unsigned char)getc(IN); - table_R[j] = (unsigned char)getc(IN); - getc(IN); - has_color += - !(table_R[j] == table_G[j] && table_R[j] == table_B[j]); - } - if(has_color) gray_scale = 0; - - /* Place the cursor at the beginning of the image information */ - fseek(IN, 0, SEEK_SET); - fseek(IN, File_h.bfOffBits, SEEK_SET); - - W = Info_h.biWidth; - H = Info_h.biHeight; - if (Info_h.biWidth % 2) - W++; - - numcomps = gray_scale ? 1 : 3; - color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB; - /* initialize image components */ - memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); - for(i = 0; i < numcomps; i++) - { - cmptparm[i].prec = 8; - cmptparm[i].bpp = 8; - cmptparm[i].sgnd = 0; - cmptparm[i].dx = subsampling_dx; - cmptparm[i].dy = subsampling_dy; - cmptparm[i].w = w; - cmptparm[i].h = h; - } - /* create the image */ - image = opj_image_create(numcomps, &cmptparm[0], color_space); - if(!image) - { - fclose(IN); - free(table_R); free(table_G); free(table_B); - return NULL; - } + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, (long)File_h.bfOffBits, SEEK_SET); - /* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - 1) * subsampling_dx + 1; - image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - 1) * subsampling_dy + 1; + W = Info_h.biWidth; + H = Info_h.biHeight; - /* set image data */ + /* PAD = 4 - (3 * W) % 4; */ + /* PAD = (PAD == 4) ? 0 : PAD; */ + PAD = (3 * W) % 4 ? 4 - (3 * W) % 4 : 0; - RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char)); - - if ( fread(RGB, sizeof(unsigned char), W * H, IN) != W * H ) - { - free(table_R); - free(table_G); - free(table_B); - free(RGB); - opj_image_destroy(image); - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return NULL; - } - if (gray_scale) - { - index = 0; - for (j = 0; j < W * H; j++) - { - if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) - { - image->comps[0].data[index] = - table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]; - index++; - } - } + RGB = (unsigned char *) + malloc((3 * W + PAD) * H * sizeof(unsigned char)); - } - else - { - index = 0; - for (j = 0; j < W * H; j++) - { - if ((j % W < W - 1 && Info_h.biWidth % 2) - || !(Info_h.biWidth % 2)) - { - unsigned char pixel_index = - RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]; - image->comps[0].data[index] = table_R[pixel_index]; - image->comps[1].data[index] = table_G[pixel_index]; - image->comps[2].data[index] = table_B[pixel_index]; - index++; - } - } - } - free(RGB); - free(table_R); - free(table_G); - free(table_B); - }/* RGB8 */ - else - if (Info_h.biBitCount == 8 && Info_h.biCompression == 1)/*RLE8*/ - { - unsigned char *pix, *beyond; - int *gray, *red, *green, *blue; - unsigned int x, y, max; - int i, c, c1; - unsigned char uc; + if ( fread(RGB, sizeof(unsigned char), (3 * W + PAD) * H, IN) != (3 * W + PAD) * H ) + { + free(RGB); + opj_image_destroy(image); + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return NULL; + } - if (Info_h.biClrUsed == 0) - Info_h.biClrUsed = 256; - else if (Info_h.biClrUsed > 256) - Info_h.biClrUsed = 256; + index = 0; - table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); - table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); - table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); + for(y = 0; y < H; y++) + { + unsigned char *scanline = RGB + (3 * (unsigned int)W + PAD) * ((unsigned int)H - 1 - (unsigned int)y); + for(x = 0; x < W; x++) + { + unsigned char *pixel = &scanline[3 * x]; + image->comps[0].data[index] = pixel[2]; /* R */ + image->comps[1].data[index] = pixel[1]; /* G */ + image->comps[2].data[index] = pixel[0]; /* B */ + index++; + } + } + free(RGB); + }/* if (Info_h.biBitCount == 24) */ + else + if (Info_h.biBitCount == 8 && Info_h.biCompression == 0)/*RGB */ + { + if(Info_h.biClrUsed == 0) Info_h.biClrUsed = 256; + else + if(Info_h.biClrUsed > 256) Info_h.biClrUsed = 256; - has_color = 0; - for (j = 0; j < Info_h.biClrUsed; j++) - { - table_B[j] = (unsigned char)getc(IN); - table_G[j] = (unsigned char)getc(IN); - table_R[j] = (unsigned char)getc(IN); - getc(IN); - has_color += !(table_R[j] == table_G[j] && table_R[j] == table_B[j]); - } + table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); - if (has_color) - gray_scale = 0; + has_color = 0; + for (j = 0; j < Info_h.biClrUsed; j++) + { + table_B[j] = (unsigned char)getc(IN); + table_G[j] = (unsigned char)getc(IN); + table_R[j] = (unsigned char)getc(IN); + getc(IN); + has_color += + !(table_R[j] == table_G[j] && table_R[j] == table_B[j]); + } + if(has_color) gray_scale = 0; - numcomps = gray_scale ? 1 : 3; - color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB; - /* initialize image components */ - memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); - for (i = 0; i < numcomps; i++) - { - cmptparm[i].prec = 8; - cmptparm[i].bpp = 8; - cmptparm[i].sgnd = 0; - cmptparm[i].dx = subsampling_dx; - cmptparm[i].dy = subsampling_dy; - cmptparm[i].w = w; - cmptparm[i].h = h; - } - /* create the image */ - image = opj_image_create(numcomps, &cmptparm[0], color_space); - if (!image) - { - fclose(IN); - free(table_R); - free(table_G); - free(table_B); - return NULL; - } + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, (long)File_h.bfOffBits, SEEK_SET); - /* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : image->x0 + (w - - 1) * subsampling_dx + 1; - image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : image->y0 + (h - - 1) * subsampling_dy + 1; + W = Info_h.biWidth; + H = Info_h.biHeight; + if (Info_h.biWidth % 2) + W++; - /* set image data */ + numcomps = gray_scale ? 1 : 3; + color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) + { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = (OPJ_UINT32)subsampling_dx; + cmptparm[i].dy = (OPJ_UINT32)subsampling_dy; + cmptparm[i].w = (OPJ_UINT32)w; + cmptparm[i].h = (OPJ_UINT32)h; + } + /* create the image */ + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); + if(!image) + { + fclose(IN); + free(table_R); free(table_G); free(table_B); + return NULL; + } - /* Place the cursor at the beginning of the image information */ - fseek(IN, 0, SEEK_SET); - fseek(IN, File_h.bfOffBits, SEEK_SET); + /* set image offset and reference grid */ + image->x0 = (OPJ_UINT32)parameters->image_offset_x0; + image->y0 = (OPJ_UINT32)parameters->image_offset_y0; + image->x1 = !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 : image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1; + image->y1 = !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 : image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1; - W = Info_h.biWidth; - H = Info_h.biHeight; - RGB = (unsigned char *) calloc(1, W * H * sizeof(unsigned char)); - beyond = RGB + W * H; - pix = beyond - W; - x = y = 0; + /* set image data */ - while (y < H) - { - c = getc(IN); + RGB = (unsigned char *) malloc(W * H * sizeof(unsigned char)); - if (c) - { - c1 = getc(IN); + if ( fread(RGB, sizeof(unsigned char), W * H, IN) != W * H ) + { + free(table_R); + free(table_G); + free(table_B); + free(RGB); + opj_image_destroy(image); + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return NULL; + } + if (gray_scale) + { + index = 0; + for (j = 0; j < W * H; j++) + { + if ((j % W < W - 1 && Info_h.biWidth % 2) || !(Info_h.biWidth % 2)) + { + image->comps[0].data[index] = + table_R[RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]]; + index++; + } + } - for (i = 0; i < c && x < W && pix < beyond; i++, x++, pix++) - *pix = (unsigned char)c1; - } - else - { - c = getc(IN); + } + else + { + index = 0; + for (j = 0; j < W * H; j++) + { + if ((j % W < W - 1 && Info_h.biWidth % 2) + || !(Info_h.biWidth % 2)) + { + unsigned char pixel_index = + RGB[W * H - ((j) / (W) + 1) * W + (j) % (W)]; + image->comps[0].data[index] = table_R[pixel_index]; + image->comps[1].data[index] = table_G[pixel_index]; + image->comps[2].data[index] = table_B[pixel_index]; + index++; + } + } + } + free(RGB); + free(table_R); + free(table_G); + free(table_B); + }/* RGB8 */ + else + if (Info_h.biBitCount == 8 && Info_h.biCompression == 1)/*RLE8*/ + { + unsigned char *pix, *beyond; + int *gray, *red, *green, *blue; + unsigned int max; + int c, c1; + unsigned char uc; - if (c == 0x00) /* EOL */ - { - x = 0; - ++y; - pix = RGB + x + (H - y - 1) * W; - } - else if (c == 0x01) /* EOP */ - break; - else if (c == 0x02) /* MOVE by dxdy */ - { - c = getc(IN); - x += c; - c = getc(IN); - y += c; - pix = RGB + (H - y - 1) * W + x; - } - else /* 03 .. 255 */ - { - i = 0; - for (; i < c && x < W && pix < beyond; i++, x++, pix++) - { - c1 = getc(IN); - *pix = (unsigned char)c1; - } - if (c & 1) /* skip padding byte */ - getc(IN); - } - } - }/* while() */ + if (Info_h.biClrUsed == 0) + Info_h.biClrUsed = 256; + else if (Info_h.biClrUsed > 256) + Info_h.biClrUsed = 256; - if (gray_scale) - { - gray = image->comps[0].data; - pix = RGB; - max = W * H; + table_R = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_G = (unsigned char *) malloc(256 * sizeof(unsigned char)); + table_B = (unsigned char *) malloc(256 * sizeof(unsigned char)); - while (max--) - { - uc = *pix++; + has_color = 0; + for (j = 0; j < Info_h.biClrUsed; j++) + { + table_B[j] = (unsigned char)getc(IN); + table_G[j] = (unsigned char)getc(IN); + table_R[j] = (unsigned char)getc(IN); + getc(IN); + has_color += !(table_R[j] == table_G[j] && table_R[j] == table_B[j]); + } - *gray++ = table_R[uc]; - } - } - else - { - /*int *red, *green, *blue;*/ + if (has_color) + gray_scale = 0; - red = image->comps[0].data; - green = image->comps[1].data; - blue = image->comps[2].data; - pix = RGB; - max = W * H; + numcomps = gray_scale ? 1 : 3; + color_space = gray_scale ? OPJ_CLRSPC_GRAY : OPJ_CLRSPC_SRGB; + /* initialize image components */ + memset(&cmptparm[0], 0, 3 * sizeof(opj_image_cmptparm_t)); + for (i = 0; i < numcomps; i++) + { + cmptparm[i].prec = 8; + cmptparm[i].bpp = 8; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = (OPJ_UINT32)subsampling_dx; + cmptparm[i].dy = (OPJ_UINT32)subsampling_dy; + cmptparm[i].w = (OPJ_UINT32)w; + cmptparm[i].h = (OPJ_UINT32)h; + } + /* create the image */ + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); + if (!image) + { + fclose(IN); + free(table_R); + free(table_G); + free(table_B); + return NULL; + } - while (max--) - { - uc = *pix++; + /* set image offset and reference grid */ + image->x0 = (OPJ_UINT32)parameters->image_offset_x0; + image->y0 = (OPJ_UINT32)parameters->image_offset_y0; + image->x1 = !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 : image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1; + image->y1 = !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 : image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1; - *red++ = table_R[uc]; - *green++ = table_G[uc]; - *blue++ = table_B[uc]; - } - } - free(RGB); - free(table_R); - free(table_G); - free(table_B); - }/* RLE8 */ - else - { - fprintf(stderr, - "Other system than 24 bits/pixels or 8 bits (no RLE coding) " - "is not yet implemented [%d]\n", Info_h.biBitCount); - } - fclose(IN); - return image; + /* set image data */ + + /* Place the cursor at the beginning of the image information */ + fseek(IN, 0, SEEK_SET); + fseek(IN, (long)File_h.bfOffBits, SEEK_SET); + + W = Info_h.biWidth; + H = Info_h.biHeight; + RGB = (unsigned char *) calloc(1, W * H * sizeof(unsigned char)); + beyond = RGB + W * H; + pix = beyond - W; + x = y = 0; + + while (y < H) + { + c = getc(IN); + + if (c) + { + c1 = getc(IN); + + for (i = 0; i < c && x < W && pix < beyond; i++, x++, pix++) + *pix = (unsigned char)c1; + } + else + { + c = getc(IN); + + if (c == 0x00) /* EOL */ + { + x = 0; + ++y; + pix = RGB + x + (H - y - 1) * W; + } + else if (c == 0x01) /* EOP */ + break; + else if (c == 0x02) /* MOVE by dxdy */ + { + c = getc(IN); + x += (unsigned int)c; + c = getc(IN); + y += (unsigned int)c; + pix = RGB + (H - y - 1) * W + x; + } + else /* 03 .. 255 */ + { + i = 0; + for (; i < c && x < W && pix < beyond; i++, x++, pix++) + { + c1 = getc(IN); + *pix = (unsigned char)c1; + } + if (c & 1) /* skip padding byte */ + getc(IN); + } + } + }/* while() */ + + if (gray_scale) + { + gray = image->comps[0].data; + pix = RGB; + max = W * H; + + while (max--) + { + uc = *pix++; + + *gray++ = table_R[uc]; + } + } + else + { + /*int *red, *green, *blue;*/ + + red = image->comps[0].data; + green = image->comps[1].data; + blue = image->comps[2].data; + pix = RGB; + max = W * H; + + while (max--) + { + uc = *pix++; + + *red++ = table_R[uc]; + *green++ = table_G[uc]; + *blue++ = table_B[uc]; + } + } + free(RGB); + free(table_R); + free(table_G); + free(table_B); + }/* RLE8 */ + else + { + fprintf(stderr, + "Other system than 24 bits/pixels or 8 bits (no RLE coding) " + "is not yet implemented [%d]\n", Info_h.biBitCount); + } + fclose(IN); + return image; } int imagetobmp(opj_image_t * image, const char *outfile) { - int w, h; - int i, pad; - FILE *fdest = NULL; - int adjustR, adjustG, adjustB; + int w, h; + int i, pad; + FILE *fdest = NULL; + int adjustR, adjustG, adjustB; - if (image->comps[0].prec < 8) { - fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec); - return 1; - } - if (image->numcomps >= 3 && image->comps[0].dx == image->comps[1].dx - && image->comps[1].dx == image->comps[2].dx - && image->comps[0].dy == image->comps[1].dy - && image->comps[1].dy == image->comps[2].dy - && image->comps[0].prec == image->comps[1].prec - && image->comps[1].prec == image->comps[2].prec) { - - /* -->> -->> -->> -->> - 24 bits color - <<-- <<-- <<-- <<-- */ - - fdest = fopen(outfile, "wb"); - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); - return 1; - } - - w = image->comps[0].w; - h = image->comps[0].h; - - fprintf(fdest, "BM"); - - /* FILE HEADER */ - /* ------------- */ - fprintf(fdest, "%c%c%c%c", - (unsigned char) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff, - (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 8) & 0xff, - (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 16) & 0xff, - (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff); - - /* INFO HEADER */ - /* ------------- */ - fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff), - (unsigned char) ((w) >> 8) & 0xff, - (unsigned char) ((w) >> 16) & 0xff, - (unsigned char) ((w) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff), - (unsigned char) ((h) >> 8) & 0xff, - (unsigned char) ((h) >> 16) & 0xff, - (unsigned char) ((h) >> 24) & 0xff); - fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); - fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * h * w + 3 * h * (w % 2)) & 0xff, - (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff, - (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff, - (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - - if (image->comps[0].prec > 8) { - adjustR = image->comps[0].prec - 8; - printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec); - } - else - adjustR = 0; - if (image->comps[1].prec > 8) { - adjustG = image->comps[1].prec - 8; - printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec); - } - else - adjustG = 0; - if (image->comps[2].prec > 8) { - adjustB = image->comps[2].prec - 8; - printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec); - } - else - adjustB = 0; + if (image->comps[0].prec < 8) { + fprintf(stderr, "Unsupported number of components: %d\n", image->comps[0].prec); + return 1; + } + if (image->numcomps >= 3 && image->comps[0].dx == image->comps[1].dx + && image->comps[1].dx == image->comps[2].dx + && image->comps[0].dy == image->comps[1].dy + && image->comps[1].dy == image->comps[2].dy + && image->comps[0].prec == image->comps[1].prec + && image->comps[1].prec == image->comps[2].prec) { - for (i = 0; i < w * h; i++) { - unsigned char rc, gc, bc; - int r, g, b; - - r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; - r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); - r = ((r >> adjustR)+((r >> (adjustR-1))%2)); - if(r > 255) r = 255; else if(r < 0) r = 0; - rc = (unsigned char)r; + /* -->> -->> -->> -->> + 24 bits color + <<-- <<-- <<-- <<-- */ - g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; - g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); - g = ((g >> adjustG)+((g >> (adjustG-1))%2)); - if(g > 255) g = 255; else if(g < 0) g = 0; - gc = (unsigned char)g; + fdest = fopen(outfile, "wb"); + if (!fdest) { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); + return 1; + } - b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; - b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); - b = ((b >> adjustB)+((b >> (adjustB-1))%2)); - if(b > 255) b = 255; else if(b < 0) b = 0; - bc = (unsigned char)b; + w = (int)image->comps[0].w; + h = (int)image->comps[0].h; - fprintf(fdest, "%c%c%c", bc, gc, rc); - - if ((i + 1) % w == 0) { - for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--) /* ADD */ - fprintf(fdest, "%c", 0); - } - } - fclose(fdest); - } else { /* Gray-scale */ + fprintf(fdest, "BM"); - /* -->> -->> -->> -->> - 8 bits non code (Gray scale) - <<-- <<-- <<-- <<-- */ + /* FILE HEADER */ + /* ------------- */ + fprintf(fdest, "%c%c%c%c", + (unsigned char) (h * w * 3 + 3 * h * (w % 2) + 54) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 8) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 16) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2) + 54) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (54) & 0xff, ((54) >> 8) & 0xff,((54) >> 16) & 0xff, ((54) >> 24) & 0xff); - fdest = fopen(outfile, "wb"); - w = image->comps[0].w; - h = image->comps[0].h; - - fprintf(fdest, "BM"); - - /* FILE HEADER */ - /* ------------- */ - fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + 54 + 1024 + h * (w % 2)) & 0xff, - (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff, - (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff, - (unsigned char) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, - ((54 + 1024) >> 16) & 0xff, - ((54 + 1024) >> 24) & 0xff); - - /* INFO HEADER */ - /* ------------- */ - fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff), - (unsigned char) ((w) >> 8) & 0xff, - (unsigned char) ((w) >> 16) & 0xff, - (unsigned char) ((w) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff), - (unsigned char) ((h) >> 8) & 0xff, - (unsigned char) ((h) >> 16) & 0xff, - (unsigned char) ((h) >> 24) & 0xff); - fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); - fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff); - fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + h * (w % 2)) & 0xff, - (unsigned char) ((h * w + h * (w % 2)) >> 8) & 0xff, - (unsigned char) ((h * w + h * (w % 2)) >> 16) & 0xff, - (unsigned char) ((h * w + h * (w % 2)) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); - fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + /* INFO HEADER */ + /* ------------- */ + fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff), + (unsigned char) ((w) >> 8) & 0xff, + (unsigned char) ((w) >> 16) & 0xff, + (unsigned char) ((w) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff), + (unsigned char) ((h) >> 8) & 0xff, + (unsigned char) ((h) >> 16) & 0xff, + (unsigned char) ((h) >> 24) & 0xff); + fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(fdest, "%c%c", (24) & 0xff, ((24) >> 8) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) (3 * h * w + 3 * h * (w % 2)) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 8) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 16) & 0xff, + (unsigned char) ((h * w * 3 + 3 * h * (w % 2)) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); - if (image->comps[0].prec > 8) { - adjustR = image->comps[0].prec - 8; - printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec); - }else - adjustR = 0; + if (image->comps[0].prec > 8) { + adjustR = (int)image->comps[0].prec - 8; + printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec); + } + else + adjustR = 0; + if (image->comps[1].prec > 8) { + adjustG = (int)image->comps[1].prec - 8; + printf("BMP CONVERSION: Truncating component 1 from %d bits to 8 bits\n", image->comps[1].prec); + } + else + adjustG = 0; + if (image->comps[2].prec > 8) { + adjustB = (int)image->comps[2].prec - 8; + printf("BMP CONVERSION: Truncating component 2 from %d bits to 8 bits\n", image->comps[2].prec); + } + else + adjustB = 0; - for (i = 0; i < 256; i++) { - fprintf(fdest, "%c%c%c%c", i, i, i, 0); - } + for (i = 0; i < w * h; i++) { + unsigned char rc, gc, bc; + int r, g, b; - for (i = 0; i < w * h; i++) { - int r; - - r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; - r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); - r = ((r >> adjustR)+((r >> (adjustR-1))%2)); - if(r > 255) r = 255; else if(r < 0) r = 0; + r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + r = ((r >> adjustR)+((r >> (adjustR-1))%2)); + if(r > 255) r = 255; else if(r < 0) r = 0; + rc = (unsigned char)r; - fprintf(fdest, "%c", (unsigned char)r); + g = image->comps[1].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + g += (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); + g = ((g >> adjustG)+((g >> (adjustG-1))%2)); + if(g > 255) g = 255; else if(g < 0) g = 0; + gc = (unsigned char)g; - if ((i + 1) % w == 0) { - for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--) /* ADD */ - fprintf(fdest, "%c", 0); - } - } - fclose(fdest); - } + b = image->comps[2].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + b += (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); + b = ((b >> adjustB)+((b >> (adjustB-1))%2)); + if(b > 255) b = 255; else if(b < 0) b = 0; + bc = (unsigned char)b; - return 0; + fprintf(fdest, "%c%c%c", bc, gc, rc); + + if ((i + 1) % w == 0) { + for (pad = (3 * w) % 4 ? 4 - (3 * w) % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(fdest, "%c", 0); + } + } + fclose(fdest); + } else { /* Gray-scale */ + + /* -->> -->> -->> -->> + 8 bits non code (Gray scale) + <<-- <<-- <<-- <<-- */ + + fdest = fopen(outfile, "wb"); + w = (int)image->comps[0].w; + h = (int)image->comps[0].h; + + fprintf(fdest, "BM"); + + /* FILE HEADER */ + /* ------------- */ + fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + 54 + 1024 + h * (w % 2)) & 0xff, + (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 8) & 0xff, + (unsigned char) ((h * w + 54 + 1024 + h * (w % 2)) >> 16) & 0xff, + (unsigned char) ((h * w + 54 + 1024 + w * (w % 2)) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (54 + 1024) & 0xff, ((54 + 1024) >> 8) & 0xff, + ((54 + 1024) >> 16) & 0xff, + ((54 + 1024) >> 24) & 0xff); + + /* INFO HEADER */ + /* ------------- */ + fprintf(fdest, "%c%c%c%c", (40) & 0xff, ((40) >> 8) & 0xff, ((40) >> 16) & 0xff, ((40) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((w) & 0xff), + (unsigned char) ((w) >> 8) & 0xff, + (unsigned char) ((w) >> 16) & 0xff, + (unsigned char) ((w) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) ((h) & 0xff), + (unsigned char) ((h) >> 8) & 0xff, + (unsigned char) ((h) >> 16) & 0xff, + (unsigned char) ((h) >> 24) & 0xff); + fprintf(fdest, "%c%c", (1) & 0xff, ((1) >> 8) & 0xff); + fprintf(fdest, "%c%c", (8) & 0xff, ((8) >> 8) & 0xff); + fprintf(fdest, "%c%c%c%c", (0) & 0xff, ((0) >> 8) & 0xff, ((0) >> 16) & 0xff, ((0) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (unsigned char) (h * w + h * (w % 2)) & 0xff, + (unsigned char) ((h * w + h * (w % 2)) >> 8) & 0xff, + (unsigned char) ((h * w + h * (w % 2)) >> 16) & 0xff, + (unsigned char) ((h * w + h * (w % 2)) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (7834) & 0xff, ((7834) >> 8) & 0xff, ((7834) >> 16) & 0xff, ((7834) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + fprintf(fdest, "%c%c%c%c", (256) & 0xff, ((256) >> 8) & 0xff, ((256) >> 16) & 0xff, ((256) >> 24) & 0xff); + + if (image->comps[0].prec > 8) { + adjustR = (int)image->comps[0].prec - 8; + printf("BMP CONVERSION: Truncating component 0 from %d bits to 8 bits\n", image->comps[0].prec); + }else + adjustR = 0; + + for (i = 0; i < 256; i++) { + fprintf(fdest, "%c%c%c%c", i, i, i, 0); + } + + for (i = 0; i < w * h; i++) { + int r; + + r = image->comps[0].data[w * h - ((i) / (w) + 1) * w + (i) % (w)]; + r += (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + r = ((r >> adjustR)+((r >> (adjustR-1))%2)); + if(r > 255) r = 255; else if(r < 0) r = 0; + + fprintf(fdest, "%c", (unsigned char)r); + + if ((i + 1) % w == 0) { + for (pad = w % 4 ? 4 - w % 4 : 0; pad > 0; pad--) /* ADD */ + fprintf(fdest, "%c", 0); + } + } + fclose(fdest); + } + + return 0; } /* -->> -->> -->> -->> @@ -1204,263 +1226,295 @@ PGX IMAGE FORMAT static unsigned char readuchar(FILE * f) { - unsigned char c1; - if ( !fread(&c1, 1, 1, f) ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return 0; - } - return c1; + unsigned char c1; + if ( !fread(&c1, 1, 1, f) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return 0; + } + return c1; } static unsigned short readushort(FILE * f, int bigendian) { - unsigned char c1, c2; - if ( !fread(&c1, 1, 1, f) ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return 0; - } - if ( !fread(&c2, 1, 1, f) ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return 0; - } - if (bigendian) - return (c1 << 8) + c2; - else - return (c2 << 8) + c1; + unsigned char c1, c2; + if ( !fread(&c1, 1, 1, f) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return 0; + } + if ( !fread(&c2, 1, 1, f) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return 0; + } + if (bigendian) + return (unsigned short)((c1 << 8) + c2); + else + return (unsigned short)((c2 << 8) + c1); } static unsigned int readuint(FILE * f, int bigendian) { - unsigned char c1, c2, c3, c4; - if ( !fread(&c1, 1, 1, f) ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return 0; - } - if ( !fread(&c2, 1, 1, f) ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return 0; - } - if ( !fread(&c3, 1, 1, f) ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return 0; - } - if ( !fread(&c4, 1, 1, f) ) - { - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - return 0; - } - if (bigendian) - return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4; - else - return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1; + unsigned char c1, c2, c3, c4; + if ( !fread(&c1, 1, 1, f) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return 0; + } + if ( !fread(&c2, 1, 1, f) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return 0; + } + if ( !fread(&c3, 1, 1, f) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return 0; + } + if ( !fread(&c4, 1, 1, f) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + return 0; + } + if (bigendian) + return (unsigned int)(c1 << 24) + (unsigned int)(c2 << 16) + (unsigned int)(c3 << 8) + c4; + else + return (unsigned int)(c4 << 24) + (unsigned int)(c3 << 16) + (unsigned int)(c2 << 8) + c1; } opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) { - FILE *f = NULL; - int w, h, prec; - int i, numcomps, max; - OPJ_COLOR_SPACE color_space; - opj_image_cmptparm_t cmptparm; /* maximum of 1 component */ - opj_image_t * image = NULL; - int adjustS, ushift, dshift, force8; + FILE *f = NULL; + int w, h, prec; + int i, numcomps, max; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm; /* maximum of 1 component */ + opj_image_t * image = NULL; + int adjustS, ushift, dshift, force8; - char endian1,endian2,sign; - char signtmp[32]; + char endian1,endian2,sign; + char signtmp[32]; - char temp[32]; - int bigendian; - opj_image_comp_t *comp = NULL; + char temp[32]; + int bigendian; + opj_image_comp_t *comp = NULL; - numcomps = 1; - color_space = OPJ_CLRSPC_GRAY; + numcomps = 1; + color_space = OPJ_CLRSPC_GRAY; - memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t)); + memset(&cmptparm, 0, sizeof(opj_image_cmptparm_t)); - max = 0; + max = 0; - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "Failed to open %s for reading !\n", filename); - return NULL; - } + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !\n", filename); + return NULL; + } - fseek(f, 0, SEEK_SET); - if( fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h) != 9){ - fprintf(stderr, "ERROR: Failed to read the right number of element from the fscanf() function!\n"); - return NULL; - } + fseek(f, 0, SEEK_SET); + if( fscanf(f, "PG%[ \t]%c%c%[ \t+-]%d%[ \t]%d%[ \t]%d",temp,&endian1,&endian2,signtmp,&prec,temp,&w,temp,&h) != 9){ + fprintf(stderr, "ERROR: Failed to read the right number of element from the fscanf() function!\n"); + return NULL; + } - i=0; - sign='+'; - while (signtmp[i]!='\0') { - if (signtmp[i]=='-') sign='-'; - i++; - } - - fgetc(f); - if (endian1=='M' && endian2=='L') { - bigendian = 1; - } else if (endian2=='M' && endian1=='L') { - bigendian = 0; - } else { - fprintf(stderr, "Bad pgx header, please check input file\n"); - return NULL; - } + i=0; + sign='+'; + while (signtmp[i]!='\0') { + if (signtmp[i]=='-') sign='-'; + i++; + } - /* initialize image component */ + fgetc(f); + if (endian1=='M' && endian2=='L') { + bigendian = 1; + } else if (endian2=='M' && endian1=='L') { + bigendian = 0; + } else { + fprintf(stderr, "Bad pgx header, please check input file\n"); + return NULL; + } - cmptparm.x0 = parameters->image_offset_x0; - cmptparm.y0 = parameters->image_offset_y0; - cmptparm.w = !cmptparm.x0 ? (w - 1) * parameters->subsampling_dx + 1 : cmptparm.x0 + (w - 1) * parameters->subsampling_dx + 1; - cmptparm.h = !cmptparm.y0 ? (h - 1) * parameters->subsampling_dy + 1 : cmptparm.y0 + (h - 1) * parameters->subsampling_dy + 1; - - if (sign == '-') { - cmptparm.sgnd = 1; - } else { - cmptparm.sgnd = 0; - } - if(prec < 8) - { - force8 = 1; - ushift = 8 - prec; dshift = prec - ushift; - if(cmptparm.sgnd) adjustS = (1<<(prec - 1)); else adjustS = 0; - cmptparm.sgnd = 0; - prec = 8; - } - else ushift = dshift = force8 = adjustS = 0; + /* initialize image component */ - cmptparm.prec = prec; - cmptparm.bpp = prec; - cmptparm.dx = parameters->subsampling_dx; - cmptparm.dy = parameters->subsampling_dy; - - /* create the image */ - image = opj_image_create(numcomps, &cmptparm, color_space); - if(!image) { - fclose(f); - return NULL; - } - /* set image offset and reference grid */ - image->x0 = cmptparm.x0; - image->y0 = cmptparm.x0; - image->x1 = cmptparm.w; - image->y1 = cmptparm.h; + cmptparm.x0 = (OPJ_UINT32)parameters->image_offset_x0; + cmptparm.y0 = (OPJ_UINT32)parameters->image_offset_y0; + cmptparm.w = !cmptparm.x0 ? (OPJ_UINT32)((w - 1) * parameters->subsampling_dx + 1) : cmptparm.x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)parameters->subsampling_dx + 1; + cmptparm.h = !cmptparm.y0 ? (OPJ_UINT32)((h - 1) * parameters->subsampling_dy + 1) : cmptparm.y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)parameters->subsampling_dy + 1; - /* set image data */ + if (sign == '-') { + cmptparm.sgnd = 1; + } else { + cmptparm.sgnd = 0; + } + if(prec < 8) + { + force8 = 1; + ushift = 8 - prec; dshift = prec - ushift; + if(cmptparm.sgnd) adjustS = (1<<(prec - 1)); else adjustS = 0; + cmptparm.sgnd = 0; + prec = 8; + } + else ushift = dshift = force8 = adjustS = 0; - comp = &image->comps[0]; + cmptparm.prec = (OPJ_UINT32)prec; + cmptparm.bpp = (OPJ_UINT32)prec; + cmptparm.dx = (OPJ_UINT32)parameters->subsampling_dx; + cmptparm.dy = (OPJ_UINT32)parameters->subsampling_dy; - for (i = 0; i < w * h; i++) { - int v; - if(force8) - { - v = readuchar(f) + adjustS; - v = (v<>dshift); - comp->data[i] = (unsigned char)v; + /* create the image */ + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm, color_space); + if(!image) { + fclose(f); + return NULL; + } + /* set image offset and reference grid */ + image->x0 = cmptparm.x0; + image->y0 = cmptparm.x0; + image->x1 = cmptparm.w; + image->y1 = cmptparm.h; - if(v > max) max = v; + /* set image data */ - continue; - } - if (comp->prec == 8) { - if (!comp->sgnd) { - v = readuchar(f); - } else { - v = (char) readuchar(f); - } - } else if (comp->prec <= 16) { - if (!comp->sgnd) { - v = readushort(f, bigendian); - } else { - v = (short) readushort(f, bigendian); - } - } else { - if (!comp->sgnd) { - v = readuint(f, bigendian); - } else { - v = (int) readuint(f, bigendian); - } - } - if (v > max) - max = v; - comp->data[i] = v; - } - fclose(f); - comp->bpp = int_floorlog2(max) + 1; + comp = &image->comps[0]; - return image; + for (i = 0; i < w * h; i++) { + int v; + if(force8) + { + v = readuchar(f) + adjustS; + v = (v<>dshift); + comp->data[i] = (unsigned char)v; + + if(v > max) max = v; + + continue; + } + if (comp->prec == 8) { + if (!comp->sgnd) { + v = readuchar(f); + } else { + v = (char) readuchar(f); + } + } else if (comp->prec <= 16) { + if (!comp->sgnd) { + v = readushort(f, bigendian); + } else { + v = (short) readushort(f, bigendian); + } + } else { + if (!comp->sgnd) { + v = (int)readuint(f, bigendian); + } else { + v = (int) readuint(f, bigendian); + } + } + if (v > max) + max = v; + comp->data[i] = v; + } + fclose(f); + comp->bpp = (OPJ_UINT32)int_floorlog2(max) + 1; + + return image; } -int imagetopgx(opj_image_t * image, const char *outfile) { - int w, h; - int i, j, compno; - FILE *fdest = NULL; +#define CLAMP(x,a,b) x < a ? a : (x > b ? b : x) - for (compno = 0; compno < image->numcomps; compno++) { - opj_image_comp_t *comp = &image->comps[compno]; - char bname[256]; /* buffer for name */ +static INLINE int clamp( const int value, const int prec, const int sgnd ) +{ + if( sgnd ) + { + if (prec <= 8) return CLAMP(value,-128,127); + else if (prec <= 16) return CLAMP(value,-32768,32767); + else return CLAMP(value,-2147483647-1,2147483647); + } + else + { + if (prec <= 8) return CLAMP(value,0,255); + else if (prec <= 16) return CLAMP(value,0,65535); + else return value; /*CLAMP(value,0,4294967295);*/ + } +} + +int imagetopgx(opj_image_t * image, const char *outfile) +{ + int w, h; + int i, j, fails = 1; + unsigned int compno; + FILE *fdest = NULL; + + for (compno = 0; compno < image->numcomps; compno++) + { + opj_image_comp_t *comp = &image->comps[compno]; + char bname[256]; /* buffer for name */ char *name = bname; /* pointer */ int nbytes = 0; size_t res; const size_t olen = strlen(outfile); const size_t dotpos = olen - 4; const size_t total = dotpos + 1 + 1 + 4; /* '-' + '[1-3]' + '.pgx' */ - if( outfile[dotpos] != '.' ) { + + if( outfile[dotpos] != '.' ) + { /* `pgx` was recognized but there is no dot at expected position */ fprintf(stderr, "ERROR -> Impossible happen." ); - return 1; + goto fin; } - if( total > 256 ) { + if( total > 256 ) + { name = (char*)malloc(total+1); } strncpy(name, outfile, dotpos); - /*if (image->numcomps > 1) {*/ - sprintf(name+dotpos, "_%d.pgx", compno); - /*} else { - strcpy(name+dotpos, ".pgx"); - }*/ - fdest = fopen(name, "wb"); - if (!fdest) { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); - return 1; - } + sprintf(name+dotpos, "_%d.pgx", compno); + fdest = fopen(name, "wb"); /* dont need name anymore */ - if( total > 256 ) { - free(name); + if( total > 256 ) free(name); + if (!fdest) + { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", name); + goto fin; } - w = image->comps[compno].w; - h = image->comps[compno].h; - - fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, w, h); - if (comp->prec <= 8) { - nbytes = 1; - } else if (comp->prec <= 16) { - nbytes = 2; - } else { - nbytes = 4; - } - for (i = 0; i < w * h; i++) { - int v = image->comps[compno].data[i]; - for (j = nbytes - 1; j >= 0; j--) { - char byte = (char) (v >> (j * 8)); - res = fwrite(&byte, 1, 1, fdest); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", name); - return 1; - } - } - } - fclose(fdest); - } + w = (int)image->comps[compno].w; + h = (int)image->comps[compno].h; - return 0; + fprintf(fdest, "PG ML %c %d %d %d\n", comp->sgnd ? '-' : '+', comp->prec, + w, h); + + if (comp->prec <= 8) + nbytes = 1; + else if (comp->prec <= 16) + nbytes = 2; + else + nbytes = 4; + + for (i = 0; i < w * h; i++) + { + /* FIXME: clamp func is being called within a loop */ + const int val = clamp(image->comps[compno].data[i], + (int)comp->prec, (int)comp->sgnd); + + for (j = nbytes - 1; j >= 0; j--) + { + int v = (int)(val >> (j * 8)); + unsigned char byte = (unsigned char)v; + res = fwrite(&byte, 1, 1, fdest); + + if( res < 1 ) + { + fprintf(stderr, "failed to write 1 byte for %s\n", name); + goto fin; + } + } + } + fclose(fdest); fdest = NULL; + } + fails = 0; +fin: + if(fdest) fclose(fdest); + + return fails; } /* -->> -->> -->> -->> @@ -1479,11 +1533,11 @@ struct pnm_header static char *skip_white(char *s) { while(*s) - { - if(*s == '\n' || *s == '\r') return NULL; - if(isspace(*s)) { ++s; continue; } - return s; - } + { + if(*s == '\n' || *s == '\r') return NULL; + if(isspace(*s)) { ++s; continue; } + return s; + } return NULL; } @@ -1499,10 +1553,10 @@ static char *skip_int(char *start, int *out_n) start = s; while(*s) - { - if( !isdigit(*s)) break; - ++s; - } + { + if( !isdigit(*s)) break; + ++s; + } c = *s; *s = 0; *out_n = atoi(start); *s = c; return s; } @@ -1517,10 +1571,10 @@ static char *skip_idf(char *start, char out_idf[256]) start = s; while(*s) - { - if(isalpha(*s) || *s == '_') { ++s; continue; } - break; - } + { + if(isalpha(*s) || *s == '_') { ++s; continue; } + break; + } c = *s; *s = 0; strncpy(out_idf, start, 255); *s = c; return s; } @@ -1534,149 +1588,149 @@ static void read_pnm_header(FILE *reader, struct pnm_header *ph) if (fgets(line, 250, reader) == NULL) { - fprintf(stderr,"\nWARNING: fgets return a NULL value"); - return; + fprintf(stderr,"\nWARNING: fgets return a NULL value"); + return; } if(line[0] != 'P') - { - fprintf(stderr,"read_pnm_header:PNM:magic P missing\n"); return; - } + { + fprintf(stderr,"read_pnm_header:PNM:magic P missing\n"); return; + } format = atoi(line + 1); if(format < 1 || format > 7) - { - fprintf(stderr,"read_pnm_header:magic format %d invalid\n", format); - return; - } + { + fprintf(stderr,"read_pnm_header:magic format %d invalid\n", format); + return; + } ph->format = format; ttype = end = have_wh = 0; while(fgets(line, 250, reader)) - { - if(*line == '#') continue; + { + if(*line == '#') continue; - s = line; + s = line; - if(format == 7) - { - s = skip_idf(s, idf); + if(format == 7) + { + s = skip_idf(s, idf); - if(s == NULL || *s == 0) return; + if(s == NULL || *s == 0) return; - if(strcmp(idf, "ENDHDR") == 0) - { - end = 1; break; - } - if(strcmp(idf, "WIDTH") == 0) - { - s = skip_int(s, &ph->width); - if(s == NULL || *s == 0) return; + if(strcmp(idf, "ENDHDR") == 0) + { + end = 1; break; + } + if(strcmp(idf, "WIDTH") == 0) + { + s = skip_int(s, &ph->width); + if(s == NULL || *s == 0) return; - continue; - } - if(strcmp(idf, "HEIGHT") == 0) - { - s = skip_int(s, &ph->height); - if(s == NULL || *s == 0) return; + continue; + } + if(strcmp(idf, "HEIGHT") == 0) + { + s = skip_int(s, &ph->height); + if(s == NULL || *s == 0) return; - continue; - } - if(strcmp(idf, "DEPTH") == 0) - { - s = skip_int(s, &ph->depth); - if(s == NULL || *s == 0) return; + continue; + } + if(strcmp(idf, "DEPTH") == 0) + { + s = skip_int(s, &ph->depth); + if(s == NULL || *s == 0) return; - continue; - } - if(strcmp(idf, "MAXVAL") == 0) - { - s = skip_int(s, &ph->maxval); - if(s == NULL || *s == 0) return; + continue; + } + if(strcmp(idf, "MAXVAL") == 0) + { + s = skip_int(s, &ph->maxval); + if(s == NULL || *s == 0) return; - continue; - } - if(strcmp(idf, "TUPLTYPE") == 0) - { - s = skip_idf(s, type); - if(s == NULL || *s == 0) return; + continue; + } + if(strcmp(idf, "TUPLTYPE") == 0) + { + s = skip_idf(s, type); + if(s == NULL || *s == 0) return; - if(strcmp(type, "BLACKANDWHITE") == 0) - { - ph->bw = 1; ttype = 1; continue; - } - if(strcmp(type, "GRAYSCALE") == 0) - { - ph->gray = 1; ttype = 1; continue; - } - if(strcmp(type, "GRAYSCALE_ALPHA") == 0) - { - ph->graya = 1; ttype = 1; continue; - } - if(strcmp(type, "RGB") == 0) - { - ph->rgb = 1; ttype = 1; continue; - } - if(strcmp(type, "RGB_ALPHA") == 0) - { - ph->rgba = 1; ttype = 1; continue; - } - fprintf(stderr,"read_pnm_header:unknown P7 TUPLTYPE %s\n",type); - return; - } - fprintf(stderr,"read_pnm_header:unknown P7 idf %s\n",idf); - return; - } /* if(format == 7) */ + if(strcmp(type, "BLACKANDWHITE") == 0) + { + ph->bw = 1; ttype = 1; continue; + } + if(strcmp(type, "GRAYSCALE") == 0) + { + ph->gray = 1; ttype = 1; continue; + } + if(strcmp(type, "GRAYSCALE_ALPHA") == 0) + { + ph->graya = 1; ttype = 1; continue; + } + if(strcmp(type, "RGB") == 0) + { + ph->rgb = 1; ttype = 1; continue; + } + if(strcmp(type, "RGB_ALPHA") == 0) + { + ph->rgba = 1; ttype = 1; continue; + } + fprintf(stderr,"read_pnm_header:unknown P7 TUPLTYPE %s\n",type); + return; + } + fprintf(stderr,"read_pnm_header:unknown P7 idf %s\n",idf); + return; + } /* if(format == 7) */ - if( !have_wh) - { - s = skip_int(s, &ph->width); + if( !have_wh) + { + s = skip_int(s, &ph->width); - s = skip_int(s, &ph->height); + s = skip_int(s, &ph->height); - have_wh = 1; + have_wh = 1; - if(format == 1 || format == 4) break; + if(format == 1 || format == 4) break; - continue; - } - if(format == 2 || format == 3 || format == 5 || format == 6) - { -/* P2, P3, P5, P6: */ - s = skip_int(s, &ph->maxval); + continue; + } + if(format == 2 || format == 3 || format == 5 || format == 6) + { + /* P2, P3, P5, P6: */ + s = skip_int(s, &ph->maxval); - if(ph->maxval > 65535) return; - } - break; - }/* while(fgets( ) */ + if(ph->maxval > 65535) return; + } + break; + }/* while(fgets( ) */ if(format == 2 || format == 3 || format > 4) - { - if(ph->maxval < 1 || ph->maxval > 65535) return; - } + { + if(ph->maxval < 1 || ph->maxval > 65535) return; + } if(ph->width < 1 || ph->height < 1) return; if(format == 7) - { - if(!end) - { - fprintf(stderr,"read_pnm_header:P7 without ENDHDR\n"); return; - } - if(ph->depth < 1 || ph->depth > 4) return; + { + if(!end) + { + fprintf(stderr,"read_pnm_header:P7 without ENDHDR\n"); return; + } + if(ph->depth < 1 || ph->depth > 4) return; - if(ph->width && ph->height && ph->depth & ph->maxval && ttype) - ph->ok = 1; - } + if(ph->width && ph->height && ph->depth && ph->maxval && ttype) + ph->ok = 1; + } else - { - if(format != 1 && format != 4) - { - if(ph->width && ph->height && ph->maxval) ph->ok = 1; - } - else - { - if(ph->width && ph->height) ph->ok = 1; - ph->maxval = 255; - } - } + { + if(format != 1 && format != 4) + { + if(ph->width && ph->height && ph->maxval) ph->ok = 1; + } + else + { + if(ph->width && ph->height) ph->ok = 1; + ph->maxval = 255; + } + } } static int has_prec(int val) @@ -1700,31 +1754,31 @@ static int has_prec(int val) } opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) { - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; - FILE *fp = NULL; - int i, compno, numcomps, w, h, prec, format; - OPJ_COLOR_SPACE color_space; - opj_image_cmptparm_t cmptparm[4]; /* RGBA: max. 4 components */ - opj_image_t * image = NULL; - struct pnm_header header_info; - - if((fp = fopen(filename, "rb")) == NULL) - { - fprintf(stderr, "pnmtoimage:Failed to open %s for reading!\n",filename); - return NULL; - } - memset(&header_info, 0, sizeof(struct pnm_header)); + FILE *fp = NULL; + int i, compno, numcomps, w, h, prec, format; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm[4]; /* RGBA: max. 4 components */ + opj_image_t * image = NULL; + struct pnm_header header_info; - read_pnm_header(fp, &header_info); + if((fp = fopen(filename, "rb")) == NULL) + { + fprintf(stderr, "pnmtoimage:Failed to open %s for reading!\n",filename); + return NULL; + } + memset(&header_info, 0, sizeof(struct pnm_header)); - if(!header_info.ok) { fclose(fp); return NULL; } + read_pnm_header(fp, &header_info); - format = header_info.format; + if(!header_info.ok) { fclose(fp); return NULL; } + + format = header_info.format; switch(format) - { + { case 1: /* ascii bitmap */ case 4: /* raw bitmap */ numcomps = 1; @@ -1742,141 +1796,145 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) { case 7: /* arbitrary map */ numcomps = header_info.depth; - break; + break; default: fclose(fp); return NULL; - } + } if(numcomps < 3) - color_space = OPJ_CLRSPC_GRAY;/* GRAY, GRAYA */ + color_space = OPJ_CLRSPC_GRAY;/* GRAY, GRAYA */ else - color_space = OPJ_CLRSPC_SRGB;/* RGB, RGBA */ + color_space = OPJ_CLRSPC_SRGB;/* RGB, RGBA */ prec = has_prec(header_info.maxval); - if(prec < 8) prec = 8; + if(prec < 8) prec = 8; w = header_info.width; h = header_info.height; subsampling_dx = parameters->subsampling_dx; subsampling_dy = parameters->subsampling_dy; - memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t)); + memset(&cmptparm[0], 0, (size_t)numcomps * sizeof(opj_image_cmptparm_t)); for(i = 0; i < numcomps; i++) - { - cmptparm[i].prec = prec; - cmptparm[i].bpp = prec; - cmptparm[i].sgnd = 0; - cmptparm[i].dx = subsampling_dx; - cmptparm[i].dy = subsampling_dy; - cmptparm[i].w = w; - cmptparm[i].h = h; - } - image = opj_image_create(numcomps, &cmptparm[0], color_space); + { + cmptparm[i].prec = (OPJ_UINT32)prec; + cmptparm[i].bpp = (OPJ_UINT32)prec; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = (OPJ_UINT32)subsampling_dx; + cmptparm[i].dy = (OPJ_UINT32)subsampling_dy; + cmptparm[i].w = (OPJ_UINT32)w; + cmptparm[i].h = (OPJ_UINT32)h; + } + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); if(!image) { fclose(fp); return NULL; } -/* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1; - image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1; + /* set image offset and reference grid */ + image->x0 = (OPJ_UINT32)parameters->image_offset_x0; + image->y0 = (OPJ_UINT32)parameters->image_offset_y0; + image->x1 = (OPJ_UINT32)(parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1); + image->y1 = (OPJ_UINT32)(parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1); if((format == 2) || (format == 3)) /* ascii pixmap */ - { - unsigned int index; + { + unsigned int index; - for (i = 0; i < w * h; i++) - { - for(compno = 0; compno < numcomps; compno++) - { - index = 0; - if (fscanf(fp, "%u", &index) != 1) - fprintf(stderr, "\nWARNING: fscanf return a number of element different from the expected.\n"); + for (i = 0; i < w * h; i++) + { + for(compno = 0; compno < numcomps; compno++) + { + index = 0; + if (fscanf(fp, "%u", &index) != 1) + fprintf(stderr, "\nWARNING: fscanf return a number of element different from the expected.\n"); - image->comps[compno].data[i] = (index * 255)/header_info.maxval; - } - } - } + image->comps[compno].data[i] = (OPJ_INT32)(index * 255)/header_info.maxval; + } + } + } else - if((format == 5) - || (format == 6) - ||((format == 7) - && ( header_info.gray || header_info.graya - || header_info.rgb || header_info.rgba)))/* binary pixmap */ - { - unsigned char c0, c1, one; + if((format == 5) + || (format == 6) + ||((format == 7) + && ( header_info.gray || header_info.graya + || header_info.rgb || header_info.rgba)))/* binary pixmap */ + { + unsigned char c0, c1, one; - one = (prec < 9); + one = (prec < 9); - for (i = 0; i < w * h; i++) - { - for(compno = 0; compno < numcomps; compno++) - { - if ( !fread(&c0, 1, 1, fp) ) - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - if(one) - { - image->comps[compno].data[i] = c0; - } + for (i = 0; i < w * h; i++) + { + for(compno = 0; compno < numcomps; compno++) + { + if ( !fread(&c0, 1, 1, fp) ) + { + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + opj_image_destroy(image); + return NULL; + } + if(one) + { + image->comps[compno].data[i] = c0; + } + else + { + if ( !fread(&c1, 1, 1, fp) ) + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + /* netpbm: */ + image->comps[compno].data[i] = ((c0<<8) | c1); + } + } + } + } else - { - if ( !fread(&c1, 1, 1, fp) ) - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); -/* netpbm: */ - image->comps[compno].data[i] = ((c0<<8) | c1); - } - } - } - } - else - if(format == 1) /* ascii bitmap */ - { - for (i = 0; i < w * h; i++) - { - unsigned int index; + if(format == 1) /* ascii bitmap */ + { + for (i = 0; i < w * h; i++) + { + unsigned int index; - if ( fscanf(fp, "%u", &index) != 1) - fprintf(stderr, "\nWARNING: fscanf return a number of element different from the expected.\n"); + if ( fscanf(fp, "%u", &index) != 1) + fprintf(stderr, "\nWARNING: fscanf return a number of element different from the expected.\n"); - image->comps[0].data[i] = (index?0:255); - } - } - else - if(format == 4) - { - int x, y, bit; - unsigned char uc; + image->comps[0].data[i] = (index?0:255); + } + } + else + if(format == 4) + { + int x, y, bit; + unsigned char uc; - i = 0; - for(y = 0; y < h; ++y) - { - bit = -1; uc = 0; + i = 0; + for(y = 0; y < h; ++y) + { + bit = -1; uc = 0; - for(x = 0; x < w; ++x) - { - if(bit == -1) - { - bit = 7; - uc = (unsigned char)getc(fp); - } - image->comps[0].data[i] = (((uc>>bit) & 1)?0:255); - --bit; ++i; - } - } - } - else - if((format == 7 && header_info.bw)) /*MONO*/ - { - unsigned char uc; + for(x = 0; x < w; ++x) + { + if(bit == -1) + { + bit = 7; + uc = (unsigned char)getc(fp); + } + image->comps[0].data[i] = (((uc>>bit) & 1)?0:255); + --bit; ++i; + } + } + } + else + if((format == 7 && header_info.bw)) /*MONO*/ + { + unsigned char uc; - for(i = 0; i < w * h; ++i) - { - if ( !fread(&uc, 1, 1, fp) ) - fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); - image->comps[0].data[i] = (uc & 1)?0:255; - } - } + for(i = 0; i < w * h; ++i) + { + if ( !fread(&uc, 1, 1, fp) ) + fprintf(stderr, "\nError: fread return a number of element different from the expected.\n"); + image->comps[0].data[i] = (uc & 1)?0:255; + } + } fclose(fp); return image; @@ -1884,563 +1942,633 @@ opj_image_t* pnmtoimage(const char *filename, opj_cparameters_t *parameters) { int imagetopnm(opj_image_t * image, const char *outfile) { - int *red, *green, *blue, *alpha; - int wr, hr, max; - int i, compno, ncomp; - int adjustR, adjustG, adjustB, adjustA; - int fails, two, want_gray, has_alpha, triple; - int prec, v; - FILE *fdest = NULL; - const char *tmp = outfile; - char *destname; - alpha = NULL; - if((prec = image->comps[0].prec) > 16) - { - fprintf(stderr,"%s:%d:imagetopnm\n\tprecision %d is larger than 16" - "\n\t: refused.\n",__FILE__,__LINE__,prec); - return 1; - } + int *red, *green, *blue, *alpha; + int wr, hr, max; + int i; + unsigned int compno, ncomp; + int adjustR, adjustG, adjustB, adjustA; + int fails, two, want_gray, has_alpha, triple; + int prec, v; + FILE *fdest = NULL; + const char *tmp = outfile; + char *destname; + + alpha = NULL; + + if((prec = (int)image->comps[0].prec) > 16) + { + fprintf(stderr,"%s:%d:imagetopnm\n\tprecision %d is larger than 16" + "\n\t: refused.\n",__FILE__,__LINE__,prec); + return 1; + } two = has_alpha = 0; fails = 1; - ncomp = image->numcomps; + ncomp = image->numcomps; - while (*tmp) ++tmp; tmp -= 2; - want_gray = (*tmp == 'g' || *tmp == 'G'); - ncomp = image->numcomps; + while (*tmp) ++tmp; tmp -= 2; + want_gray = (*tmp == 'g' || *tmp == 'G'); + ncomp = image->numcomps; - if(want_gray) ncomp = 1; + if(want_gray) ncomp = 1; - if (ncomp == 2 /* GRAYA */ - || (ncomp > 2 /* RGB, RGBA */ - && image->comps[0].dx == image->comps[1].dx - && image->comps[1].dx == image->comps[2].dx - && image->comps[0].dy == image->comps[1].dy - && image->comps[1].dy == image->comps[2].dy - && image->comps[0].prec == image->comps[1].prec - && image->comps[1].prec == image->comps[2].prec - )) - { - fdest = fopen(outfile, "wb"); + if (ncomp == 2 /* GRAYA */ + || (ncomp > 2 /* RGB, RGBA */ + && image->comps[0].dx == image->comps[1].dx + && image->comps[1].dx == image->comps[2].dx + && image->comps[0].dy == image->comps[1].dy + && image->comps[1].dy == image->comps[2].dy + && image->comps[0].prec == image->comps[1].prec + && image->comps[1].prec == image->comps[2].prec + )) + { + fdest = fopen(outfile, "wb"); - if (!fdest) - { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", outfile); - return fails; - } - two = (prec > 8); - triple = (ncomp > 2); - wr = image->comps[0].w; hr = image->comps[0].h; - max = (1< failed to open %s for writing\n", outfile); + return fails; + } + two = (prec > 8); + triple = (ncomp > 2); + wr = (int)image->comps[0].w; hr = (int)image->comps[0].h; + max = (1<comps[0].data; + red = image->comps[0].data; - if(triple) - { - green = image->comps[1].data; - blue = image->comps[2].data; - } - else green = blue = NULL; - - if(has_alpha) - { - const char *tt = (triple?"RGB_ALPHA":"GRAYSCALE_ALPHA"); - - fprintf(fdest, "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH %d\n" - "MAXVAL %d\nTUPLTYPE %s\nENDHDR\n", opj_version(), - wr, hr, ncomp, max, tt); - alpha = image->comps[ncomp - 1].data; - adjustA = (image->comps[ncomp - 1].sgnd ? - 1 << (image->comps[ncomp - 1].prec - 1) : 0); - } - else - { - fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n", - opj_version(), wr, hr, max); - adjustA = 0; - } - adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); - - if(triple) - { - adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); - adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); - } - else adjustG = adjustB = 0; - - for(i = 0; i < wr * hr; ++i) - { - if(two) - { - v = *red + adjustR; ++red; -/* netpbm: */ - fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); - - if(triple) - { - v = *green + adjustG; ++green; -/* netpbm: */ - fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); - - v = *blue + adjustB; ++blue; -/* netpbm: */ - fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); - - }/* if(triple) */ + if(triple) + { + green = image->comps[1].data; + blue = image->comps[2].data; + } + else green = blue = NULL; if(has_alpha) - { - v = *alpha + adjustA; ++alpha; -/* netpbm: */ - fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); - } - continue; + { + const char *tt = (triple?"RGB_ALPHA":"GRAYSCALE_ALPHA"); - } /* if(two) */ + fprintf(fdest, "P7\n# OpenJPEG-%s\nWIDTH %d\nHEIGHT %d\nDEPTH %d\n" + "MAXVAL %d\nTUPLTYPE %s\nENDHDR\n", opj_version(), + wr, hr, ncomp, max, tt); + alpha = image->comps[ncomp - 1].data; + adjustA = (image->comps[ncomp - 1].sgnd ? + 1 << (image->comps[ncomp - 1].prec - 1) : 0); + } + else + { + fprintf(fdest, "P6\n# OpenJPEG-%s\n%d %d\n%d\n", + opj_version(), wr, hr, max); + adjustA = 0; + } + adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); -/* prec <= 8: */ + if(triple) + { + adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); + adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); + } + else adjustG = adjustB = 0; - fprintf(fdest, "%c", (unsigned char)*red++); - if(triple) - fprintf(fdest, "%c%c",(unsigned char)*green++, (unsigned char)*blue++); + for(i = 0; i < wr * hr; ++i) + { + if(two) + { + v = *red + adjustR; ++red; +if(v > 65535) v = 65535; else if(v < 0) v = 0; - if(has_alpha) - fprintf(fdest, "%c", (unsigned char)*alpha++); + /* netpbm: */ + fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); - } /* for(i */ + if(triple) + { + v = *green + adjustG; ++green; +if(v > 65535) v = 65535; else if(v < 0) v = 0; - fclose(fdest); return 0; - } + /* netpbm: */ + fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); -/* YUV or MONO: */ + v = *blue + adjustB; ++blue; +if(v > 65535) v = 65535; else if(v < 0) v = 0; - if (image->numcomps > ncomp) - { - fprintf(stderr,"WARNING -> [PGM file] Only the first component\n"); - fprintf(stderr," is written to the file\n"); - } - destname = (char*)malloc(strlen(outfile) + 8); + /* netpbm: */ + fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); - for (compno = 0; compno < ncomp; compno++) - { - if (ncomp > 1) - sprintf(destname, "%d.%s", compno, outfile); - else - sprintf(destname, "%s", outfile); + }/* if(triple) */ - fdest = fopen(destname, "wb"); - if (!fdest) - { - fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname); - free(destname); - return 1; - } - wr = image->comps[compno].w; hr = image->comps[compno].h; - prec = image->comps[compno].prec; - max = (1< 65535) v = 65535; else if(v < 0) v = 0; - fprintf(fdest, "P5\n#OpenJPEG-%s\n%d %d\n%d\n", - opj_version(), wr, hr, max); + /* netpbm: */ + fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); + } + continue; - red = image->comps[compno].data; - adjustR = - (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0); + } /* if(two) */ - if(prec > 8) - { - for (i = 0; i < wr * hr; i++) + /* prec <= 8: */ + v = *red++; + if(v > 255) v = 255; else if(v < 0) v = 0; + + fprintf(fdest, "%c", (unsigned char)v); + if(triple) { - v = *red + adjustR; ++red; -/* netpbm: */ - fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); + v = *green++; + if(v > 255) v = 255; else if(v < 0) v = 0; - if(has_alpha) - { - v = *alpha++; -/* netpbm: */ - fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); - } - }/* for(i */ - } - else /* prec <= 8 */ - { - for(i = 0; i < wr * hr; ++i) - { - fprintf(fdest, "%c", (unsigned char)(*red + adjustR)); ++red; + fprintf(fdest, "%c", (unsigned char)v); + v = *blue++; + if(v > 255) v = 255; else if(v < 0) v = 0; + + fprintf(fdest, "%c", (unsigned char)v); } - } - fclose(fdest); - } /* for (compno */ - free(destname); + if(has_alpha) + { + v = *alpha++; + if(v > 255) v = 255; else if(v < 0) v = 0; - return 0; + fprintf(fdest, "%c", (unsigned char)v); + } + } /* for(i */ + + fclose(fdest); return 0; + } + + /* YUV or MONO: */ + + if (image->numcomps > ncomp) + { + fprintf(stderr,"WARNING -> [PGM file] Only the first component\n"); + fprintf(stderr," is written to the file\n"); + } + destname = (char*)malloc(strlen(outfile) + 8); + + for (compno = 0; compno < ncomp; compno++) + { + if (ncomp > 1) + { + /*sprintf(destname, "%d.%s", compno, outfile);*/ + const size_t olen = strlen(outfile); + const size_t dotpos = olen - 4; + + strncpy(destname, outfile, dotpos); + sprintf(destname+dotpos, "_%d.pgm", compno); + } + else + sprintf(destname, "%s", outfile); + + fdest = fopen(destname, "wb"); + if (!fdest) + { + fprintf(stderr, "ERROR -> failed to open %s for writing\n", destname); + free(destname); + return 1; + } + wr = (int)image->comps[compno].w; hr = (int)image->comps[compno].h; + prec = (int)image->comps[compno].prec; + max = (1<comps[compno].data; + adjustR = + (image->comps[compno].sgnd ? 1 << (image->comps[compno].prec - 1) : 0); + + if(prec > 8) + { + for (i = 0; i < wr * hr; i++) + { + v = *red + adjustR; ++red; +if(v > 65535) v = 65535; else if(v < 0) v = 0; + + /* netpbm: */ + fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); + + if(has_alpha) + { + v = *alpha++; +if(v > 65535) v = 65535; else if(v < 0) v = 0; + + /* netpbm: */ + fprintf(fdest, "%c%c",(unsigned char)(v>>8), (unsigned char)v); + } + }/* for(i */ + } + else /* prec <= 8 */ + { + for(i = 0; i < wr * hr; ++i) + { + v = *red + adjustR; ++red; + if(v > 255) v = 255; else if(v < 0) v = 0; + + fprintf(fdest, "%c", (unsigned char)v); + } + } + fclose(fdest); + } /* for (compno */ + free(destname); + + return 0; }/* imagetopnm() */ -#ifdef HAVE_LIBTIFF +#ifdef OPJ_HAVE_LIBTIFF /* -->> -->> -->> -->> - TIFF IMAGE FORMAT + TIFF IMAGE FORMAT <<-- <<-- <<-- <<-- */ int imagetotif(opj_image_t * image, const char *outfile) { - int width, height, imgsize; - int bps,index,adjust, sgnd; - int ushift, dshift, has_alpha, force16; - TIFF *tif; - tdata_t buf; - tstrip_t strip; - tsize_t strip_size; + int width, height, imgsize; + int bps,index,adjust, sgnd; + int ushift, dshift, has_alpha, force16; + TIFF *tif; + tdata_t buf; + tstrip_t strip; + tsize_t strip_size; - ushift = dshift = force16 = has_alpha = 0; - bps = image->comps[0].prec; + ushift = dshift = force16 = has_alpha = 0; + bps = (int)image->comps[0].prec; - if(bps > 8 && bps < 16) - { - ushift = 16 - bps; dshift = bps - ushift; - bps = 16; force16 = 1; - } + if(bps > 8 && bps < 16) + { + ushift = 16 - bps; dshift = bps - ushift; + bps = 16; force16 = 1; + } - if(bps != 8 && bps != 16) - { - fprintf(stderr,"imagetotif: Bits=%d, Only 8 and 16 bits implemented\n", - bps); - fprintf(stderr,"\tAborting\n"); - return 1; - } - tif = TIFFOpen(outfile, "wb"); + if(bps != 8 && bps != 16) + { + fprintf(stderr,"imagetotif: Bits=%d, Only 8 and 16 bits implemented\n", + bps); + fprintf(stderr,"\tAborting\n"); + return 1; + } + tif = TIFFOpen(outfile, "wb"); - if (!tif) - { - fprintf(stderr, "imagetotif:failed to open %s for writing\n", outfile); - return 1; - } - sgnd = image->comps[0].sgnd; - adjust = sgnd ? 1 << (image->comps[0].prec - 1) : 0; + if (!tif) + { + fprintf(stderr, "imagetotif:failed to open %s for writing\n", outfile); + return 1; + } + sgnd = (int)image->comps[0].sgnd; + adjust = sgnd ? 1 << (image->comps[0].prec - 1) : 0; - if(image->numcomps >= 3 - && image->comps[0].dx == image->comps[1].dx - && image->comps[1].dx == image->comps[2].dx - && image->comps[0].dy == image->comps[1].dy - && image->comps[1].dy == image->comps[2].dy - && image->comps[0].prec == image->comps[1].prec - && image->comps[1].prec == image->comps[2].prec) - { - has_alpha = (image->numcomps == 4); + if(image->numcomps >= 3 + && image->comps[0].dx == image->comps[1].dx + && image->comps[1].dx == image->comps[2].dx + && image->comps[0].dy == image->comps[1].dy + && image->comps[1].dy == image->comps[2].dy + && image->comps[0].prec == image->comps[1].prec + && image->comps[1].prec == image->comps[2].prec) + { + has_alpha = (image->numcomps == 4); - width = image->comps[0].w; - height = image->comps[0].h; - imgsize = width * height ; - - TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); - TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height); - TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3 + has_alpha); - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); - TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); - TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); - strip_size = TIFFStripSize(tif); - buf = _TIFFmalloc(strip_size); - index=0; + width = (int)image->comps[0].w; + height = (int)image->comps[0].h; + imgsize = width * height ; - for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++) - { - unsigned char *dat8; - tsize_t i, ssize, last_i = 0; - int step, restx; - ssize = TIFFStripSize(tif); - dat8 = (unsigned char*)buf; + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 3 + has_alpha); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); + strip_size = TIFFStripSize(tif); + buf = _TIFFmalloc(strip_size); + index=0; - if(bps == 8) - { - step = 3 + has_alpha; - restx = step - 1; + for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++) + { + unsigned char *dat8; + tsize_t i, ssize, last_i = 0; + int step, restx; + ssize = TIFFStripSize(tif); + dat8 = (unsigned char*)buf; - for(i=0; i < ssize - restx; i += step) - { - int r, g, b, a = 0; + if(bps == 8) + { + step = 3 + has_alpha; + restx = step - 1; - if(index < imgsize) - { - r = image->comps[0].data[index]; - g = image->comps[1].data[index]; - b = image->comps[2].data[index]; - if(has_alpha) a = image->comps[3].data[index]; + for(i=0; i < ssize - restx; i += step) + { + int r, g, b, a = 0; - if(sgnd) - { - r += adjust; - g += adjust; - b += adjust; - if(has_alpha) a += adjust; - } - dat8[i+0] = r ; - dat8[i+1] = g ; - dat8[i+2] = b ; - if(has_alpha) dat8[i+3] = a; + if(index < imgsize) + { + r = image->comps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if(has_alpha) a = image->comps[3].data[index]; - index++; - last_i = i + step; - } - else - break; - }/*for(i = 0;)*/ - - if(last_i < ssize) - { - for(i = last_i; i < ssize; i += step) - { - int r, g, b, a = 0; - - if(index < imgsize) - { - r = image->comps[0].data[index]; - g = image->comps[1].data[index]; - b = image->comps[2].data[index]; - if(has_alpha) a = image->comps[3].data[index]; - - if(sgnd) - { - r += adjust; - g += adjust; - b += adjust; - if(has_alpha) a += adjust; - } - dat8[i+0] = r ; - if(i+1 < ssize) dat8[i+1] = g ; else break; - if(i+2 < ssize) dat8[i+2] = b ; else break; - if(has_alpha) - { - if(i+3 < ssize) dat8[i+3] = a ; else break; - } - index++; - } - else - break; - }/*for(i)*/ - }/*if(last_i < ssize)*/ - - } /*if(bps == 8)*/ - else - if(bps == 16) - { - step = 6 + has_alpha + has_alpha; - restx = step - 1; - - for(i = 0; i < ssize - restx ; i += step) - { - int r, g, b, a = 0; - - if(index < imgsize) - { - r = image->comps[0].data[index]; - g = image->comps[1].data[index]; - b = image->comps[2].data[index]; - if(has_alpha) a = image->comps[3].data[index]; - - if(sgnd) - { - r += adjust; - g += adjust; - b += adjust; - if(has_alpha) a += adjust; - } - if(force16) - { - r = (r<>dshift); - g = (g<>dshift); - b = (b<>dshift); - if(has_alpha) a = (a<>dshift); - } - dat8[i+0] = r;/*LSB*/ - dat8[i+1] = (r >> 8);/*MSB*/ - dat8[i+2] = g; - dat8[i+3] = (g >> 8); - dat8[i+4] = b; - dat8[i+5] = (b >> 8); + if(sgnd) + { + r += adjust; + g += adjust; + b += adjust; + if(has_alpha) a += adjust; + } + if(r > 255) r = 255; else if(r < 0) r = 0; + dat8[i+0] = (unsigned char)r ; + if(g > 255) g = 255; else if(g < 0) g = 0; + dat8[i+1] = (unsigned char)g ; + if(b > 255) b = 255; else if(b < 0) b = 0; + dat8[i+2] = (unsigned char)b ; if(has_alpha) - { - dat8[i+6] = a; - dat8[i+7] = (a >> 8); + { + if(a > 255) a = 255; else if(a < 0) a = 0; + dat8[i+3] = (unsigned char)a; } + + index++; + last_i = i + step; + } + else + break; + }/*for(i = 0;)*/ + + if(last_i < ssize) + { + for(i = last_i; i < ssize; i += step) + { + int r, g, b, a = 0; + + if(index < imgsize) + { + r = image->comps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if(has_alpha) a = image->comps[3].data[index]; + + if(sgnd) + { + r += adjust; + g += adjust; + b += adjust; + if(has_alpha) a += adjust; + } + if(r > 255) r = 255; else if(r < 0) r = 0; + if(g > 255) g = 255; else if(g < 0) g = 0; + if(b > 255) b = 255; else if(b < 0) b = 0; + + dat8[i+0] = (unsigned char)r ; + if(i+1 < ssize) dat8[i+1] = (unsigned char)g ; else break; + if(i+2 < ssize) dat8[i+2] = (unsigned char)b ; else break; + if(has_alpha) + { + if(a > 255) a = 255; else if(a < 0) a = 0; + + if(i+3 < ssize) dat8[i+3] = (unsigned char)a ; else break; + } + index++; + } + else + break; + }/*for(i)*/ + }/*if(last_i < ssize)*/ + + } /*if(bps == 8)*/ + else + if(bps == 16) + { + step = 6 + has_alpha + has_alpha; + restx = step - 1; + + for(i = 0; i < ssize - restx ; i += step) + { + int r, g, b, a = 0; + + if(index < imgsize) + { + r = image->comps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if(has_alpha) a = image->comps[3].data[index]; + + if(sgnd) + { + r += adjust; + g += adjust; + b += adjust; + if(has_alpha) a += adjust; + } + if(force16) + { + r = (r<>dshift); + g = (g<>dshift); + b = (b<>dshift); + if(has_alpha) a = (a<>dshift); + } + if(r > 65535) r = 65535; else if(r < 0) r = 0; + if(g > 65535) g = 65535; else if(g < 0) g = 0; + if(b > 65535) b = 65535; else if(b < 0) b = 0; + + dat8[i+0] = (unsigned char)r;/*LSB*/ + dat8[i+1] = (unsigned char)(r >> 8);/*MSB*/ + dat8[i+2] = (unsigned char)g; + dat8[i+3] = (unsigned char)(g >> 8); + dat8[i+4] = (unsigned char)b; + dat8[i+5] = (unsigned char)(b >> 8); + if(has_alpha) + { + if(a > 65535) a = 65535; else if(a < 0) a = 0; + dat8[i+6] = (unsigned char)a; + dat8[i+7] = (unsigned char)(a >> 8); + } + index++; + last_i = i + step; + } + else + break; + }/*for(i = 0;)*/ + + if(last_i < ssize) + { + for(i = last_i ; i < ssize ; i += step) + { + int r, g, b, a = 0; + + if(index < imgsize) + { + r = image->comps[0].data[index]; + g = image->comps[1].data[index]; + b = image->comps[2].data[index]; + if(has_alpha) a = image->comps[3].data[index]; + + if(sgnd) + { + r += adjust; + g += adjust; + b += adjust; + if(has_alpha) a += adjust; + } + if(force16) + { + r = (r<>dshift); + g = (g<>dshift); + b = (b<>dshift); + if(has_alpha) a = (a<>dshift); + } + if(r > 65535) r = 65535; else if(r < 0) r = 0; + if(g > 65535) g = 65535; else if(g < 0) g = 0; + if(b > 65535) b = 65535; else if(b < 0) b = 0; + + dat8[i+0] = (unsigned char) r;/*LSB*/ + if(i+1 < ssize) dat8[i+1] = (unsigned char)(r >> 8);else break;/*MSB*/ + if(i+2 < ssize) dat8[i+2] = (unsigned char) g; else break; + if(i+3 < ssize) dat8[i+3] = (unsigned char)(g >> 8);else break; + if(i+4 < ssize) dat8[i+4] = (unsigned char) b; else break; + if(i+5 < ssize) dat8[i+5] = (unsigned char)(b >> 8);else break; + + if(has_alpha) + { + if(a > 65535) a = 65535; else if(a < 0) a = 0; + if(i+6 < ssize) dat8[i+6] = (unsigned char)a; else break; + if(i+7 < ssize) dat8[i+7] = (unsigned char)(a >> 8); else break; + } + index++; + } + else + break; + }/*for(i)*/ + }/*if(last_i < ssize)*/ + + }/*if(bps == 16)*/ + (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size); + }/*for(strip = 0; )*/ + + _TIFFfree((void*)buf); + TIFFClose(tif); + + return 0; + }/*RGB(A)*/ + + if(image->numcomps == 1 /* GRAY */ + || ( image->numcomps == 2 /* GRAY_ALPHA */ + && image->comps[0].dx == image->comps[1].dx + && image->comps[0].dy == image->comps[1].dy + && image->comps[0].prec == image->comps[1].prec)) + { + int step; + + has_alpha = (image->numcomps == 2); + + width = (int)image->comps[0].w; + height = (int)image->comps[0].h; + imgsize = width * height; + + /* Set tags */ + TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); + TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height); + TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1 + has_alpha); + TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); + TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); + TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); + TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); + TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); + + /* Get a buffer for the data */ + strip_size = TIFFStripSize(tif); + buf = _TIFFmalloc(strip_size); + index = 0; + + for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++) + { + unsigned char *dat8; + tsize_t i, ssize = TIFFStripSize(tif); + dat8 = (unsigned char*)buf; + + if(bps == 8) + { + step = 1 + has_alpha; + + for(i=0; i < ssize; i += step) + { + if(index < imgsize) + { + int r, a = 0; + + r = image->comps[0].data[index]; + if(has_alpha) a = image->comps[1].data[index]; + + if(sgnd) + { + r += adjust; + if(has_alpha) a += adjust; + } + if(r > 255) r = 255; else if(r < 0) r = 0; + dat8[i+0] = (unsigned char)r; + + if(has_alpha) + { + if(a > 255) a = 255; else if(a < 0) a = 0; + dat8[i+1] = (unsigned char)a; + } index++; - last_i = i + step; } - else - break; - }/*for(i = 0;)*/ + else + break; + }/*for(i )*/ + }/*if(bps == 8*/ + else + if(bps == 16) + { + step = 2 + has_alpha + has_alpha; - if(last_i < ssize) - { - for(i = last_i ; i < ssize ; i += step) - { - int r, g, b, a = 0; + for(i=0; i < ssize; i += step) + { + if(index < imgsize) + { + int r, a = 0; - if(index < imgsize) - { - r = image->comps[0].data[index]; - g = image->comps[1].data[index]; - b = image->comps[2].data[index]; - if(has_alpha) a = image->comps[3].data[index]; + r = image->comps[0].data[index]; + if(has_alpha) a = image->comps[1].data[index]; - if(sgnd) - { - r += adjust; - g += adjust; - b += adjust; - if(has_alpha) a += adjust; - } - if(force16) - { - r = (r<>dshift); - g = (g<>dshift); - b = (b<>dshift); - if(has_alpha) a = (a<>dshift); - } - dat8[i+0] = r;/*LSB*/ - if(i+1 < ssize) dat8[i+1] = (r >> 8);else break;/*MSB*/ - if(i+2 < ssize) dat8[i+2] = g; else break; - if(i+3 < ssize) dat8[i+3] = (g >> 8);else break; - if(i+4 < ssize) dat8[i+4] = b; else break; - if(i+5 < ssize) dat8[i+5] = (b >> 8);else break; + if(sgnd) + { + r += adjust; + if(has_alpha) a += adjust; + } + if(force16) + { + r = (r<>dshift); + if(has_alpha) a = (a<>dshift); + } + if(r > 65535) r = 65535; else if(r < 0) r = 0; + dat8[i+0] = (unsigned char)r;/*LSB*/ + dat8[i+1] = (unsigned char)(r >> 8);/*MSB*/ + if(has_alpha) + { + if(a > 65535) a = 65535; else if(a < 0) a = 0; + dat8[i+2] = (unsigned char)a; + dat8[i+3] = (unsigned char)(a >> 8); + } + index++; + }/*if(index < imgsize)*/ + else + break; + }/*for(i )*/ + } + (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size); + }/*for(strip*/ - if(has_alpha) - { - if(i+6 < ssize) dat8[i+6] = a; else break; - if(i+7 < ssize) dat8[i+7] = (a >> 8); else break; - } - index++; - } - else - break; - }/*for(i)*/ - }/*if(last_i < ssize)*/ + _TIFFfree(buf); + TIFFClose(tif); - }/*if(bps == 16)*/ - (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size); - }/*for(strip = 0; )*/ + return 0; + } - _TIFFfree((void*)buf); - TIFFClose(tif); + TIFFClose(tif); - return 0; - }/*RGB(A)*/ + fprintf(stderr,"imagetotif: Bad color format.\n" + "\tOnly RGB(A) and GRAY(A) has been implemented\n"); + fprintf(stderr,"\tFOUND: numcomps(%d)\n\tAborting\n", + image->numcomps); - if(image->numcomps == 1 /* GRAY */ - || ( image->numcomps == 2 /* GRAY_ALPHA */ - && image->comps[0].dx == image->comps[1].dx - && image->comps[0].dy == image->comps[1].dy - && image->comps[0].prec == image->comps[1].prec)) - { - int step; - - has_alpha = (image->numcomps == 2); - - width = image->comps[0].w; - height = image->comps[0].h; - imgsize = width * height; - -/* Set tags */ - TIFFSetField(tif, TIFFTAG_IMAGEWIDTH, width); - TIFFSetField(tif, TIFFTAG_IMAGELENGTH, height); - TIFFSetField(tif, TIFFTAG_SAMPLESPERPIXEL, 1 + has_alpha); - TIFFSetField(tif, TIFFTAG_BITSPERSAMPLE, bps); - TIFFSetField(tif, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT); - TIFFSetField(tif, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG); - TIFFSetField(tif, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK); - TIFFSetField(tif, TIFFTAG_ROWSPERSTRIP, 1); - -/* Get a buffer for the data */ - strip_size = TIFFStripSize(tif); - buf = _TIFFmalloc(strip_size); - index = 0; - - for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++) - { - unsigned char *dat8; - tsize_t i, ssize = TIFFStripSize(tif); - dat8 = (unsigned char*)buf; - - if(bps == 8) - { - step = 1 + has_alpha; - - for(i=0; i < ssize; i += step) - { - if(index < imgsize) - { - int r, a = 0; - - r = image->comps[0].data[index]; - if(has_alpha) a = image->comps[1].data[index]; - - if(sgnd) - { - r += adjust; - if(has_alpha) a += adjust; - } - dat8[i+0] = r; - if(has_alpha) dat8[i+1] = a; - index++; - } - else - break; - }/*for(i )*/ - }/*if(bps == 8*/ - else - if(bps == 16) - { - step = 2 + has_alpha + has_alpha; - - for(i=0; i < ssize; i += step) - { - if(index < imgsize) - { - int r, a = 0; - - r = image->comps[0].data[index]; - if(has_alpha) a = image->comps[1].data[index]; - - if(sgnd) - { - r += adjust; - if(has_alpha) a += adjust; - } - if(force16) - { - r = (r<>dshift); - if(has_alpha) a = (a<>dshift); - } - dat8[i+0] = r;/*LSB*/ - dat8[i+1] = r >> 8;/*MSB*/ - if(has_alpha) - { - dat8[i+2] = a; - dat8[i+3] = a >> 8; - } - index++; - }/*if(index < imgsize)*/ - else - break; - }/*for(i )*/ - } - (void)TIFFWriteEncodedStrip(tif, strip, (void*)buf, strip_size); - }/*for(strip*/ - - _TIFFfree(buf); - TIFFClose(tif); - - return 0; - } - - TIFFClose(tif); - - fprintf(stderr,"imagetotif: Bad color format.\n" - "\tOnly RGB(A) and GRAY(A) has been implemented\n"); - fprintf(stderr,"\tFOUND: numcomps(%d)\n\tAborting\n", - image->numcomps); - - return 1; + return 1; }/* imagetotif() */ /* @@ -2449,643 +2577,627 @@ int imagetotif(opj_image_t * image, const char *outfile) */ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters) { - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; - TIFF *tif; - tdata_t buf; - tstrip_t strip; - tsize_t strip_size; - int j, numcomps, w, h,index; - OPJ_COLOR_SPACE color_space; - opj_image_cmptparm_t cmptparm[4]; /* RGBA */ - opj_image_t *image = NULL; - int imgsize = 0; - int has_alpha = 0; - unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC; - unsigned int tiWidth, tiHeight; + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; + TIFF *tif; + tdata_t buf; + tstrip_t strip; + tsize_t strip_size; + int j, numcomps, w, h,index; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t cmptparm[4]; /* RGBA */ + opj_image_t *image = NULL; + int imgsize = 0; + int has_alpha = 0; + unsigned short tiBps, tiPhoto, tiSf, tiSpp, tiPC; + unsigned int tiWidth, tiHeight; - tif = TIFFOpen(filename, "r"); + tif = TIFFOpen(filename, "r"); - if(!tif) - { - fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename); - return 0; - } - tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0; - tiWidth = tiHeight = 0; + if(!tif) + { + fprintf(stderr, "tiftoimage:Failed to open %s for reading\n", filename); + return 0; + } + tiBps = tiPhoto = tiSf = tiSpp = tiPC = 0; + tiWidth = tiHeight = 0; - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight); - TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps); - TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf); - TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp); - TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto); - TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC); - w= tiWidth; - h= tiHeight; + TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &tiWidth); + TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &tiHeight); + TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &tiBps); + TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &tiSf); + TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &tiSpp); + TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &tiPhoto); + TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &tiPC); + w= (int)tiWidth; + h= (int)tiHeight; - if(tiBps != 8 && tiBps != 16 && tiBps != 12) tiBps = 0; - if(tiPhoto != 1 && tiPhoto != 2) tiPhoto = 0; + if(tiBps != 8 && tiBps != 16 && tiBps != 12) tiBps = 0; + if(tiPhoto != 1 && tiPhoto != 2) tiPhoto = 0; if( !tiBps || !tiPhoto) - { - if( !tiBps) - fprintf(stderr,"imagetotif: Bits=%d, Only 8 and 16 bits" - " implemented\n",tiBps); - else - if( !tiPhoto) - fprintf(stderr,"tiftoimage: Bad color format %d.\n\tOnly RGB(A)" - " and GRAY(A) has been implemented\n",(int) tiPhoto); + { + if( !tiBps) + fprintf(stderr,"tiftoimage: Bits=%d, Only 8 and 16 bits" + " implemented\n",tiBps); + else + if( !tiPhoto) + fprintf(stderr,"tiftoimage: Bad color format %d.\n\tOnly RGB(A)" + " and GRAY(A) has been implemented\n",(int) tiPhoto); - fprintf(stderr,"\tAborting\n"); - TIFFClose(tif); + fprintf(stderr,"\tAborting\n"); + TIFFClose(tif); - return NULL; - } + return NULL; + } - {/* From: tiff-4.0.x/libtiff/tif_getimage.c : */ - uint16* sampleinfo; - uint16 extrasamples; + {/* From: tiff-4.0.x/libtiff/tif_getimage.c : */ + uint16* sampleinfo; + uint16 extrasamples; - TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, - &extrasamples, &sampleinfo); + TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES, + &extrasamples, &sampleinfo); - if(extrasamples >= 1) - { - switch(sampleinfo[0]) - { - case EXTRASAMPLE_UNSPECIFIED: -/* Workaround for some images without correct info about alpha channel + if(extrasamples >= 1) + { + switch(sampleinfo[0]) + { + case EXTRASAMPLE_UNSPECIFIED: + /* Workaround for some images without correct info about alpha channel */ - if(tiSpp > 3) - has_alpha = 1; - break; + if(tiSpp > 3) + has_alpha = 1; + break; - case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */ - case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */ - has_alpha = 1; - break; - } - } - else /* extrasamples == 0 */ - if(tiSpp == 4 || tiSpp == 2) has_alpha = 1; - } + case EXTRASAMPLE_ASSOCALPHA: /* data pre-multiplied */ + case EXTRASAMPLE_UNASSALPHA: /* data not pre-multiplied */ + has_alpha = 1; + break; + } + } + else /* extrasamples == 0 */ + if(tiSpp == 4 || tiSpp == 2) has_alpha = 1; + } -/* initialize image components + /* initialize image components */ - memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); + memset(&cmptparm[0], 0, 4 * sizeof(opj_image_cmptparm_t)); - if(tiPhoto == PHOTOMETRIC_RGB) /* RGB(A) */ - { - numcomps = 3 + has_alpha; - color_space = OPJ_CLRSPC_SRGB; + if ((tiPhoto == PHOTOMETRIC_RGB) && (parameters->cp_cinema)) { + fprintf(stdout,"WARNING:\n" + "Input image bitdepth is %d bits\n" + "TIF conversion has automatically rescaled to 12-bits\n" + "to comply with cinema profiles.\n", + tiBps); + } -/*#define USETILEMODE*/ - for(j = 0; j < numcomps; j++) - { - if(parameters->cp_cinema) - { - cmptparm[j].prec = 12; - cmptparm[j].bpp = 12; - } - else - { - cmptparm[j].prec = tiBps; - cmptparm[j].bpp = tiBps; - } - cmptparm[j].dx = subsampling_dx; - cmptparm[j].dy = subsampling_dy; - cmptparm[j].w = w; - cmptparm[j].h = h; + if(tiPhoto == PHOTOMETRIC_RGB) /* RGB(A) */ + { + numcomps = 3 + has_alpha; + color_space = OPJ_CLRSPC_SRGB; + + /*#define USETILEMODE*/ + for(j = 0; j < numcomps; j++) + { + if(parameters->cp_cinema) + { + cmptparm[j].prec = 12; + cmptparm[j].bpp = 12; + } + else + { + cmptparm[j].prec = tiBps; + cmptparm[j].bpp = tiBps; + } + cmptparm[j].dx = (OPJ_UINT32)subsampling_dx; + cmptparm[j].dy = (OPJ_UINT32)subsampling_dy; + cmptparm[j].w = (OPJ_UINT32)w; + cmptparm[j].h = (OPJ_UINT32)h; #ifdef USETILEMODE - cmptparm[j].x0 = 0; - cmptparm[j].y0 = 0; + cmptparm[j].x0 = 0; + cmptparm[j].y0 = 0; #endif - } + } #ifdef USETILEMODE - image = opj_image_tile_create(numcomps,&cmptparm[0],color_space); + image = opj_image_tile_create(numcomps,&cmptparm[0],color_space); #else - image = opj_image_create(numcomps, &cmptparm[0], color_space); + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); #endif - if(!image) - { - TIFFClose(tif); - return NULL; - } -/* set image offset and reference grid + if(!image) + { + TIFFClose(tif); + return NULL; + } + /* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : - image->x0 + (w - 1) * subsampling_dx + 1; - image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : - image->y0 + (h - 1) * subsampling_dy + 1; + image->x0 = (OPJ_UINT32)parameters->image_offset_x0; + image->y0 = (OPJ_UINT32)parameters->image_offset_y0; + image->x1 = !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 : + image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1; + image->y1 = !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 : + image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1; - buf = _TIFFmalloc(TIFFStripSize(tif)); + buf = _TIFFmalloc(TIFFStripSize(tif)); - strip_size=TIFFStripSize(tif); - index = 0; - imgsize = image->comps[0].w * image->comps[0].h ; -/* Read the Image components + strip_size=TIFFStripSize(tif); + index = 0; + imgsize = (int)(image->comps[0].w * image->comps[0].h); + /* Read the Image components */ - for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++) - { - unsigned char *dat8; - int step; - tsize_t i, ssize; - ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size); - dat8 = (unsigned char*)buf; + for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++) + { + unsigned char *dat8; + int step; + tsize_t i, ssize; + ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size); + dat8 = (unsigned char*)buf; - if(tiBps == 16) - { - step = 6 + has_alpha + has_alpha; + if(tiBps == 16) + { + step = 6 + has_alpha + has_alpha; - for(i = 0; i < ssize; i += step) - { - if(index < imgsize) - { - image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; /* R */ - image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; /* G */ - image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; /* B */ - if(has_alpha) - image->comps[3].data[index] = ( dat8[i+7] << 8 ) | dat8[i+6]; + for(i = 0; i < ssize; i += step) + { + if(index < imgsize) + { + image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; /* R */ + image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; /* G */ + image->comps[2].data[index] = ( dat8[i+5] << 8 ) | dat8[i+4]; /* B */ + if(has_alpha) + image->comps[3].data[index] = ( dat8[i+7] << 8 ) | dat8[i+6]; - if(parameters->cp_cinema) - { -/* Rounding 16 to 12 bits + if(parameters->cp_cinema) + { + /* Rounding 16 to 12 bits */ - image->comps[0].data[index] = - (image->comps[0].data[index] + 0x08) >> 4 ; - image->comps[1].data[index] = - (image->comps[1].data[index] + 0x08) >> 4 ; - image->comps[2].data[index] = - (image->comps[2].data[index] + 0x08) >> 4 ; - if(has_alpha) - image->comps[3].data[index] = - (image->comps[3].data[index] + 0x08) >> 4 ; - } - index++; - } - else - break; - }/*for(i = 0)*/ - }/*if(tiBps == 16)*/ - else - if(tiBps == 8) - { - step = 3 + has_alpha; + image->comps[0].data[index] = + (image->comps[0].data[index] + 0x08) >> 4 ; + image->comps[1].data[index] = + (image->comps[1].data[index] + 0x08) >> 4 ; + image->comps[2].data[index] = + (image->comps[2].data[index] + 0x08) >> 4 ; + if(has_alpha) + image->comps[3].data[index] = + (image->comps[3].data[index] + 0x08) >> 4 ; + } + index++; + } + else + break; + }/*for(i = 0)*/ + }/*if(tiBps == 16)*/ + else + if(tiBps == 8) + { + step = 3 + has_alpha; - for(i = 0; i < ssize; i += step) - { - if(index < imgsize) - { + for(i = 0; i < ssize; i += step) + { + if(index < imgsize) + { #ifndef USETILEMODE - image->comps[0].data[index] = dat8[i+0];/* R */ - image->comps[1].data[index] = dat8[i+1];/* G */ - image->comps[2].data[index] = dat8[i+2];/* B */ - if(has_alpha) - image->comps[3].data[index] = dat8[i+3]; + image->comps[0].data[index] = dat8[i+0];/* R */ + image->comps[1].data[index] = dat8[i+1];/* G */ + image->comps[2].data[index] = dat8[i+2];/* B */ + if(has_alpha) + image->comps[3].data[index] = dat8[i+3]; #endif - if(parameters->cp_cinema) - { -/* Rounding 8 to 12 bits + if(parameters->cp_cinema) + { + /* Rounding 8 to 12 bits */ #ifndef USETILEMODE - image->comps[0].data[index] = image->comps[0].data[index] << 4 ; - image->comps[1].data[index] = image->comps[1].data[index] << 4 ; - image->comps[2].data[index] = image->comps[2].data[index] << 4 ; - if(has_alpha) - image->comps[3].data[index] = image->comps[3].data[index] << 4 ; + image->comps[0].data[index] = image->comps[0].data[index] << 4 ; + image->comps[1].data[index] = image->comps[1].data[index] << 4 ; + image->comps[2].data[index] = image->comps[2].data[index] << 4 ; + if(has_alpha) + image->comps[3].data[index] = image->comps[3].data[index] << 4 ; #endif - } - index++; - }/*if(index*/ - else - break; - }/*for(i )*/ - }/*if( tiBps == 8)*/ - else - if(tiBps == 12)/* CINEMA file */ - { - step = 9; + } + index++; + }/*if(index*/ + else + break; + }/*for(i )*/ + }/*if( tiBps == 8)*/ + else + if(tiBps == 12)/* CINEMA file */ + { + step = 9; - for(i = 0; i < ssize; i += step) - { - if((index < imgsize)&(index+1 < imgsize)) - { - image->comps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4); - image->comps[1].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; + for(i = 0; i < ssize; i += step) + { + if((index < imgsize)&(index+1 < imgsize)) + { + image->comps[0].data[index] = ( dat8[i+0]<<4 ) |(dat8[i+1]>>4); + image->comps[1].data[index] = ((dat8[i+1]& 0x0f)<< 8) | dat8[i+2]; - image->comps[2].data[index] = ( dat8[i+3]<<4) |(dat8[i+4]>>4); - image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5]; + image->comps[2].data[index] = ( dat8[i+3]<<4) |(dat8[i+4]>>4); + image->comps[0].data[index+1] = ((dat8[i+4]& 0x0f)<< 8) | dat8[i+5]; - image->comps[1].data[index+1] = ( dat8[i+6] <<4) |(dat8[i+7]>>4); - image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8]; + image->comps[1].data[index+1] = ( dat8[i+6] <<4) |(dat8[i+7]>>4); + image->comps[2].data[index+1] = ((dat8[i+7]& 0x0f)<< 8) | dat8[i+8]; - index += 2; - } - else - break; - }/*for(i )*/ - } - }/*for(strip = 0; )*/ + index += 2; + } + else + break; + }/*for(i )*/ + } + }/*for(strip = 0; )*/ - _TIFFfree(buf); - TIFFClose(tif); + _TIFFfree(buf); + TIFFClose(tif); - return image; - }/*RGB(A)*/ + return image; + }/*RGB(A)*/ - if(tiPhoto == PHOTOMETRIC_MINISBLACK) /* GRAY(A) */ - { - numcomps = 1 + has_alpha; - color_space = OPJ_CLRSPC_GRAY; + if(tiPhoto == PHOTOMETRIC_MINISBLACK) /* GRAY(A) */ + { + numcomps = 1 + has_alpha; + color_space = OPJ_CLRSPC_GRAY; - for(j = 0; j < numcomps; ++j) - { - cmptparm[j].prec = tiBps; - cmptparm[j].bpp = tiBps; - cmptparm[j].dx = subsampling_dx; - cmptparm[j].dy = subsampling_dy; - cmptparm[j].w = w; - cmptparm[j].h = h; - } + for(j = 0; j < numcomps; ++j) + { + cmptparm[j].prec = tiBps; + cmptparm[j].bpp = tiBps; + cmptparm[j].dx = (OPJ_UINT32)subsampling_dx; + cmptparm[j].dy = (OPJ_UINT32)subsampling_dy; + cmptparm[j].w = (OPJ_UINT32)w; + cmptparm[j].h = (OPJ_UINT32)h; + } #ifdef USETILEMODE - image = opj_image_tile_create(numcomps,&cmptparm[0],color_space); + image = opj_image_tile_create(numcomps,&cmptparm[0],color_space); #else - image = opj_image_create(numcomps, &cmptparm[0], color_space); + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); #endif - if(!image) - { - TIFFClose(tif); - return NULL; - } -/* set image offset and reference grid + if(!image) + { + TIFFClose(tif); + return NULL; + } + /* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = !image->x0 ? (w - 1) * subsampling_dx + 1 : - image->x0 + (w - 1) * subsampling_dx + 1; - image->y1 = !image->y0 ? (h - 1) * subsampling_dy + 1 : - image->y0 + (h - 1) * subsampling_dy + 1; + image->x0 = (OPJ_UINT32)parameters->image_offset_x0; + image->y0 = (OPJ_UINT32)parameters->image_offset_y0; + image->x1 = !image->x0 ? (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1 : + image->x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1; + image->y1 = !image->y0 ? (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1 : + image->y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1; - buf = _TIFFmalloc(TIFFStripSize(tif)); + buf = _TIFFmalloc(TIFFStripSize(tif)); - strip_size = TIFFStripSize(tif); - index = 0; - imgsize = image->comps[0].w * image->comps[0].h ; -/* Read the Image components + strip_size = TIFFStripSize(tif); + index = 0; + imgsize = (int)(image->comps[0].w * image->comps[0].h); + /* Read the Image components */ - for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++) - { - unsigned char *dat8; - tsize_t i, ssize; - int step; + for(strip = 0; strip < TIFFNumberOfStrips(tif); strip++) + { + unsigned char *dat8; + tsize_t i, ssize; + int step; - ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size); - dat8 = (unsigned char*)buf; + ssize = TIFFReadEncodedStrip(tif, strip, buf, strip_size); + dat8 = (unsigned char*)buf; - if(tiBps == 16) - { - step = 2 + has_alpha + has_alpha; + if(tiBps == 16) + { + step = 2 + has_alpha + has_alpha; - for(i = 0; i < ssize; i += step) - { - if(index < imgsize) - { - image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; - if(has_alpha) - image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; - index++; - } - else - break; - }/*for(i )*/ - } - else - if(tiBps == 8) - { - step = 1 + has_alpha; + for(i = 0; i < ssize; i += step) + { + if(index < imgsize) + { + image->comps[0].data[index] = ( dat8[i+1] << 8 ) | dat8[i+0]; + if(has_alpha) + image->comps[1].data[index] = ( dat8[i+3] << 8 ) | dat8[i+2]; + index++; + } + else + break; + }/*for(i )*/ + } + else + if(tiBps == 8) + { + step = 1 + has_alpha; - for(i = 0; i < ssize; i += step) - { - if(index < imgsize) - { - image->comps[0].data[index] = dat8[i+0]; - if(has_alpha) - image->comps[1].data[index] = dat8[i+1]; - index++; - } - else - break; - }/*for(i )*/ - } - }/*for(strip = 0;*/ + for(i = 0; i < ssize; i += step) + { + if(index < imgsize) + { + image->comps[0].data[index] = dat8[i+0]; + if(has_alpha) + image->comps[1].data[index] = dat8[i+1]; + index++; + } + else + break; + }/*for(i )*/ + } + }/*for(strip = 0;*/ - _TIFFfree(buf); - TIFFClose(tif); + _TIFFfree(buf); + TIFFClose(tif); - }/*GRAY(A)*/ + }/*GRAY(A)*/ - return image; + return image; }/* tiftoimage() */ -#endif /* HAVE_LIBTIFF */ +#endif /* OPJ_HAVE_LIBTIFF */ /* -->> -->> -->> -->> - RAW IMAGE FORMAT + RAW IMAGE FORMAT <<-- <<-- <<-- <<-- */ static opj_image_t* rawtoimage_common(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp, OPJ_BOOL big_endian) { - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; + int subsampling_dx = parameters->subsampling_dx; + int subsampling_dy = parameters->subsampling_dy; - FILE *f = NULL; - int i, compno, numcomps, w, h; - OPJ_COLOR_SPACE color_space; - opj_image_cmptparm_t *cmptparm; - opj_image_t * image = NULL; - unsigned short ch; - - if((! (raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp & raw_cp->rawBitDepth)) == 0) - { - fprintf(stderr,"\nError: invalid raw image parameters\n"); - fprintf(stderr,"Please use the Format option -F:\n"); - fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); - fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); - fprintf(stderr,"Aborting\n"); - return NULL; - } + FILE *f = NULL; + int i, compno, numcomps, w, h; + OPJ_COLOR_SPACE color_space; + opj_image_cmptparm_t *cmptparm; + opj_image_t * image = NULL; + unsigned short ch; - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "Failed to open %s for reading !!\n", filename); - fprintf(stderr,"Aborting\n"); - return NULL; - } - numcomps = raw_cp->rawComp; - color_space = OPJ_CLRSPC_SRGB; - w = raw_cp->rawWidth; - h = raw_cp->rawHeight; - cmptparm = (opj_image_cmptparm_t*) malloc(numcomps * sizeof(opj_image_cmptparm_t)); - - /* initialize image components */ - memset(&cmptparm[0], 0, numcomps * sizeof(opj_image_cmptparm_t)); - for(i = 0; i < numcomps; i++) { - cmptparm[i].prec = raw_cp->rawBitDepth; - cmptparm[i].bpp = raw_cp->rawBitDepth; - cmptparm[i].sgnd = raw_cp->rawSigned; - cmptparm[i].dx = subsampling_dx; - cmptparm[i].dy = subsampling_dy; - cmptparm[i].w = w; - cmptparm[i].h = h; - } - /* create the image */ - image = opj_image_create(numcomps, &cmptparm[0], color_space); - if(!image) { - fclose(f); - return NULL; - } - /* set image offset and reference grid */ - image->x0 = parameters->image_offset_x0; - image->y0 = parameters->image_offset_y0; - image->x1 = parameters->image_offset_x0 + (w - 1) * subsampling_dx + 1; - image->y1 = parameters->image_offset_y0 + (h - 1) * subsampling_dy + 1; + if((! (raw_cp->rawWidth & raw_cp->rawHeight & raw_cp->rawComp & raw_cp->rawBitDepth)) == 0) + { + fprintf(stderr,"\nError: invalid raw image parameters\n"); + fprintf(stderr,"Please use the Format option -F:\n"); + fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); + fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); + fprintf(stderr,"Aborting\n"); + return NULL; + } - if(raw_cp->rawBitDepth <= 8) - { - unsigned char value = 0; - for(compno = 0; compno < numcomps; compno++) { - for (i = 0; i < w * h; i++) { - if (!fread(&value, 1, 1, f)) { - fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); - return NULL; - } - image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value; - } - } - } - else if(raw_cp->rawBitDepth <= 16) - { - unsigned short value; - for(compno = 0; compno < numcomps; compno++) { - for (i = 0; i < w * h; i++) { - unsigned char temp1; - unsigned char temp2; - if (!fread(&temp1, 1, 1, f)) { - fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); - return NULL; - } - if (!fread(&temp2, 1, 1, f)) { - fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); - return NULL; - } - if( big_endian ) - { - value = temp1 << 8; - value += temp2; - } - else - { - value = temp2 << 8; - value += temp1; - } - image->comps[compno].data[i] = raw_cp->rawSigned?(short)value:value; - } - } - } - else { - fprintf(stderr,"OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n"); - return NULL; - } + f = fopen(filename, "rb"); + if (!f) { + fprintf(stderr, "Failed to open %s for reading !!\n", filename); + fprintf(stderr,"Aborting\n"); + return NULL; + } + numcomps = raw_cp->rawComp; + color_space = OPJ_CLRSPC_SRGB; + w = raw_cp->rawWidth; + h = raw_cp->rawHeight; + cmptparm = (opj_image_cmptparm_t*) malloc((size_t)numcomps * sizeof(opj_image_cmptparm_t)); - if (fread(&ch, 1, 1, f)) { - fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n"); - } - fclose(f); + /* initialize image components */ + memset(&cmptparm[0], 0, (size_t)numcomps * sizeof(opj_image_cmptparm_t)); + for(i = 0; i < numcomps; i++) { + cmptparm[i].prec = (OPJ_UINT32)raw_cp->rawBitDepth; + cmptparm[i].bpp = (OPJ_UINT32)raw_cp->rawBitDepth; + cmptparm[i].sgnd = (OPJ_UINT32)raw_cp->rawSigned; + cmptparm[i].dx = (OPJ_UINT32)subsampling_dx; + cmptparm[i].dy = (OPJ_UINT32)subsampling_dy; + cmptparm[i].w = (OPJ_UINT32)w; + cmptparm[i].h = (OPJ_UINT32)h; + } + /* create the image */ + image = opj_image_create((OPJ_UINT32)numcomps, &cmptparm[0], color_space); + free(cmptparm); + if(!image) { + fclose(f); + return NULL; + } + /* set image offset and reference grid */ + image->x0 = (OPJ_UINT32)parameters->image_offset_x0; + image->y0 = (OPJ_UINT32)parameters->image_offset_y0; + image->x1 = (OPJ_UINT32)parameters->image_offset_x0 + (OPJ_UINT32)(w - 1) * (OPJ_UINT32)subsampling_dx + 1; + image->y1 = (OPJ_UINT32)parameters->image_offset_y0 + (OPJ_UINT32)(h - 1) * (OPJ_UINT32)subsampling_dy + 1; - return image; + if(raw_cp->rawBitDepth <= 8) + { + unsigned char value = 0; + for(compno = 0; compno < numcomps; compno++) { + for (i = 0; i < w * h; i++) { + if (!fread(&value, 1, 1, f)) { + fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + return NULL; + } + image->comps[compno].data[i] = raw_cp->rawSigned?(char)value:value; + } + } + } + else if(raw_cp->rawBitDepth <= 16) + { + unsigned short value; + for(compno = 0; compno < numcomps; compno++) { + for (i = 0; i < w * h; i++) { + unsigned char temp1; + unsigned char temp2; + if (!fread(&temp1, 1, 1, f)) { + fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + return NULL; + } + if (!fread(&temp2, 1, 1, f)) { + fprintf(stderr,"Error reading raw file. End of file probably reached.\n"); + return NULL; + } + if( big_endian ) + { + value = (unsigned short)((temp1 << 8) + temp2); + } + else + { + value = (unsigned short)((temp2 << 8) + temp1); + } + image->comps[compno].data[i] = raw_cp->rawSigned?(short)value:value; + } + } + } + else { + fprintf(stderr,"OpenJPEG cannot encode raw components with bit depth higher than 16 bits.\n"); + return NULL; + } + + if (fread(&ch, 1, 1, f)) { + fprintf(stderr,"Warning. End of raw file not reached... processing anyway\n"); + } + fclose(f); + + return image; } opj_image_t* rawltoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) { - return rawtoimage_common(filename, parameters, raw_cp, OPJ_FALSE); + return rawtoimage_common(filename, parameters, raw_cp, OPJ_FALSE); } opj_image_t* rawtoimage(const char *filename, opj_cparameters_t *parameters, raw_cparameters_t *raw_cp) { - return rawtoimage_common(filename, parameters, raw_cp, OPJ_TRUE); + return rawtoimage_common(filename, parameters, raw_cp, OPJ_TRUE); } static int imagetoraw_common(opj_image_t * image, const char *outfile, OPJ_BOOL big_endian) { - FILE *rawFile = NULL; - size_t res; - int compno; - int w, h; - int line, row; - int *ptr; + FILE *rawFile = NULL; + size_t res; + unsigned int compno; + int w, h, fails; + int line, row, curr, mask; + int *ptr; + unsigned char uc; + (void)big_endian; - if((image->numcomps * image->x1 * image->y1) == 0) - { - fprintf(stderr,"\nError: invalid raw image parameters\n"); - return 1; - } + if((image->numcomps * image->x1 * image->y1) == 0) + { + fprintf(stderr,"\nError: invalid raw image parameters\n"); + return 1; + } - rawFile = fopen(outfile, "wb"); - if (!rawFile) { - fprintf(stderr, "Failed to open %s for writing !!\n", outfile); - return 1; - } + rawFile = fopen(outfile, "wb"); + if (!rawFile) { + fprintf(stderr, "Failed to open %s for writing !!\n", outfile); + return 1; + } - fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps); + fails = 1; + fprintf(stdout,"Raw image characteristics: %d components\n", image->numcomps); - for(compno = 0; compno < image->numcomps; compno++) - { - fprintf(stdout,"Component %d characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w, - image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned"); + for(compno = 0; compno < image->numcomps; compno++) + { + fprintf(stdout,"Component %d characteristics: %dx%dx%d %s\n", compno, image->comps[compno].w, + image->comps[compno].h, image->comps[compno].prec, image->comps[compno].sgnd==1 ? "signed": "unsigned"); - w = image->comps[compno].w; - h = image->comps[compno].h; + w = (int)image->comps[compno].w; + h = (int)image->comps[compno].h; - if(image->comps[compno].prec <= 8) - { - if(image->comps[compno].sgnd == 1) - { - signed char curr; - int mask = (1 << image->comps[compno].prec) - 1; - ptr = image->comps[compno].data; - for (line = 0; line < h; line++) { - for(row = 0; row < w; row++) { - curr = (signed char) (*ptr & mask); - res = fwrite(&curr, sizeof(signed char), 1, rawFile); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; + if(image->comps[compno].prec <= 8) + { + if(image->comps[compno].sgnd == 1) + { + mask = (1 << image->comps[compno].prec) - 1; + ptr = image->comps[compno].data; + for (line = 0; line < h; line++) { + for(row = 0; row < w; row++) { + curr = *ptr; + if(curr > 127) curr = 127; else if(curr < -128) curr = -128; + uc = (unsigned char) (curr & mask); + res = fwrite(&uc, 1, 1, rawFile); + if( res < 1 ) { + fprintf(stderr, "failed to write 1 byte for %s\n", outfile); + goto fin; + } + ptr++; + } + } } - ptr++; - } - } - } - else if(image->comps[compno].sgnd == 0) - { - unsigned char curr; - int mask = (1 << image->comps[compno].prec) - 1; - ptr = image->comps[compno].data; - for (line = 0; line < h; line++) { - for(row = 0; row < w; row++) { - curr = (unsigned char) (*ptr & mask); - res = fwrite(&curr, sizeof(unsigned char), 1, rawFile); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; + else if(image->comps[compno].sgnd == 0) + { + mask = (1 << image->comps[compno].prec) - 1; + ptr = image->comps[compno].data; + for (line = 0; line < h; line++) { + for(row = 0; row < w; row++) { + curr = *ptr; + if(curr > 255) curr = 255; else if(curr < 0) curr = 0; + uc = (unsigned char) (curr & mask); + res = fwrite(&uc, 1, 1, rawFile); + if( res < 1 ) { + fprintf(stderr, "failed to write 1 byte for %s\n", outfile); + goto fin; + } + ptr++; + } + } } - ptr++; - } - } - } - } - else if(image->comps[compno].prec <= 16) - { - if(image->comps[compno].sgnd == 1) - { - signed short int curr; - int mask = (1 << image->comps[compno].prec) - 1; - ptr = image->comps[compno].data; - for (line = 0; line < h; line++) { - for(row = 0; row < w; row++) { - unsigned char temp1; - unsigned char temp2; - curr = (signed short int) (*ptr & mask); - if( big_endian ) - { - temp1 = (unsigned char) (curr >> 8); - temp2 = (unsigned char) curr; - } - else - { - temp2 = (unsigned char) (curr >> 8); - temp1 = (unsigned char) curr; - } - res = fwrite(&temp1, 1, 1, rawFile); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; + } + else if(image->comps[compno].prec <= 16) + { + if(image->comps[compno].sgnd == 1) + { + union { signed short val; signed char vals[2]; } uc16; + mask = (1 << image->comps[compno].prec) - 1; + ptr = image->comps[compno].data; + for (line = 0; line < h; line++) { + for(row = 0; row < w; row++) { + curr = *ptr; + if(curr > 32767 ) curr = 32767; else if( curr < -32768) curr = -32768; + uc16.val = (signed short)(curr & mask); + res = fwrite(uc16.vals, 1, 2, rawFile); + if( res < 2 ) { + fprintf(stderr, "failed to write 2 byte for %s\n", outfile); + goto fin; + } + ptr++; + } + } } - res = fwrite(&temp2, 1, 1, rawFile); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; + else if(image->comps[compno].sgnd == 0) + { + union { unsigned short val; unsigned char vals[2]; } uc16; + mask = (1 << image->comps[compno].prec) - 1; + ptr = image->comps[compno].data; + for (line = 0; line < h; line++) { + for(row = 0; row < w; row++) { + curr = *ptr; + if(curr > 65536 ) curr = 65536; else if( curr < 0) curr = 0; + uc16.val = (unsigned short)(curr & mask); + res = fwrite(uc16.vals, 1, 2, rawFile); + if( res < 2 ) { + fprintf(stderr, "failed to write 2 byte for %s\n", outfile); + goto fin; + } + ptr++; + } + } } - ptr++; - } - } - } - else if(image->comps[compno].sgnd == 0) - { - unsigned short int curr; - int mask = (1 << image->comps[compno].prec) - 1; - ptr = image->comps[compno].data; - for (line = 0; line < h; line++) { - for(row = 0; row < w; row++) { - unsigned char temp1; - unsigned char temp2; - curr = (unsigned short int) (*ptr & mask); - if( big_endian ) - { - temp1 = (unsigned char) (curr >> 8); - temp2 = (unsigned char) curr; - } - else - { - temp2 = (unsigned char) (curr >> 8); - temp1 = (unsigned char) curr; - } - res = fwrite(&temp1, 1, 1, rawFile); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; - } - res = fwrite(&temp2, 1, 1, rawFile); - if( res < 1 ) { - fprintf(stderr, "failed to write 1 byte for %s\n", outfile); - return 1; - } - ptr++; - } - } - } - } - else if (image->comps[compno].prec <= 32) - { - fprintf(stderr,"More than 16 bits per component no handled yet\n"); - return 1; - } - else - { - fprintf(stderr,"Error: invalid precision: %d\n", image->comps[compno].prec); - return 1; - } - } - fclose(rawFile); - return 0; + } + else if (image->comps[compno].prec <= 32) + { + fprintf(stderr,"More than 16 bits per component no handled yet\n"); + goto fin; + } + else + { + fprintf(stderr,"Error: invalid precision: %d\n", image->comps[compno].prec); + goto fin; + } + } + fails = 0; +fin: + fclose(rawFile); + return fails; } int imagetoraw(opj_image_t * image, const char *outfile) { - return imagetoraw_common(image, outfile, OPJ_TRUE); + return imagetoraw_common(image, outfile, OPJ_TRUE); } int imagetorawl(opj_image_t * image, const char *outfile) { - return imagetoraw_common(image, outfile, OPJ_FALSE); + return imagetoraw_common(image, outfile, OPJ_FALSE); } -#ifdef HAVE_LIBPNG +#ifdef OPJ_HAVE_LIBPNG #define PNG_MAGIC "\x89PNG\x0d\x0a\x1a\x0a" #define MAGIC_SIZE 8 @@ -3093,257 +3205,257 @@ int imagetorawl(opj_image_t * image, const char *outfile) opj_image_t *pngtoimage(const char *read_idf, opj_cparameters_t * params) { - png_structp png; - png_infop info; - double gamma, display_exponent; - int bit_depth, interlace_type,compression_type, filter_type; - int unit; - png_uint_32 resx, resy; - unsigned int i, j; - png_uint_32 width, height; - int color_type, has_alpha, is16; - unsigned char *s; - FILE *reader; - unsigned char **rows; -/* j2k: */ - opj_image_t *image; - opj_image_cmptparm_t cmptparm[4]; - int sub_dx, sub_dy; - unsigned int nr_comp; - int *r, *g, *b, *a; - unsigned char sigbuf[8]; + png_structp png; + png_infop info; + double gamma, display_exponent; + int bit_depth, interlace_type,compression_type, filter_type; + int unit; + png_uint_32 resx, resy; + unsigned int i, j; + png_uint_32 width, height; + int color_type, has_alpha, is16; + unsigned char *s; + FILE *reader; + unsigned char **rows; + /* j2k: */ + opj_image_t *image; + opj_image_cmptparm_t cmptparm[4]; + int sub_dx, sub_dy; + unsigned int nr_comp; + int *r, *g, *b, *a = NULL; + unsigned char sigbuf[8]; - if((reader = fopen(read_idf, "rb")) == NULL) - { - fprintf(stderr,"pngtoimage: can not open %s\n",read_idf); - return NULL; - } - image = NULL; png = NULL; rows = NULL; + if((reader = fopen(read_idf, "rb")) == NULL) + { + fprintf(stderr,"pngtoimage: can not open %s\n",read_idf); + return NULL; + } + image = NULL; png = NULL; rows = NULL; - if(fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE - || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0) - { - fprintf(stderr,"pngtoimage: %s is no valid PNG file\n",read_idf); - goto fin; - } -/* libpng-VERSION/example.c: + if(fread(sigbuf, 1, MAGIC_SIZE, reader) != MAGIC_SIZE + || memcmp(sigbuf, PNG_MAGIC, MAGIC_SIZE) != 0) + { + fprintf(stderr,"pngtoimage: %s is no valid PNG file\n",read_idf); + goto fin; + } + /* libpng-VERSION/example.c: * PC : screen_gamma = 2.2; * Mac: screen_gamma = 1.7 or 1.0; */ - display_exponent = 2.2; + display_exponent = 2.2; - if((png = png_create_read_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL)) == NULL) - goto fin; - if((info = png_create_info_struct(png)) == NULL) - goto fin; + if((png = png_create_read_struct(PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL)) == NULL) + goto fin; + if((info = png_create_info_struct(png)) == NULL) + goto fin; - if(setjmp(png_jmpbuf(png))) - goto fin; + if(setjmp(png_jmpbuf(png))) + goto fin; - png_init_io(png, reader); - png_set_sig_bytes(png, MAGIC_SIZE); + png_init_io(png, reader); + png_set_sig_bytes(png, MAGIC_SIZE); - png_read_info(png, info); + png_read_info(png, info); - if(png_get_IHDR(png, info, &width, &height, - &bit_depth, &color_type, &interlace_type, - &compression_type, &filter_type) == 0) - goto fin; + if(png_get_IHDR(png, info, &width, &height, + &bit_depth, &color_type, &interlace_type, + &compression_type, &filter_type) == 0) + goto fin; -/* png_set_expand(): + /* png_set_expand(): * expand paletted images to RGB, expand grayscale images of * less than 8-bit depth to 8-bit depth, and expand tRNS chunks * to alpha channels. */ - if(color_type == PNG_COLOR_TYPE_PALETTE) - png_set_expand(png); - else - if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_expand(png); + if(color_type == PNG_COLOR_TYPE_PALETTE) + png_set_expand(png); + else + if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_expand(png); - if(png_get_valid(png, info, PNG_INFO_tRNS)) - png_set_expand(png); + if(png_get_valid(png, info, PNG_INFO_tRNS)) + png_set_expand(png); - is16 = (bit_depth == 16); + is16 = (bit_depth == 16); -/* GRAY => RGB; GRAY_ALPHA => RGBA + /* GRAY => RGB; GRAY_ALPHA => RGBA */ - if(color_type == PNG_COLOR_TYPE_GRAY - || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - { - png_set_gray_to_rgb(png); - color_type = - (color_type == PNG_COLOR_TYPE_GRAY? PNG_COLOR_TYPE_RGB: - PNG_COLOR_TYPE_RGB_ALPHA); - } - if( !png_get_gAMA(png, info, &gamma)) - gamma = 0.45455; + if(color_type == PNG_COLOR_TYPE_GRAY + || color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + { + png_set_gray_to_rgb(png); + color_type = + (color_type == PNG_COLOR_TYPE_GRAY? PNG_COLOR_TYPE_RGB: + PNG_COLOR_TYPE_RGB_ALPHA); + } + if( !png_get_gAMA(png, info, &gamma)) + gamma = 0.45455; - png_set_gamma(png, display_exponent, gamma); + png_set_gamma(png, display_exponent, gamma); - png_read_update_info(png, info); + png_read_update_info(png, info); - png_get_pHYs(png, info, &resx, &resy, &unit); + png_get_pHYs(png, info, &resx, &resy, &unit); - color_type = png_get_color_type(png, info); + color_type = png_get_color_type(png, info); - has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA); + has_alpha = (color_type == PNG_COLOR_TYPE_RGB_ALPHA); - nr_comp = 3 + has_alpha; + nr_comp = 3 + (unsigned int)has_alpha; - bit_depth = png_get_bit_depth(png, info); + bit_depth = png_get_bit_depth(png, info); - rows = (unsigned char**)calloc(height+1, sizeof(unsigned char*)); - for(i = 0; i < height; ++i) - rows[i] = (unsigned char*)malloc(png_get_rowbytes(png,info)); + rows = (unsigned char**)calloc(height+1, sizeof(unsigned char*)); + for(i = 0; i < height; ++i) + rows[i] = (unsigned char*)malloc(png_get_rowbytes(png,info)); - png_read_image(png, rows); + png_read_image(png, rows); - memset(&cmptparm, 0, 4 * sizeof(opj_image_cmptparm_t)); + memset(cmptparm, 0, sizeof(cmptparm)); - sub_dx = params->subsampling_dx; sub_dy = params->subsampling_dy; + sub_dx = params->subsampling_dx; sub_dy = params->subsampling_dy; - for(i = 0; i < nr_comp; ++i) - { - cmptparm[i].prec = bit_depth; -/* bits_per_pixel: 8 or 16 */ - cmptparm[i].bpp = bit_depth; - cmptparm[i].sgnd = 0; - cmptparm[i].dx = sub_dx; - cmptparm[i].dy = sub_dy; - cmptparm[i].w = width; - cmptparm[i].h = height; - } + for(i = 0; i < nr_comp; ++i) + { + cmptparm[i].prec = (OPJ_UINT32)bit_depth; + /* bits_per_pixel: 8 or 16 */ + cmptparm[i].bpp = (OPJ_UINT32)bit_depth; + cmptparm[i].sgnd = 0; + cmptparm[i].dx = (OPJ_UINT32)sub_dx; + cmptparm[i].dy = (OPJ_UINT32)sub_dy; + cmptparm[i].w = (OPJ_UINT32)width; + cmptparm[i].h = (OPJ_UINT32)height; + } - image = opj_image_create(nr_comp, &cmptparm[0], OPJ_CLRSPC_SRGB); + image = opj_image_create(nr_comp, &cmptparm[0], OPJ_CLRSPC_SRGB); - if(image == NULL) goto fin; + if(image == NULL) goto fin; - image->x0 = params->image_offset_x0; - image->y0 = params->image_offset_y0; - image->x1 = image->x0 + (width - 1) * sub_dx + 1 + image->x0; - image->y1 = image->y0 + (height - 1) * sub_dy + 1 + image->y0; + image->x0 = (OPJ_UINT32)params->image_offset_x0; + image->y0 = (OPJ_UINT32)params->image_offset_y0; + image->x1 = (OPJ_UINT32)(image->x0 + (width - 1) * (OPJ_UINT32)sub_dx + 1 + image->x0); + image->y1 = (OPJ_UINT32)(image->y0 + (height - 1) * (OPJ_UINT32)sub_dy + 1 + image->y0); - r = image->comps[0].data; - g = image->comps[1].data; - b = image->comps[2].data; - a = image->comps[3].data; + r = image->comps[0].data; + g = image->comps[1].data; + b = image->comps[2].data; + if(has_alpha) a = image->comps[3].data; - for(i = 0; i < height; ++i) - { - s = rows[i]; + for(i = 0; i < height; ++i) + { + s = rows[i]; - for(j = 0; j < width; ++j) - { - if(is16) - { - *r++ = s[0]<<8|s[1]; s += 2; + for(j = 0; j < width; ++j) + { + if(is16) + { + *r++ = s[0]<<8|s[1]; s += 2; - *g++ = s[0]<<8|s[1]; s += 2; - - *b++ = s[0]<<8|s[1]; s += 2; - - if(has_alpha) { *a++ = s[0]<<8|s[1]; s += 2; } + *g++ = s[0]<<8|s[1]; s += 2; - continue; - } - *r++ = *s++; *g++ = *s++; *b++ = *s++; + *b++ = s[0]<<8|s[1]; s += 2; - if(has_alpha) *a++ = *s++; - } - } + if(has_alpha) { *a++ = s[0]<<8|s[1]; s += 2; } + + continue; + } + *r++ = *s++; *g++ = *s++; *b++ = *s++; + + if(has_alpha) *a++ = *s++; + } + } fin: - if(rows) - { - for(i = 0; i < height; ++i) - free(rows[i]); - free(rows); - } - if(png) - png_destroy_read_struct(&png, &info, NULL); + if(rows) + { + for(i = 0; i < height; ++i) + free(rows[i]); + free(rows); + } + if(png) + png_destroy_read_struct(&png, &info, NULL); - fclose(reader); + fclose(reader); - return image; + return image; }/* pngtoimage() */ int imagetopng(opj_image_t * image, const char *write_idf) { - FILE *writer; - png_structp png; - png_infop info; - int *red, *green, *blue, *alpha; - unsigned char *row_buf, *d; - int has_alpha, width, height, nr_comp, color_type; - int adjustR, adjustG, adjustB, adjustA, x, y, fails; - int prec, ushift, dshift, is16, force16, force8; - unsigned short mask = 0xffff; - png_color_8 sig_bit; + FILE *writer; + png_structp png; + png_infop info; + int *red, *green, *blue, *alpha; + unsigned char *row_buf, *d; + int has_alpha, width, height, nr_comp, color_type; + int adjustR, adjustG, adjustB, adjustA, x, y, fails; + int prec, ushift, dshift, is16, force16, force8; + unsigned short mask = 0xffff; + png_color_8 sig_bit; - is16 = force16 = force8 = ushift = dshift = 0; fails = 1; - prec = image->comps[0].prec; - nr_comp = image->numcomps; + is16 = force16 = force8 = ushift = dshift = 0; fails = 1; + prec = (int)image->comps[0].prec; + nr_comp = (int)image->numcomps; - if(prec > 8 && prec < 16) - { - ushift = 16 - prec; dshift = prec - ushift; - prec = 16; force16 = 1; - } - else - if(prec < 8 && nr_comp > 1)/* GRAY_ALPHA, RGB, RGB_ALPHA */ - { - ushift = 8 - prec; dshift = 8 - ushift; - prec = 8; force8 = 1; - } + if(prec > 8 && prec < 16) + { + ushift = 16 - prec; dshift = prec - ushift; + prec = 16; force16 = 1; + } + else + if(prec < 8 && nr_comp > 1)/* GRAY_ALPHA, RGB, RGB_ALPHA */ + { + ushift = 8 - prec; dshift = 8 - ushift; + prec = 8; force8 = 1; + } - if(prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16) - { - fprintf(stderr,"imagetopng: can not create %s" - "\n\twrong bit_depth %d\n", write_idf, prec); - return fails; - } - writer = fopen(write_idf, "wb"); + if(prec != 1 && prec != 2 && prec != 4 && prec != 8 && prec != 16) + { + fprintf(stderr,"imagetopng: can not create %s" + "\n\twrong bit_depth %d\n", write_idf, prec); + return fails; + } + writer = fopen(write_idf, "wb"); - if(writer == NULL) return fails; + if(writer == NULL) return fails; - info = NULL; has_alpha = 0; + info = NULL; has_alpha = 0; -/* Create and initialize the png_struct with the desired error handler + /* Create and initialize the png_struct with the desired error handler * functions. If you want to use the default stderr and longjump method, * you can supply NULL for the last three parameters. We also check that * the library version is compatible with the one used at compile time, * in case we are using dynamically linked libraries. REQUIRED. */ - png = png_create_write_struct(PNG_LIBPNG_VER_STRING, - NULL, NULL, NULL); -/*png_voidp user_error_ptr, user_error_fn, user_warning_fn); */ + png = png_create_write_struct(PNG_LIBPNG_VER_STRING, + NULL, NULL, NULL); + /*png_voidp user_error_ptr, user_error_fn, user_warning_fn); */ - if(png == NULL) goto fin; + if(png == NULL) goto fin; -/* Allocate/initialize the image information data. REQUIRED + /* Allocate/initialize the image information data. REQUIRED */ - info = png_create_info_struct(png); + info = png_create_info_struct(png); - if(info == NULL) goto fin; + if(info == NULL) goto fin; -/* Set error handling. REQUIRED if you are not supplying your own + /* Set error handling. REQUIRED if you are not supplying your own * error handling functions in the png_create_write_struct() call. */ - if(setjmp(png_jmpbuf(png))) goto fin; + if(setjmp(png_jmpbuf(png))) goto fin; -/* I/O initialization functions is REQUIRED + /* I/O initialization functions is REQUIRED */ - png_init_io(png, writer); + png_init_io(png, writer); -/* Set the image information here. Width and height are up to 2^31, + /* Set the image information here. Width and height are up to 2^31, * bit_depth is one of 1, 2, 4, 8, or 16, but valid values also depend on * the color_type selected. color_type is one of PNG_COLOR_TYPE_GRAY, * PNG_COLOR_TYPE_GRAY_ALPHA, PNG_COLOR_TYPE_PALETTE, PNG_COLOR_TYPE_RGB, * or PNG_COLOR_TYPE_RGB_ALPHA. interlace is either PNG_INTERLACE_NONE or * PNG_INTERLACE_ADAM7, and the compression_type and filter_type MUST - * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. + * currently be PNG_COMPRESSION_TYPE_BASE and PNG_FILTER_TYPE_BASE. * REQUIRED * * ERRORS: @@ -3352,276 +3464,292 @@ int imagetopng(opj_image_t * image, const char *write_idf) * color_type == PNG_COLOR_TYPE_RGB && bit_depth < 8 * color_type == PNG_COLOR_TYPE_GRAY_ALPHA && bit_depth < 8 * color_type == PNG_COLOR_TYPE_RGB_ALPHA) && bit_depth < 8 - * + * */ - png_set_compression_level(png, Z_BEST_COMPRESSION); + png_set_compression_level(png, Z_BEST_COMPRESSION); - if(prec == 16) mask = 0xffff; - else - if(prec == 8) mask = 0x00ff; - else - if(prec == 4) mask = 0x000f; - else - if(prec == 2) mask = 0x0003; - else - if(prec == 1) mask = 0x0001; + if(prec == 16) mask = 0xffff; + else + if(prec == 8) mask = 0x00ff; + else + if(prec == 4) mask = 0x000f; + else + if(prec == 2) mask = 0x0003; + else + if(prec == 1) mask = 0x0001; - if(nr_comp >= 3 - && image->comps[0].dx == image->comps[1].dx - && image->comps[1].dx == image->comps[2].dx - && image->comps[0].dy == image->comps[1].dy - && image->comps[1].dy == image->comps[2].dy - && image->comps[0].prec == image->comps[1].prec - && image->comps[1].prec == image->comps[2].prec) - { - int v; + if(nr_comp >= 3 + && image->comps[0].dx == image->comps[1].dx + && image->comps[1].dx == image->comps[2].dx + && image->comps[0].dy == image->comps[1].dy + && image->comps[1].dy == image->comps[2].dy + && image->comps[0].prec == image->comps[1].prec + && image->comps[1].prec == image->comps[2].prec) + { + int v; - has_alpha = (nr_comp > 3); + has_alpha = (nr_comp > 3); - is16 = (prec == 16); - - width = image->comps[0].w; - height = image->comps[0].h; + is16 = (prec == 16); - red = image->comps[0].data; - green = image->comps[1].data; - blue = image->comps[2].data; + width = (int)image->comps[0].w; + height = (int)image->comps[0].h; - sig_bit.red = sig_bit.green = sig_bit.blue = prec; + red = image->comps[0].data; + green = image->comps[1].data; + blue = image->comps[2].data; - if(has_alpha) - { - sig_bit.alpha = prec; - alpha = image->comps[3].data; - color_type = PNG_COLOR_TYPE_RGB_ALPHA; - adjustA = (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0); - } - else - { - sig_bit.alpha = 0; alpha = NULL; - color_type = PNG_COLOR_TYPE_RGB; - adjustA = 0; - } - png_set_sBIT(png, info, &sig_bit); + sig_bit.red = sig_bit.green = sig_bit.blue = (png_byte)prec; - png_set_IHDR(png, info, width, height, prec, - color_type, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + if(has_alpha) + { + sig_bit.alpha = (png_byte)prec; + alpha = image->comps[3].data; + color_type = PNG_COLOR_TYPE_RGB_ALPHA; + adjustA = (image->comps[3].sgnd ? 1 << (image->comps[3].prec - 1) : 0); + } + else + { + sig_bit.alpha = 0; alpha = NULL; + color_type = PNG_COLOR_TYPE_RGB; + adjustA = 0; + } + png_set_sBIT(png, info, &sig_bit); - png_set_gamma(png, 2.2, 1./2.2); - png_set_sRGB(png, info, PNG_sRGB_INTENT_PERCEPTUAL); -/*=============================*/ - png_write_info(png, info); -/*=============================*/ - if(prec < 8) - { - png_set_packing(png); - } - adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); - adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); - adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); + png_set_IHDR(png, info, (png_uint_32)width, (png_uint_32)height, prec, + color_type, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - row_buf = (unsigned char*)malloc(width * nr_comp * 2); + png_set_gamma(png, 2.2, 1./2.2); + png_set_sRGB(png, info, PNG_sRGB_INTENT_PERCEPTUAL); + /*=============================*/ + png_write_info(png, info); + /*=============================*/ + if(prec < 8) + { + png_set_packing(png); + } +printf("%s:%d:sgnd(%d,%d,%d) w(%d) h(%d) alpha(%d)\n",__FILE__,__LINE__, +image->comps[0].sgnd, +image->comps[1].sgnd,image->comps[2].sgnd,width,height,has_alpha); - for(y = 0; y < height; ++y) - { - d = row_buf; + adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + adjustG = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); + adjustB = (image->comps[2].sgnd ? 1 << (image->comps[2].prec - 1) : 0); - for(x = 0; x < width; ++x) - { - if(is16) - { - v = *red + adjustR; ++red; - - if(force16) { v = (v<>dshift); } + row_buf = (unsigned char*)malloc((size_t)width * (size_t)nr_comp * 2); - *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; + for(y = 0; y < height; ++y) + { + d = row_buf; - v = *green + adjustG; ++green; - - if(force16) { v = (v<>dshift); } + for(x = 0; x < width; ++x) + { + if(is16) + { + v = *red + adjustR; ++red; + if(v > 65535) v = 65535; else if(v < 0) v = 0; - *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; + if(force16) { v = (v<>dshift); } - v = *blue + adjustB; ++blue; - - if(force16) { v = (v<>dshift); } + *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; - *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; + v = *green + adjustG; ++green; + if(v > 65535) v = 65535; else if(v < 0) v = 0; - if(has_alpha) - { - v = *alpha + adjustA; ++alpha; - - if(force16) { v = (v<>dshift); } + if(force16) { v = (v<>dshift); } - *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; - } - continue; - }/* if(is16) */ + *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; - v = *red + adjustR; ++red; + v = *blue + adjustB; ++blue; + if(v > 65535) v = 65535; else if(v < 0) v = 0; - if(force8) { v = (v<>dshift); } + if(force16) { v = (v<>dshift); } - *d++ = (unsigned char)(v & mask); + *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; - v = *green + adjustG; ++green; + if(has_alpha) + { + v = *alpha + adjustA; ++alpha; + if(v > 65535) v = 65535; else if(v < 0) v = 0; - if(force8) { v = (v<>dshift); } + if(force16) { v = (v<>dshift); } - *d++ = (unsigned char)(v & mask); + *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; + } + continue; + }/* if(is16) */ - v = *blue + adjustB; ++blue; + v = *red + adjustR; ++red; + if(v > 255) v = 255; else if(v < 0) v = 0; - if(force8) { v = (v<>dshift); } + if(force8) { v = (v<>dshift); } - *d++ = (unsigned char)(v & mask); + *d++ = (unsigned char)(v & mask); - if(has_alpha) - { - v = *alpha + adjustA; ++alpha; + v = *green + adjustG; ++green; + if(v > 255) v = 255; else if(v < 0) v = 0; - if(force8) { v = (v<>dshift); } + if(force8) { v = (v<>dshift); } - *d++ = (unsigned char)(v & mask); - } - } /* for(x) */ + *d++ = (unsigned char)(v & mask); - png_write_row(png, row_buf); + v = *blue + adjustB; ++blue; + if(v > 255) v = 255; else if(v < 0) v = 0; - } /* for(y) */ - free(row_buf); + if(force8) { v = (v<>dshift); } - }/* nr_comp >= 3 */ - else - if(nr_comp == 1 /* GRAY */ - || ( nr_comp == 2 /* GRAY_ALPHA */ - && image->comps[0].dx == image->comps[1].dx - && image->comps[0].dy == image->comps[1].dy - && image->comps[0].prec == image->comps[1].prec)) - { - int v; + *d++ = (unsigned char)(v & mask); - red = image->comps[0].data; + if(has_alpha) + { + v = *alpha + adjustA; ++alpha; + if(v > 255) v = 255; else if(v < 0) v = 0; - sig_bit.gray = prec; - sig_bit.red = sig_bit.green = sig_bit.blue = sig_bit.alpha = 0; - alpha = NULL; adjustA = 0; - color_type = PNG_COLOR_TYPE_GRAY; + if(force8) { v = (v<>dshift); } - if(nr_comp == 2) - { - has_alpha = 1; sig_bit.alpha = prec; - alpha = image->comps[1].data; - color_type = PNG_COLOR_TYPE_GRAY_ALPHA; - adjustA = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); - } - width = image->comps[0].w; - height = image->comps[0].h; + *d++ = (unsigned char)(v & mask); + } + } /* for(x) */ - png_set_IHDR(png, info, width, height, sig_bit.gray, - color_type, - PNG_INTERLACE_NONE, - PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); + png_write_row(png, row_buf); - png_set_sBIT(png, info, &sig_bit); + } /* for(y) */ + free(row_buf); - png_set_gamma(png, 2.2, 1./2.2); - png_set_sRGB(png, info, PNG_sRGB_INTENT_PERCEPTUAL); -/*=============================*/ - png_write_info(png, info); -/*=============================*/ - adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); + }/* nr_comp >= 3 */ + else + if(nr_comp == 1 /* GRAY */ + || ( nr_comp == 2 /* GRAY_ALPHA */ + && image->comps[0].dx == image->comps[1].dx + && image->comps[0].dy == image->comps[1].dy + && image->comps[0].prec == image->comps[1].prec)) + { + int v; - if(prec < 8) - { - png_set_packing(png); - } + red = image->comps[0].data; - if(prec > 8) - { - row_buf = (unsigned char*) - malloc(width * nr_comp * sizeof(unsigned short)); + sig_bit.gray = (png_byte)prec; + sig_bit.red = sig_bit.green = sig_bit.blue = sig_bit.alpha = 0; + alpha = NULL; adjustA = 0; + color_type = PNG_COLOR_TYPE_GRAY; - for(y = 0; y < height; ++y) - { - d = row_buf; + if(nr_comp == 2) + { + has_alpha = 1; sig_bit.alpha = (png_byte)prec; + alpha = image->comps[1].data; + color_type = PNG_COLOR_TYPE_GRAY_ALPHA; + adjustA = (image->comps[1].sgnd ? 1 << (image->comps[1].prec - 1) : 0); + } + width = (int)image->comps[0].w; + height = (int)image->comps[0].h; - for(x = 0; x < width; ++x) - { - v = *red + adjustR; ++red; + png_set_IHDR(png, info, (png_uint_32)width, (png_uint_32)height, sig_bit.gray, + color_type, + PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); - if(force16) { v = (v<>dshift); } + png_set_sBIT(png, info, &sig_bit); - *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; + png_set_gamma(png, 2.2, 1./2.2); + png_set_sRGB(png, info, PNG_sRGB_INTENT_PERCEPTUAL); + /*=============================*/ + png_write_info(png, info); + /*=============================*/ + adjustR = (image->comps[0].sgnd ? 1 << (image->comps[0].prec - 1) : 0); - if(has_alpha) - { - v = *alpha++; + if(prec < 8) + { + png_set_packing(png); + } - if(force16) { v = (v<>dshift); } + if(prec > 8) + { + row_buf = (unsigned char*) + malloc((size_t)width * (size_t)nr_comp * sizeof(unsigned short)); - *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; - } - }/* for(x) */ - png_write_row(png, row_buf); + for(y = 0; y < height; ++y) + { + d = row_buf; - } /* for(y) */ - free(row_buf); - } - else /* prec <= 8 */ - { - row_buf = (unsigned char*)calloc(width, nr_comp * 2); + for(x = 0; x < width; ++x) + { + v = *red + adjustR; ++red; + if(v > 65535) v = 65535; else if(v < 0) v = 0; - for(y = 0; y < height; ++y) - { - d = row_buf; + if(force16) { v = (v<>dshift); } - for(x = 0; x < width; ++x) - { - v = *red + adjustR; ++red; + *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; - if(force8) { v = (v<>dshift); } + if(has_alpha) + { + v = *alpha++; + if(v > 65535) v = 65535; else if(v < 0) v = 0; - *d++ = (unsigned char)(v & mask); + if(force16) { v = (v<>dshift); } - if(has_alpha) - { - v = *alpha + adjustA; ++alpha; + *d++ = (unsigned char)(v>>8); *d++ = (unsigned char)v; + } + }/* for(x) */ + png_write_row(png, row_buf); - if(force8) { v = (v<>dshift); } + } /* for(y) */ + free(row_buf); + } + else /* prec <= 8 */ + { + row_buf = (unsigned char*)calloc((size_t)width, (size_t)nr_comp * 2); - *d++ = (unsigned char)(v & mask); - } - }/* for(x) */ + for(y = 0; y < height; ++y) + { + d = row_buf; - png_write_row(png, row_buf); + for(x = 0; x < width; ++x) + { + v = *red + adjustR; ++red; + if(v > 255) v = 255; else if(v < 0) v = 0; - } /* for(y) */ - free(row_buf); - } - } - else - { - fprintf(stderr,"imagetopng: can not create %s\n",write_idf); - goto fin; - } - png_write_end(png, info); + if(force8) { v = (v<>dshift); } - fails = 0; + *d++ = (unsigned char)(v & mask); + + if(has_alpha) + { + v = *alpha + adjustA; ++alpha; + if(v > 255) v = 255; else if(v < 0) v = 0; + + if(force8) { v = (v<>dshift); } + + *d++ = (unsigned char)(v & mask); + } + }/* for(x) */ + + png_write_row(png, row_buf); + + } /* for(y) */ + free(row_buf); + } + } + else + { + fprintf(stderr,"imagetopng: can not create %s\n",write_idf); + goto fin; + } + png_write_end(png, info); + + fails = 0; fin: - if(png) - { - png_destroy_write_struct(&png, &info); - } - fclose(writer); + if(png) + { + png_destroy_write_struct(&png, &info); + } + fclose(writer); - if(fails) remove(write_idf); + if(fails) remove(write_idf); - return fails; + return fails; }/* imagetopng() */ -#endif /* HAVE_LIBPNG */ +#endif /* OPJ_HAVE_LIBPNG */ diff --git a/src/bin/jp2/opj_compress.c b/src/bin/jp2/opj_compress.c index 9c957502..ba1d8374 100644 --- a/src/bin/jp2/opj_compress.c +++ b/src/bin/jp2/opj_compress.c @@ -7,7 +7,7 @@ * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2006-2007, Parvatha Elangovan * Copyright (c) 2008, Jerome Fimes, Communications & Systemes - * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France + * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France * Copyright (c) 2012, CS Systemes d'Information, France * All rights reserved. * @@ -53,7 +53,7 @@ #include #endif /* _WIN32 */ -#include "opj_config.h" +#include "opj_apps_config.h" #include "openjpeg.h" #include "opj_getopt.h" #include "convert.h" @@ -61,1525 +61,1387 @@ #include "format_defs.h" -#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/ -#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/ -#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/ -#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/ - typedef struct dircnt{ - /** Buffer for holding images read from Directory*/ - char *filename_buf; - /** Pointer to the buffer*/ - char **filename; + /** Buffer for holding images read from Directory*/ + char *filename_buf; + /** Pointer to the buffer*/ + char **filename; }dircnt_t; typedef struct img_folder{ - /** The directory path of the folder containing input images*/ - char *imgdirpath; - /** Output format*/ - char *out_format; - /** Enable option*/ - char set_imgdir; - /** Enable Cod Format for output*/ - char set_out_format; - /** User specified rate stored in case of cinema option*/ - float *rates; + /** The directory path of the folder containing input images*/ + char *imgdirpath; + /** Output format*/ + char *out_format; + /** Enable option*/ + char set_imgdir; + /** Enable Cod Format for output*/ + char set_out_format; }img_fol_t; static void encode_help_display(void) { - fprintf(stdout,"HELP for opj_compress\n----\n\n"); - fprintf(stdout,"- the -h option displays this help information on screen\n\n"); + fprintf(stdout,"HELP for opj_compress\n----\n\n"); + fprintf(stdout,"- the -h option displays this help information on screen\n\n"); -/* UniPG>> */ - fprintf(stdout,"List of parameters for the JPEG 2000 " + /* UniPG>> */ + fprintf(stdout,"List of parameters for the JPEG 2000 " + #ifdef USE_JPWL + "+ JPWL " + #endif /* USE_JPWL */ + "encoder:\n"); + /* <YCC conversion if at least 3 components\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"); + /* UniPG>> */ #ifdef USE_JPWL - "+ JPWL " + fprintf(stdout," * No JPWL protection\n"); #endif /* USE_JPWL */ - "encoder:\n"); -/* <> */ + /* < \n"); + fprintf(stdout," Currently accepts PBM, PGM, PPM, PNM, PAM, PGX, PNG, BMP, TIF, RAW (MSB), RAWL (LSB) and TGA formats\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-i : source file (-i source.pnm also *pbm, *.pgm, *.ppm, *.pam, *.pgx, *png, *.bmp, *.tif, *.raw, *.tga) \n"); + fprintf(stdout," When using this option -o must be used\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"Optional Parameters:\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-h : display the help information \n "); + fprintf(stdout,"\n"); + fprintf(stdout,"-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-CINEMA2K 24 or 48) \n"); + fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n"); + fprintf(stdout," Frames per second not required. Default value is 24fps\n"); + fprintf(stdout,"\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,"\n"); + fprintf(stdout," (options -r and -q cannot be used together)\n "); + fprintf(stdout,"\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"); + fprintf(stdout,"-n : number of resolutions (-n 3) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-b : size of code block (-b 32,32) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-c : size of precinct (-c 128,128) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-t : size of tile (-t 512,512) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-p : progression order (-p LRCP) [LRCP, RLCP, RPCL, PCRL, CPRL] \n"); + fprintf(stdout,"\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,"\n"); + fprintf(stdout,"-POC : Progression order change (-POC T1=0,0,1,5,3,CPRL/T1=5,0,1,6,3,CPRL) \n"); + fprintf(stdout," Example: T1=0,0,1,5,3,CPRL \n"); + fprintf(stdout," : Ttilenumber=Resolution num start,Component num start,Layer num end,Resolution num end,Component num end,Progression order\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-SOP : write SOP marker before each packet \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-EPH : write EPH marker after each header packet \n"); + fprintf(stdout,"\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," ex: RESTART(4) + RESET(2) + SEGMARK(32) = -M 38\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-TP : divide packets of every tile into tile-parts (-TP R) [R, L, C]\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-x : create an index file *.Idx (-x index_name.Idx) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-ROI : 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,"\n"); + fprintf(stdout,"-d : offset of the origin of the image (-d 150,300) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-T : offset of the origin of the tiles (-T 100,75) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-I : use the irreversible DWT 9-7 (-I) \n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-F : characteristics of the raw input image\n"); + fprintf(stdout," -F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); + fprintf(stdout," Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); + fprintf(stdout,"\n"); + fprintf(stdout,"-mct {0,1,2} : explicitely specifies if an Multiple Component Transform has to be used.\n"); + fprintf(stdout," 0: no MCT ; 1: RGB->YCC conversion ; 2: custom MCT.\n"); + fprintf(stdout," If custom MCT, \"-m\" option has to be used (see hereunder).\n"); + fprintf(stdout," By default, RGB->YCC conversion is used if there are 3 components or more,\n"); + fprintf(stdout," no conversion otherwise.\n"); + fprintf(stdout,"-m : use array-based MCT, values are coma separated, line by line\n"); + fprintf(stdout," no specific separators between lines, no space allowed between values\n"); + fprintf(stdout," If this option is used, it automatically sets \"-mct\" option to 2.\n"); + fprintf(stdout,"-jpip : write jpip codestream index box in JP2 output file\n"); + fprintf(stdout," NOTICE: currently supports only RPCL order\n"); + fprintf(stdout,"\n"); + /* UniPG>> */ #ifdef USE_JPWL - fprintf(stdout," * No JPWL protection\n"); + fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n"); + fprintf(stdout," The parameters can be written and repeated in any order:\n"); + fprintf(stdout," [h<=type>,s<=method>,a=,...\n"); + fprintf(stdout," ...,z=,g=,p<=type>]\n"); + fprintf(stdout,"\n"); + fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n"); + fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n"); + fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n"); + fprintf(stdout," if 'tilepart' is present, it applies from that tile\n"); + fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n"); + fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS); + fprintf(stdout,"\n"); + fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n"); + fprintf(stdout," to be applied to raw data: 'type' can be\n"); + fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n"); + fprintf(stdout," if 'tilepart:pack' is absent, it is from tile 0, packet 0\n"); + fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n"); + fprintf(stdout," and that packet onwards, up to the next packet spec\n"); + fprintf(stdout," or to the last packet in the last tilepart in the stream\n"); + fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS); + fprintf(stdout,"\n"); + fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n"); + fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n"); + fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n"); + fprintf(stdout," if 'tilepart' is absent, it is for main header only\n"); + fprintf(stdout," if 'tilepart' is present, it applies from that tile\n"); + fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n"); + fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS); + fprintf(stdout,"\n"); + fprintf(stdout," g determines the addressing mode: can be\n"); + fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n"); + fprintf(stdout,"\n"); + fprintf(stdout," a determines the size of data addressing: can be\n"); + fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n"); + fprintf(stdout,"\n"); + fprintf(stdout," z determines the size of sensitivity values: can be\n"); + fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n"); + fprintf(stdout,"\n"); + fprintf(stdout," ex.:\n"); + fprintf(stdout," h,h0=64,h3=16,h5=32,p0=78,p0:24=56,p1,p3:0=0,p3:20=32,s=0,\n"); + fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n"); + fprintf(stdout," means\n"); + fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n"); + fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n"); + fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n"); + fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n"); + fprintf(stdout," UEP rs default for packets of tilepart 1,\n"); + fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n"); + fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n"); + fprintf(stdout," relative sensitivity ESD for MH,\n"); + fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n"); + fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n"); + fprintf(stdout,"\n"); + fprintf(stdout," ex.:\n"); + fprintf(stdout," h,s,p\n"); + fprintf(stdout," means\n"); + fprintf(stdout," default protection to headers (MH and TPHs) as well as\n"); + fprintf(stdout," data packets, one ESD in MH\n"); + fprintf(stdout,"\n"); + fprintf(stdout," N.B.: use the following recommendations when specifying\n"); + fprintf(stdout," the JPWL parameters list\n"); + fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n"); + fprintf(stdout," \n"); #endif /* USE_JPWL */ -/* < \n"); - fprintf(stdout," Currently accepts PBM, PGM, PPM, PNM, PAM, PGX, PNG, BMP, TIF, RAW, RAWL and TGA formats\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-i : source file (-i source.pnm also *pbm, *.pgm, *.ppm, *.pam, *.pgx, *png, *.bmp, *.tif, *.raw, *.tga) \n"); - fprintf(stdout," When using this option -o must be used\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-o : destination file (-o dest.j2k or .jp2) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"Optional Parameters:\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-h : display the help information \n "); - fprintf(stdout,"\n"); - fprintf(stdout,"-cinema2K : Digital Cinema 2K profile compliant codestream for 2K resolution.(-CINEMA2K 24 or 48) \n"); - fprintf(stdout," Need to specify the frames per second for a 2K resolution. Only 24 or 48 fps is allowed\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-cinema4K : Digital Cinema 4K profile compliant codestream for 4K resolution \n"); - fprintf(stdout," Frames per second not required. Default value is 24fps\n"); - fprintf(stdout,"\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,"\n"); - fprintf(stdout," (options -r and -q cannot be used together)\n "); - fprintf(stdout,"\n"); + /* <> */ -#ifdef USE_JPWL - fprintf(stdout,"-W : adoption of JPWL (Part 11) capabilities (-W params)\n"); - fprintf(stdout," The parameters can be written and repeated in any order:\n"); - fprintf(stdout," [h<=type>,s<=method>,a=,...\n"); - fprintf(stdout," ...,z=,g=,p<=type>]\n"); - fprintf(stdout,"\n"); - fprintf(stdout," h selects the header error protection (EPB): 'type' can be\n"); - fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n"); - fprintf(stdout," if 'tilepart' is absent, it is for main and tile headers\n"); - fprintf(stdout," if 'tilepart' is present, it applies from that tile\n"); - fprintf(stdout," onwards, up to the next h<> spec, or to the last tilepart\n"); - fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS); - fprintf(stdout,"\n"); - fprintf(stdout," p selects the packet error protection (EEP/UEP with EPBs)\n"); - fprintf(stdout," to be applied to raw data: 'type' can be\n"); - fprintf(stdout," [0=none 1,absent=predefined 16=CRC-16 32=CRC-32 37-128=RS]\n"); - fprintf(stdout," if 'tilepart:pack' is absent, it is from tile 0, packet 0\n"); - fprintf(stdout," if 'tilepart:pack' is present, it applies from that tile\n"); - fprintf(stdout," and that packet onwards, up to the next packet spec\n"); - fprintf(stdout," or to the last packet in the last tilepart in the stream\n"); - fprintf(stdout," (max. %d specs)\n", JPWL_MAX_NO_PACKSPECS); - fprintf(stdout,"\n"); - fprintf(stdout," s enables sensitivity data insertion (ESD): 'method' can be\n"); - fprintf(stdout," [-1=NO ESD 0=RELATIVE ERROR 1=MSE 2=MSE REDUCTION 3=PSNR\n"); - fprintf(stdout," 4=PSNR INCREMENT 5=MAXERR 6=TSE 7=RESERVED]\n"); - fprintf(stdout," if 'tilepart' is absent, it is for main header only\n"); - fprintf(stdout," if 'tilepart' is present, it applies from that tile\n"); - fprintf(stdout," onwards, up to the next s<> spec, or to the last tilepart\n"); - fprintf(stdout," in the codestream (max. %d specs)\n", JPWL_MAX_NO_TILESPECS); - fprintf(stdout,"\n"); - fprintf(stdout," g determines the addressing mode: can be\n"); - fprintf(stdout," [0=PACKET 1=BYTE RANGE 2=PACKET RANGE]\n"); - fprintf(stdout,"\n"); - fprintf(stdout," a determines the size of data addressing: can be\n"); - fprintf(stdout," 2/4 bytes (small/large codestreams). If not set, auto-mode\n"); - fprintf(stdout,"\n"); - fprintf(stdout," z determines the size of sensitivity values: can be\n"); - fprintf(stdout," 1/2 bytes, for the transformed pseudo-floating point value\n"); - fprintf(stdout,"\n"); - fprintf(stdout," ex.:\n"); - fprintf(stdout," h,h0=64,h3=16,h5=32,p0=78,p0:24=56,p1,p3:0=0,p3:20=32,s=0,\n"); - fprintf(stdout," s0=6,s3=-1,a=0,g=1,z=1\n"); - fprintf(stdout," means\n"); - fprintf(stdout," predefined EPB in MH, rs(64,32) from TPH 0 to TPH 2,\n"); - fprintf(stdout," CRC-16 in TPH 3 and TPH 4, CRC-32 in remaining TPHs,\n"); - fprintf(stdout," UEP rs(78,32) for packets 0 to 23 of tile 0,\n"); - fprintf(stdout," UEP rs(56,32) for packs. 24 to the last of tilepart 0,\n"); - fprintf(stdout," UEP rs default for packets of tilepart 1,\n"); - fprintf(stdout," no UEP for packets 0 to 19 of tilepart 3,\n"); - fprintf(stdout," UEP CRC-32 for packs. 20 of tilepart 3 to last tilepart,\n"); - fprintf(stdout," relative sensitivity ESD for MH,\n"); - fprintf(stdout," TSE ESD from TPH 0 to TPH 2, byte range with automatic\n"); - fprintf(stdout," size of addresses and 1 byte for each sensitivity value\n"); - fprintf(stdout,"\n"); - fprintf(stdout," ex.:\n"); - fprintf(stdout," h,s,p\n"); - fprintf(stdout," means\n"); - fprintf(stdout," default protection to headers (MH and TPHs) as well as\n"); - fprintf(stdout," data packets, one ESD in MH\n"); - fprintf(stdout,"\n"); - fprintf(stdout," N.B.: use the following recommendations when specifying\n"); - fprintf(stdout," the JPWL parameters list\n"); - fprintf(stdout," - when you use UEP, always pair the 'p' option with 'h'\n"); - fprintf(stdout," \n"); -#endif /* USE_JPWL */ -/* <d_name)==0 || strcmp("..",content->d_name)==0 ) - continue; - num_images++; - } - return num_images; + num_images=0; + while((content=readdir(dir))!=NULL){ + if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 ) + continue; + num_images++; + } + return num_images; } static int load_images(dircnt_t *dirptr, char *imgdirpath){ - DIR *dir; - struct dirent* content; - int i = 0; + DIR *dir; + struct dirent* content; + int i = 0; - /*Reading the input images from given input directory*/ + /*Reading the input images from given input directory*/ - dir= opendir(imgdirpath); - if(!dir){ - fprintf(stderr,"Could not open Folder %s\n",imgdirpath); - return 1; - }else { - fprintf(stderr,"Folder opened successfully\n"); - } + dir= opendir(imgdirpath); + if(!dir){ + fprintf(stderr,"Could not open Folder %s\n",imgdirpath); + return 1; + }else { + fprintf(stderr,"Folder opened successfully\n"); + } - while((content=readdir(dir))!=NULL){ - if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 ) - continue; + while((content=readdir(dir))!=NULL){ + if(strcmp(".",content->d_name)==0 || strcmp("..",content->d_name)==0 ) + continue; - strcpy(dirptr->filename[i],content->d_name); - i++; - } - return 0; + strcpy(dirptr->filename[i],content->d_name); + i++; + } + return 0; } static int get_file_format(char *filename) { - unsigned int i; - static const char *extension[] = { - "pgx", "pnm", "pgm", "ppm", "pbm", "pam", "bmp", "tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "j2c", "jpc" + unsigned int i; + static const char *extension[] = { + "pgx", "pnm", "pgm", "ppm", "pbm", "pam", "bmp", "tif", "raw", "rawl", "tga", "png", "j2k", "jp2", "j2c", "jpc" }; - static const int format[] = { - PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, J2K_CFMT, J2K_CFMT + static const int format[] = { + PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, RAWL_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, J2K_CFMT, J2K_CFMT }; - char * ext = strrchr(filename, '.'); - if (ext == NULL) - return -1; - ext++; - for(i = 0; i < sizeof(format)/sizeof(*format); i++) { - if(strcasecmp(ext, extension[i]) == 0) { - return format[i]; - } - } - return -1; + char * ext = strrchr(filename, '.'); + if (ext == NULL) + return -1; + ext++; + for(i = 0; i < sizeof(format)/sizeof(*format); i++) { + if(strcasecmp(ext, extension[i]) == 0) { + return format[i]; + } + } + return -1; } static char * get_file_name(char *name){ - char *fname; - fname= (char*)malloc(OPJ_PATH_LEN*sizeof(char)); - fname= strtok(name,"."); - return fname; + char *fname = strtok(name,"."); + return fname; } static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_cparameters_t *parameters){ - char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN]; - char *temp_p, temp1[OPJ_PATH_LEN]=""; + char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN]; + char *temp_p, temp1[OPJ_PATH_LEN]=""; - strcpy(image_filename,dirptr->filename[imageno]); - fprintf(stderr,"File Number %d \"%s\"\n",imageno,image_filename); - parameters->decod_format = get_file_format(image_filename); - if (parameters->decod_format == -1) - return 1; - sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename); - strncpy(parameters->infile, infilename, sizeof(infilename)); + strcpy(image_filename,dirptr->filename[imageno]); + fprintf(stderr,"File Number %d \"%s\"\n",imageno,image_filename); + parameters->decod_format = get_file_format(image_filename); + if (parameters->decod_format == -1) + return 1; + sprintf(infilename,"%s/%s",img_fol->imgdirpath,image_filename); + strncpy(parameters->infile, infilename, sizeof(infilename)); - /*Set output file*/ - strcpy(temp_ofname,get_file_name(image_filename)); - while((temp_p = strtok(NULL,".")) != NULL){ - strcat(temp_ofname,temp1); - sprintf(temp1,".%s",temp_p); - } - if(img_fol->set_out_format==1){ - sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format); - strncpy(parameters->outfile, outfilename, sizeof(outfilename)); - } - return 0; -} - -static int initialise_4K_poc(opj_poc_t *POC, int numres){ - POC[0].tile = 1; - POC[0].resno0 = 0; - POC[0].compno0 = 0; - POC[0].layno1 = 1; - POC[0].resno1 = numres-1; - POC[0].compno1 = 3; - POC[0].prg1 = OPJ_CPRL; - POC[1].tile = 1; - POC[1].resno0 = numres-1; - POC[1].compno0 = 0; - POC[1].layno1 = 1; - POC[1].resno1 = numres; - POC[1].compno1 = 3; - POC[1].prg1 = OPJ_CPRL; - return 2; -} - -static void cinema_parameters(opj_cparameters_t *parameters){ - parameters->tile_size_on = OPJ_FALSE; - parameters->cp_tdx=1; - parameters->cp_tdy=1; - - /*Tile part*/ - parameters->tp_flag = 'C'; - parameters->tp_on = 1; - - /*Tile and Image shall be at (0,0)*/ - parameters->cp_tx0 = 0; - parameters->cp_ty0 = 0; - parameters->image_offset_x0 = 0; - parameters->image_offset_y0 = 0; - - /*Codeblock size= 32*32*/ - parameters->cblockw_init = 32; - parameters->cblockh_init = 32; - parameters->csty |= 0x01; - - /*The progression order shall be CPRL*/ - parameters->prog_order = OPJ_CPRL; - - /* No ROI */ - parameters->roi_compno = -1; - - parameters->subsampling_dx = 1; parameters->subsampling_dy = 1; - - /* 9-7 transform */ - parameters->irreversible = 1; - -} - -static void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_fol_t *img_fol){ - int i; - float temp_rate; - - switch (parameters->cp_cinema){ - case OPJ_CINEMA2K_24: - case OPJ_CINEMA2K_48: - if(parameters->numresolution > 6){ - parameters->numresolution = 6; - } - if (!((image->comps[0].w == 2048) | (image->comps[0].h == 1080))){ - fprintf(stdout,"Image coordinates %d x %d is not 2K compliant.\nJPEG Digital Cinema Profile-3 " - "(2K profile) compliance requires that at least one of coordinates match 2048 x 1080\n", - image->comps[0].w,image->comps[0].h); - parameters->cp_rsiz = OPJ_STD_RSIZ; - } - break; - - case OPJ_CINEMA4K_24: - if(parameters->numresolution < 1){ - parameters->numresolution = 1; - }else if(parameters->numresolution > 7){ - parameters->numresolution = 7; - } - if (!((image->comps[0].w == 4096) | (image->comps[0].h == 2160))){ - fprintf(stdout,"Image coordinates %d x %d is not 4K compliant.\nJPEG Digital Cinema Profile-4" - "(4K profile) compliance requires that at least one of coordinates match 4096 x 2160\n", - image->comps[0].w,image->comps[0].h); - parameters->cp_rsiz = OPJ_STD_RSIZ; - } - parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution); - break; - default : - break; - } - - switch (parameters->cp_cinema){ - case OPJ_CINEMA2K_24: - case OPJ_CINEMA4K_24: - for(i=0 ; itcp_numlayers ; i++){ - temp_rate = 0 ; - if (img_fol->rates[i]== 0){ - parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); - }else{ - temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); - if (temp_rate > CINEMA_24_CS ){ - parameters->tcp_rates[i]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); - }else{ - parameters->tcp_rates[i]= img_fol->rates[i]; - } - } - } - parameters->max_comp_size = COMP_24_CS; - break; - - case OPJ_CINEMA2K_48: - for(i=0 ; itcp_numlayers ; i++){ - temp_rate = 0 ; - if (img_fol->rates[i]== 0){ - parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); - }else{ - temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (img_fol->rates[i] * 8 * image->comps[0].dx * image->comps[0].dy); - if (temp_rate > CINEMA_48_CS ){ - parameters->tcp_rates[0]= ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ - (CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); - }else{ - parameters->tcp_rates[i]= img_fol->rates[i]; - } - } - } - parameters->max_comp_size = COMP_48_CS; - break; - default: - break; - } - parameters->cp_disto_alloc = 1; + /*Set output file*/ + strcpy(temp_ofname,get_file_name(image_filename)); + while((temp_p = strtok(NULL,".")) != NULL){ + strcat(temp_ofname,temp1); + sprintf(temp1,".%s",temp_p); + } + if(img_fol->set_out_format==1){ + sprintf(outfilename,"%s/%s.%s",img_fol->imgdirpath,temp_ofname,img_fol->out_format); + strncpy(parameters->outfile, outfilename, sizeof(outfilename)); + } + return 0; } /* ------------------------------------------------------------------------------------ */ static int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters, - img_fol_t *img_fol, raw_cparameters_t *raw_cp, char *indexfilename) { - int i, j, totlen, c; - opj_option_t long_option[]={ - {"cinema2K",REQ_ARG, NULL ,'w'}, - {"cinema4K",NO_ARG, NULL ,'y'}, - {"ImgDir",REQ_ARG, NULL ,'z'}, - {"TP",REQ_ARG, NULL ,'u'}, - {"SOP",NO_ARG, NULL ,'S'}, - {"EPH",NO_ARG, NULL ,'E'}, - {"OutFor",REQ_ARG, NULL ,'O'}, - {"POC",REQ_ARG, NULL ,'P'}, - {"ROI",REQ_ARG, NULL ,'R'}, - {"jpip",NO_ARG, NULL, 'J'} - }; + img_fol_t *img_fol, raw_cparameters_t *raw_cp, char *indexfilename) { + OPJ_UINT32 i, j; + int totlen, c; + opj_option_t long_option[]={ + {"cinema2K",REQ_ARG, NULL ,'w'}, + {"cinema4K",NO_ARG, NULL ,'y'}, + {"ImgDir",REQ_ARG, NULL ,'z'}, + {"TP",REQ_ARG, NULL ,'u'}, + {"SOP",NO_ARG, NULL ,'S'}, + {"EPH",NO_ARG, NULL ,'E'}, + {"OutFor",REQ_ARG, NULL ,'O'}, + {"POC",REQ_ARG, NULL ,'P'}, + {"ROI",REQ_ARG, NULL ,'R'}, + {"jpip",NO_ARG, NULL, 'J'}, + {"mct",REQ_ARG, NULL, 'Y'} + }; - /* parse the command line */ - const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:J" + /* parse the command line */ + const char optlist[] = "i:o:r:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:u:JY:" + #ifdef USE_JPWL + "W:" + #endif /* USE_JPWL */ + "h"; + + totlen=sizeof(long_option); + img_fol->set_out_format=0; + raw_cp->rawWidth = 0; + + do{ + c = opj_getopt_long(argc, argv, optlist,long_option,totlen); + if (c == -1) + break; + switch (c) { + case 'i': /* input file */ + { + char *infile = opj_optarg; + parameters->decod_format = get_file_format(infile); + switch(parameters->decod_format) { + case PGX_DFMT: + case PXM_DFMT: + case BMP_DFMT: + case TIF_DFMT: + case RAW_DFMT: + case RAWL_DFMT: + case TGA_DFMT: + case PNG_DFMT: + break; + default: + fprintf(stderr, + "!! Unrecognized format for infile : %s " + "[accept only *.pnm, *.pgm, *.ppm, *.pgx, *png, *.bmp, *.tif, *.raw or *.tga] !!\n\n", + infile); + return 1; + } + strncpy(parameters->infile, infile, sizeof(parameters->infile)-1); + } + break; + + /* ----------------------------------------------------- */ + + case 'o': /* output file */ + { + char *outfile = opj_optarg; + parameters->cod_format = get_file_format(outfile); + switch(parameters->cod_format) { + case J2K_CFMT: + case JP2_CFMT: + break; + default: + fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile); + return 1; + } + strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1); + } + break; + + /* ----------------------------------------------------- */ + case 'O': /* output format */ + { + char outformat[50]; + char *of = opj_optarg; + sprintf(outformat,".%s",of); + img_fol->set_out_format = 1; + parameters->cod_format = get_file_format(outformat); + switch(parameters->cod_format) { + case J2K_CFMT: + case JP2_CFMT: + img_fol->out_format = opj_optarg; + break; + default: + fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n"); + return 1; + } + } + break; + + + /* ----------------------------------------------------- */ + + + case 'r': /* rates rates/distorsion */ + { + char *s = opj_optarg; + parameters->tcp_numlayers = 0; + while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) { + parameters->tcp_numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + parameters->cp_disto_alloc = 1; + } + break; + + /* ----------------------------------------------------- */ + + + case 'F': /* Raw image format parameters */ + { + char signo; + char *s = opj_optarg; + if (sscanf(s, "%d,%d,%d,%d,%c", &raw_cp->rawWidth, &raw_cp->rawHeight, &raw_cp->rawComp, &raw_cp->rawBitDepth, &signo) == 5) { + if (signo == 's') { + raw_cp->rawSigned = OPJ_TRUE; + fprintf(stdout,"\nRaw file parameters: %d,%d,%d,%d Signed\n", raw_cp->rawWidth, raw_cp->rawHeight, raw_cp->rawComp, raw_cp->rawBitDepth); + } + else if (signo == 'u') { + raw_cp->rawSigned = OPJ_FALSE; + fprintf(stdout,"\nRaw file parameters: %d,%d,%d,%d Unsigned\n", raw_cp->rawWidth, raw_cp->rawHeight, raw_cp->rawComp, raw_cp->rawBitDepth); + } + else { + fprintf(stderr,"\nError: invalid raw image parameters: Unknown sign of raw file\n"); + fprintf(stderr,"Please use the Format option -F:\n"); + fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); + fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); + fprintf(stderr,"Aborting\n"); + } + } + else { + fprintf(stderr,"\nError: invalid raw image parameters\n"); + fprintf(stderr,"Please use the Format option -F:\n"); + fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); + fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); + fprintf(stderr,"Aborting\n"); + return 1; + } + } + break; + + /* ----------------------------------------------------- */ + + case 'q': /* add fixed_quality */ + { + char *s = opj_optarg; + while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) { + parameters->tcp_numlayers++; + while (*s && *s != ',') { + s++; + } + if (!*s) + break; + s++; + } + parameters->cp_fixed_quality = 1; + } + break; + + /* dda */ + /* ----------------------------------------------------- */ + + case 'f': /* mod fixed_quality (before : -q) */ + { + int *row = NULL, *col = NULL; + OPJ_UINT32 numlayers = 0, numresolution = 0, matrix_width = 0; + + char *s = opj_optarg; + sscanf(s, "%ud", &numlayers); + s++; + if (numlayers > 9) + s++; + + parameters->tcp_numlayers = (int)numlayers; + numresolution = (OPJ_UINT32)parameters->numresolution; + matrix_width = numresolution * 3; + parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int)); + s = s + 2; + + for (i = 0; i < numlayers; i++) { + row = ¶meters->cp_matrice[i * matrix_width]; + col = row; + 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++; + } + parameters->cp_fixed_alloc = 1; + } + break; + + /* ----------------------------------------------------- */ + + case 't': /* tiles */ + { + sscanf(opj_optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy); + parameters->tile_size_on = OPJ_TRUE; + } + break; + + /* ----------------------------------------------------- */ + + case 'n': /* resolution */ + { + sscanf(opj_optarg, "%d", ¶meters->numresolution); + } + break; + + /* ----------------------------------------------------- */ + case 'c': /* precinct dimension */ + { + char sep; + int res_spec = 0; + + char *s = opj_optarg; + int ret; + do { + sep = 0; + ret = sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec], + ¶meters->prch_init[res_spec], &sep); + if( !(ret == 2 && sep == 0) && !(ret == 3 && sep == ',') ) + { + fprintf(stderr,"\nError: could not parse precinct dimension: '%s' %x\n", s, sep); + fprintf(stderr,"Example: -i lena.raw -o lena.j2k -c [128,128],[128,128]\n"); + return 1; + } + parameters->csty |= 0x01; + res_spec++; + s = strpbrk(s, "]") + 2; + } + while (sep == ','); + 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; + } + parameters->cblockw_init = cblockw_init; + parameters->cblockh_init = cblockh_init; + } + break; + + /* ----------------------------------------------------- */ + + case 'x': /* creation of index file */ + { + char *index = opj_optarg; + strncpy(indexfilename, index, OPJ_PATH_LEN); + } + break; + + /* ----------------------------------------------------- */ + + case 'p': /* progression order */ + { + char progression[4]; + + strncpy(progression, opj_optarg, 4); + parameters->prog_order = give_progression(progression); + if (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", ¶meters->subsampling_dx, + ¶meters->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", ¶meters->image_offset_x0, + ¶meters->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 */ + encode_help_display(); + return 1; + + /* ----------------------------------------------------- */ + + 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 = parameters->POC; + + while (sscanf(s, "T%ud=%ud,%ud,%ud,%ud,%ud,%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++; + } + parameters->numpocs = (OPJ_UINT32)numpocs; + } + break; + + /* ------------------------------------------------------ */ + + case 'S': /* SOP marker */ + { + parameters->csty |= 0x02; + } + break; + + /* ------------------------------------------------------ */ + + case 'E': /* EPH marker */ + { + parameters->csty |= 0x04; + } + break; + + /* ------------------------------------------------------ */ + + case 'M': /* Mode switch pas tous au point !! */ + { + int value = 0; + if (sscanf(opj_optarg, "%d", &value) == 1) { + for (i = 0; i <= 5; i++) { + int cache = value & (1 << i); + if (cache) + parameters->mode |= (1 << i); + } + } + } + break; + + /* ------------------------------------------------------ */ + + case 'R': /* ROI */ + { + if (sscanf(opj_optarg, "c=%d,U=%d", ¶meters->roi_compno, + ¶meters->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", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) { + fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]"); + return 1; + } + } + break; + + /* ------------------------------------------------------ */ + + case 'C': /* add a comment */ + { + parameters->cp_comment = (char*)malloc(strlen(opj_optarg) + 1); + if(parameters->cp_comment) { + strcpy(parameters->cp_comment, opj_optarg); + } + } + break; + + + /* ------------------------------------------------------ */ + + case 'I': /* reversible or not */ + { + parameters->irreversible = 1; + } + break; + + /* ------------------------------------------------------ */ + + case 'u': /* Tile part generation*/ + { + parameters->tp_flag = opj_optarg[0]; + parameters->tp_on = 1; + } + break; + + /* ------------------------------------------------------ */ + + case 'z': /* Image Directory path */ + { + img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1); + strcpy(img_fol->imgdirpath,opj_optarg); + img_fol->set_imgdir=1; + } + break; + + /* ------------------------------------------------------ */ + + case 'w': /* Digital Cinema 2K profile compliance*/ + { + int fps=0; + sscanf(opj_optarg,"%d",&fps); + if(fps == 24){ + parameters->cp_cinema = OPJ_CINEMA2K_24; + }else if(fps == 48 ){ + parameters->cp_cinema = OPJ_CINEMA2K_48; + }else { + fprintf(stderr,"Incorrect value!! must be 24 or 48\n"); + return 1; + } + fprintf(stdout,"CINEMA 2K profile activated\n" + "Other options specified could be overriden\n"); + + } + break; + + /* ------------------------------------------------------ */ + + case 'y': /* Digital Cinema 4K profile compliance*/ + { + parameters->cp_cinema = OPJ_CINEMA4K_24; + fprintf(stdout,"CINEMA 4K profile activated\n" + "Other options specified could be overriden\n"); + } + break; + + /* ------------------------------------------------------ */ + + case 'Y': /* Shall we do an MCT ? 0:no_mct;1:rgb->ycc;2:custom mct (-m option required)*/ + { + int mct_mode=0; + sscanf(opj_optarg,"%d",&mct_mode); + if(mct_mode < 0 || mct_mode > 2){ + fprintf(stderr,"MCT incorrect value!! Current accepted values are 0, 1 or 2.\n"); + return 1; + } + parameters->tcp_mct = (char) mct_mode; + } + break; + + /* ------------------------------------------------------ */ + + + case 'm': /* mct input file */ + { + char *lFilename = opj_optarg; + char *lMatrix; + char *lCurrentPtr ; + float *lCurrentDoublePtr; + float *lSpace; + int *l_int_ptr; + int lNbComp = 0, lTotalComp, lMctComp, i2; + size_t lStrLen, lStrFread; + + /* Open file */ + FILE * lFile = fopen(lFilename,"r"); + if (lFile == NULL) { + return 1; + } + + /* Set size of file and read its content*/ + fseek(lFile,0,SEEK_END); + lStrLen = (size_t)ftell(lFile); + fseek(lFile,0,SEEK_SET); + lMatrix = (char *) malloc(lStrLen + 1); + lStrFread = fread(lMatrix, 1, lStrLen, lFile); + fclose(lFile); + if( lStrLen != lStrFread ) return 1; + + lMatrix[lStrLen] = 0; + lCurrentPtr = lMatrix; + + /* replace ',' by 0 */ + while (*lCurrentPtr != 0 ) { + if (*lCurrentPtr == ' ') { + *lCurrentPtr = 0; + ++lNbComp; + } + ++lCurrentPtr; + } + ++lNbComp; + lCurrentPtr = lMatrix; + + lNbComp = (int) (sqrt(4*lNbComp + 1)/2. - 0.5); + lMctComp = lNbComp * lNbComp; + lTotalComp = lMctComp + lNbComp; + lSpace = (float *) malloc((size_t)lTotalComp * sizeof(float)); + lCurrentDoublePtr = lSpace; + for (i2=0;i2> */ #ifdef USE_JPWL - "W:" + /* ------------------------------------------------------ */ + + case 'W': /* JPWL capabilities switched on */ + { + char *token = NULL; + int hprot, pprot, sens, addr, size, range; + + /* we need to enable indexing */ + if (!indexfilename || !*indexfilename) { + strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN); + } + + /* search for different protection methods */ + + /* break the option in comma points and parse the result */ + token = strtok(opj_optarg, ","); + while(token != NULL) { + + /* search header error protection method */ + if (*token == 'h') { + + static int tile = 0, tilespec = 0, lasttileno = 0; + + hprot = 1; /* predefined method */ + + if(sscanf(token, "h=%d", &hprot) == 1) { + /* Main header, specified */ + if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) || + ((hprot >= 37) && (hprot <= 128)))) { + fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot); + return 1; + } + parameters->jpwl_hprot_MH = hprot; + + } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) { + /* Tile part header, specified */ + if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) || + ((hprot >= 37) && (hprot <= 128)))) { + fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n", hprot); + return 1; + } + if (tile < 0) { + fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile); + return 1; + } + if (tilespec < JPWL_MAX_NO_TILESPECS) { + parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile; + parameters->jpwl_hprot_TPH[tilespec++] = hprot; + } + + } else if(sscanf(token, "h%d", &tile) == 1) { + /* Tile part header, unspecified */ + if (tile < 0) { + fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile); + return 1; + } + if (tilespec < JPWL_MAX_NO_TILESPECS) { + parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile; + parameters->jpwl_hprot_TPH[tilespec++] = hprot; + } + + + } else if (!strcmp(token, "h")) { + /* Main header, unspecified */ + parameters->jpwl_hprot_MH = hprot; + + } else { + fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token); + return 1; + }; + + } + + /* search packet error protection method */ + if (*token == 'p') { + + static int pack = 0, tile = 0, packspec = 0; + + pprot = 1; /* predefined method */ + + if (sscanf(token, "p=%d", &pprot) == 1) { + /* Method for all tiles and all packets */ + if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) || + ((pprot >= 37) && (pprot <= 128)))) { + fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot); + return 1; + } + parameters->jpwl_pprot_tileno[0] = 0; + parameters->jpwl_pprot_packno[0] = 0; + parameters->jpwl_pprot[0] = pprot; + + } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) { + /* method specified from that tile on */ + if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) || + ((pprot >= 37) && (pprot <= 128)))) { + fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot); + return 1; + } + if (tile < 0) { + fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile); + return 1; + } + if (packspec < JPWL_MAX_NO_PACKSPECS) { + parameters->jpwl_pprot_tileno[packspec] = tile; + parameters->jpwl_pprot_packno[packspec] = 0; + parameters->jpwl_pprot[packspec++] = pprot; + } + + } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) { + /* method fully specified from that tile and that packet on */ + if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) || + ((pprot >= 37) && (pprot <= 128)))) { + fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot); + return 1; + } + if (tile < 0) { + fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile); + return 1; + } + if (pack < 0) { + fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack); + return 1; + } + if (packspec < JPWL_MAX_NO_PACKSPECS) { + parameters->jpwl_pprot_tileno[packspec] = tile; + parameters->jpwl_pprot_packno[packspec] = pack; + parameters->jpwl_pprot[packspec++] = pprot; + } + + } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) { + /* default method from that tile and that packet on */ + if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) || + ((pprot >= 37) && (pprot <= 128)))) { + fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot); + return 1; + } + if (tile < 0) { + fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile); + return 1; + } + if (pack < 0) { + fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack); + return 1; + } + if (packspec < JPWL_MAX_NO_PACKSPECS) { + parameters->jpwl_pprot_tileno[packspec] = tile; + parameters->jpwl_pprot_packno[packspec] = pack; + parameters->jpwl_pprot[packspec++] = pprot; + } + + } else if (sscanf(token, "p%d", &tile) == 1) { + /* default from a tile on */ + if (tile < 0) { + fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile); + return 1; + } + if (packspec < JPWL_MAX_NO_PACKSPECS) { + parameters->jpwl_pprot_tileno[packspec] = tile; + parameters->jpwl_pprot_packno[packspec] = 0; + parameters->jpwl_pprot[packspec++] = pprot; + } + + + } else if (!strcmp(token, "p")) { + /* all default */ + parameters->jpwl_pprot_tileno[0] = 0; + parameters->jpwl_pprot_packno[0] = 0; + parameters->jpwl_pprot[0] = pprot; + + } else { + fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token); + return 1; + }; + + } + + /* search sensitivity method */ + if (*token == 's') { + + static int tile = 0, tilespec = 0, lasttileno = 0; + + sens = 0; /* predefined: relative error */ + + if(sscanf(token, "s=%d", &sens) == 1) { + /* Main header, specified */ + if ((sens < -1) || (sens > 7)) { + fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens); + return 1; + } + parameters->jpwl_sens_MH = sens; + + } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) { + /* Tile part header, specified */ + if ((sens < -1) || (sens > 7)) { + fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens); + return 1; + } + if (tile < 0) { + fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile); + return 1; + } + if (tilespec < JPWL_MAX_NO_TILESPECS) { + parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile; + parameters->jpwl_sens_TPH[tilespec++] = sens; + } + + } else if(sscanf(token, "s%d", &tile) == 1) { + /* Tile part header, unspecified */ + if (tile < 0) { + fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile); + return 1; + } + if (tilespec < JPWL_MAX_NO_TILESPECS) { + parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile; + parameters->jpwl_sens_TPH[tilespec++] = hprot; + } + + } else if (!strcmp(token, "s")) { + /* Main header, unspecified */ + parameters->jpwl_sens_MH = sens; + + } else { + fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token); + return 1; + }; + + parameters->jpwl_sens_size = 2; /* 2 bytes for default size */ + } + + /* search addressing size */ + if (*token == 'a') { + + + addr = 0; /* predefined: auto */ + + if(sscanf(token, "a=%d", &addr) == 1) { + /* Specified */ + if ((addr != 0) && (addr != 2) && (addr != 4)) { + fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr); + return 1; + } + parameters->jpwl_sens_addr = addr; + + } else if (!strcmp(token, "a")) { + /* default */ + parameters->jpwl_sens_addr = addr; /* auto for default size */ + + } else { + fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token); + return 1; + }; + + } + + /* search sensitivity size */ + if (*token == 'z') { + + + size = 1; /* predefined: 1 byte */ + + if(sscanf(token, "z=%d", &size) == 1) { + /* Specified */ + if ((size != 0) && (size != 1) && (size != 2)) { + fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size); + return 1; + } + parameters->jpwl_sens_size = size; + + } else if (!strcmp(token, "a")) { + /* default */ + parameters->jpwl_sens_size = size; /* 1 for default size */ + + } else { + fprintf(stderr, "ERROR -> invalid size selection = %s\n", token); + return 1; + }; + + } + + /* search range method */ + if (*token == 'g') { + + + range = 0; /* predefined: 0 (packet) */ + + if(sscanf(token, "g=%d", &range) == 1) { + /* Specified */ + if ((range < 0) || (range > 3)) { + fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range); + return 1; + } + parameters->jpwl_sens_range = range; + + } else if (!strcmp(token, "g")) { + /* default */ + parameters->jpwl_sens_range = range; + + } else { + fprintf(stderr, "ERROR -> invalid range selection = %s\n", token); + return 1; + }; + + } + + /* next token or bust */ + token = strtok(NULL, ","); + }; + + + /* some info */ + fprintf(stdout, "Info: JPWL capabilities enabled\n"); + parameters->jpwl_epc_on = OPJ_TRUE; + + } + break; #endif /* USE_JPWL */ - "h"; - - totlen=sizeof(long_option); - img_fol->set_out_format=0; - raw_cp->rawWidth = 0; - - do{ - c = opj_getopt_long(argc, argv, optlist,long_option,totlen); - if (c == -1) - break; - switch (c) { - case 'i': /* input file */ - { - char *infile = opj_optarg; - parameters->decod_format = get_file_format(infile); - switch(parameters->decod_format) { - case PGX_DFMT: - case PXM_DFMT: - case BMP_DFMT: - case TIF_DFMT: - case RAW_DFMT: - case RAWL_DFMT: - case TGA_DFMT: - case PNG_DFMT: - break; - default: - fprintf(stderr, - "!! Unrecognized format for infile : %s " - "[accept only *.pnm, *.pgm, *.ppm, *.pgx, *png, *.bmp, *.tif, *.raw or *.tga] !!\n\n", - infile); - return 1; - } - strncpy(parameters->infile, infile, sizeof(parameters->infile)-1); - } - break; - - /* ----------------------------------------------------- */ - - case 'o': /* output file */ - { - char *outfile = opj_optarg; - parameters->cod_format = get_file_format(outfile); - switch(parameters->cod_format) { - case J2K_CFMT: - case JP2_CFMT: - break; - default: - fprintf(stderr, "Unknown output format image %s [only *.j2k, *.j2c or *.jp2]!! \n", outfile); - return 1; - } - strncpy(parameters->outfile, outfile, sizeof(parameters->outfile)-1); - } - break; - - /* ----------------------------------------------------- */ - case 'O': /* output format */ - { - char outformat[50]; - char *of = opj_optarg; - sprintf(outformat,".%s",of); - img_fol->set_out_format = 1; - parameters->cod_format = get_file_format(outformat); - switch(parameters->cod_format) { - case J2K_CFMT: - case JP2_CFMT: - img_fol->out_format = opj_optarg; - break; - default: - fprintf(stderr, "Unknown output format image [only j2k, j2c, jp2]!! \n"); - return 1; - } - } - break; - - - /* ----------------------------------------------------- */ - - - case 'r': /* rates rates/distorsion */ - { - char *s = opj_optarg; - parameters->tcp_numlayers = 0; - while (sscanf(s, "%f", ¶meters->tcp_rates[parameters->tcp_numlayers]) == 1) { - parameters->tcp_numlayers++; - while (*s && *s != ',') { - s++; - } - if (!*s) - break; - s++; - } - parameters->cp_disto_alloc = 1; - } - break; - - /* ----------------------------------------------------- */ - - - case 'F': /* Raw image format parameters */ - { - char signo; - char *s = opj_optarg; - if (sscanf(s, "%d,%d,%d,%d,%c", &raw_cp->rawWidth, &raw_cp->rawHeight, &raw_cp->rawComp, &raw_cp->rawBitDepth, &signo) == 5) { - if (signo == 's') { - raw_cp->rawSigned = OPJ_TRUE; - fprintf(stdout,"\nRaw file parameters: %d,%d,%d,%d Signed\n", raw_cp->rawWidth, raw_cp->rawHeight, raw_cp->rawComp, raw_cp->rawBitDepth); - } - else if (signo == 'u') { - raw_cp->rawSigned = OPJ_FALSE; - fprintf(stdout,"\nRaw file parameters: %d,%d,%d,%d Unsigned\n", raw_cp->rawWidth, raw_cp->rawHeight, raw_cp->rawComp, raw_cp->rawBitDepth); - } - else { - fprintf(stderr,"\nError: invalid raw image parameters: Unknown sign of raw file\n"); - fprintf(stderr,"Please use the Format option -F:\n"); - fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); - fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); - fprintf(stderr,"Aborting\n"); - } - } - else { - fprintf(stderr,"\nError: invalid raw image parameters\n"); - fprintf(stderr,"Please use the Format option -F:\n"); - fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); - fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); - fprintf(stderr,"Aborting\n"); - return 1; - } - } - break; - - /* ----------------------------------------------------- */ - - case 'q': /* add fixed_quality */ - { - char *s = opj_optarg; - while (sscanf(s, "%f", ¶meters->tcp_distoratio[parameters->tcp_numlayers]) == 1) { - parameters->tcp_numlayers++; - while (*s && *s != ',') { - s++; - } - if (!*s) - break; - s++; - } - 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; - - char *s = opj_optarg; - sscanf(s, "%d", &numlayers); - s++; - if (numlayers > 9) - s++; - - parameters->tcp_numlayers = numlayers; - numresolution = parameters->numresolution; - matrix_width = numresolution * 3; - parameters->cp_matrice = (int *) malloc(numlayers * matrix_width * sizeof(int)); - s = s + 2; - - for (i = 0; i < numlayers; i++) { - row = ¶meters->cp_matrice[i * matrix_width]; - col = row; - 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++; - } - parameters->cp_fixed_alloc = 1; - } - break; - - /* ----------------------------------------------------- */ - - case 't': /* tiles */ - { - sscanf(opj_optarg, "%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy); - parameters->tile_size_on = OPJ_TRUE; - } - break; - - /* ----------------------------------------------------- */ - - case 'n': /* resolution */ - { - sscanf(opj_optarg, "%d", ¶meters->numresolution); - } - break; - - /* ----------------------------------------------------- */ - case 'c': /* precinct dimension */ - { - char sep; - int res_spec = 0; - - char *s = opj_optarg; - do { - sep = 0; - sscanf(s, "[%d,%d]%c", ¶meters->prcw_init[res_spec], - ¶meters->prch_init[res_spec], &sep); - parameters->csty |= 0x01; - res_spec++; - s = strpbrk(s, "]") + 2; - } - while (sep == ','); - 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; - } - parameters->cblockw_init = cblockw_init; - parameters->cblockh_init = cblockh_init; - } - break; - - /* ----------------------------------------------------- */ - - case 'x': /* creation of index file */ - { - char *index = opj_optarg; - strncpy(indexfilename, index, OPJ_PATH_LEN); - } - break; - - /* ----------------------------------------------------- */ - - case 'p': /* progression order */ - { - char progression[4]; - - strncpy(progression, opj_optarg, 4); - parameters->prog_order = give_progression(progression); - if (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", ¶meters->subsampling_dx, - ¶meters->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", ¶meters->image_offset_x0, - ¶meters->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 */ - encode_help_display(); - return 1; - - /* ----------------------------------------------------- */ - - 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 = 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++; - } - parameters->numpocs = numpocs; - } - break; - - /* ------------------------------------------------------ */ - - case 'S': /* SOP marker */ - { - parameters->csty |= 0x02; - } - break; - - /* ------------------------------------------------------ */ - - case 'E': /* EPH marker */ - { - parameters->csty |= 0x04; - } - break; - - /* ------------------------------------------------------ */ - - case 'M': /* Mode switch pas tous au point !! */ - { - int value = 0; - if (sscanf(opj_optarg, "%d", &value) == 1) { - for (i = 0; i <= 5; i++) { - int cache = value & (1 << i); - if (cache) - parameters->mode |= (1 << i); - } - } - } - break; - - /* ------------------------------------------------------ */ - - case 'R': /* ROI */ - { - if (sscanf(opj_optarg, "c=%d,U=%d", ¶meters->roi_compno, - ¶meters->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", ¶meters->cp_tx0, ¶meters->cp_ty0) != 2) { - fprintf(stderr, "-T 'tile offset' argument error !! [-T X0,Y0]"); - return 1; - } - } - break; - - /* ------------------------------------------------------ */ - - case 'C': /* add a comment */ - { - parameters->cp_comment = (char*)malloc(strlen(opj_optarg) + 1); - if(parameters->cp_comment) { - strcpy(parameters->cp_comment, opj_optarg); - } - } - break; - - - /* ------------------------------------------------------ */ - - case 'I': /* reversible or not */ - { - parameters->irreversible = 1; - } - break; - - /* ------------------------------------------------------ */ - - case 'u': /* Tile part generation*/ - { - parameters->tp_flag = opj_optarg[0]; - parameters->tp_on = 1; - } - break; - - /* ------------------------------------------------------ */ - - case 'z': /* Image Directory path */ - { - img_fol->imgdirpath = (char*)malloc(strlen(opj_optarg) + 1); - strcpy(img_fol->imgdirpath,opj_optarg); - img_fol->set_imgdir=1; - } - break; - - /* ------------------------------------------------------ */ - - case 'w': /* Digital Cinema 2K profile compliance*/ - { - int fps=0; - sscanf(opj_optarg,"%d",&fps); - if(fps == 24){ - parameters->cp_cinema = OPJ_CINEMA2K_24; - }else if(fps == 48 ){ - parameters->cp_cinema = OPJ_CINEMA2K_48; - }else { - fprintf(stderr,"Incorrect value!! must be 24 or 48\n"); - return 1; - } - fprintf(stdout,"CINEMA 2K compliant codestream\n"); - parameters->cp_rsiz = OPJ_CINEMA2K; - - } - break; - - /* ------------------------------------------------------ */ - - case 'y': /* Digital Cinema 4K profile compliance*/ - { - parameters->cp_cinema = OPJ_CINEMA4K_24; - fprintf(stdout,"CINEMA 4K compliant codestream\n"); - parameters->cp_rsiz = OPJ_CINEMA4K; - } - break; - - /* ------------------------------------------------------ */ - case 'm': /* mct input file */ - { - char *lFilename = opj_optarg; - char *lMatrix; - char *lCurrentPtr ; - float *lCurrentDoublePtr; - float *lSpace; - int *l_int_ptr; - int lNbComp = 0, lTotalComp, lMctComp, i, lStrLen; - - /* Open file */ - FILE * lFile = fopen(lFilename,"r"); - if (lFile == NULL) { - return 1; - } - - /* Set size of file and read its content*/ - fseek(lFile,0,SEEK_END); - lStrLen = ftell(lFile); - fseek(lFile,0,SEEK_SET); - lMatrix = (char *) malloc(lStrLen + 1); - fread(lMatrix, lStrLen, 1, lFile); - fclose(lFile); - - lMatrix[lStrLen] = 0; - lCurrentPtr = lMatrix; - - /* replace ',' by 0 */ - while (*lCurrentPtr != 0 ) { - if (*lCurrentPtr == ' ') { - *lCurrentPtr = 0; - ++lNbComp; - } - ++lCurrentPtr; - } - ++lNbComp; - lCurrentPtr = lMatrix; - - lNbComp = (int) (sqrt(4*lNbComp + 1)/2. - 0.5); - lMctComp = lNbComp * lNbComp; - lTotalComp = lMctComp + lNbComp; - lSpace = (float *) malloc(lTotalComp * sizeof(float)); - lCurrentDoublePtr = lSpace; - for (i=0;i> */ -#ifdef USE_JPWL - /* ------------------------------------------------------ */ - - case 'W': /* JPWL capabilities switched on */ - { - char *token = NULL; - int hprot, pprot, sens, addr, size, range; - - /* we need to enable indexing */ - if (!indexfilename || !*indexfilename) { - strncpy(indexfilename, JPWL_PRIVATEINDEX_NAME, OPJ_PATH_LEN); - } - - /* search for different protection methods */ - - /* break the option in comma points and parse the result */ - token = strtok(opj_optarg, ","); - while(token != NULL) { - - /* search header error protection method */ - if (*token == 'h') { - - static int tile = 0, tilespec = 0, lasttileno = 0; - - hprot = 1; /* predefined method */ - - if(sscanf(token, "h=%d", &hprot) == 1) { - /* Main header, specified */ - if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) || - ((hprot >= 37) && (hprot <= 128)))) { - fprintf(stderr, "ERROR -> invalid main header protection method h = %d\n", hprot); - return 1; - } - parameters->jpwl_hprot_MH = hprot; - - } else if(sscanf(token, "h%d=%d", &tile, &hprot) == 2) { - /* Tile part header, specified */ - if (!((hprot == 0) || (hprot == 1) || (hprot == 16) || (hprot == 32) || - ((hprot >= 37) && (hprot <= 128)))) { - fprintf(stderr, "ERROR -> invalid tile part header protection method h = %d\n", hprot); - return 1; - } - if (tile < 0) { - fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile); - return 1; - } - if (tilespec < JPWL_MAX_NO_TILESPECS) { - parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile; - parameters->jpwl_hprot_TPH[tilespec++] = hprot; - } - - } else if(sscanf(token, "h%d", &tile) == 1) { - /* Tile part header, unspecified */ - if (tile < 0) { - fprintf(stderr, "ERROR -> invalid tile part number on protection method t = %d\n", tile); - return 1; - } - if (tilespec < JPWL_MAX_NO_TILESPECS) { - parameters->jpwl_hprot_TPH_tileno[tilespec] = lasttileno = tile; - parameters->jpwl_hprot_TPH[tilespec++] = hprot; - } - - - } else if (!strcmp(token, "h")) { - /* Main header, unspecified */ - parameters->jpwl_hprot_MH = hprot; - - } else { - fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token); - return 1; - }; - - } - - /* search packet error protection method */ - if (*token == 'p') { - - static int pack = 0, tile = 0, packspec = 0; - - pprot = 1; /* predefined method */ - - if (sscanf(token, "p=%d", &pprot) == 1) { - /* Method for all tiles and all packets */ - if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) || - ((pprot >= 37) && (pprot <= 128)))) { - fprintf(stderr, "ERROR -> invalid default packet protection method p = %d\n", pprot); - return 1; - } - parameters->jpwl_pprot_tileno[0] = 0; - parameters->jpwl_pprot_packno[0] = 0; - parameters->jpwl_pprot[0] = pprot; - - } else if (sscanf(token, "p%d=%d", &tile, &pprot) == 2) { - /* method specified from that tile on */ - if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) || - ((pprot >= 37) && (pprot <= 128)))) { - fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot); - return 1; - } - if (tile < 0) { - fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile); - return 1; - } - if (packspec < JPWL_MAX_NO_PACKSPECS) { - parameters->jpwl_pprot_tileno[packspec] = tile; - parameters->jpwl_pprot_packno[packspec] = 0; - parameters->jpwl_pprot[packspec++] = pprot; - } - - } else if (sscanf(token, "p%d:%d=%d", &tile, &pack, &pprot) == 3) { - /* method fully specified from that tile and that packet on */ - if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) || - ((pprot >= 37) && (pprot <= 128)))) { - fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot); - return 1; - } - if (tile < 0) { - fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile); - return 1; - } - if (pack < 0) { - fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack); - return 1; - } - if (packspec < JPWL_MAX_NO_PACKSPECS) { - parameters->jpwl_pprot_tileno[packspec] = tile; - parameters->jpwl_pprot_packno[packspec] = pack; - parameters->jpwl_pprot[packspec++] = pprot; - } - - } else if (sscanf(token, "p%d:%d", &tile, &pack) == 2) { - /* default method from that tile and that packet on */ - if (!((pprot == 0) || (pprot == 1) || (pprot == 16) || (pprot == 32) || - ((pprot >= 37) && (pprot <= 128)))) { - fprintf(stderr, "ERROR -> invalid packet protection method p = %d\n", pprot); - return 1; - } - if (tile < 0) { - fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile); - return 1; - } - if (pack < 0) { - fprintf(stderr, "ERROR -> invalid packet number on protection method p = %d\n", pack); - return 1; - } - if (packspec < JPWL_MAX_NO_PACKSPECS) { - parameters->jpwl_pprot_tileno[packspec] = tile; - parameters->jpwl_pprot_packno[packspec] = pack; - parameters->jpwl_pprot[packspec++] = pprot; - } - - } else if (sscanf(token, "p%d", &tile) == 1) { - /* default from a tile on */ - if (tile < 0) { - fprintf(stderr, "ERROR -> invalid tile part number on protection method p = %d\n", tile); - return 1; - } - if (packspec < JPWL_MAX_NO_PACKSPECS) { - parameters->jpwl_pprot_tileno[packspec] = tile; - parameters->jpwl_pprot_packno[packspec] = 0; - parameters->jpwl_pprot[packspec++] = pprot; - } - - - } else if (!strcmp(token, "p")) { - /* all default */ - parameters->jpwl_pprot_tileno[0] = 0; - parameters->jpwl_pprot_packno[0] = 0; - parameters->jpwl_pprot[0] = pprot; - - } else { - fprintf(stderr, "ERROR -> invalid protection method selection = %s\n", token); - return 1; - }; - - } - - /* search sensitivity method */ - if (*token == 's') { - - static int tile = 0, tilespec = 0, lasttileno = 0; - - sens = 0; /* predefined: relative error */ - - if(sscanf(token, "s=%d", &sens) == 1) { - /* Main header, specified */ - if ((sens < -1) || (sens > 7)) { - fprintf(stderr, "ERROR -> invalid main header sensitivity method s = %d\n", sens); - return 1; - } - parameters->jpwl_sens_MH = sens; - - } else if(sscanf(token, "s%d=%d", &tile, &sens) == 2) { - /* Tile part header, specified */ - if ((sens < -1) || (sens > 7)) { - fprintf(stderr, "ERROR -> invalid tile part header sensitivity method s = %d\n", sens); - return 1; - } - if (tile < 0) { - fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile); - return 1; - } - if (tilespec < JPWL_MAX_NO_TILESPECS) { - parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile; - parameters->jpwl_sens_TPH[tilespec++] = sens; - } - - } else if(sscanf(token, "s%d", &tile) == 1) { - /* Tile part header, unspecified */ - if (tile < 0) { - fprintf(stderr, "ERROR -> invalid tile part number on sensitivity method t = %d\n", tile); - return 1; - } - if (tilespec < JPWL_MAX_NO_TILESPECS) { - parameters->jpwl_sens_TPH_tileno[tilespec] = lasttileno = tile; - parameters->jpwl_sens_TPH[tilespec++] = hprot; - } - - } else if (!strcmp(token, "s")) { - /* Main header, unspecified */ - parameters->jpwl_sens_MH = sens; - - } else { - fprintf(stderr, "ERROR -> invalid sensitivity method selection = %s\n", token); - return 1; - }; - - parameters->jpwl_sens_size = 2; /* 2 bytes for default size */ - } - - /* search addressing size */ - if (*token == 'a') { - - - addr = 0; /* predefined: auto */ - - if(sscanf(token, "a=%d", &addr) == 1) { - /* Specified */ - if ((addr != 0) && (addr != 2) && (addr != 4)) { - fprintf(stderr, "ERROR -> invalid addressing size a = %d\n", addr); - return 1; - } - parameters->jpwl_sens_addr = addr; - - } else if (!strcmp(token, "a")) { - /* default */ - parameters->jpwl_sens_addr = addr; /* auto for default size */ - - } else { - fprintf(stderr, "ERROR -> invalid addressing selection = %s\n", token); - return 1; - }; - - } - - /* search sensitivity size */ - if (*token == 'z') { - - - size = 1; /* predefined: 1 byte */ - - if(sscanf(token, "z=%d", &size) == 1) { - /* Specified */ - if ((size != 0) && (size != 1) && (size != 2)) { - fprintf(stderr, "ERROR -> invalid sensitivity size z = %d\n", size); - return 1; - } - parameters->jpwl_sens_size = size; - - } else if (!strcmp(token, "a")) { - /* default */ - parameters->jpwl_sens_size = size; /* 1 for default size */ - - } else { - fprintf(stderr, "ERROR -> invalid size selection = %s\n", token); - return 1; - }; - - } - - /* search range method */ - if (*token == 'g') { - - - range = 0; /* predefined: 0 (packet) */ - - if(sscanf(token, "g=%d", &range) == 1) { - /* Specified */ - if ((range < 0) || (range > 3)) { - fprintf(stderr, "ERROR -> invalid sensitivity range method g = %d\n", range); - return 1; - } - parameters->jpwl_sens_range = range; - - } else if (!strcmp(token, "g")) { - /* default */ - parameters->jpwl_sens_range = range; - - } else { - fprintf(stderr, "ERROR -> invalid range selection = %s\n", token); - return 1; - }; - - } - - /* next token or bust */ - token = strtok(NULL, ","); - }; - - - /* some info */ - fprintf(stdout, "Info: JPWL capabilities enabled\n"); - parameters->jpwl_epc_on = OPJ_TRUE; - - } - break; -#endif /* USE_JPWL */ -/* <jpip_on = OPJ_TRUE; - } - break; - /* ------------------------------------------------------ */ - - - default: - fprintf(stderr, "ERROR -> Command line not valid\n"); - return 1; - } - }while(c != -1); - - /* check for possible errors */ - if (parameters->cp_cinema){ - if(parameters->tcp_numlayers > 1){ - parameters->cp_rsiz = OPJ_STD_RSIZ; - fprintf(stdout,"Warning: DC profiles do not allow more than one quality layer. The codestream created will not be compliant with the DC profile\n"); - } - } - if(img_fol->set_imgdir == 1){ - if(!(parameters->infile[0] == 0)){ - fprintf(stderr, "Error: options -ImgDir and -i cannot be used together !!\n"); - return 1; - } - if(img_fol->set_out_format == 0){ - fprintf(stderr, "Error: When -ImgDir is used, -OutFor must be used !!\n"); - fprintf(stderr, "Only one format allowed! Valid formats are j2k and jp2!!\n"); - return 1; - } - if(!((parameters->outfile[0] == 0))){ - fprintf(stderr, "Error: options -ImgDir and -o cannot be used together !!\n"); - fprintf(stderr, "Specify OutputFormat using -OutFor !!\n"); - return 1; - } - }else{ - if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) { - fprintf(stderr, "Example: %s -i image.ppm -o image.j2k\n",argv[0]); - fprintf(stderr, " Try: %s -h\n",argv[0]); - return 1; - } - } - - if ( (parameters->decod_format == RAW_DFMT && raw_cp->rawWidth == 0) - || (parameters->decod_format == RAWL_DFMT && raw_cp->rawWidth == 0)) { - fprintf(stderr,"\nError: invalid raw image parameters\n"); - fprintf(stderr,"Please use the Format option -F:\n"); - fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); - fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); - fprintf(stderr,"Aborting\n"); - return 1; - } - - if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality) - && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ 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 (parameters->tcp_numlayers == 0) { - parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */ - parameters->tcp_numlayers++; - parameters->cp_disto_alloc = 1; - } - - if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) { - fprintf(stderr, - "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", - parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0); - return 1; - } - - for (i = 0; i < parameters->numpocs; i++) { - if (parameters->POC[i].prg == -1) { - fprintf(stderr, - "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n", - i + 1); - } - } - - return 0; + /* <jpip_on = OPJ_TRUE; + } + break; + /* ------------------------------------------------------ */ + + + default: + fprintf(stderr, "ERROR -> Command line not valid\n"); + return 1; + } + }while(c != -1); + + if(img_fol->set_imgdir == 1){ + if(!(parameters->infile[0] == 0)){ + fprintf(stderr, "Error: options -ImgDir and -i cannot be used together !!\n"); + return 1; + } + if(img_fol->set_out_format == 0){ + fprintf(stderr, "Error: When -ImgDir is used, -OutFor must be used !!\n"); + fprintf(stderr, "Only one format allowed! Valid formats are j2k and jp2!!\n"); + return 1; + } + if(!((parameters->outfile[0] == 0))){ + fprintf(stderr, "Error: options -ImgDir and -o cannot be used together !!\n"); + fprintf(stderr, "Specify OutputFormat using -OutFor !!\n"); + return 1; + } + }else{ + if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) { + fprintf(stderr, "Example: %s -i image.ppm -o image.j2k\n",argv[0]); + fprintf(stderr, " Try: %s -h\n",argv[0]); + return 1; + } + } + + if ( (parameters->decod_format == RAW_DFMT && raw_cp->rawWidth == 0) + || (parameters->decod_format == RAWL_DFMT && raw_cp->rawWidth == 0)) { + fprintf(stderr,"\nError: invalid raw image parameters\n"); + fprintf(stderr,"Please use the Format option -F:\n"); + fprintf(stderr,"-F rawWidth,rawHeight,rawComp,rawBitDepth,s/u (Signed/Unsigned)\n"); + fprintf(stderr,"Example: -i lena.raw -o lena.j2k -F 512,512,3,8,u\n"); + fprintf(stderr,"Aborting\n"); + return 1; + } + + if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality) + && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_alloc ^ 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 (parameters->tcp_numlayers == 0) { + parameters->tcp_rates[0] = 0; /* MOD antonin : losslessbug */ + parameters->tcp_numlayers++; + parameters->cp_disto_alloc = 1; + } + + if((parameters->cp_tx0 > parameters->image_offset_x0) || (parameters->cp_ty0 > parameters->image_offset_y0)) { + fprintf(stderr, + "Error: Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) \n", + parameters->cp_tx0, parameters->image_offset_x0, parameters->cp_ty0, parameters->image_offset_y0); + return 1; + } + + for (i = 0; i < parameters->numpocs; i++) { + if (parameters->POC[i].prg == -1) { + fprintf(stderr, + "Unrecognized progression order in option -P (POC n %d) [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n", + i + 1); + } + } + + return 0; } /* -------------------------------------------------------------------------- */ -/** -sample error callback expecting a FILE* client object -*/ -static void error_file_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 -*/ -static void warning_file_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 -*/ -static void info_file_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[INFO] %s", msg); -} - /** sample error debug callback expecting no client object */ static void error_callback(const char *msg, void *client_data) { - (void)client_data; - fprintf(stdout, "[ERROR] %s", msg); + (void)client_data; + fprintf(stdout, "[ERROR] %s", msg); } /** sample warning debug callback expecting no client object */ static void warning_callback(const char *msg, void *client_data) { - (void)client_data; - fprintf(stdout, "[WARNING] %s", msg); + (void)client_data; + fprintf(stdout, "[WARNING] %s", msg); } /** sample debug callback expecting no client object */ static void info_callback(const char *msg, void *client_data) { - (void)client_data; - fprintf(stdout, "[INFO] %s", msg); + (void)client_data; + fprintf(stdout, "[INFO] %s", msg); } /* -------------------------------------------------------------------------- */ @@ -1590,239 +1452,241 @@ static void info_callback(const char *msg, void *client_data) { int main(int argc, char **argv) { FILE *fout = NULL; - opj_cparameters_t parameters; /* compression parameters */ + opj_cparameters_t parameters; /* compression parameters */ - opj_stream_t *l_stream = 00; - opj_codec_t* l_codec = 00; - opj_image_t *image = NULL; - raw_cparameters_t raw_cp; + opj_stream_t *l_stream = 00; + opj_codec_t* l_codec = 00; + opj_image_t *image = NULL; + raw_cparameters_t raw_cp; - char indexfilename[OPJ_PATH_LEN]; /* index file name */ + char indexfilename[OPJ_PATH_LEN]; /* index file name */ - unsigned int i, num_images, imageno; - img_fol_t img_fol; - dircnt_t *dirptr = NULL; + unsigned int i, num_images, imageno; + img_fol_t img_fol; + dircnt_t *dirptr = NULL; - OPJ_BOOL bSuccess; - OPJ_BOOL bUseTiles = OPJ_FALSE; /* OPJ_TRUE */ - OPJ_UINT32 l_nb_tiles = 4; + OPJ_BOOL bSuccess; + OPJ_BOOL bUseTiles = OPJ_FALSE; /* OPJ_TRUE */ + OPJ_UINT32 l_nb_tiles = 4; - /* set encoding parameters to default values */ - opj_set_default_encoder_parameters(¶meters); + /* set encoding parameters to default values */ + opj_set_default_encoder_parameters(¶meters); - /* Initialize indexfilename and img_fol */ - *indexfilename = 0; - memset(&img_fol,0,sizeof(img_fol_t)); + /* Initialize indexfilename and img_fol */ + *indexfilename = 0; + memset(&img_fol,0,sizeof(img_fol_t)); - /* parse input and get user encoding parameters */ - if(parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, &raw_cp, indexfilename) == 1) { - return 1; - } - - if (parameters.cp_cinema){ - img_fol.rates = (float*)malloc(parameters.tcp_numlayers * sizeof(float)); - for(i=0; i< parameters.tcp_numlayers; i++){ - img_fol.rates[i] = parameters.tcp_rates[i]; - } - cinema_parameters(¶meters); - } - - /* Create comment for codestream */ - if(parameters.cp_comment == NULL) { - const char comment[] = "Created by OpenJPEG version "; - const size_t clen = strlen(comment); - const char *version = opj_version(); -/* UniPG>> */ -#ifdef USE_JPWL - parameters.cp_comment = (char*)malloc(clen+strlen(version)+11); - sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version); -#else - parameters.cp_comment = (char*)malloc(clen+strlen(version)+1); - sprintf(parameters.cp_comment,"%s%s", comment, version); -#endif -/* <filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ - dirptr->filename = (char**) malloc(num_images*sizeof(char*)); - if(!dirptr->filename_buf){ - return 0; - } - for(i=0;ifilename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN; - } - } - if(load_images(dirptr,img_fol.imgdirpath)==1){ - return 0; - } - if (num_images==0){ - fprintf(stdout,"Folder is empty\n"); - return 0; - } - }else{ - num_images=1; - } - /*Encoding image one by one*/ - for(imageno=0;imagenonumcomps == 3 ? 1 : 0; - - if(parameters.cp_cinema){ - cinema_setup_encoder(¶meters,image,&img_fol); - } - - /* encode the destination image */ - /* ---------------------------- */ - - switch(parameters.cod_format) { - case J2K_CFMT: /* JPEG-2000 codestream */ - { - /* Get a decoder handle */ - l_codec = opj_create_compress(OPJ_CODEC_J2K); - break; - } - case JP2_CFMT: /* JPEG 2000 compressed image data */ - { - /* Get a decoder handle */ - l_codec = opj_create_compress(OPJ_CODEC_JP2); - break; - } - default: - fprintf(stderr, "skipping file..\n"); - opj_stream_destroy(l_stream); - continue; - } - - /* catch events using our callbacks and give a local context */ - opj_set_info_handler(l_codec, info_callback,00); - opj_set_warning_handler(l_codec, warning_callback,00); - opj_set_error_handler(l_codec, error_callback,00); - - if( bUseTiles ) { - parameters.cp_tx0 = 0; - parameters.cp_ty0 = 0; - parameters.tile_size_on = OPJ_TRUE; - parameters.cp_tdx = 512; - parameters.cp_tdy = 512; + /* parse input and get user encoding parameters */ + parameters.tcp_mct = -1; /* This will be set later according to the input image or the provided option */ + if(parse_cmdline_encoder(argc, argv, ¶meters,&img_fol, &raw_cp, indexfilename) == 1) { + return 1; } - opj_setup_encoder(l_codec, ¶meters, image); + + /* Create comment for codestream */ + if(parameters.cp_comment == NULL) { + const char comment[] = "Created by OpenJPEG version "; + const size_t clen = strlen(comment); + const char *version = opj_version(); + /* UniPG>> */ +#ifdef USE_JPWL + parameters.cp_comment = (char*)malloc(clen+strlen(version)+11); + sprintf(parameters.cp_comment,"%s%s with JPWL", comment, version); +#else + parameters.cp_comment = (char*)malloc(clen+strlen(version)+1); + sprintf(parameters.cp_comment,"%s%s", comment, version); +#endif + /* <filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ + dirptr->filename = (char**) malloc(num_images*sizeof(char*)); + if(!dirptr->filename_buf){ + return 0; + } + for(i=0;ifilename[i] = dirptr->filename_buf + i*OPJ_PATH_LEN; + } + } + if(load_images(dirptr,img_fol.imgdirpath)==1){ + return 0; + } + if (num_images==0){ + fprintf(stdout,"Folder is empty\n"); + return 0; + } + }else{ + num_images=1; + } + /*Encoding image one by one*/ + for(imageno=0;imagenonumcomps >= 3 ? 1 : 0; + } else { /* mct mode has been set in commandline */ + if ((parameters.tcp_mct == 1) && (image->numcomps < 3)){ + fprintf(stderr, "RGB->YCC conversion cannot be used:\n"); + fprintf(stderr, "Input image has less than 3 components\n"); + return 1; + } + if ((parameters.tcp_mct == 2) && (!parameters.mct_data)){ + fprintf(stderr, "Custom MCT has been set but no array-based MCT\n"); + fprintf(stderr, "has been provided. Aborting.\n"); + return 1; + } + } + + /* encode the destination image */ + /* ---------------------------- */ + + switch(parameters.cod_format) { + case J2K_CFMT: /* JPEG-2000 codestream */ + { + /* Get a decoder handle */ + l_codec = opj_create_compress(OPJ_CODEC_J2K); + break; + } + case JP2_CFMT: /* JPEG 2000 compressed image data */ + { + /* Get a decoder handle */ + l_codec = opj_create_compress(OPJ_CODEC_JP2); + break; + } + default: + fprintf(stderr, "skipping file..\n"); + opj_stream_destroy(l_stream); + continue; + } + + /* catch events using our callbacks and give a local context */ + opj_set_info_handler(l_codec, info_callback,00); + opj_set_warning_handler(l_codec, warning_callback,00); + opj_set_error_handler(l_codec, error_callback,00); + + if( bUseTiles ) { + parameters.cp_tx0 = 0; + parameters.cp_ty0 = 0; + parameters.tile_size_on = OPJ_TRUE; + parameters.cp_tdx = 512; + parameters.cp_tdy = 512; + } + opj_setup_encoder(l_codec, ¶meters, image); /* Open the output file*/ fout = fopen(parameters.outfile, "wb"); @@ -1832,72 +1696,71 @@ int main(int argc, char **argv) { return 1; } - /* open a byte stream for writing and allocate memory for all tiles */ - l_stream = opj_stream_create_default_file_stream(fout,OPJ_FALSE); - if (! l_stream){ - return 1; - } - - /* encode the image */ - bSuccess = opj_start_compress(l_codec,image,l_stream); - if (!bSuccess) { - fprintf(stderr, "failed to encode image: opj_start_compress\n"); - } - if( bUseTiles ) { - OPJ_BYTE *l_data; - OPJ_UINT32 l_data_size = 512*512*3; - l_data = (OPJ_BYTE*) malloc( l_data_size * sizeof(OPJ_BYTE)); - memset(l_data, 0, l_data_size ); - assert( l_data ); - for (i=0;i test_tile_encoder: failed to write the tile %d!\n",i); - opj_stream_destroy(l_stream); - fclose(fout); - opj_destroy_codec(l_codec); - opj_image_destroy(image); - return 1; + /* open a byte stream for writing and allocate memory for all tiles */ + l_stream = opj_stream_create_default_file_stream(fout,OPJ_FALSE); + if (! l_stream){ + return 1; } - } - free(l_data); - } - else { - bSuccess = bSuccess && opj_encode(l_codec, l_stream); - if (!bSuccess) { - fprintf(stderr, "failed to encode image: opj_encode\n"); - } - } - bSuccess = bSuccess && opj_end_compress(l_codec, l_stream); - if (!bSuccess) { - fprintf(stderr, "failed to encode image: opj_end_compress\n"); - } - if (!bSuccess) { - opj_stream_destroy(l_stream); - fclose(fout); - opj_destroy_codec(l_codec); - opj_image_destroy(image); - fprintf(stderr, "failed to encode image\n"); - return 1; - } + /* encode the image */ + bSuccess = opj_start_compress(l_codec,image,l_stream); + if (!bSuccess) { + fprintf(stderr, "failed to encode image: opj_start_compress\n"); + } + if( bUseTiles ) { + OPJ_BYTE *l_data; + OPJ_UINT32 l_data_size = 512*512*3; + l_data = (OPJ_BYTE*) malloc( l_data_size * sizeof(OPJ_BYTE)); + memset(l_data, 0, l_data_size ); + assert( l_data ); + for (i=0;i test_tile_encoder: failed to write the tile %d!\n",i); + opj_stream_destroy(l_stream); + fclose(fout); + opj_destroy_codec(l_codec); + opj_image_destroy(image); + return 1; + } + } + free(l_data); + } + else { + bSuccess = bSuccess && opj_encode(l_codec, l_stream); + if (!bSuccess) { + fprintf(stderr, "failed to encode image: opj_encode\n"); + } + } + bSuccess = bSuccess && opj_end_compress(l_codec, l_stream); + if (!bSuccess) { + fprintf(stderr, "failed to encode image: opj_end_compress\n"); + } - fprintf(stderr,"Generated outfile %s\n",parameters.outfile); - /* close and free the byte stream */ - opj_stream_destroy(l_stream); + if (!bSuccess) { + opj_stream_destroy(l_stream); + fclose(fout); + opj_destroy_codec(l_codec); + opj_image_destroy(image); + fprintf(stderr, "failed to encode image\n"); + return 1; + } + + fprintf(stderr,"Generated outfile %s\n",parameters.outfile); + /* close and free the byte stream */ + opj_stream_destroy(l_stream); fclose(fout); - /* free remaining compression structures */ - opj_destroy_codec(l_codec); + /* free remaining compression structures */ + opj_destroy_codec(l_codec); - /* free image data */ - opj_image_destroy(image); + /* free image data */ + opj_image_destroy(image); - } + } - /* free user parameters structure */ - if(parameters.cp_comment) free(parameters.cp_comment); - if(parameters.cp_matrice) free(parameters.cp_matrice); - if(parameters.cp_cinema) free(img_fol.rates); + /* free user parameters structure */ + if(parameters.cp_comment) free(parameters.cp_comment); + if(parameters.cp_matrice) free(parameters.cp_matrice); - return 0; + return 0; } diff --git a/src/bin/jp2/opj_decompress.c b/src/bin/jp2/opj_decompress.c index df2978db..9adebd91 100644 --- a/src/bin/jp2/opj_decompress.c +++ b/src/bin/jp2/opj_decompress.c @@ -31,7 +31,7 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#include "opj_config.h" +#include "opj_apps_config.h" #include #include @@ -57,10 +57,10 @@ #include "convert.h" #include "index.h" -#ifdef HAVE_LIBLCMS2 +#ifdef OPJ_HAVE_LIBLCMS2 #include #endif -#ifdef HAVE_LIBLCMS1 +#ifdef OPJ_HAVE_LIBLCMS1 #include #endif #include "color.h" @@ -271,7 +271,7 @@ static int infile_format(const char *fname) const char *s, *magic_s; int ext_format, magic_format; unsigned char buf[12]; - unsigned int l_nb_read; + OPJ_SIZE_T l_nb_read; reader = fopen(fname, "rb"); @@ -447,7 +447,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i case 'r': /* reduce option */ { - sscanf(opj_optarg, "%d", ¶meters->cp_reduce); + sscanf(opj_optarg, "%ud", ¶meters->cp_reduce); } break; @@ -456,7 +456,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i case 'l': /* layering option */ { - sscanf(opj_optarg, "%d", ¶meters->cp_layer); + sscanf(opj_optarg, "%ud", ¶meters->cp_layer); } break; @@ -481,7 +481,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i case 'd': /* Input decode ROI */ { int size_optarg = (int)strlen(opj_optarg) + 1; - char *ROI_values = (char*) malloc(size_optarg); + char *ROI_values = (char*) malloc((size_t)size_optarg); ROI_values[0] = '\0'; strncpy(ROI_values, opj_optarg, strlen(opj_optarg)); ROI_values[strlen(opj_optarg)] = '\0'; @@ -496,7 +496,7 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i case 't': /* Input tile index */ { - sscanf(opj_optarg, "%d", ¶meters->tile_index); + sscanf(opj_optarg, "%ud", ¶meters->tile_index); parameters->nb_tile_to_decode = 1; } break; @@ -639,8 +639,8 @@ int parse_DA_values( char* inArg, unsigned int *DA_x0, unsigned int *DA_y0, unsi return EXIT_FAILURE; } else{ - *DA_x0 = values[0]; *DA_y0 = values[1]; - *DA_x1 = values[2]; *DA_y1 = values[3]; + *DA_x0 = (OPJ_UINT32)values[0]; *DA_y0 = (OPJ_UINT32)values[1]; + *DA_x1 = (OPJ_UINT32)values[2]; *DA_y1 = (OPJ_UINT32)values[3]; return EXIT_SUCCESS; } } @@ -689,6 +689,7 @@ int main(int argc, char **argv) OPJ_INT32 num_images, imageno; img_fol_t img_fol; dircnt_t *dirptr = NULL; + int failed = 0; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); @@ -711,8 +712,8 @@ int main(int argc, char **argv) dirptr=(dircnt_t*)malloc(sizeof(dircnt_t)); if(dirptr){ - dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ - dirptr->filename = (char**) malloc(num_images*sizeof(char*)); + dirptr->filename_buf = (char*)malloc((size_t)num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ + dirptr->filename = (char**) malloc((size_t)num_images*sizeof(char*)); if(!dirptr->filename_buf){ return EXIT_FAILURE; @@ -794,7 +795,7 @@ int main(int argc, char **argv) /* Setup the decoder decoding parameters using user parameters */ if ( !opj_setup_decoder(l_codec, ¶meters) ){ - fprintf(stderr, "ERROR -> j2k_dump: failed to setup the decoder\n"); + fprintf(stderr, "ERROR -> opj_compress: failed to setup the decoder\n"); opj_stream_destroy(l_stream); fclose(fsrc); opj_destroy_codec(l_codec); @@ -814,8 +815,8 @@ int main(int argc, char **argv) if (!parameters.nb_tile_to_decode) { /* Optional if you want decode the entire image */ - if (!opj_set_decode_area(l_codec, image, parameters.DA_x0, - parameters.DA_y0, parameters.DA_x1, parameters.DA_y1)){ + if (!opj_set_decode_area(l_codec, image, (OPJ_INT32)parameters.DA_x0, + (OPJ_INT32)parameters.DA_y0, (OPJ_INT32)parameters.DA_x1, (OPJ_INT32)parameters.DA_y1)){ fprintf(stderr, "ERROR -> opj_decompress: failed to set the decoded area\n"); opj_stream_destroy(l_stream); opj_destroy_codec(l_codec); @@ -864,9 +865,16 @@ int main(int argc, char **argv) if(image->color_space == OPJ_CLRSPC_SYCC){ color_sycc_to_rgb(image); /* FIXME */ } + + if( image->color_space != OPJ_CLRSPC_SYCC + && image->numcomps == 3 && image->comps[0].dx == image->comps[0].dy + && image->comps[1].dx != 1 ) + image->color_space = OPJ_CLRSPC_SYCC; + else if (image->numcomps <= 2) + image->color_space = OPJ_CLRSPC_GRAY; if(image->icc_profile_buf) { -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +#if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2) color_apply_icc_profile(image); /* FIXME */ #endif free(image->icc_profile_buf); @@ -878,7 +886,8 @@ int main(int argc, char **argv) switch (parameters.cod_format) { case PXM_DFMT: /* PNM PGM PPM */ if (imagetopnm(image, parameters.outfile)) { - fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); + fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); + failed = 1; } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); @@ -887,7 +896,8 @@ int main(int argc, char **argv) case PGX_DFMT: /* PGX */ if(imagetopgx(image, parameters.outfile)){ - fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); + fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); + failed = 1; } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); @@ -896,25 +906,28 @@ int main(int argc, char **argv) case BMP_DFMT: /* BMP */ if(imagetobmp(image, parameters.outfile)){ - fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); + fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); + failed = 1; } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; -#ifdef HAVE_LIBTIFF +#ifdef OPJ_HAVE_LIBTIFF case TIF_DFMT: /* TIFF */ if(imagetotif(image, parameters.outfile)){ - fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); + fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); + failed = 1; } else { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; -#endif /* HAVE_LIBTIFF */ +#endif /* OPJ_HAVE_LIBTIFF */ case RAW_DFMT: /* RAW */ if(imagetoraw(image, parameters.outfile)){ - fprintf(stdout,"Error generating raw file. Outfile %s not generated\n",parameters.outfile); + fprintf(stderr,"Error generating raw file. Outfile %s not generated\n",parameters.outfile); + failed = 1; } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); @@ -923,7 +936,8 @@ int main(int argc, char **argv) case RAWL_DFMT: /* RAWL */ if(imagetorawl(image, parameters.outfile)){ - fprintf(stdout,"Error generating rawl file. Outfile %s not generated\n",parameters.outfile); + fprintf(stderr,"Error generating rawl file. Outfile %s not generated\n",parameters.outfile); + failed = 1; } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); @@ -932,27 +946,30 @@ int main(int argc, char **argv) case TGA_DFMT: /* TGA */ if(imagetotga(image, parameters.outfile)){ - fprintf(stdout,"Error generating tga file. Outfile %s not generated\n",parameters.outfile); + fprintf(stderr,"Error generating tga file. Outfile %s not generated\n",parameters.outfile); + failed = 1; } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; -#ifdef HAVE_LIBPNG +#ifdef OPJ_HAVE_LIBPNG case PNG_DFMT: /* PNG */ if(imagetopng(image, parameters.outfile)){ - fprintf(stdout,"Error generating png file. Outfile %s not generated\n",parameters.outfile); + fprintf(stderr,"Error generating png file. Outfile %s not generated\n",parameters.outfile); + failed = 1; } else { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; -#endif /* HAVE_LIBPNG */ +#endif /* OPJ_HAVE_LIBPNG */ /* Can happen if output file is TIFF or PNG - * and HAVE_LIBTIF or HAVE_LIBPNG is undefined + * and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined */ default: fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); + failed = 1; } /* free remaining structures */ @@ -968,7 +985,7 @@ int main(int argc, char **argv) opj_destroy_cstr_index(&cstr_index); } - return EXIT_SUCCESS; + return failed ? EXIT_FAILURE : EXIT_SUCCESS; } /*end main*/ diff --git a/src/bin/jp2/opj_dump.c b/src/bin/jp2/opj_dump.c index 2bc1893a..7d2200a1 100644 --- a/src/bin/jp2/opj_dump.c +++ b/src/bin/jp2/opj_dump.c @@ -71,18 +71,18 @@ typedef struct img_folder{ /** Enable Cod Format for output*/ char set_out_format; + int flag; }img_fol_t; /* -------------------------------------------------------------------------- */ /* Declarations */ -int get_num_images(char *imgdirpath); -int load_images(dircnt_t *dirptr, char *imgdirpath); -int get_file_format(const char *filename); -char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters); +static int get_num_images(char *imgdirpath); +static int load_images(dircnt_t *dirptr, char *imgdirpath); +static int get_file_format(const char *filename); +static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters); static int infile_format(const char *fname); -int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol); -int parse_DA_values( char* inArg, unsigned int *DA_x0, unsigned int *DA_y0, unsigned int *DA_x1, unsigned int *DA_y1); +static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol); /* -------------------------------------------------------------------------- */ static void decode_help_display(void) { @@ -116,7 +116,7 @@ static void decode_help_display(void) { } /* -------------------------------------------------------------------------- */ -int get_num_images(char *imgdirpath){ +static int get_num_images(char *imgdirpath){ DIR *dir; struct dirent* content; int num_images = 0; @@ -138,7 +138,7 @@ int get_num_images(char *imgdirpath){ } /* -------------------------------------------------------------------------- */ -int load_images(dircnt_t *dirptr, char *imgdirpath){ +static int load_images(dircnt_t *dirptr, char *imgdirpath){ DIR *dir; struct dirent* content; int i = 0; @@ -164,7 +164,7 @@ int load_images(dircnt_t *dirptr, char *imgdirpath){ } /* -------------------------------------------------------------------------- */ -int get_file_format(const char *filename) { +static int get_file_format(const char *filename) { unsigned int i; static const char *extension[] = {"pgx", "pnm", "pgm", "ppm", "bmp","tif", "raw", "tga", "png", "j2k", "jp2", "jpt", "j2c", "jpc" }; static const int format[] = { PGX_DFMT, PXM_DFMT, PXM_DFMT, PXM_DFMT, BMP_DFMT, TIF_DFMT, RAW_DFMT, TGA_DFMT, PNG_DFMT, J2K_CFMT, JP2_CFMT, JPT_CFMT, J2K_CFMT, J2K_CFMT }; @@ -184,7 +184,7 @@ int get_file_format(const char *filename) { } /* -------------------------------------------------------------------------- */ -char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters){ +static char get_next_file(int imageno,dircnt_t *dirptr,img_fol_t *img_fol, opj_dparameters_t *parameters){ char image_filename[OPJ_PATH_LEN], infilename[OPJ_PATH_LEN],outfilename[OPJ_PATH_LEN],temp_ofname[OPJ_PATH_LEN]; char *temp_p, temp1[OPJ_PATH_LEN]=""; @@ -221,7 +221,7 @@ static int infile_format(const char *fname) const char *s, *magic_s; int ext_format, magic_format; unsigned char buf[12]; - unsigned int l_nb_read; + size_t l_nb_read; reader = fopen(fname, "rb"); @@ -269,12 +269,12 @@ static int infile_format(const char *fname) * Parse the command line */ /* -------------------------------------------------------------------------- */ -int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) { +static int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,img_fol_t *img_fol) { int totlen, c; opj_option_t long_option[]={ {"ImgDir",REQ_ARG, NULL ,'y'}, }; - const char optlist[] = "i:o:hv"; + const char optlist[] = "i:o:f:hv"; totlen=sizeof(long_option); img_fol->set_out_format = 0; @@ -314,6 +314,10 @@ int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters,i break; /* ----------------------------------------------------- */ + case 'f': /* flag */ + img_fol->flag = atoi(opj_optarg); + break; + /* ----------------------------------------------------- */ case 'h': /* display an help description */ decode_help_display(); @@ -425,6 +429,7 @@ int main(int argc, char *argv[]) /* Initialize img_fol */ memset(&img_fol,0,sizeof(img_fol_t)); + img_fol.flag = OPJ_IMG_INFO | OPJ_J2K_MH_INFO | OPJ_J2K_MH_IND; /* Parse input and get user encoding parameters */ if(parse_cmdline_decoder(argc, argv, ¶meters,&img_fol) == 1) { @@ -438,8 +443,8 @@ int main(int argc, char *argv[]) dirptr=(dircnt_t*)malloc(sizeof(dircnt_t)); if(dirptr){ - dirptr->filename_buf = (char*)malloc(num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ - dirptr->filename = (char**) malloc(num_images*sizeof(char*)); + dirptr->filename_buf = (char*)malloc((size_t)num_images*OPJ_PATH_LEN*sizeof(char)); /* Stores at max 10 image file names*/ + dirptr->filename = (char**) malloc((size_t)num_images*sizeof(char*)); if(!dirptr->filename_buf){ return EXIT_FAILURE; @@ -553,7 +558,7 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - opj_dump_codec(l_codec, OPJ_IMG_INFO | OPJ_J2K_MH_INFO | OPJ_J2K_MH_IND, fout ); + opj_dump_codec(l_codec, img_fol.flag, fout ); cstr_info = opj_get_cstr_info(l_codec); diff --git a/src/bin/jp3d/opj_jp3d_compress.c b/src/bin/jp3d/opj_jp3d_compress.c index 066de350..b774e149 100755 --- a/src/bin/jp3d/opj_jp3d_compress.c +++ b/src/bin/jp3d/opj_jp3d_compress.c @@ -488,7 +488,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters) case 's': /* subsampling factor */ { - if (sscanf(opj_optarg, "%d,%d,%d", ¶meters->subsampling_dx, ¶meters->subsampling_dy, ¶meters->subsampling_dz) != 2) { + if (sscanf(opj_optarg, "%d,%d,%d", ¶meters->subsampling_dx, ¶meters->subsampling_dy, ¶meters->subsampling_dz) != 3) { fprintf(stdout, "[ERROR] '-s' sub-sampling argument error ! [-s dx,dy,dz]\n"); return 1; } diff --git a/src/bin/jp3d/opj_jp3d_decompress.c b/src/bin/jp3d/opj_jp3d_decompress.c index 0a58b678..c2cdb321 100755 --- a/src/bin/jp3d/opj_jp3d_decompress.c +++ b/src/bin/jp3d/opj_jp3d_decompress.c @@ -518,7 +518,8 @@ int main(int argc, char **argv) { fprintf(stdout, "[RESULT] Volume: %d x %d x %d (x %d bpv)\n ", (volume->comps[0].w >> volume->comps[0].factor[0]), (volume->comps[0].h >> volume->comps[0].factor[1]), - (volume->comps[0].l >> volume->comps[0].factor[2]),volume->comps[0].prec); + (volume->comps[0].l >> volume->comps[0].factor[2]), + volume->comps[0].prec); if(original){ psnr = calc_PSNR(original,volume); diff --git a/src/bin/jpip/CMakeLists.txt b/src/bin/jpip/CMakeLists.txt index 45f0007b..821b2015 100644 --- a/src/bin/jpip/CMakeLists.txt +++ b/src/bin/jpip/CMakeLists.txt @@ -23,7 +23,7 @@ if(BUILD_JPIP_SERVER) # Build executable add_executable(opj_server ${OPJ_SERVER_SRCS}) - target_link_libraries(opj_server openjpip_server) + target_link_libraries(opj_server ${FCGI_LIBRARIES} openjpip_server) set_property( TARGET opj_server APPEND PROPERTY @@ -59,6 +59,14 @@ endforeach() # Build the two java clients: find_package(Java 1.5 COMPONENTS Development) # javac, jar +# User can override this: +if(NOT DEFINED JAVA_SOURCE_VERSION) + set(JAVA_SOURCE_VERSION 1.5) +endif() +if(NOT DEFINED JAVA_TARGET_VERSION) + set(JAVA_TARGET_VERSION 1.5) +endif() + # Only build the java viewer if dev is found: if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE) set(jflags $ENV{JFLAGS}) @@ -97,6 +105,7 @@ if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE) add_custom_command( OUTPUT ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar COMMAND ${Java_JAVAC_EXECUTABLE} ${jflags} + -source ${JAVA_SOURCE_VERSION} -target ${JAVA_TARGET_VERSION} -classpath ${APACHE_XERCES_JAR} ${java2_srcs} -d ${CMAKE_CURRENT_BINARY_DIR}/classes2 COMMAND ${Java_JAR_EXECUTABLE} cfm ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar @@ -127,6 +136,7 @@ if(Java_Development_FOUND AND Java_JAVAC_EXECUTABLE) add_custom_command( OUTPUT ${LIBRARY_OUTPUT_PATH}/opj_jpip_viewer.jar COMMAND ${Java_JAVAC_EXECUTABLE} ${jflags} + -source ${JAVA_SOURCE_VERSION} -target ${JAVA_TARGET_VERSION} ${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 diff --git a/src/bin/jpip/opj_jpip_transcode.c b/src/bin/jpip/opj_jpip_transcode.c index 825c087a..6776f1a6 100644 --- a/src/bin/jpip/opj_jpip_transcode.c +++ b/src/bin/jpip/opj_jpip_transcode.c @@ -42,28 +42,21 @@ * or * % ./jpip_to_jp2 input.jpp output.jp2 */ -static int jpip_to_jp2(int argc,char *argv[]) +static int jpip_to_jp2(char *argv[]) { jpip_dec_param_t *dec; - if( argc < 3){ - fprintf( stderr, "Too few arguments:\n"); - fprintf( stderr, " - input jpt or jpp file\n"); - fprintf( stderr, " - output jp2 file\n"); - return -1; - } - dec = init_jpipdecoder( OPJ_TRUE); if(!( fread_jpip( argv[1], dec))) - return -1; + return 1; decode_jpip( dec); if(!(fwrite_jp2k( argv[2], dec))) - return -1; + return 1; - output_log( OPJ_TRUE, OPJ_FALSE, OPJ_TRUE, dec); + /* output_log( OPJ_TRUE, OPJ_FALSE, OPJ_TRUE, dec); */ destroy_jpipdecoder( &dec); @@ -81,26 +74,19 @@ static int jpip_to_jp2(int argc,char *argv[]) * or * % ./jpip_to_j2k input.jpp output.j2k */ -static int jpip_to_j2k(int argc,char *argv[]) +static int jpip_to_j2k(char *argv[]) { jpip_dec_param_t *dec; - if( argc < 3){ - fprintf( stderr, "Too few arguments:\n"); - fprintf( stderr, " - input jpt or jpp file\n"); - fprintf( stderr, " - output j2k file\n"); - return -1; - } - dec = init_jpipdecoder( OPJ_FALSE); if(!( fread_jpip( argv[1], dec))) - return -1; + return 1; decode_jpip( dec); - if(!( fwrite_jp2k( argv[2], dec))) - return -1; + if(!(fwrite_jp2k( argv[2], dec))) + return 1; /* output_log( OPJ_TRUE, OPJ_FALSE, OPJ_FALSE, dec); */ @@ -111,6 +97,28 @@ static int jpip_to_j2k(int argc,char *argv[]) int main(int argc,char *argv[]) { - /* MM: FIXME */ - return jpip_to_jp2(argc,argv); + char *ext; + if( argc < 3){ + fprintf( stderr, "Too few arguments:\n"); + fprintf( stderr, " - input jpt or jpp file\n"); + fprintf( stderr, " - output j2k file\n"); + return 1; + } + + ext = strrchr( argv[2], '.' ); + if( ext ) + { + /* strcasecmp ? */ + if( strcmp(ext, ".jp2" ) == 0 ) + { + return jpip_to_jp2(argv); + } + if( strcmp(ext, ".j2k" ) == 0 ) + { + return jpip_to_j2k(argv); + } + } + + fprintf( stderr, "Invalid file extension for output file: %s\n", argv[2]); + return 1; } diff --git a/src/bin/jpip/opj_server.c b/src/bin/jpip/opj_server.c index 3534ad42..9ef9a5f2 100644 --- a/src/bin/jpip/opj_server.c +++ b/src/bin/jpip/opj_server.c @@ -48,6 +48,7 @@ #include #include #include +#include "fcgi_stdio.h" #include "openjpip.h" #ifndef QUIT_SIGNAL diff --git a/src/bin/jpwl/CMakeLists.txt b/src/bin/jpwl/CMakeLists.txt index 7bb0b496..5df225de 100644 --- a/src/bin/jpwl/CMakeLists.txt +++ b/src/bin/jpwl/CMakeLists.txt @@ -11,6 +11,7 @@ set(common_SRCS # Headers file are located here: include_directories( ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h + ${OPENJPEG_BINARY_DIR}/src/bin/common # opj_apps_config.h ${OPENJPEG_SOURCE_DIR}/src/lib/openmj2 ${OPENJPEG_SOURCE_DIR}/src/bin/common ${LCMS_INCLUDE_DIRNAME} diff --git a/src/bin/jpwl/convert.c b/src/bin/jpwl/convert.c index 11e89f7b..50123257 100644 --- a/src/bin/jpwl/convert.c +++ b/src/bin/jpwl/convert.c @@ -29,21 +29,21 @@ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ -#include "opj_config.h" +#include "opj_apps_config.h" #include #include #include #include -#ifdef HAVE_LIBTIFF +#ifdef OPJ_HAVE_LIBTIFF #include -#endif /* HAVE_LIBTIFF */ +#endif /* OPJ_HAVE_LIBTIFF */ -#ifdef HAVE_LIBPNG +#ifdef OPJ_HAVE_LIBPNG #include #include -#endif /* HAVE_LIBPNG */ +#endif /* OPJ_HAVE_LIBPNG */ #include "openjpeg.h" #include "convert.h" @@ -94,7 +94,7 @@ struct tga_header static unsigned short get_ushort(unsigned short val) { -#ifdef WORDS_BIGENDIAN +#ifdef OPJ_BIG_ENDIAN return( ((val & 0xff) << 8) + (val >> 8) ); #else return( val ); @@ -179,7 +179,7 @@ static int tga_readheader(FILE *fp, unsigned int *bits_per_pixel, return 1; } -#if WORDS_BIGENDIAN == 1 +#ifdef OPJ_BIG_ENDIAN static inline int16_t swap16(int16_t x) { @@ -226,7 +226,7 @@ static int tga_writeheader(FILE *fp, int bits_per_pixel, int width, int height, image_w = (unsigned short)width; image_h = (unsigned short) height; -#if WORDS_BIGENDIAN == 0 +#ifndef OPJ_BIG_ENDIAN if(fwrite(&image_w, 2, 1, fp) != 1) goto fails; if(fwrite(&image_h, 2, 1, fp) != 1) goto fails; #else @@ -2074,7 +2074,7 @@ int imagetopnm(opj_image_t * image, const char *outfile) return 0; }/* imagetopnm() */ -#ifdef HAVE_LIBTIFF +#ifdef OPJ_HAVE_LIBTIFF /* -->> -->> -->> -->> TIFF IMAGE FORMAT @@ -2781,7 +2781,7 @@ opj_image_t* tiftoimage(const char *filename, opj_cparameters_t *parameters) }/* tiftoimage() */ -#endif /* HAVE_LIBTIFF */ +#endif /* OPJ_HAVE_LIBTIFF */ /* -->> -->> -->> -->> @@ -3027,7 +3027,7 @@ int imagetoraw(opj_image_t * image, const char *outfile) return 0; } -#ifdef HAVE_LIBPNG +#ifdef OPJ_HAVE_LIBPNG #define PNG_MAGIC "\x89PNG\x0d\x0a\x1a\x0a" #define MAGIC_SIZE 8 @@ -3560,4 +3560,4 @@ fin: return fails; }/* imagetopng() */ -#endif /* HAVE_LIBPNG */ +#endif /* OPJ_HAVE_LIBPNG */ diff --git a/src/bin/jpwl/opj_jpwl_compress.c b/src/bin/jpwl/opj_jpwl_compress.c index c98eea17..b5bfc05b 100644 --- a/src/bin/jpwl/opj_jpwl_compress.c +++ b/src/bin/jpwl/opj_jpwl_compress.c @@ -49,7 +49,7 @@ #include #endif /* _WIN32 */ -#include "opj_config.h" +#include "opj_apps_config.h" #include "openjpeg.h" #include "opj_getopt.h" #include "convert.h" @@ -1627,7 +1627,7 @@ int main(int argc, char **argv) { return 1; } break; -#ifdef HAVE_LIBTIFF +#ifdef OPJ_HAVE_LIBTIFF case TIF_DFMT: image = tiftoimage(parameters.infile, ¶meters); if (!image) { @@ -1635,7 +1635,7 @@ int main(int argc, char **argv) { return 1; } break; -#endif /* HAVE_LIBTIFF */ +#endif /* OPJ_HAVE_LIBTIFF */ case RAW_DFMT: image = rawtoimage(parameters.infile, ¶meters, &raw_cp); if (!image) { @@ -1651,7 +1651,7 @@ int main(int argc, char **argv) { return 1; } break; -#ifdef HAVE_LIBPNG +#ifdef OPJ_HAVE_LIBPNG case PNG_DFMT: image = pngtoimage(parameters.infile, ¶meters); if (!image) { @@ -1659,10 +1659,10 @@ int main(int argc, char **argv) { return 1; } break; -#endif /* HAVE_LIBPNG */ +#endif /* OPJ_HAVE_LIBPNG */ } /* Can happen if input file is TIFF or PNG - * and HAVE_LIBTIF or HAVE_LIBPNG is undefined + * and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined */ if( !image) { diff --git a/src/bin/jpwl/opj_jpwl_decompress.c b/src/bin/jpwl/opj_jpwl_decompress.c index 36967b27..860c078c 100644 --- a/src/bin/jpwl/opj_jpwl_decompress.c +++ b/src/bin/jpwl/opj_jpwl_decompress.c @@ -49,16 +49,16 @@ #define _strnicmp strncasecmp #endif /* _WIN32 */ -#include "opj_config.h" +#include "opj_apps_config.h" #include "openjpeg.h" #include "opj_getopt.h" #include "convert.h" #include "index.h" -#ifdef HAVE_LIBLCMS2 +#ifdef OPJ_HAVE_LIBLCMS2 #include #endif -#ifdef HAVE_LIBLCMS1 +#ifdef OPJ_HAVE_LIBLCMS1 #include #endif #include "color.h" @@ -753,7 +753,7 @@ int main(int argc, char **argv) { if(image->icc_profile_buf) { -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +#if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2) color_apply_icc_profile(image); #endif @@ -790,7 +790,7 @@ int main(int argc, char **argv) { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; -#ifdef HAVE_LIBTIFF +#ifdef OPJ_HAVE_LIBTIFF case TIF_DFMT: /* TIFF */ if(imagetotif(image, parameters.outfile)){ fprintf(stdout,"Outfile %s not generated\n",parameters.outfile); @@ -799,7 +799,7 @@ int main(int argc, char **argv) { fprintf(stdout,"Generated Outfile %s\n",parameters.outfile); } break; -#endif /* HAVE_LIBTIFF */ +#endif /* OPJ_HAVE_LIBTIFF */ case RAW_DFMT: /* RAW */ if(imagetoraw(image, parameters.outfile)){ fprintf(stdout,"Error generating raw file. Outfile %s not generated\n",parameters.outfile); @@ -817,7 +817,7 @@ int main(int argc, char **argv) { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; -#ifdef HAVE_LIBPNG +#ifdef OPJ_HAVE_LIBPNG case PNG_DFMT: /* PNG */ if(imagetopng(image, parameters.outfile)){ fprintf(stdout,"Error generating png file. Outfile %s not generated\n",parameters.outfile); @@ -826,9 +826,9 @@ int main(int argc, char **argv) { fprintf(stdout,"Successfully generated Outfile %s\n",parameters.outfile); } break; -#endif /* HAVE_LIBPNG */ +#endif /* OPJ_HAVE_LIBPNG */ /* Can happen if output file is TIFF or PNG - * and HAVE_LIBTIF or HAVE_LIBPNG is undefined + * and OPJ_HAVE_LIBTIF or OPJ_HAVE_LIBPNG is undefined */ default: fprintf(stderr,"Outfile %s not generated\n",parameters.outfile); diff --git a/src/bin/mj2/CMakeLists.txt b/src/bin/mj2/CMakeLists.txt index a270829f..78ad7543 100644 --- a/src/bin/mj2/CMakeLists.txt +++ b/src/bin/mj2/CMakeLists.txt @@ -13,6 +13,7 @@ endif() # Headers file are located here: include_directories( ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h + ${OPENJPEG_BINARY_DIR}/src/bin/common # opj_apps_config.h ${OPENJPEG_SOURCE_DIR}/src/lib/openmj2 ${OPENJPEG_SOURCE_DIR}/src/bin/common ${LCMS_INCLUDE_DIRNAME} @@ -31,6 +32,10 @@ foreach(exe ${MJ2_SRCS} ${OPENJPEG_SOURCE_DIR}/src/bin/common/color.c ) + set_property( + TARGET ${exe} + APPEND PROPERTY COMPILE_DEFINITIONS USE_MJ2 + ) target_link_libraries(${exe} ${LCMS_LIBNAME} openmj2) if(UNIX) diff --git a/src/bin/mj2/opj_mj2_compress.c b/src/bin/mj2/opj_mj2_compress.c index 73ddcbe8..afe37679 100644 --- a/src/bin/mj2/opj_mj2_compress.c +++ b/src/bin/mj2/opj_mj2_compress.c @@ -29,7 +29,7 @@ #include #include -#include "opj_config.h" +#include "opj_apps_config.h" #include "openjpeg.h" #include "j2k_lib.h" #include "cio.h" @@ -61,13 +61,6 @@ static 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 -*/ -static void info_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[INFO] %s", msg); -} /* -------------------------------------------------------------------------- */ diff --git a/src/bin/mj2/opj_mj2_decompress.c b/src/bin/mj2/opj_mj2_decompress.c index ee312f61..086918c7 100644 --- a/src/bin/mj2/opj_mj2_decompress.c +++ b/src/bin/mj2/opj_mj2_decompress.c @@ -29,7 +29,7 @@ #include #include -#include "opj_config.h" +#include "opj_apps_config.h" #include "openjpeg.h" #include "j2k_lib.h" #include "cio.h" @@ -38,10 +38,10 @@ #include "mj2.h" #include "mj2_convert.h" -#ifdef HAVE_LIBLCMS2 +#ifdef OPJ_HAVE_LIBLCMS2 #include #endif -#ifdef HAVE_LIBLCMS1 +#ifdef OPJ_HAVE_LIBLCMS1 #include #endif #include "color.h" @@ -61,13 +61,6 @@ static 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 -*/ -static void info_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[INFO] %s", msg); -} /* -------------------------------------------------------------------------- */ @@ -188,7 +181,7 @@ int main(int argc, char *argv[]) { if(img->icc_profile_buf) { -#if defined(HAVE_LIBLCMS1) || defined(HAVE_LIBLCMS2) +#if defined(OPJ_HAVE_LIBLCMS1) || defined(OPJ_HAVE_LIBLCMS2) color_apply_icc_profile(img); #endif diff --git a/src/bin/wx/OPJViewer/CMakeLists.txt b/src/bin/wx/OPJViewer/CMakeLists.txt index 1b61c830..66cf01d2 100644 --- a/src/bin/wx/OPJViewer/CMakeLists.txt +++ b/src/bin/wx/OPJViewer/CMakeLists.txt @@ -9,6 +9,7 @@ include_directories( ${OPENJPEG_SOURCE_DIR}/src/lib ${OPENJPEG_SOURCE_DIR}/src/bin ${OPENJPEG_SOURCE_DIR}/src/lib/openjp2 + ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h and opj_config_private.h ) # original flags: diff --git a/src/lib/openjp2/CMakeLists.txt b/src/lib/openjp2/CMakeLists.txt index a6359890..5c87f297 100644 --- a/src/lib/openjp2/CMakeLists.txt +++ b/src/lib/openjp2/CMakeLists.txt @@ -5,7 +5,7 @@ install( FILES ${CMAKE_CURRENT_BINARY_DIR}/opj_config.h DESTINATION ${OPENJPEG_INSTALL_INCLUDE_DIR} COMPONENT Headers) include_directories( - ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h + ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h and opj_config_private.h ) # Defines the source code for the library set(OPENJPEG_SRCS diff --git a/src/lib/openjp2/bio.c b/src/lib/openjp2/bio.c index 797e01e1..213a9941 100644 --- a/src/lib/openjp2/bio.c +++ b/src/lib/openjp2/bio.c @@ -146,17 +146,17 @@ void opj_bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) { } void opj_bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n) { - OPJ_INT32 i; - for (i = n - 1; i >= 0; i--) { + OPJ_UINT32 i; + for (i = n - 1; i < n; i--) { opj_bio_putbit(bio, (v >> i) & 1); } } OPJ_UINT32 opj_bio_read(opj_bio_t *bio, OPJ_UINT32 n) { - OPJ_INT32 i; + OPJ_UINT32 i; OPJ_UINT32 v; v = 0; - for (i = n - 1; i >= 0; i--) { + for (i = n - 1; i < n; i--) { v += opj_bio_getbit(bio) << i; } return v; diff --git a/src/lib/openjp2/cidx_manager.c b/src/lib/openjp2/cidx_manager.c index b0e6d9c3..8324717f 100644 --- a/src/lib/openjp2/cidx_manager.c +++ b/src/lib/openjp2/cidx_manager.c @@ -79,25 +79,25 @@ int opj_write_cidx( int offset, opj_stream_private_t *cio, opj_codestream_info_t opj_write_manf( i, num_box, box, cio,p_manager); num_box = 0; - box[num_box].length = opj_write_mainmhix( offset, cstr_info, cio,p_manager); + box[num_box].length = (OPJ_UINT32)opj_write_mainmhix( offset, cstr_info, cio,p_manager); box[num_box].type = JPIP_MHIX; num_box++; - box[num_box].length = opj_write_tpix( offset, cstr_info, j2klen, cio,p_manager); + box[num_box].length = (OPJ_UINT32)opj_write_tpix( offset, cstr_info, j2klen, cio,p_manager); box[num_box].type = JPIP_TPIX; num_box++; - box[num_box].length = opj_write_thix( offset, cstr_info, cio, p_manager); + box[num_box].length = (OPJ_UINT32)opj_write_thix( offset, cstr_info, cio, p_manager); box[num_box].type = JPIP_THIX; num_box++; EPHused = opj_check_EPHuse( offset, cstr_info.marker, cstr_info.marknum, cio,p_manager); - box[num_box].length = opj_write_ppix( offset, cstr_info, EPHused, j2klen, cio,p_manager); + box[num_box].length = (OPJ_UINT32)opj_write_ppix( offset, cstr_info, EPHused, j2klen, cio,p_manager); box[num_box].type = JPIP_PPIX; num_box++; - box[num_box].length = opj_write_phix( offset, cstr_info, EPHused, j2klen, cio,p_manager); + box[num_box].length = (OPJ_UINT32)opj_write_phix( offset, cstr_info, EPHused, j2klen, cio,p_manager); box[num_box].type = JPIP_PHIX; num_box++; @@ -110,7 +110,7 @@ int opj_write_cidx( int offset, opj_stream_private_t *cio, opj_codestream_info_t opj_free( box); - return len; + return (int)len; } @@ -128,8 +128,8 @@ void opj_write_cptr(int coff, int clen, opj_stream_private_t *cio, opj_write_bytes( l_data_header, JPIP_CPTR, 4); /* T */ opj_write_bytes( l_data_header+4, 0, 2); /* DR A PRECISER !! */ opj_write_bytes( l_data_header+6, 0, 2); /* CONT */ - opj_write_bytes( l_data_header+8, coff, 8); /* COFF A PRECISER !! */ - opj_write_bytes( l_data_header+16, clen, 8); /* CLEN */ + opj_write_bytes( l_data_header+8, (OPJ_UINT32)coff, 8); /* COFF A PRECISER !! */ + opj_write_bytes( l_data_header+16, (OPJ_UINT32)clen, 8); /* CLEN */ opj_stream_write_data(cio,l_data_header,3*8,p_manager); len = (OPJ_UINT32) (opj_stream_tell(cio) - lenp); @@ -179,7 +179,7 @@ int opj_write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_stream_pr opj_event_mgr_t * p_manager ) { OPJ_BYTE l_data_header [8]; - int i; + OPJ_UINT32 i; OPJ_UINT32 len; OPJ_OFF_T lenp; @@ -188,16 +188,16 @@ int opj_write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_stream_pr opj_write_bytes(l_data_header,JPIP_MHIX,4); /* MHIX */ opj_stream_write_data(cio,l_data_header,4,p_manager); - opj_write_bytes(l_data_header, cstr_info.main_head_end-cstr_info.main_head_start+1, 8); /* TLEN */ + opj_write_bytes(l_data_header, (OPJ_UINT32)(cstr_info.main_head_end-cstr_info.main_head_start+1), 8); /* TLEN */ opj_stream_write_data(cio,l_data_header,8,p_manager); - for(i = 1; i < cstr_info.marknum; i++){ /* Marker restricted to 1 apparition, skip SOC marker */ + for(i = 1; i < (OPJ_UINT32)cstr_info.marknum; i++){ /* Marker restricted to 1 apparition, skip SOC marker */ opj_write_bytes( l_data_header, cstr_info.marker[i].type, 2); opj_write_bytes( l_data_header+2, 0, 2); opj_stream_write_data(cio,l_data_header,4,p_manager); opj_write_bytes( l_data_header,(OPJ_UINT32) (cstr_info.marker[i].pos-coff), 8); opj_stream_write_data(cio,l_data_header,8,p_manager); - opj_write_bytes( l_data_header, cstr_info.marker[i].len, 2); + opj_write_bytes( l_data_header, (OPJ_UINT32)cstr_info.marker[i].len, 2); opj_stream_write_data(cio,l_data_header,2,p_manager); } @@ -207,7 +207,7 @@ int opj_write_mainmhix( int coff, opj_codestream_info_t cstr_info, opj_stream_pr opj_stream_write_data(cio,l_data_header,4,p_manager); opj_stream_seek(cio, lenp+len,p_manager); - return len; + return (int)len; } OPJ_BOOL opj_check_EPHuse( int coff, opj_marker_info_t *markers, int marknum, opj_stream_private_t *cio, diff --git a/src/lib/openjp2/cio.c b/src/lib/openjp2/cio.c index e6ba8362..7d332085 100644 --- a/src/lib/openjp2/cio.c +++ b/src/lib/openjp2/cio.c @@ -241,12 +241,16 @@ void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_strea void OPJ_CALLCONV opj_stream_set_user_data(opj_stream_t* p_stream, void * p_data) { opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; + if (!l_stream) + return; l_stream->m_user_data = p_data; } void OPJ_CALLCONV opj_stream_set_user_data_length(opj_stream_t* p_stream, OPJ_UINT64 data_length) { opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; + if (!l_stream) + return; l_stream->m_user_data_length = data_length; } @@ -503,7 +507,6 @@ OPJ_OFF_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_OFF_T p_si if (! l_is_written) { p_stream->m_status |= opj_stream_e_error; p_stream->m_bytes_in_buffer = 0; - p_stream->m_current_data = p_stream->m_current_data; return (OPJ_OFF_T) -1; } /* then skip */ diff --git a/src/lib/openjp2/dwt.c b/src/lib/openjp2/dwt.c index 7d87a9f8..b36d68dd 100644 --- a/src/lib/openjp2/dwt.c +++ b/src/lib/openjp2/dwt.c @@ -389,23 +389,20 @@ INLINE OPJ_BOOL opj_dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_fun OPJ_INT32 rw; /* width of the resolution level computed */ OPJ_INT32 rh; /* height of the resolution level computed */ - OPJ_INT32 l_data_size; + OPJ_UINT32 l_data_size; opj_tcd_resolution_t * l_cur_res = 0; opj_tcd_resolution_t * l_last_res = 0; w = tilec->x1-tilec->x0; - l = tilec->numresolutions-1; + l = (OPJ_INT32)tilec->numresolutions-1; a = tilec->data; l_cur_res = tilec->resolutions + l; l_last_res = l_cur_res - 1; - rw = l_cur_res->x1 - l_cur_res->x0; - rh = l_cur_res->y1 - l_cur_res->y0; - - l_data_size = opj_dwt_max_resolution( tilec->resolutions,tilec->numresolutions) * sizeof(OPJ_INT32); - bj = (OPJ_INT32*)opj_malloc(l_data_size); + l_data_size = opj_dwt_max_resolution( tilec->resolutions,tilec->numresolutions) * (OPJ_UINT32)sizeof(OPJ_INT32); + bj = (OPJ_INT32*)opj_malloc((size_t)l_data_size); if (! bj) { return OPJ_FALSE; } @@ -531,7 +528,7 @@ void opj_dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec) { OPJ_FLOAT64 norm = opj_dwt_norms_real[orient][level]; stepsize = (1 << (gain)) / norm; } - opj_dwt_encode_stepsize((OPJ_INT32) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]); + opj_dwt_encode_stepsize((OPJ_INT32) floor(stepsize * 8192.0), (OPJ_INT32)(prec + gain), &tccp->stepsizes[bandno]); } } @@ -543,9 +540,9 @@ OPJ_UINT32 opj_dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i OPJ_UINT32 w; while( --i ) { ++r; - if( mr < ( w = r->x1 - r->x0 ) ) + if( mr < ( w = (OPJ_UINT32)(r->x1 - r->x0) ) ) mr = w ; - if( mr < ( w = r->y1 - r->y0 ) ) + if( mr < ( w = (OPJ_UINT32)(r->y1 - r->y0) ) ) mr = w ; } return mr ; @@ -560,10 +557,10 @@ OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1D opj_tcd_resolution_t* tr = tilec->resolutions; - OPJ_UINT32 rw = tr->x1 - tr->x0; /* width of the resolution level computed */ - OPJ_UINT32 rh = tr->y1 - tr->y0; /* height of the resolution level computed */ + OPJ_UINT32 rw = (OPJ_UINT32)(tr->x1 - tr->x0); /* width of the resolution level computed */ + OPJ_UINT32 rh = (OPJ_UINT32)(tr->y1 - tr->y0); /* height of the resolution level computed */ - OPJ_UINT32 w = tilec->x1 - tilec->x0; + OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0); h.mem = (OPJ_INT32*) opj_aligned_malloc(opj_dwt_max_resolution(tr, numres) * sizeof(OPJ_INT32)); @@ -578,13 +575,13 @@ OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1D OPJ_UINT32 j; ++tr; - h.sn = rw; - v.sn = rh; + h.sn = (OPJ_INT32)rw; + v.sn = (OPJ_INT32)rh; - rw = tr->x1 - tr->x0; - rh = tr->y1 - tr->y0; + rw = (OPJ_UINT32)(tr->x1 - tr->x0); + rh = (OPJ_UINT32)(tr->y1 - tr->y0); - h.dn = rw - h.sn; + h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn); h.cas = tr->x0 % 2; for(j = 0; j < rh; ++j) { @@ -593,12 +590,12 @@ OPJ_BOOL opj_dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1D memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32)); } - v.dn = rh - v.sn; + v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn); v.cas = tr->y0 % 2; for(j = 0; j < rw; ++j){ OPJ_UINT32 k; - opj_dwt_interleave_v(&v, &tiledp[j], w); + opj_dwt_interleave_v(&v, &tiledp[j], (OPJ_INT32)w); (dwt_1D)(&v); for(k = 0; k < rh; ++k) { tiledp[k * w + j] = v.mem[k]; @@ -657,14 +654,14 @@ void opj_v4dwt_interleave_v(opj_v4dwt_t* restrict v , OPJ_FLOAT32* restrict a , OPJ_INT32 i; for(i = 0; i < v->sn; ++i){ - memcpy(&bi[i*2], &a[i*x], nb_elts_read * sizeof(OPJ_FLOAT32)); + memcpy(&bi[i*2], &a[i*x], (size_t)nb_elts_read * sizeof(OPJ_FLOAT32)); } a += v->sn * x; bi = v->wavelet + 1 - v->cas; for(i = 0; i < v->dn; ++i){ - memcpy(&bi[i*2], &a[i*x], nb_elts_read * sizeof(OPJ_FLOAT32)); + memcpy(&bi[i*2], &a[i*x], (size_t)nb_elts_read * sizeof(OPJ_FLOAT32)); } } @@ -833,40 +830,40 @@ OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numr opj_tcd_resolution_t* res = tilec->resolutions; - OPJ_UINT32 rw = res->x1 - res->x0; /* width of the resolution level computed */ - OPJ_UINT32 rh = res->y1 - res->y0; /* height of the resolution level computed */ + OPJ_UINT32 rw = (OPJ_UINT32)(res->x1 - res->x0); /* width of the resolution level computed */ + OPJ_UINT32 rh = (OPJ_UINT32)(res->y1 - res->y0); /* height of the resolution level computed */ - OPJ_UINT32 w = tilec->x1 - tilec->x0; + OPJ_UINT32 w = (OPJ_UINT32)(tilec->x1 - tilec->x0); h.wavelet = (opj_v4_t*) opj_aligned_malloc((opj_dwt_max_resolution(res, numres)+5) * sizeof(opj_v4_t)); v.wavelet = h.wavelet; while( --numres) { OPJ_FLOAT32 * restrict aj = (OPJ_FLOAT32*) tilec->data; - OPJ_UINT32 bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0); + OPJ_UINT32 bufsize = (OPJ_UINT32)((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)); OPJ_INT32 j; - h.sn = rw; - v.sn = rh; + h.sn = (OPJ_INT32)rw; + v.sn = (OPJ_INT32)rh; ++res; - rw = res->x1 - res->x0; /* width of the resolution level computed */ - rh = res->y1 - res->y0; /* height of the resolution level computed */ + rw = (OPJ_UINT32)(res->x1 - res->x0); /* width of the resolution level computed */ + rh = (OPJ_UINT32)(res->y1 - res->y0); /* height of the resolution level computed */ - h.dn = rw - h.sn; + h.dn = (OPJ_INT32)(rw - (OPJ_UINT32)h.sn); h.cas = res->x0 % 2; - for(j = rh; j > 3; j -= 4) { + for(j = (OPJ_INT32)rh; j > 3; j -= 4) { OPJ_INT32 k; - opj_v4dwt_interleave_h(&h, aj, w, bufsize); + opj_v4dwt_interleave_h(&h, aj, (OPJ_INT32)w, (OPJ_INT32)bufsize); opj_v4dwt_decode(&h); - for(k = rw; --k >= 0;){ - aj[k ] = h.wavelet[k].f[0]; - aj[k+w ] = h.wavelet[k].f[1]; - aj[k+w*2] = h.wavelet[k].f[2]; - aj[k+w*3] = h.wavelet[k].f[3]; + for(k = (OPJ_INT32)rw; --k >= 0;){ + aj[k ] = h.wavelet[k].f[0]; + aj[k+(OPJ_INT32)w ] = h.wavelet[k].f[1]; + aj[k+(OPJ_INT32)w*2] = h.wavelet[k].f[2]; + aj[k+(OPJ_INT32)w*3] = h.wavelet[k].f[3]; } aj += w*4; @@ -876,25 +873,25 @@ OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numr if (rh & 0x03) { OPJ_INT32 k; j = rh & 0x03; - opj_v4dwt_interleave_h(&h, aj, w, bufsize); + opj_v4dwt_interleave_h(&h, aj, (OPJ_INT32)w, (OPJ_INT32)bufsize); opj_v4dwt_decode(&h); - for(k = rw; --k >= 0;){ + for(k = (OPJ_INT32)rw; --k >= 0;){ switch(j) { - case 3: aj[k+w*2] = h.wavelet[k].f[2]; - case 2: aj[k+w ] = h.wavelet[k].f[1]; - case 1: aj[k ] = h.wavelet[k].f[0]; + case 3: aj[k+(OPJ_INT32)w*2] = h.wavelet[k].f[2]; + case 2: aj[k+(OPJ_INT32)w ] = h.wavelet[k].f[1]; + case 1: aj[k ] = h.wavelet[k].f[0]; } } } - v.dn = rh - v.sn; + v.dn = (OPJ_INT32)(rh - (OPJ_UINT32)v.sn); v.cas = res->y0 % 2; aj = (OPJ_FLOAT32*) tilec->data; - for(j = rw; j > 3; j -= 4){ + for(j = (OPJ_INT32)rw; j > 3; j -= 4){ OPJ_UINT32 k; - opj_v4dwt_interleave_v(&v, aj, w, 4); + opj_v4dwt_interleave_v(&v, aj, (OPJ_INT32)w, 4); opj_v4dwt_decode(&v); for(k = 0; k < rh; ++k){ @@ -908,11 +905,11 @@ OPJ_BOOL opj_dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numr j = rw & 0x03; - opj_v4dwt_interleave_v(&v, aj, w, j); + opj_v4dwt_interleave_v(&v, aj, (OPJ_INT32)w, j); opj_v4dwt_decode(&v); for(k = 0; k < rh; ++k){ - memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(OPJ_FLOAT32)); + memcpy(&aj[k*w], &v.wavelet[k], (size_t)j * sizeof(OPJ_FLOAT32)); } } } diff --git a/src/lib/openjp2/event.c b/src/lib/openjp2/event.c index 6c53515b..42f59f0f 100644 --- a/src/lib/openjp2/event.c +++ b/src/lib/openjp2/event.c @@ -118,7 +118,7 @@ OPJ_BOOL opj_event_msg(opj_event_mgr_t* p_event_mgr, OPJ_INT32 event_type, const str_length = (strlen(fmt) > OPJ_MSG_SIZE) ? OPJ_MSG_SIZE : strlen(fmt); (void)str_length; /* parse the format string and put the result in 'message' */ - vsprintf(message, fmt, arg); /* UniPG */ + vsnprintf(message, OPJ_MSG_SIZE, fmt, arg); /* UniPG */ /* deinitialize the optional parameter list */ va_end(arg); diff --git a/src/lib/openjp2/image.c b/src/lib/openjp2/image.c index 7e48de1a..24f868d4 100644 --- a/src/lib/openjp2/image.c +++ b/src/lib/openjp2/image.c @@ -40,7 +40,7 @@ opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts, opj_image_cmptpa image->color_space = clrspc; image->numcomps = numcmpts; /* allocate memory for the per-component information */ - image->comps = (opj_image_comp_t*)opj_malloc(image->numcomps * sizeof(opj_image_comp_t)); + image->comps = (opj_image_comp_t*)opj_calloc(1,image->numcomps * sizeof(opj_image_comp_t)); if(!image->comps) { fprintf(stderr,"Unable to allocate memory for image.\n"); opj_image_destroy(image); @@ -106,23 +106,23 @@ void opj_image_comp_header_update(opj_image_t * p_image_header, const struct opj OPJ_INT32 l_comp_x0, l_comp_y0, l_comp_x1, l_comp_y1; opj_image_comp_t* l_img_comp = NULL; - l_x0 = opj_int_max(p_cp->tx0 , p_image_header->x0); - l_y0 = opj_int_max(p_cp->ty0 , p_image_header->y0); - l_x1 = opj_int_min(p_cp->tx0 + p_cp->tw * p_cp->tdx, p_image_header->x1); - l_y1 = opj_int_min(p_cp->ty0 + p_cp->th * p_cp->tdy, p_image_header->y1); + l_x0 = opj_int_max((OPJ_INT32)p_cp->tx0 , (OPJ_INT32)p_image_header->x0); + l_y0 = opj_int_max((OPJ_INT32)p_cp->ty0 , (OPJ_INT32)p_image_header->y0); + l_x1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + p_cp->tw * p_cp->tdx), (OPJ_INT32)p_image_header->x1); + l_y1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + p_cp->th * p_cp->tdy), (OPJ_INT32)p_image_header->y1); l_img_comp = p_image_header->comps; for (i = 0; i < p_image_header->numcomps; ++i) { - l_comp_x0 = opj_int_ceildiv(l_x0, l_img_comp->dx); - l_comp_y0 = opj_int_ceildiv(l_y0, l_img_comp->dy); - l_comp_x1 = opj_int_ceildiv(l_x1, l_img_comp->dx); - l_comp_y1 = opj_int_ceildiv(l_y1, l_img_comp->dy); - l_width = opj_int_ceildivpow2(l_comp_x1 - l_comp_x0, l_img_comp->factor); - l_height = opj_int_ceildivpow2(l_comp_y1 - l_comp_y0, l_img_comp->factor); + l_comp_x0 = opj_int_ceildiv(l_x0, (OPJ_INT32)l_img_comp->dx); + l_comp_y0 = opj_int_ceildiv(l_y0, (OPJ_INT32)l_img_comp->dy); + l_comp_x1 = opj_int_ceildiv(l_x1, (OPJ_INT32)l_img_comp->dx); + l_comp_y1 = opj_int_ceildiv(l_y1, (OPJ_INT32)l_img_comp->dy); + l_width = (OPJ_UINT32)opj_int_ceildivpow2(l_comp_x1 - l_comp_x0, (OPJ_INT32)l_img_comp->factor); + l_height = (OPJ_UINT32)opj_int_ceildivpow2(l_comp_y1 - l_comp_y0, (OPJ_INT32)l_img_comp->factor); l_img_comp->w = l_width; l_img_comp->h = l_height; - l_img_comp->x0 = l_comp_x0/*l_x0*/; - l_img_comp->y0 = l_comp_y0/*l_y0*/; + l_img_comp->x0 = (OPJ_UINT32)l_comp_x0/*l_x0*/; + l_img_comp->y0 = (OPJ_UINT32)l_comp_y0/*l_y0*/; ++l_img_comp; } } diff --git a/src/lib/openjp2/invert.c b/src/lib/openjp2/invert.c index 5e2d6614..bb6672d4 100644 --- a/src/lib/openjp2/invert.c +++ b/src/lib/openjp2/invert.c @@ -67,8 +67,8 @@ OPJ_BOOL opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix, OPJ_UINT32 nb_compo) { OPJ_BYTE * l_data = 00; - OPJ_UINT32 l_permutation_size = nb_compo * sizeof(OPJ_UINT32); - OPJ_UINT32 l_swap_size = nb_compo * sizeof(OPJ_FLOAT32); + OPJ_UINT32 l_permutation_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_UINT32); + OPJ_UINT32 l_swap_size = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32); OPJ_UINT32 l_total_size = l_permutation_size + 3 * l_swap_size; OPJ_UINT32 * lPermutations = 00; OPJ_FLOAT32 * l_double_data = 00; @@ -109,7 +109,7 @@ OPJ_BOOL opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations, OPJ_UINT32 i,j,k; OPJ_FLOAT32 p; OPJ_UINT32 lLastColum = nb_compo - 1; - OPJ_UINT32 lSwapSize = nb_compo * sizeof(OPJ_FLOAT32); + OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32); OPJ_FLOAT32 * lTmpMatrix = matrix; OPJ_FLOAT32 * lColumnMatrix,* lDestMatrix; OPJ_UINT32 offset = 1; @@ -250,7 +250,7 @@ void opj_lupSolve (OPJ_FLOAT32 * pResult, lTmpMatrix = lLineMatrix; u = *(lTmpMatrix++); lCurrentPtr = lDestPtr--; - for (j = k + 1; j < nb_compo; ++j) { + for (j = (OPJ_UINT32)(k + 1); j < nb_compo; ++j) { /* sum += matrix[k][j] * x[j] */ sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++)); } @@ -272,7 +272,7 @@ void opj_lupInvert (OPJ_FLOAT32 * pSrcMatrix, OPJ_UINT32 j,i; OPJ_FLOAT32 * lCurrentPtr; OPJ_FLOAT32 * lLineMatrix = pDestMatrix; - OPJ_UINT32 lSwapSize = nb_compo * sizeof(OPJ_FLOAT32); + OPJ_UINT32 lSwapSize = nb_compo * (OPJ_UINT32)sizeof(OPJ_FLOAT32); for (j = 0; j < nb_compo; ++j) { lCurrentPtr = lLineMatrix++; diff --git a/src/lib/openjp2/j2k.c b/src/lib/openjp2/j2k.c index 3b439fc7..92ec2385 100644 --- a/src/lib/openjp2/j2k.c +++ b/src/lib/openjp2/j2k.c @@ -36,6 +36,11 @@ #include "opj_includes.h" +#define CINEMA_24_CS 1302083 /*Codestream length for 24fps*/ +#define CINEMA_48_CS 651041 /*Codestream length for 48fps*/ +#define COMP_24_CS 1041666 /*Maximum size per color component for 2K & 4K @ 24fps*/ +#define COMP_48_CS 520833 /*Maximum size per color component for 2K @ 48fps*/ + /** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ /*@{*/ @@ -468,6 +473,7 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager); +#if 0 /** * Writes the COC marker (Coding style component) * @@ -480,6 +486,9 @@ static OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); +#endif + +#if 0 /** * Writes the COC marker (Coding style component) * @@ -494,6 +503,7 @@ static void opj_j2k_write_coc_in_memory(opj_j2k_t *p_j2k, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, opj_event_mgr_t * p_manager ); +#endif /** * Gets the maximum size taken by a coc. @@ -536,6 +546,7 @@ static OPJ_BOOL opj_j2k_read_qcd ( opj_j2k_t *p_j2k, OPJ_BYTE * p_header_data, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager ); +#if 0 /** * Writes the QCC marker (quantization component) * @@ -548,7 +559,9 @@ static OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); +#endif +#if 0 /** * Writes the QCC marker (quantization component) * @@ -563,6 +576,7 @@ static void opj_j2k_write_qcc_in_memory(opj_j2k_t *p_j2k, OPJ_BYTE * p_data, OPJ_UINT32 * p_data_written, opj_event_mgr_t * p_manager ); +#endif /** * Gets the maximum size taken by a qcc. @@ -846,6 +860,7 @@ static OPJ_BOOL opj_j2k_write_eoc( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); +#if 0 /** * Reads a EOC marker (End Of Codestream) * @@ -856,6 +871,7 @@ static OPJ_BOOL opj_j2k_write_eoc( opj_j2k_t *p_j2k, static OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); +#endif /** * Writes the CBD-MCT-MCC-MCO markers (Multi components transform) @@ -1039,16 +1055,31 @@ static OPJ_BOOL opj_j2k_read_cbd ( opj_j2k_t *p_j2k, OPJ_UINT32 p_header_size, opj_event_mgr_t * p_manager); +#if 0 /** - * Writes the image components. + * Writes COC marker for each component. * * @param p_stream the stream to write data to. * @param p_j2k J2K codec. * @param p_manager the user event manager. */ -static OPJ_BOOL opj_j2k_write_image_components( opj_j2k_t *p_j2k, +static OPJ_BOOL opj_j2k_write_all_coc( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ); +#endif + +#if 0 +/** + * Writes QCC marker for each component. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static OPJ_BOOL opj_j2k_write_all_qcc( opj_j2k_t *p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager ); +#endif /** * Writes regions of interests. @@ -1131,6 +1162,12 @@ static OPJ_FLOAT32 opj_j2k_get_tp_stride (opj_tcp_t * p_tcp); static OPJ_FLOAT32 opj_j2k_get_default_stride (opj_tcp_t * p_tcp); +static int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres); + +static void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager); + +static OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_CINEMA_MODE cinema_mode, opj_event_mgr_t *p_manager); + /*@}*/ /*@}*/ @@ -1464,6 +1501,7 @@ OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs, memset(packet_array,0,step_l * p_num_layers* sizeof(OPJ_UINT32)); if (p_nb_pocs == 0) { + opj_free(packet_array); return OPJ_TRUE; } @@ -1547,7 +1585,7 @@ OPJ_BOOL opj_j2k_check_poc_val( const opj_poc_t *p_pocs, OPJ_UINT32 opj_j2k_get_num_tp(opj_cp_t *cp, OPJ_UINT32 pino, OPJ_UINT32 tileno) { const OPJ_CHAR *prog = 00; - OPJ_UINT32 i; + OPJ_INT32 i; OPJ_UINT32 tpnum = 1; opj_tcp_t *tcp = 00; opj_poc_t * l_current_poc = 00; @@ -1932,6 +1970,23 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, return OPJ_FALSE; } + /* testcase 4035.pdf.SIGSEGV.d8b.3375 */ + if (l_image->x0 > l_image->x1 || l_image->y0 > l_image->y1) { + opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: negative image size (%d x %d)\n", l_image->x1 - l_image->x0, l_image->y1 - l_image->y0); + return OPJ_FALSE; + } + /* testcase 2539.pdf.SIGFPE.706.1712 (also 3622.pdf.SIGFPE.706.2916 and 4008.pdf.SIGFPE.706.3345 and maybe more) */ + if (!(l_cp->tdx * l_cp->tdy)) { + opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker: invalid tile size (tdx: %d, tdy: %d)\n", l_cp->tdx, l_cp->tdy); + return OPJ_FALSE; + } + + /* testcase 1610.pdf.SIGSEGV.59c.681 */ + if (((OPJ_UINT64)l_image->x1) * ((OPJ_UINT64)l_image->y1) != (l_image->x1 * l_image->y1)) { + opj_event_msg(p_manager, EVT_ERROR, "Prevent buffer overflow (x1: %d, y1: %d)\n", l_image->x1, l_image->y1); + return OPJ_FALSE; + } + #ifdef USE_JPWL if (l_cp->correct) { /* if JPWL is on, we check whether TX errors have damaged @@ -1994,10 +2049,17 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, l_img_comp->sgnd = tmp >> 7; opj_read_bytes(p_header_data,&tmp,1); /* XRsiz_i */ ++p_header_data; - l_img_comp->dx = (OPJ_INT32)tmp; /* should be between 1 and 255 */ + l_img_comp->dx = (OPJ_UINT32)tmp; /* should be between 1 and 255 */ opj_read_bytes(p_header_data,&tmp,1); /* YRsiz_i */ ++p_header_data; - l_img_comp->dy = (OPJ_INT32)tmp; /* should be between 1 and 255 */ + l_img_comp->dy = (OPJ_UINT32)tmp; /* should be between 1 and 255 */ + if( l_img_comp->dx < 1 || l_img_comp->dx > 255 || + l_img_comp->dy < 1 || l_img_comp->dy > 255 ) { + opj_event_msg(p_manager, EVT_ERROR, + "Invalid values for comp = %d : dx=%u dy=%u\n (should be between 1 and 255 according the JPEG2000 norm)", + i, l_img_comp->dx, l_img_comp->dy); + return OPJ_FALSE; + } if( l_img_comp->dx < 1 || l_img_comp->dx > 255 || l_img_comp->dy < 1 || l_img_comp->dy > 255 ) { opj_event_msg(p_manager, EVT_ERROR, @@ -2039,8 +2101,16 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, } /* Compute the number of tiles */ - l_cp->tw = opj_int_ceildiv(l_image->x1 - l_cp->tx0, l_cp->tdx); - l_cp->th = opj_int_ceildiv(l_image->y1 - l_cp->ty0, l_cp->tdy); + l_cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->x1 - l_cp->tx0), (OPJ_INT32)l_cp->tdx); + l_cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(l_image->y1 - l_cp->ty0), (OPJ_INT32)l_cp->tdy); + + /* Check that the number of tiles is valid */ + if (l_cp->tw == 0 || l_cp->th == 0 || l_cp->tw > 65535 / l_cp->th) { + opj_event_msg( p_manager, EVT_ERROR, + "Invalid number of tiles : %u x %u (maximum fixed by jpeg2000 norm is 65535 tiles)\n", + l_cp->tw, l_cp->th); + return OPJ_FALSE; + } /* Check that the number of tiles is valid */ if (l_cp->tw == 0 || l_cp->th == 0 || l_cp->tw > 65535 / l_cp->th) { @@ -2055,8 +2125,8 @@ static OPJ_BOOL opj_j2k_read_siz(opj_j2k_t *p_j2k, if (p_j2k->m_specific_param.m_decoder.m_discard_tiles) { p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_j2k->m_specific_param.m_decoder.m_start_tile_x - l_cp->tx0) / l_cp->tdx; p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_j2k->m_specific_param.m_decoder.m_start_tile_y - l_cp->ty0) / l_cp->tdy; - p_j2k->m_specific_param.m_decoder.m_end_tile_x = opj_int_ceildiv((p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0), l_cp->tdx); - p_j2k->m_specific_param.m_decoder.m_end_tile_y = opj_int_ceildiv((p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0), l_cp->tdy); + p_j2k->m_specific_param.m_decoder.m_end_tile_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_x - l_cp->tx0), (OPJ_INT32)l_cp->tdx); + p_j2k->m_specific_param.m_decoder.m_end_tile_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0), (OPJ_INT32)l_cp->tdy); } else { p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0; @@ -2196,7 +2266,7 @@ OPJ_BOOL opj_j2k_write_com( opj_j2k_t *p_j2k, assert(p_manager != 00); l_comment = p_j2k->m_cp.comment; - l_comment_size = strlen(l_comment); + l_comment_size = (OPJ_UINT32)strlen(l_comment); l_total_com_size = l_comment_size + 6; if (l_total_com_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { @@ -2417,6 +2487,7 @@ static OPJ_BOOL opj_j2k_read_cod ( opj_j2k_t *p_j2k, return OPJ_TRUE; } +#if 0 OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, opj_stream_private_t *p_stream, @@ -2461,7 +2532,9 @@ OPJ_BOOL opj_j2k_write_coc( opj_j2k_t *p_j2k, return OPJ_TRUE; } +#endif +#if 0 void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, @@ -2506,6 +2579,7 @@ void opj_j2k_write_coc_in_memory( opj_j2k_t *p_j2k, opj_j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager); * p_data_written = l_coc_size; } +#endif OPJ_UINT32 opj_j2k_get_max_coc_size(opj_j2k_t *p_j2k) { @@ -2679,6 +2753,7 @@ static OPJ_BOOL opj_j2k_read_qcd ( opj_j2k_t *p_j2k, return OPJ_TRUE; } +#if 0 OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, opj_stream_private_t *p_stream, @@ -2692,7 +2767,8 @@ OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, assert(p_manager != 00); assert(p_stream != 00); - l_qcc_size = 6 + opj_j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no); + l_qcc_size = 5 + opj_j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no); + l_qcc_size += p_j2k->m_private_image->numcomps <= 256 ? 0:1; l_remaining_size = l_qcc_size; if (l_qcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) { @@ -2716,7 +2792,9 @@ OPJ_BOOL opj_j2k_write_qcc( opj_j2k_t *p_j2k, return OPJ_TRUE; } +#endif +#if 0 void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k, OPJ_UINT32 p_comp_no, OPJ_BYTE * p_data, @@ -2765,6 +2843,7 @@ void opj_j2k_write_qcc_in_memory( opj_j2k_t *p_j2k, *p_data_written = l_qcc_size; } +#endif OPJ_UINT32 opj_j2k_get_max_qcc_size (opj_j2k_t *p_j2k) { @@ -2974,9 +3053,9 @@ void opj_j2k_write_poc_in_memory( opj_j2k_t *p_j2k, ++l_current_data; /* change the value of the max layer according to the actual number of layers in the file, components and resolutions*/ - l_current_poc->layno1 = opj_int_min(l_current_poc->layno1, l_tcp->numlayers); - l_current_poc->resno1 = opj_int_min(l_current_poc->resno1, l_tccp->numresolutions); - l_current_poc->compno1 = opj_int_min(l_current_poc->compno1, l_nb_comp); + l_current_poc->layno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32)l_current_poc->layno1, (OPJ_INT32)l_tcp->numlayers); + l_current_poc->resno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32)l_current_poc->resno1, (OPJ_INT32)l_tccp->numresolutions); + l_current_poc->compno1 = (OPJ_UINT32)opj_int_min((OPJ_INT32)l_current_poc->compno1, (OPJ_INT32)l_nb_comp); ++l_current_poc; } @@ -3099,6 +3178,11 @@ static OPJ_BOOL opj_j2k_read_poc ( opj_j2k_t *p_j2k, l_old_poc_nb = l_tcp->POC ? l_tcp->numpocs + 1 : 0; l_current_poc_nb += l_old_poc_nb; + if(l_current_poc_nb >= 32) + { + opj_event_msg(p_manager, EVT_ERROR, "Too many POCs %d\n", l_current_poc_nb); + return OPJ_FALSE; + } assert(l_current_poc_nb < 32); /* now poc is in use.*/ @@ -3111,6 +3195,8 @@ static OPJ_BOOL opj_j2k_read_poc ( opj_j2k_t *p_j2k, opj_read_bytes(p_header_data,&(l_current_poc->compno0),l_comp_room); /* CSpoc_i */ p_header_data+=l_comp_room; opj_read_bytes(p_header_data,&(l_current_poc->layno1),2); /* LYEpoc_i */ + /* make sure layer end is in acceptable bounds */ + l_current_poc->layno1 = opj_uint_min(l_current_poc->layno1, l_tcp->numlayers); p_header_data+=2; opj_read_bytes(p_header_data,&(l_current_poc->resno1),1); /* REpoc_i */ ++p_header_data; @@ -3489,6 +3575,17 @@ OPJ_BOOL j2k_read_ppm_v3 ( p_header_data+=4; p_header_size-=4; + /* sanity check: how much bytes is left for Ippm */ + if( p_header_size < l_N_ppm ) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm ); + opj_free(l_cp->ppm_data); + l_cp->ppm_data = NULL; + l_cp->ppm_buffer = NULL; + l_cp->ppm = 0; /* do not use PPM */ + return OPJ_FALSE; + } + /* First PPM marker: Initialization */ l_cp->ppm_len = l_N_ppm; l_cp->ppm_data_read = 0; @@ -3523,6 +3620,16 @@ OPJ_BOOL j2k_read_ppm_v3 ( p_header_data+=4; p_header_size-=4; + /* sanity check: how much bytes is left for Ippm */ + if( p_header_size < l_N_ppm ) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough bytes (%u) to hold Ippm series (%u), Index (%d)\n", p_header_size, l_N_ppm, l_Z_ppm ); + opj_free(l_cp->ppm_data); + l_cp->ppm_data = NULL; + l_cp->ppm_buffer = NULL; + l_cp->ppm = 0; /* do not use PPM */ + return OPJ_FALSE; + } /* Increase the size of ppm_data to add the new Ippm series*/ assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating"); new_ppm_data = (OPJ_BYTE *) opj_realloc(l_cp->ppm_data, l_cp->ppm_len + l_N_ppm); @@ -3568,7 +3675,7 @@ OPJ_BOOL j2k_read_ppm_v3 ( l_remaining_data = p_header_size; /* Next Ippm series is a complete series ?*/ - if (l_remaining_data > l_N_ppm) { + if (l_remaining_data >= l_N_ppm) { OPJ_BYTE *new_ppm_data; /* Increase the size of ppm_data to add the new Ippm series*/ assert(l_cp->ppm_data == l_cp->ppm_buffer && "We need ppm_data and ppm_buffer to be the same when reallocating"); @@ -3716,6 +3823,7 @@ static OPJ_BOOL opj_j2k_read_ppt ( opj_j2k_t *p_j2k, l_tcp->ppt_data_size = 0; l_tcp->ppt_len = p_header_size; + opj_free(l_tcp->ppt_buffer); l_tcp->ppt_buffer = (OPJ_BYTE *) opj_calloc(l_tcp->ppt_len, sizeof(OPJ_BYTE) ); if (l_tcp->ppt_buffer == 00) { opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to read PPT marker\n"); @@ -3875,6 +3983,12 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, opj_read_bytes(p_header_data,&(p_j2k->m_current_tile_number),2); /* Isot */ p_header_data+=2; + /* testcase 2.pdf.SIGFPE.706.1112 */ + if (p_j2k->m_current_tile_number >= l_cp->tw * l_cp->th) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid tile number %d\n", p_j2k->m_current_tile_number); + return OPJ_FALSE; + } + l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; l_tile_x = p_j2k->m_current_tile_number % l_cp->tw; l_tile_y = p_j2k->m_current_tile_number / l_cp->tw; @@ -3972,12 +4086,19 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, return OPJ_FALSE; } } + if( l_current_part >= l_num_parts ) { + /* testcase 451.pdf.SIGSEGV.ce9.3723 */ + opj_event_msg(p_manager, EVT_ERROR, "In SOT marker, TPSot (%d) is not valid regards to the current " + "number of tile-part (header) (%d), giving up\n", l_current_part, l_num_parts ); + p_j2k->m_specific_param.m_decoder.m_last_tile_part = 1; + return OPJ_FALSE; + } l_tcp->m_nb_tile_parts = l_num_parts; } /* If know the number of tile part header we will check if we didn't read the last*/ if (l_tcp->m_nb_tile_parts) { - if (l_tcp->m_nb_tile_parts == (l_current_part + 1)) { + if (l_tcp->m_nb_tile_parts == (l_current_part+1)) { p_j2k->m_specific_param.m_decoder.m_can_decode = 1; /* Process the last tile-part header*/ } } @@ -4046,7 +4167,7 @@ OPJ_BOOL opj_j2k_read_sot ( opj_j2k_t *p_j2k, if ( l_current_part >= p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps ){ opj_tp_index_t *new_tp_index; - p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps += 10; + p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps = l_current_part + 1; new_tp_index = (opj_tp_index_t *) opj_realloc( p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].tp_index, p_j2k->cstr_index->tile_index[p_j2k->m_current_tile_number].current_nb_tps * sizeof(opj_tp_index_t)); @@ -4174,7 +4295,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k, opj_event_mgr_t * p_manager ) { - OPJ_UINT32 l_current_read_size; + OPJ_SIZE_T l_current_read_size; opj_codestream_index_t * l_cstr_index = 00; OPJ_BYTE ** l_current_data = 00; opj_tcp_t * l_tcp = 00; @@ -4279,7 +4400,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k, p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_TPHSOT; } - *l_tile_len += l_current_read_size; + *l_tile_len += (OPJ_UINT32)l_current_read_size; return OPJ_TRUE; } @@ -4331,7 +4452,7 @@ OPJ_BOOL opj_j2k_read_sod (opj_j2k_t *p_j2k, opj_write_bytes(l_current_data, 0,1); /* Srgn */ ++l_current_data; - opj_write_bytes(l_current_data, l_tccp->roishift,1); /* SPrgn */ + opj_write_bytes(l_current_data, (OPJ_UINT32)l_tccp->roishift,1); /* SPrgn */ ++l_current_data; if (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_rgn_size,p_manager) != l_rgn_size) { @@ -4436,6 +4557,14 @@ static OPJ_BOOL opj_j2k_read_rgn (opj_j2k_t *p_j2k, }; #endif /* USE_JPWL */ + /* testcase 3635.pdf.asan.77.2930 */ + if (l_comp_no >= l_nb_comp) { + opj_event_msg(p_manager, EVT_ERROR, + "bad component number in RGN (%d when there are only %d)\n", + l_comp_no, l_nb_comp); + return OPJ_FALSE; + } + opj_read_bytes(p_header_data,(OPJ_UINT32 *) (&(l_tcp->tccps[l_comp_no].roishift)),1); /* SPrgn */ ++p_header_data; @@ -4483,7 +4612,7 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, l_bits_empty = 8 * l_image->comps->dx * l_image->comps->dy; l_size_pixel = l_image->numcomps * l_image->comps->prec; - l_sot_remove = ((OPJ_FLOAT32) opj_stream_tell(p_stream)) / (l_cp->th * l_cp->tw); + l_sot_remove = (OPJ_FLOAT32) opj_stream_tell(p_stream) / (OPJ_FLOAT32)(l_cp->th * l_cp->tw); if (l_cp->m_specific_param.m_enc.m_tp_on) { l_tp_stride_func = opj_j2k_get_tp_stride; @@ -4494,21 +4623,21 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, for (i=0;ith;++i) { for (j=0;jtw;++j) { - OPJ_FLOAT32 l_offset = ((*l_tp_stride_func)(l_tcp)) / l_tcp->numlayers; + OPJ_FLOAT32 l_offset = (OPJ_FLOAT32)(*l_tp_stride_func)(l_tcp) / (OPJ_FLOAT32)l_tcp->numlayers; /* 4 borders of the tile rescale on the image if necessary */ - l_x0 = opj_int_max(l_cp->tx0 + j * l_cp->tdx, l_image->x0); - l_y0 = opj_int_max(l_cp->ty0 + i * l_cp->tdy, l_image->y0); - l_x1 = opj_int_min(l_cp->tx0 + (j + 1) * l_cp->tdx, l_image->x1); - l_y1 = opj_int_min(l_cp->ty0 + (i + 1) * l_cp->tdy, l_image->y1); + l_x0 = opj_int_max((OPJ_INT32)(l_cp->tx0 + j * l_cp->tdx), (OPJ_INT32)l_image->x0); + l_y0 = opj_int_max((OPJ_INT32)(l_cp->ty0 + i * l_cp->tdy), (OPJ_INT32)l_image->y0); + l_x1 = opj_int_min((OPJ_INT32)(l_cp->tx0 + (j + 1) * l_cp->tdx), (OPJ_INT32)l_image->x1); + l_y1 = opj_int_min((OPJ_INT32)(l_cp->ty0 + (i + 1) * l_cp->tdy), (OPJ_INT32)l_image->y1); l_rates = l_tcp->rates; /* Modification of the RATE >> */ if (*l_rates) { - *l_rates = (( (OPJ_FLOAT32) (l_size_pixel * (l_x1 - l_x0) * (l_y1 - l_y0))) + *l_rates = (( (OPJ_FLOAT32) (l_size_pixel * (OPJ_UINT32)(l_x1 - l_x0) * (OPJ_UINT32)(l_y1 - l_y0))) / - ((*l_rates) * l_bits_empty) + ((*l_rates) * (OPJ_FLOAT32)l_bits_empty) ) - l_offset; @@ -4518,9 +4647,9 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, for (k = 1; k < l_tcp->numlayers; ++k) { if (*l_rates) { - *l_rates = (( (OPJ_FLOAT32) (l_size_pixel * (l_x1 - l_x0) * (l_y1 - l_y0))) + *l_rates = (( (OPJ_FLOAT32) (l_size_pixel * (OPJ_UINT32)(l_x1 - l_x0) * (OPJ_UINT32)(l_y1 - l_y0))) / - ((*l_rates) * l_bits_empty) + ((*l_rates) * (OPJ_FLOAT32)l_bits_empty) ) - l_offset; @@ -4616,6 +4745,7 @@ OPJ_BOOL opj_j2k_update_rates( opj_j2k_t *p_j2k, return OPJ_TRUE; } +#if 0 OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, opj_event_mgr_t * p_manager ) @@ -4664,6 +4794,7 @@ OPJ_BOOL opj_j2k_read_eoc ( opj_j2k_t *p_j2k, opj_tcd_destroy(l_tcd); return OPJ_TRUE; } +#endif OPJ_BOOL opj_j2k_get_end_header(opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, @@ -4727,7 +4858,8 @@ OPJ_BOOL opj_j2k_write_mct_data_group( opj_j2k_t *p_j2k, return OPJ_TRUE; } -OPJ_BOOL opj_j2k_write_image_components(opj_j2k_t *p_j2k, +#if 0 +OPJ_BOOL opj_j2k_write_all_coc(opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager ) { @@ -4738,12 +4870,31 @@ OPJ_BOOL opj_j2k_write_image_components(opj_j2k_t *p_j2k, assert(p_manager != 00); assert(p_stream != 00); - for (compno = 1; compno < p_j2k->m_private_image->numcomps; ++compno) + for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) { if (! opj_j2k_write_coc(p_j2k,compno,p_stream, p_manager)) { return OPJ_FALSE; } + } + return OPJ_TRUE; +} +#endif + +#if 0 +OPJ_BOOL opj_j2k_write_all_qcc(opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager ) +{ + OPJ_UINT32 compno; + + /* preconditions */ + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + for (compno = 0; compno < p_j2k->m_private_image->numcomps; ++compno) + { if (! opj_j2k_write_qcc(p_j2k,compno,p_stream, p_manager)) { return OPJ_FALSE; } @@ -4751,6 +4902,8 @@ OPJ_BOOL opj_j2k_write_image_components(opj_j2k_t *p_j2k, return OPJ_TRUE; } +#endif + OPJ_BOOL opj_j2k_write_regions( opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, @@ -4793,12 +4946,12 @@ OPJ_BOOL opj_j2k_write_epc( opj_j2k_t *p_j2k, l_cstr_index = p_j2k->cstr_index; if (l_cstr_index) { - l_cstr_index->codestream_size = opj_stream_tell(p_stream); + l_cstr_index->codestream_size = (OPJ_UINT64)opj_stream_tell(p_stream); /* UniPG>> */ /* The following adjustment is done to adjust the codestream size */ /* if SOD is not at 0 in the buffer. Useful in case of JP2, where */ /* the first bunch of bytes is not in the codestream */ - l_cstr_index->codestream_size -= l_cstr_index->main_head_start; + l_cstr_index->codestream_size -= (OPJ_UINT64)l_cstr_index->main_head_start; /* <numcomps * p_image->numcomps; - l_mct_size = l_nb_elem * sizeof(OPJ_FLOAT32); + l_mct_size = l_nb_elem * (OPJ_UINT32)sizeof(OPJ_FLOAT32); p_tcp->m_mct_decoding_matrix = (OPJ_FLOAT32*)opj_malloc(l_mct_size); if (! p_tcp->m_mct_decoding_matrix ) { @@ -5559,7 +5712,7 @@ OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_ } l_nb_elem = p_image->numcomps; - l_offset_size = l_nb_elem * sizeof(OPJ_UINT32); + l_offset_size = l_nb_elem * (OPJ_UINT32)sizeof(OPJ_UINT32); l_offset_data = (OPJ_UINT32*)opj_malloc(l_offset_size); if (! l_offset_data ) { @@ -5572,7 +5725,7 @@ OPJ_BOOL opj_j2k_add_mct(opj_tcp_t * p_tcp, opj_image_t * p_image, OPJ_UINT32 p_ l_current_offset_data = l_offset_data; for (i=0;inumcomps;++i) { - l_tccp->m_dc_level_shift = *(l_current_offset_data++); + l_tccp->m_dc_level_shift = (OPJ_INT32)*(l_current_offset_data++); ++l_tccp; } @@ -5749,6 +5902,259 @@ opj_j2k_t* opj_j2k_create_compress(void) return l_j2k; } +int opj_j2k_initialise_4K_poc(opj_poc_t *POC, int numres){ + POC[0].tile = 1; + POC[0].resno0 = 0; + POC[0].compno0 = 0; + POC[0].layno1 = 1; + POC[0].resno1 = (OPJ_UINT32)(numres-1); + POC[0].compno1 = 3; + POC[0].prg1 = OPJ_CPRL; + POC[1].tile = 1; + POC[1].resno0 = (OPJ_UINT32)(numres-1); + POC[1].compno0 = 0; + POC[1].layno1 = 1; + POC[1].resno1 = (OPJ_UINT32)numres; + POC[1].compno1 = 3; + POC[1].prg1 = OPJ_CPRL; + return 2; +} + +void opj_j2k_set_cinema_parameters(opj_cparameters_t *parameters, opj_image_t *image, opj_event_mgr_t *p_manager) +{ + /* Configure cinema parameters */ + OPJ_FLOAT32 max_rate = 0; + OPJ_FLOAT32 temp_rate = 0; + int i; + + /* profile (Rsiz) */ + switch (parameters->cp_cinema){ + case OPJ_CINEMA2K_24: + case OPJ_CINEMA2K_48: + parameters->cp_rsiz = OPJ_CINEMA2K; + break; + case OPJ_CINEMA4K_24: + parameters->cp_rsiz = OPJ_CINEMA4K; + break; + case OPJ_OFF: + assert(0); + break; + } + + /* No tiling */ + parameters->tile_size_on = OPJ_FALSE; + parameters->cp_tdx=1; + parameters->cp_tdy=1; + + /* One tile part for each component */ + parameters->tp_flag = 'C'; + parameters->tp_on = 1; + + /* Tile and Image shall be at (0,0) */ + parameters->cp_tx0 = 0; + parameters->cp_ty0 = 0; + parameters->image_offset_x0 = 0; + parameters->image_offset_y0 = 0; + + /* Codeblock size= 32*32 */ + parameters->cblockw_init = 32; + parameters->cblockh_init = 32; + + /* Codeblock style: no mode switch enabled */ + parameters->mode = 0; + + /* No ROI */ + parameters->roi_compno = -1; + + /* No subsampling */ + parameters->subsampling_dx = 1; + parameters->subsampling_dy = 1; + + /* 9-7 transform */ + parameters->irreversible = 1; + + /* Number of layers */ + if (parameters->tcp_numlayers > 1){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n" + "1 single quality layer" + "-> Number of layers forced to 1 (rather than %d)\n", + parameters->tcp_numlayers); + parameters->tcp_numlayers = 1; + } + + /* Resolution levels */ + switch (parameters->cp_cinema){ + case OPJ_CINEMA2K_24: + case OPJ_CINEMA2K_48: + if(parameters->numresolution > 6){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 (2k dc profile) requires:\n" + "Number of decomposition levels <= 5\n" + "-> Number of decomposition levels forced to 5 (rather than %d)\n", + parameters->numresolution+1); + parameters->numresolution = 6; + } + break; + case OPJ_CINEMA4K_24: + if(parameters->numresolution < 2){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-4 (4k dc profile) requires:\n" + "Number of decomposition levels >= 1 && <= 6\n" + "-> Number of decomposition levels forced to 1 (rather than %d)\n", + parameters->numresolution+1); + parameters->numresolution = 1; + }else if(parameters->numresolution > 7){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-4 (4k dc profile) requires:\n" + "Number of decomposition levels >= 1 && <= 6\n" + "-> Number of decomposition levels forced to 6 (rather than %d)\n", + parameters->numresolution+1); + parameters->numresolution = 7; + } + break; + default : + break; + } + + /* Precincts */ + parameters->csty |= 0x01; + parameters->res_spec = parameters->numresolution-1; + for (i = 0; ires_spec; i++) { + parameters->prcw_init[i] = 256; + parameters->prch_init[i] = 256; + } + + /* The progression order shall be CPRL */ + parameters->prog_order = OPJ_CPRL; + + /* Progression order changes for 4K, disallowed for 2K */ + if (parameters->cp_cinema == OPJ_CINEMA4K_24) { + parameters->numpocs = (OPJ_UINT32)opj_j2k_initialise_4K_poc(parameters->POC,parameters->numresolution); + } else { + parameters->numpocs = 0; + } + + /* Limited bit-rate */ + parameters->cp_disto_alloc = 1; + switch (parameters->cp_cinema){ + case OPJ_CINEMA2K_24: + case OPJ_CINEMA4K_24: + max_rate = (OPJ_FLOAT32) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)/ + (OPJ_FLOAT32)(CINEMA_24_CS * 8 * image->comps[0].dx * image->comps[0].dy); + if (parameters->tcp_rates[0] == 0){ + parameters->tcp_rates[0] = max_rate; + }else{ + temp_rate =(OPJ_FLOAT32)(image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec)/ + (parameters->tcp_rates[0] * 8 * (OPJ_FLOAT32)image->comps[0].dx * (OPJ_FLOAT32)image->comps[0].dy); + if (temp_rate > CINEMA_24_CS ){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 and 4 (2k/4k dc profile) requires:\n" + "Maximum 1302083 compressed bytes @ 24fps\n" + "-> Specified rate (%3.1f) exceeds this limit. Rate will be forced to %3.1f.\n", + parameters->tcp_rates[0], max_rate); + parameters->tcp_rates[0]= max_rate; + }else{ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 and 4 (2k/4k dc profile):\n" + "INFO : Specified rate (%3.1f) is below the 2k/4k limit @ 24fps.\n", + parameters->tcp_rates[0]); + } + } + parameters->max_comp_size = COMP_24_CS; + break; + case OPJ_CINEMA2K_48: + max_rate = ((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ + (float)(CINEMA_48_CS * 8 * image->comps[0].dx * image->comps[0].dy); + if (parameters->tcp_rates[0] == 0){ + parameters->tcp_rates[0] = max_rate; + }else{ + temp_rate =((float) (image->numcomps * image->comps[0].w * image->comps[0].h * image->comps[0].prec))/ + (parameters->tcp_rates[0] * 8 * (float)image->comps[0].dx * (float)image->comps[0].dy); + if (temp_rate > CINEMA_48_CS ){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 (2k dc profile) requires:\n" + "Maximum 651041 compressed bytes @ 48fps\n" + "-> Specified rate (%3.1f) exceeds this limit. Rate will be forced to %3.1f.\n", + parameters->tcp_rates[0], max_rate); + parameters->tcp_rates[0]= max_rate; + }else{ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 (2k dc profile):\n" + "INFO : Specified rate (%3.1f) is below the 2k limit @ 48 fps.\n", + parameters->tcp_rates[0]); + } + } + parameters->max_comp_size = COMP_48_CS; + break; + default: + break; + } +} + +OPJ_BOOL opj_j2k_is_cinema_compliant(opj_image_t *image, OPJ_CINEMA_MODE cinema_mode, opj_event_mgr_t *p_manager) +{ + OPJ_UINT32 i; + + /* Number of components */ + if (image->numcomps != 3){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 (2k dc profile) requires:\n" + "3 components" + "-> Number of components of input image (%d) is not compliant\n" + "-> Non-profile-3 codestream will be generated\n", + image->numcomps); + return OPJ_FALSE; + } + + /* Bitdepth */ + for (i = 0; i < image->numcomps; i++) { + if ((image->comps[i].bpp != 12) | (image->comps[i].sgnd)){ + char signed_str[] = "signed"; + char unsigned_str[] = "unsigned"; + char *tmp_str = image->comps[i].sgnd?signed_str:unsigned_str; + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 (2k dc profile) requires:\n" + "Precision of each component shall be 12 bits unsigned" + "-> At least component %d of input image (%d bits, %s) is not compliant\n" + "-> Non-profile-3 codestream will be generated\n", + i,image->comps[i].bpp, tmp_str); + return OPJ_FALSE; + } + } + + /* Image size */ + switch (cinema_mode){ + case OPJ_CINEMA2K_24: + case OPJ_CINEMA2K_48: + if (((image->comps[0].w > 2048) | (image->comps[0].h > 1080))){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-3 (2k dc profile) requires:\n" + "width <= 2048 and height <= 1080\n" + "-> Input image size %d x %d is not compliant\n" + "-> Non-profile-3 codestream will be generated\n", + image->comps[0].w,image->comps[0].h); + return OPJ_FALSE; + } + break; + case OPJ_CINEMA4K_24: + if (((image->comps[0].w > 4096) | (image->comps[0].h > 2160))){ + opj_event_msg(p_manager, EVT_WARNING, + "JPEG 2000 Profile-4 (4k dc profile) requires:\n" + "width <= 4096 and height <= 2160\n" + "-> Image size %d x %d is not compliant\n" + "-> Non-profile-4 codestream will be generated\n", + image->comps[0].w,image->comps[0].h); + return OPJ_FALSE; + } + break; + default : + break; + } + + return OPJ_TRUE; +} + void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, opj_cparameters_t *parameters, opj_image_t *image, @@ -5768,30 +6174,38 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, cp->tw = 1; cp->th = 1; + /* set cinema parameters if required */ + if (parameters->cp_cinema){ + opj_j2k_set_cinema_parameters(parameters,image,p_manager); + if (!opj_j2k_is_cinema_compliant(image,parameters->cp_cinema,p_manager)) { + parameters->cp_rsiz = OPJ_STD_RSIZ; + } + } + /* copy user encoding parameters */ cp->m_specific_param.m_enc.m_cinema = parameters->cp_cinema; - cp->m_specific_param.m_enc.m_max_comp_size = parameters->max_comp_size; + cp->m_specific_param.m_enc.m_max_comp_size = (OPJ_UINT32)parameters->max_comp_size; cp->rsiz = parameters->cp_rsiz; - cp->m_specific_param.m_enc.m_disto_alloc = parameters->cp_disto_alloc; - cp->m_specific_param.m_enc.m_fixed_alloc = parameters->cp_fixed_alloc; - cp->m_specific_param.m_enc.m_fixed_quality = parameters->cp_fixed_quality; + cp->m_specific_param.m_enc.m_disto_alloc = (OPJ_UINT32)parameters->cp_disto_alloc & 1u; + cp->m_specific_param.m_enc.m_fixed_alloc = (OPJ_UINT32)parameters->cp_fixed_alloc & 1u; + cp->m_specific_param.m_enc.m_fixed_quality = (OPJ_UINT32)parameters->cp_fixed_quality & 1u; /* mod fixed_quality */ - if (parameters->cp_matrice) { - size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(OPJ_INT32); + if (parameters->cp_fixed_alloc && parameters->cp_matrice) { + size_t array_size = (size_t)parameters->tcp_numlayers * (size_t)parameters->numresolution * 3 * sizeof(OPJ_INT32); cp->m_specific_param.m_enc.m_matrice = (OPJ_INT32 *) opj_malloc(array_size); memcpy(cp->m_specific_param.m_enc.m_matrice, parameters->cp_matrice, array_size); } /* tiles */ - cp->tdx = parameters->cp_tdx; - cp->tdy = parameters->cp_tdy; + cp->tdx = (OPJ_UINT32)parameters->cp_tdx; + cp->tdy = (OPJ_UINT32)parameters->cp_tdy; /* tile offset */ - cp->tx0 = parameters->cp_tx0; - cp->ty0 = parameters->cp_ty0; + cp->tx0 = (OPJ_UINT32)parameters->cp_tx0; + cp->ty0 = (OPJ_UINT32)parameters->cp_ty0; /* comment string */ if(parameters->cp_comment) { @@ -5806,15 +6220,15 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, */ if (parameters->tile_size_on) { - cp->tw = opj_int_ceildiv(image->x1 - cp->tx0, cp->tdx); - cp->th = opj_int_ceildiv(image->y1 - cp->ty0, cp->tdy); + cp->tw = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(image->x1 - cp->tx0), (OPJ_INT32)cp->tdx); + cp->th = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)(image->y1 - cp->ty0), (OPJ_INT32)cp->tdy); } else { cp->tdx = image->x1 - cp->tx0; cp->tdy = image->y1 - cp->ty0; } if (parameters->tp_on) { - cp->m_specific_param.m_enc.m_tp_flag = parameters->tp_flag; + cp->m_specific_param.m_enc.m_tp_flag = (OPJ_BYTE)parameters->tp_flag; cp->m_specific_param.m_enc.m_tp_on = 1; } @@ -5879,13 +6293,13 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t)); if (parameters->numpocs) { /* initialisation of POC */ - opj_j2k_check_poc_val(parameters->POC,parameters->numpocs, parameters->numresolution, image->numcomps, parameters->tcp_numlayers, p_manager); + opj_j2k_check_poc_val(parameters->POC,parameters->numpocs, (OPJ_UINT32)parameters->numresolution, image->numcomps, (OPJ_UINT32)parameters->tcp_numlayers, p_manager); /* TODO MSD use the return value*/ } for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { opj_tcp_t *tcp = &cp->tcps[tileno]; - tcp->numlayers = parameters->tcp_numlayers; + tcp->numlayers = (OPJ_UINT32)parameters->tcp_numlayers; for (j = 0; j < tcp->numlayers; j++) { if(cp->m_specific_param.m_enc.m_cinema){ @@ -5902,9 +6316,9 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, } } - tcp->csty = parameters->csty; + tcp->csty = (OPJ_UINT32)parameters->csty; tcp->prg = parameters->prog_order; - tcp->mct = parameters->tcp_mct; + tcp->mct = (OPJ_UINT32)parameters->tcp_mct; numpocs_tile = 0; tcp->POC = 0; @@ -5937,7 +6351,7 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, if (parameters->mct_data) { - OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * sizeof(OPJ_FLOAT32); + OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * (OPJ_UINT32)sizeof(OPJ_FLOAT32); OPJ_FLOAT32 * lTmpBuf = (OPJ_FLOAT32*)opj_malloc(lMctSize); OPJ_INT32 * l_dc_shift = (OPJ_INT32 *) ((OPJ_BYTE *) parameters->mct_data + lMctSize); @@ -5977,10 +6391,10 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, opj_tccp_t *tccp = &tcp->tccps[i]; tccp->csty = parameters->csty & 0x01; /* 0 => one precinct || 1 => custom precinct */ - tccp->numresolutions = parameters->numresolution; - tccp->cblkw = opj_int_floorlog2(parameters->cblockw_init); - tccp->cblkh = opj_int_floorlog2(parameters->cblockh_init); - tccp->cblksty = parameters->mode; + tccp->numresolutions = (OPJ_UINT32)parameters->numresolution; + tccp->cblkw = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockw_init); + tccp->cblkh = (OPJ_UINT32)opj_int_floorlog2(parameters->cblockh_init); + tccp->cblksty = (OPJ_UINT32)parameters->mode; tccp->qmfbid = parameters->irreversible ? 0 : 1; tccp->qntsty = parameters->irreversible ? J2K_CCP_QNTSTY_SEQNT : J2K_CCP_QNTSTY_NOQNT; tccp->numgbits = 2; @@ -5991,31 +6405,22 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, tccp->roishift = 0; } - if(parameters->cp_cinema) { - /*Precinct size for lowest frequency subband=128*/ - tccp->prcw[0] = 7; - tccp->prch[0] = 7; - /*Precinct size at all other resolutions = 256*/ - for (j = 1; j < tccp->numresolutions; j++) { - tccp->prcw[j] = 8; - tccp->prch[j] = 8; - } - }else{ if (parameters->csty & J2K_CCP_CSTY_PRT) { OPJ_INT32 p = 0, it_res; - for (it_res = tccp->numresolutions - 1; it_res >= 0; it_res--) { + assert( tccp->numresolutions > 0 ); + for (it_res = (OPJ_INT32)tccp->numresolutions - 1; it_res >= 0; it_res--) { if (p < parameters->res_spec) { if (parameters->prcw_init[p] < 1) { tccp->prcw[it_res] = 1; } else { - tccp->prcw[it_res] = opj_int_floorlog2(parameters->prcw_init[p]); + tccp->prcw[it_res] = (OPJ_UINT32)opj_int_floorlog2(parameters->prcw_init[p]); } if (parameters->prch_init[p] < 1) { tccp->prch[it_res] = 1; }else { - tccp->prch[it_res] = opj_int_floorlog2(parameters->prch_init[p]); + tccp->prch[it_res] = (OPJ_UINT32)opj_int_floorlog2(parameters->prch_init[p]); } } else { @@ -6031,13 +6436,13 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, if (size_prcw < 1) { tccp->prcw[it_res] = 1; } else { - tccp->prcw[it_res] = opj_int_floorlog2(size_prcw); + tccp->prcw[it_res] = (OPJ_UINT32)opj_int_floorlog2(size_prcw); } if (size_prch < 1) { tccp->prch[it_res] = 1; } else { - tccp->prch[it_res] = opj_int_floorlog2(size_prch); + tccp->prch[it_res] = (OPJ_UINT32)opj_int_floorlog2(size_prch); } } p++; @@ -6049,7 +6454,6 @@ void opj_j2k_setup_encoder( opj_j2k_t *p_j2k, tccp->prch[j] = 15; } } - } opj_dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec); } @@ -6068,7 +6472,7 @@ static OPJ_BOOL opj_j2k_add_mhmarker(opj_codestream_index_t *cstr_index, OPJ_UIN /* expand the list? */ if ((cstr_index->marknum + 1) > cstr_index->maxmarknum) { opj_marker_info_t *new_marker; - cstr_index->maxmarknum = 100 + (OPJ_INT32) ((OPJ_FLOAT32) cstr_index->maxmarknum * 1.0F); + cstr_index->maxmarknum = (OPJ_UINT32)(100 + (OPJ_FLOAT32) cstr_index->maxmarknum); new_marker = (opj_marker_info_t *) opj_realloc(cstr_index->marker, cstr_index->maxmarknum *sizeof(opj_marker_info_t)); if (! new_marker) { opj_free(cstr_index->marker); @@ -6097,7 +6501,7 @@ static OPJ_BOOL opj_j2k_add_tlmarker(OPJ_UINT32 tileno, opj_codestream_index_t * /* expand the list? */ if ((cstr_index->tile_index[tileno].marknum + 1) > cstr_index->tile_index[tileno].maxmarknum) { opj_marker_info_t *new_marker; - cstr_index->tile_index[tileno].maxmarknum = 100 + (OPJ_INT32) ((OPJ_FLOAT32) cstr_index->tile_index[tileno].maxmarknum * 1.0F); + cstr_index->tile_index[tileno].maxmarknum = (OPJ_UINT32)(100 + (OPJ_FLOAT32) cstr_index->tile_index[tileno].maxmarknum); new_marker = (opj_marker_info_t *) opj_realloc( cstr_index->tile_index[tileno].marker, cstr_index->tile_index[tileno].maxmarknum *sizeof(opj_marker_info_t)); @@ -6679,9 +7083,9 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2 l_image = p_j2k->m_private_image; l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; l_tcp = p_j2k->m_cp.tcps; - l_tccp_size = l_image->numcomps * sizeof(opj_tccp_t); + l_tccp_size = l_image->numcomps * (OPJ_UINT32)sizeof(opj_tccp_t); l_default_tcp = p_j2k->m_specific_param.m_decoder.m_default_tcp; - l_mct_size = l_image->numcomps * l_image->numcomps * sizeof(OPJ_FLOAT32); + l_mct_size = l_image->numcomps * l_image->numcomps * (OPJ_UINT32)sizeof(OPJ_FLOAT32); /* For each tile */ for (i=0; im_nb_max_mct_records * sizeof(opj_mct_data_t); + l_mct_records_size = l_default_tcp->m_nb_max_mct_records * (OPJ_UINT32)sizeof(opj_mct_data_t); l_tcp->m_mct_records = (opj_mct_data_t*)opj_malloc(l_mct_records_size); if (! l_tcp->m_mct_records) { return OPJ_FALSE; @@ -6732,7 +7136,7 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2 } /* Get the mcc_record of the dflt_tile_cp and copy them into the current tile cp*/ - l_mcc_records_size = l_default_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t); + l_mcc_records_size = l_default_tcp->m_nb_max_mcc_records * (OPJ_UINT32)sizeof(opj_simple_mcc_decorrelation_data_t); l_tcp->m_mcc_records = (opj_simple_mcc_decorrelation_data_t*) opj_malloc(l_mcc_records_size); if (! l_tcp->m_mcc_records) { return OPJ_FALSE; @@ -6746,12 +7150,12 @@ static OPJ_BOOL opj_j2k_copy_default_tcp_and_create_tcd ( opj_j2k_t * p_j2 for (j=0;jm_nb_max_mcc_records;++j) { if (l_src_mcc_rec->m_decorrelation_array) { - l_offset = l_src_mcc_rec->m_decorrelation_array - l_default_tcp->m_mct_records; + l_offset = (OPJ_UINT32)(l_src_mcc_rec->m_decorrelation_array - l_default_tcp->m_mct_records); l_dest_mcc_rec->m_decorrelation_array = l_tcp->m_mct_records + l_offset; } if (l_src_mcc_rec->m_offset_array) { - l_offset = l_src_mcc_rec->m_offset_array - l_default_tcp->m_mct_records; + l_offset = (OPJ_UINT32)(l_src_mcc_rec->m_offset_array - l_default_tcp->m_mct_records); l_dest_mcc_rec->m_offset_array = l_tcp->m_mct_records + l_offset; } @@ -7033,6 +7437,12 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k, /* Try to read until the Start Of Data is detected */ while (l_current_marker != J2K_MS_SOD) { + + if(opj_stream_get_number_byte_left(p_stream) == 0) + { + p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC; + break; + } /* Try to read 2 bytes (the marker size) from stream and copy them into the buffer */ if (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) { @@ -7043,6 +7453,12 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k, /* Read 2 bytes from the buffer as the marker size */ opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2); + /* cf. https://code.google.com/p/openjpeg/issues/detail?id=226 */ + if (l_current_marker == 0x8080 && opj_stream_get_number_byte_left(p_stream) == 0) { + p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC; + break; + } + /* Why this condition? FIXME */ if (p_j2k->m_specific_param.m_decoder.m_state & J2K_STATE_TPH){ p_j2k->m_specific_param.m_decoder.m_sot_length -= (l_marker_size + 2); @@ -7127,6 +7543,9 @@ OPJ_BOOL opj_j2k_read_tile_header( opj_j2k_t * p_j2k, opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2); } } + if(opj_stream_get_number_byte_left(p_stream) == 0 + && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) + break; /* If we didn't skip data before, we need to read the SOD marker*/ if (! p_j2k->m_specific_param.m_decoder.m_skip_data) { @@ -7244,6 +7663,7 @@ OPJ_BOOL opj_j2k_decode_tile ( opj_j2k_t * p_j2k, p_j2k->cstr_index) ) { opj_j2k_tcp_destroy(l_tcp); p_j2k->m_specific_param.m_decoder.m_state |= 0x8000;/*FIXME J2K_DEC_STATE_ERR;*/ + opj_event_msg(p_manager, EVT_ERROR, "Failed to decode.\n"); return OPJ_FALSE; } @@ -7258,7 +7678,12 @@ OPJ_BOOL opj_j2k_decode_tile ( opj_j2k_t * p_j2k, opj_j2k_tcp_data_destroy(l_tcp); p_j2k->m_specific_param.m_decoder.m_can_decode = 0; - p_j2k->m_specific_param.m_decoder.m_state &= (~ (0x0080));/* FIXME J2K_DEC_STATE_DATA);*/ + p_j2k->m_specific_param.m_decoder.m_state &= (~ (0x0080u));/* FIXME J2K_DEC_STATE_DATA);*/ + + if(opj_stream_get_number_byte_left(p_stream) == 0 + && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC){ + return OPJ_TRUE; + } if (p_j2k->m_specific_param.m_decoder.m_state != 0x0100){ /*FIXME J2K_DEC_STATE_EOC)*/ if (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) { @@ -7275,6 +7700,11 @@ OPJ_BOOL opj_j2k_decode_tile ( opj_j2k_t * p_j2k, else if (l_current_marker != J2K_MS_SOT) { opj_event_msg(p_manager, EVT_ERROR, "Stream too short, expected SOT\n"); + + if(opj_stream_get_number_byte_left(p_stream) == 0) { + p_j2k->m_specific_param.m_decoder.m_state = J2K_STATE_NEOC; + return OPJ_TRUE; + } return OPJ_FALSE; } } @@ -7343,12 +7773,12 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im l_res->x0, l_res->x1, l_res->y0, l_res->y1); }*/ - l_width_src = (l_res->x1 - l_res->x0); - l_height_src = (l_res->y1 - l_res->y0); + l_width_src = (OPJ_UINT32)(l_res->x1 - l_res->x0); + l_height_src = (OPJ_UINT32)(l_res->y1 - l_res->y0); /* Border of the current output component*/ - l_x0_dest = opj_int_ceildivpow2(l_img_comp_dest->x0, l_img_comp_dest->factor); - l_y0_dest = opj_int_ceildivpow2(l_img_comp_dest->y0, l_img_comp_dest->factor); + l_x0_dest = (OPJ_UINT32)opj_int_ceildivpow2((OPJ_INT32)l_img_comp_dest->x0, (OPJ_INT32)l_img_comp_dest->factor); + l_y0_dest = (OPJ_UINT32)opj_int_ceildivpow2((OPJ_INT32)l_img_comp_dest->y0, (OPJ_INT32)l_img_comp_dest->factor); l_x1_dest = l_x0_dest + l_img_comp_dest->w; l_y1_dest = l_y0_dest + l_img_comp_dest->h; @@ -7367,7 +7797,7 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im assert( l_res->x0 >= 0); assert( l_res->x1 >= 0); if ( l_x0_dest < (OPJ_UINT32)l_res->x0 ) { - l_start_x_dest = l_res->x0 - l_x0_dest; + l_start_x_dest = (OPJ_UINT32)l_res->x0 - l_x0_dest; l_offset_x0_src = 0; if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) { @@ -7375,26 +7805,26 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im l_offset_x1_src = 0; } else { - l_width_dest = l_x1_dest - l_res->x0 ; - l_offset_x1_src = l_width_src - l_width_dest; + l_width_dest = l_x1_dest - (OPJ_UINT32)l_res->x0 ; + l_offset_x1_src = (OPJ_INT32)(l_width_src - l_width_dest); } } else { l_start_x_dest = 0 ; - l_offset_x0_src = l_x0_dest - l_res->x0; + l_offset_x0_src = (OPJ_INT32)l_x0_dest - l_res->x0; if ( l_x1_dest >= (OPJ_UINT32)l_res->x1 ) { - l_width_dest = l_width_src - l_offset_x0_src; + l_width_dest = l_width_src - (OPJ_UINT32)l_offset_x0_src; l_offset_x1_src = 0; } else { l_width_dest = l_img_comp_dest->w ; - l_offset_x1_src = l_res->x1 - l_x1_dest; + l_offset_x1_src = l_res->x1 - (OPJ_INT32)l_x1_dest; } } if ( l_y0_dest < (OPJ_UINT32)l_res->y0 ) { - l_start_y_dest = l_res->y0 - l_y0_dest; + l_start_y_dest = (OPJ_UINT32)l_res->y0 - l_y0_dest; l_offset_y0_src = 0; if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) { @@ -7402,37 +7832,41 @@ OPJ_BOOL opj_j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data, opj_im l_offset_y1_src = 0; } else { - l_height_dest = l_y1_dest - l_res->y0 ; - l_offset_y1_src = l_height_src - l_height_dest; + l_height_dest = l_y1_dest - (OPJ_UINT32)l_res->y0 ; + l_offset_y1_src = (OPJ_INT32)(l_height_src - l_height_dest); } } else { l_start_y_dest = 0 ; - l_offset_y0_src = l_y0_dest - l_res->y0; + l_offset_y0_src = (OPJ_INT32)l_y0_dest - l_res->y0; if ( l_y1_dest >= (OPJ_UINT32)l_res->y1 ) { - l_height_dest = l_height_src - l_offset_y0_src; + l_height_dest = l_height_src - (OPJ_UINT32)l_offset_y0_src; l_offset_y1_src = 0; } else { l_height_dest = l_img_comp_dest->h ; - l_offset_y1_src = l_res->y1 - l_y1_dest; + l_offset_y1_src = l_res->y1 - (OPJ_INT32)l_y1_dest; } } if( (l_offset_x0_src < 0 ) || (l_offset_y0_src < 0 ) || (l_offset_x1_src < 0 ) || (l_offset_y1_src < 0 ) ){ return OPJ_FALSE; } + /* testcase 2977.pdf.asan.67.2198 */ + if ((OPJ_INT32)l_width_dest < 0 || (OPJ_INT32)l_height_dest < 0) { + return OPJ_FALSE; + } /*-----*/ /* Compute the input buffer offset */ - l_start_offset_src = l_offset_x0_src + l_offset_y0_src * l_width_src; + l_start_offset_src = l_offset_x0_src + l_offset_y0_src * (OPJ_INT32)l_width_src; l_line_offset_src = l_offset_x1_src + l_offset_x0_src; - l_end_offset_src = l_offset_y1_src * l_width_src - l_offset_x0_src; + l_end_offset_src = l_offset_y1_src * (OPJ_INT32)l_width_src - l_offset_x0_src; /* Compute the output buffer offset */ - l_start_offset_dest = l_start_x_dest + l_start_y_dest * l_img_comp_dest->w; - l_line_offset_dest = l_img_comp_dest->w - l_width_dest; + l_start_offset_dest = (OPJ_INT32)(l_start_x_dest + l_start_y_dest * l_img_comp_dest->w); + l_line_offset_dest = (OPJ_INT32)(l_img_comp_dest->w - l_width_dest); /* Move the output buffer to the first place where we will write*/ l_dest_ptr = l_img_comp_dest->data + l_start_offset_dest; @@ -7591,8 +8025,8 @@ OPJ_BOOL opj_j2k_set_decode_area( opj_j2k_t *p_j2k, p_image->x0 = l_image->x0; } else { - p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_start_x - l_cp->tx0) / l_cp->tdx; - p_image->x0 = p_start_x; + p_j2k->m_specific_param.m_decoder.m_start_tile_x = ((OPJ_UINT32)p_start_x - l_cp->tx0) / l_cp->tdx; + p_image->x0 = (OPJ_UINT32)p_start_x; } /* Up */ @@ -7610,8 +8044,8 @@ OPJ_BOOL opj_j2k_set_decode_area( opj_j2k_t *p_j2k, p_image->y0 = l_image->y0; } else { - p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_start_y - l_cp->ty0) / l_cp->tdy; - p_image->y0 = p_start_y; + p_j2k->m_specific_param.m_decoder.m_start_tile_y = ((OPJ_UINT32)p_start_y - l_cp->ty0) / l_cp->tdy; + p_image->y0 = (OPJ_UINT32)p_start_y; } /* Right */ @@ -7631,8 +8065,8 @@ OPJ_BOOL opj_j2k_set_decode_area( opj_j2k_t *p_j2k, p_image->x1 = l_image->x1; } else { - p_j2k->m_specific_param.m_decoder.m_end_tile_x = opj_int_ceildiv((p_end_x - l_cp->tx0), l_cp->tdx); - p_image->x1 = p_end_x; + p_j2k->m_specific_param.m_decoder.m_end_tile_x = (OPJ_UINT32)opj_int_ceildiv(p_end_x - (OPJ_INT32)l_cp->tx0, (OPJ_INT32)l_cp->tdx); + p_image->x1 = (OPJ_UINT32)p_end_x; } /* Bottom */ @@ -7650,8 +8084,8 @@ OPJ_BOOL opj_j2k_set_decode_area( opj_j2k_t *p_j2k, p_image->y1 = l_image->y1; } else{ - p_j2k->m_specific_param.m_decoder.m_end_tile_y = opj_int_ceildiv((p_end_y - l_cp->ty0), l_cp->tdy); - p_image->y1 = p_end_y; + p_j2k->m_specific_param.m_decoder.m_end_tile_y = (OPJ_UINT32)opj_int_ceildiv(p_end_y - (OPJ_INT32)l_cp->ty0, (OPJ_INT32)l_cp->tdy); + p_image->y1 = (OPJ_UINT32)p_end_y; } /* ----- */ @@ -7662,30 +8096,30 @@ OPJ_BOOL opj_j2k_set_decode_area( opj_j2k_t *p_j2k, { OPJ_INT32 l_h,l_w; - l_img_comp->x0 = opj_int_ceildiv(p_image->x0, l_img_comp->dx); - l_img_comp->y0 = opj_int_ceildiv(p_image->y0, l_img_comp->dy); - l_comp_x1 = opj_int_ceildiv(p_image->x1, l_img_comp->dx); - l_comp_y1 = opj_int_ceildiv(p_image->y1, l_img_comp->dy); + l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0, (OPJ_INT32)l_img_comp->dx); + l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0, (OPJ_INT32)l_img_comp->dy); + l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx); + l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy); - l_w = opj_int_ceildivpow2(l_comp_x1, l_img_comp->factor) - - opj_int_ceildivpow2(l_img_comp->x0, l_img_comp->factor); + l_w = opj_int_ceildivpow2(l_comp_x1, (OPJ_INT32)l_img_comp->factor) + - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->x0, (OPJ_INT32)l_img_comp->factor); if (l_w < 0){ opj_event_msg(p_manager, EVT_ERROR, "Size x of the decoded component image is incorrect (comp[%d].w=%d).\n", it_comp, l_w); return OPJ_FALSE; } - l_img_comp->w = l_w; + l_img_comp->w = (OPJ_UINT32)l_w; - l_h = opj_int_ceildivpow2(l_comp_y1, l_img_comp->factor) - - opj_int_ceildivpow2(l_img_comp->y0, l_img_comp->factor); + l_h = opj_int_ceildivpow2(l_comp_y1, (OPJ_INT32)l_img_comp->factor) + - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->y0, (OPJ_INT32)l_img_comp->factor); if (l_h < 0){ opj_event_msg(p_manager, EVT_ERROR, "Size y of the decoded component image is incorrect (comp[%d].h=%d).\n", it_comp, l_h); return OPJ_FALSE; } - l_img_comp->h = l_h; + l_img_comp->h = (OPJ_UINT32)l_h; l_img_comp++; } @@ -7998,7 +8432,7 @@ void opj_j2k_copy_tile_component_parameters( opj_j2k_t *p_j2k ) l_ref_tccp = &l_tcp->tccps[0]; l_copied_tccp = l_ref_tccp + 1; - l_prc_size = l_ref_tccp->numresolutions * sizeof(OPJ_UINT32); + l_prc_size = l_ref_tccp->numresolutions * (OPJ_UINT32)sizeof(OPJ_UINT32); for (i=1; im_private_image->numcomps; ++i) { l_copied_tccp->numresolutions = l_ref_tccp->numresolutions; @@ -8086,7 +8520,7 @@ OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k, ++p_data; for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) { - l_expn = l_tccp->stepsizes[l_band_no].expn; + l_expn = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].expn; opj_write_bytes(p_data, l_expn << 3, 1); /* SPqcx_i */ ++p_data; } @@ -8103,8 +8537,8 @@ OPJ_BOOL opj_j2k_write_SQcd_SQcc( opj_j2k_t *p_j2k, ++p_data; for (l_band_no = 0; l_band_no < l_num_bands; ++l_band_no) { - l_expn = l_tccp->stepsizes[l_band_no].expn; - l_mant = l_tccp->stepsizes[l_band_no].mant; + l_expn = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].expn; + l_mant = (OPJ_UINT32)l_tccp->stepsizes[l_band_no].mant; opj_write_bytes(p_data, (l_expn << 11) + l_mant, 2); /* SPqcx_i */ p_data += 2; @@ -8202,7 +8636,7 @@ OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k, opj_read_bytes(l_current_ptr, &l_tmp ,1); /* SPqcx_i */ ++l_current_ptr; if (l_band_no < OPJ_J2K_MAXBANDS){ - l_tccp->stepsizes[l_band_no].expn = l_tmp>>3; + l_tccp->stepsizes[l_band_no].expn = (OPJ_INT32)(l_tmp >> 3); l_tccp->stepsizes[l_band_no].mant = 0; } } @@ -8213,7 +8647,7 @@ OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k, opj_read_bytes(l_current_ptr, &l_tmp ,2); /* SPqcx_i */ l_current_ptr+=2; if (l_band_no < OPJ_J2K_MAXBANDS){ - l_tccp->stepsizes[l_band_no].expn = l_tmp >> 11; + l_tccp->stepsizes[l_band_no].expn = (OPJ_INT32)(l_tmp >> 11); l_tccp->stepsizes[l_band_no].mant = l_tmp & 0x7ff; } } @@ -8224,8 +8658,8 @@ OPJ_BOOL opj_j2k_read_SQcd_SQcc(opj_j2k_t *p_j2k, if (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) { for (l_band_no = 1; l_band_no < OPJ_J2K_MAXBANDS; l_band_no++) { l_tccp->stepsizes[l_band_no].expn = - ((l_tccp->stepsizes[0].expn) - ((l_band_no - 1) / 3) > 0) ? - (l_tccp->stepsizes[0].expn) - ((l_band_no - 1) / 3) : 0; + ((OPJ_INT32)(l_tccp->stepsizes[0].expn) - (OPJ_INT32)((l_band_no - 1) / 3) > 0) ? + (OPJ_INT32)(l_tccp->stepsizes[0].expn) - (OPJ_INT32)((l_band_no - 1) / 3) : 0; l_tccp->stepsizes[l_band_no].mant = l_tccp->stepsizes[0].mant; } } @@ -8262,6 +8696,58 @@ void opj_j2k_copy_tile_quantization_parameters( opj_j2k_t *p_j2k ) } } +static void opj_j2k_dump_tile_info( opj_tcp_t * l_default_tile,OPJ_INT32 numcomps,FILE* out_stream) +{ + if (l_default_tile) + { + OPJ_INT32 compno; + + fprintf(out_stream, "\t default tile {\n"); + fprintf(out_stream, "\t\t csty=%#x\n", l_default_tile->csty); + fprintf(out_stream, "\t\t prg=%#x\n", l_default_tile->prg); + fprintf(out_stream, "\t\t numlayers=%d\n", l_default_tile->numlayers); + fprintf(out_stream, "\t\t mct=%x\n", l_default_tile->mct); + + for (compno = 0; compno < numcomps; compno++) { + opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]); + OPJ_UINT32 resno; + OPJ_INT32 bandno, numbands; + + /* coding style*/ + fprintf(out_stream, "\t\t comp %d {\n", compno); + fprintf(out_stream, "\t\t\t csty=%#x\n", l_tccp->csty); + fprintf(out_stream, "\t\t\t numresolutions=%d\n", l_tccp->numresolutions); + fprintf(out_stream, "\t\t\t cblkw=2^%d\n", l_tccp->cblkw); + fprintf(out_stream, "\t\t\t cblkh=2^%d\n", l_tccp->cblkh); + fprintf(out_stream, "\t\t\t cblksty=%#x\n", l_tccp->cblksty); + fprintf(out_stream, "\t\t\t qmfbid=%d\n", l_tccp->qmfbid); + + fprintf(out_stream, "\t\t\t preccintsize (w,h)="); + for (resno = 0; resno < l_tccp->numresolutions; resno++) { + fprintf(out_stream, "(%d,%d) ", l_tccp->prcw[resno], l_tccp->prch[resno]); + } + fprintf(out_stream, "\n"); + + /* quantization style*/ + fprintf(out_stream, "\t\t\t qntsty=%d\n", l_tccp->qntsty); + fprintf(out_stream, "\t\t\t numgbits=%d\n", l_tccp->numgbits); + fprintf(out_stream, "\t\t\t stepsizes (m,e)="); + numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (OPJ_INT32)l_tccp->numresolutions * 3 - 2; + for (bandno = 0; bandno < numbands; bandno++) { + fprintf(out_stream, "(%d,%d) ", l_tccp->stepsizes[bandno].mant, + l_tccp->stepsizes[bandno].expn); + } + fprintf(out_stream, "\n"); + + /* RGN value*/ + fprintf(out_stream, "\t\t\t roishift=%d\n", l_tccp->roishift); + + fprintf(out_stream, "\t\t }\n"); + } /*end of component of default tile*/ + fprintf(out_stream, "\t }\n"); /*end of default tile*/ + } +} + void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream) { /* Check if the flag is compatible with j2k file*/ @@ -8280,6 +8766,16 @@ void j2k_dump (opj_j2k_t* p_j2k, OPJ_INT32 flag, FILE* out_stream) if (flag & OPJ_J2K_MH_INFO){ opj_j2k_dump_MH_info(p_j2k, out_stream); } + /* Dump all tile/codestream info */ + if (flag & OPJ_J2K_TCH_INFO){ + OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; + OPJ_UINT32 i; + opj_tcp_t * l_tcp = p_j2k->m_cp.tcps; + for (i=0;im_private_image->numcomps, out_stream); + ++l_tcp; + } + } /* Dump the codestream info of the current tile */ if (flag & OPJ_J2K_TH_INFO){ @@ -8366,70 +8862,17 @@ void opj_j2k_dump_MH_index(opj_j2k_t* p_j2k, FILE* out_stream) } + void opj_j2k_dump_MH_info(opj_j2k_t* p_j2k, FILE* out_stream) { - opj_tcp_t * l_default_tile=NULL; fprintf(out_stream, "Codestream info from main header: {\n"); fprintf(out_stream, "\t tx0=%d, ty0=%d\n", p_j2k->m_cp.tx0, p_j2k->m_cp.ty0); fprintf(out_stream, "\t tdx=%d, tdy=%d\n", p_j2k->m_cp.tdx, p_j2k->m_cp.tdy); fprintf(out_stream, "\t tw=%d, th=%d\n", p_j2k->m_cp.tw, p_j2k->m_cp.th); - - l_default_tile = p_j2k->m_specific_param.m_decoder.m_default_tcp; - if (l_default_tile) - { - OPJ_INT32 compno; - OPJ_INT32 numcomps = p_j2k->m_private_image->numcomps; - - fprintf(out_stream, "\t default tile {\n"); - fprintf(out_stream, "\t\t csty=%#x\n", l_default_tile->csty); - fprintf(out_stream, "\t\t prg=%#x\n", l_default_tile->prg); - fprintf(out_stream, "\t\t numlayers=%d\n", l_default_tile->numlayers); - fprintf(out_stream, "\t\t mct=%x\n", l_default_tile->mct); - - for (compno = 0; compno < numcomps; compno++) { - opj_tccp_t *l_tccp = &(l_default_tile->tccps[compno]); - OPJ_UINT32 resno; - OPJ_INT32 bandno, numbands; - - /* coding style*/ - fprintf(out_stream, "\t\t comp %d {\n", compno); - fprintf(out_stream, "\t\t\t csty=%#x\n", l_tccp->csty); - fprintf(out_stream, "\t\t\t numresolutions=%d\n", l_tccp->numresolutions); - fprintf(out_stream, "\t\t\t cblkw=2^%d\n", l_tccp->cblkw); - fprintf(out_stream, "\t\t\t cblkh=2^%d\n", l_tccp->cblkh); - fprintf(out_stream, "\t\t\t cblksty=%#x\n", l_tccp->cblksty); - fprintf(out_stream, "\t\t\t qmfbid=%d\n", l_tccp->qmfbid); - - fprintf(out_stream, "\t\t\t preccintsize (w,h)="); - for (resno = 0; resno < l_tccp->numresolutions; resno++) { - fprintf(out_stream, "(%d,%d) ", l_tccp->prcw[resno], l_tccp->prch[resno]); - } - fprintf(out_stream, "\n"); - - /* quantization style*/ - fprintf(out_stream, "\t\t\t qntsty=%d\n", l_tccp->qntsty); - fprintf(out_stream, "\t\t\t numgbits=%d\n", l_tccp->numgbits); - fprintf(out_stream, "\t\t\t stepsizes (m,e)="); - numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : l_tccp->numresolutions * 3 - 2; - for (bandno = 0; bandno < numbands; bandno++) { - fprintf(out_stream, "(%d,%d) ", l_tccp->stepsizes[bandno].mant, - l_tccp->stepsizes[bandno].expn); - } - fprintf(out_stream, "\n"); - - /* RGN value*/ - fprintf(out_stream, "\t\t\t roishift=%d\n", l_tccp->roishift); - - fprintf(out_stream, "\t\t }\n"); - } /*end of component of default tile*/ - fprintf(out_stream, "\t }\n"); /*end of default tile*/ - - } - + opj_j2k_dump_tile_info(p_j2k->m_specific_param.m_decoder.m_default_tcp,(OPJ_INT32)p_j2k->m_private_image->numcomps, out_stream); fprintf(out_stream, "}\n"); - } void j2k_dump_image_header(opj_image_t* img_header, OPJ_BOOL dev_dump_flag, FILE* out_stream) @@ -8536,11 +8979,11 @@ opj_codestream_info_v2_t* j2k_get_cstr_info(opj_j2k_t* p_j2k) l_tccp_info->qntsty = l_tccp->qntsty; l_tccp_info->numgbits = l_tccp->numgbits; - numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : l_tccp->numresolutions * 3 - 2; + numbands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (OPJ_INT32)l_tccp->numresolutions * 3 - 2; if (numbands < OPJ_J2K_MAXBANDS) { for (bandno = 0; bandno < numbands; bandno++) { - l_tccp_info->stepsizes_mant[bandno] = l_tccp->stepsizes[bandno].mant; - l_tccp_info->stepsizes_expn[bandno] = l_tccp->stepsizes[bandno].expn; + l_tccp_info->stepsizes_mant[bandno] = (OPJ_UINT32)l_tccp->stepsizes[bandno].mant; + l_tccp_info->stepsizes_expn[bandno] = (OPJ_UINT32)l_tccp->stepsizes[bandno].expn; } } @@ -8691,6 +9134,7 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k, OPJ_INT32 l_tile_x0,l_tile_y0,l_tile_x1,l_tile_y1; OPJ_UINT32 l_nb_comps; OPJ_BYTE * l_current_data; + OPJ_UINT32 nr_tiles = 0; l_current_data = (OPJ_BYTE*)opj_malloc(1000); if (! l_current_data) { @@ -8730,6 +9174,7 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k, if (! opj_j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) { opj_free(l_current_data); + opj_event_msg(p_manager, EVT_ERROR, "Failed to decode tile %d/%d\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw); return OPJ_FALSE; } opj_event_msg(p_manager, EVT_INFO, "Tile %d/%d has been decoded.\n", l_current_tile_no +1, p_j2k->m_cp.th * p_j2k->m_cp.tw); @@ -8739,7 +9184,12 @@ OPJ_BOOL opj_j2k_decode_tiles ( opj_j2k_t *p_j2k, return OPJ_FALSE; } opj_event_msg(p_manager, EVT_INFO, "Image data has been updated with tile %d.\n\n", l_current_tile_no + 1); - + + if(opj_stream_get_number_byte_left(p_stream) == 0 + && p_j2k->m_specific_param.m_decoder.m_state == J2K_STATE_NEOC) + break; + if(++nr_tiles == p_j2k->m_cp.th * p_j2k->m_cp.tw) + break; } opj_free(l_current_data); @@ -8791,7 +9241,7 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, } } /* Move into the codestream to the first SOT used to decode the desired tile */ - l_tile_no_to_dec = p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec; + l_tile_no_to_dec = (OPJ_UINT32)p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec; if (p_j2k->cstr_index->tile_index) if(p_j2k->cstr_index->tile_index->tp_index) { @@ -8800,12 +9250,14 @@ static OPJ_BOOL opj_j2k_decode_one_tile ( opj_j2k_t *p_j2k, * so move to the last SOT read */ if ( !(opj_stream_read_seek(p_stream, p_j2k->m_specific_param.m_decoder.m_last_sot_read_pos+2, p_manager)) ){ opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); + opj_free(l_current_data); return OPJ_FALSE; } } else{ if ( !(opj_stream_read_seek(p_stream, p_j2k->cstr_index->tile_index[l_tile_no_to_dec].tp_index[0].start_pos+2, p_manager)) ) { opj_event_msg(p_manager, EVT_ERROR, "Problem with seek function\n"); + opj_free(l_current_data); return OPJ_FALSE; } } @@ -8921,6 +9373,13 @@ OPJ_BOOL opj_j2k_decode(opj_j2k_t * p_j2k, for (compno = 0; compno < p_image->numcomps; compno++) { p_image->comps[compno].resno_decoded = p_j2k->m_output_image->comps[compno].resno_decoded; p_image->comps[compno].data = p_j2k->m_output_image->comps[compno].data; +#if 0 + char fn[256]; + sprintf( fn, "/tmp/%d.raw", compno ); + FILE *debug = fopen( fn, "wb" ); + fwrite( p_image->comps[compno].data, sizeof(OPJ_INT32), p_image->comps[compno].w * p_image->comps[compno].h, debug ); + fclose( debug ); +#endif p_j2k->m_output_image->comps[compno].data = NULL; } @@ -8972,13 +9431,13 @@ OPJ_BOOL opj_j2k_get_tile( opj_j2k_t *p_j2k, l_img_comp->factor = p_j2k->m_private_image->comps[compno].factor; - l_img_comp->x0 = opj_int_ceildiv(p_image->x0, l_img_comp->dx); - l_img_comp->y0 = opj_int_ceildiv(p_image->y0, l_img_comp->dy); - l_comp_x1 = opj_int_ceildiv(p_image->x1, l_img_comp->dx); - l_comp_y1 = opj_int_ceildiv(p_image->y1, l_img_comp->dy); + l_img_comp->x0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->x0, (OPJ_INT32)l_img_comp->dx); + l_img_comp->y0 = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)p_image->y0, (OPJ_INT32)l_img_comp->dy); + l_comp_x1 = opj_int_ceildiv((OPJ_INT32)p_image->x1, (OPJ_INT32)l_img_comp->dx); + l_comp_y1 = opj_int_ceildiv((OPJ_INT32)p_image->y1, (OPJ_INT32)l_img_comp->dy); - l_img_comp->w = opj_int_ceildivpow2(l_comp_x1, l_img_comp->factor) - opj_int_ceildivpow2(l_img_comp->x0, l_img_comp->factor); - l_img_comp->h = opj_int_ceildivpow2(l_comp_y1, l_img_comp->factor) - opj_int_ceildivpow2(l_img_comp->y0, l_img_comp->factor); + l_img_comp->w = (OPJ_UINT32)(opj_int_ceildivpow2(l_comp_x1, (OPJ_INT32)l_img_comp->factor) - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->x0, (OPJ_INT32)l_img_comp->factor)); + l_img_comp->h = (OPJ_UINT32)(opj_int_ceildivpow2(l_comp_y1, (OPJ_INT32)l_img_comp->factor) - opj_int_ceildivpow2((OPJ_INT32)l_img_comp->y0, (OPJ_INT32)l_img_comp->factor)); l_img_comp++; } @@ -8994,7 +9453,7 @@ OPJ_BOOL opj_j2k_get_tile( opj_j2k_t *p_j2k, } opj_copy_image_header(p_image, p_j2k->m_output_image); - p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = tile_index; + p_j2k->m_specific_param.m_decoder.m_tile_ind_to_dec = (OPJ_INT32)tile_index; /* customization of the decoding */ opj_j2k_setup_decoding_tile(p_j2k); @@ -9209,13 +9668,13 @@ void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) l_size_comp = 4; } - l_width = (l_tilec->x1 - l_tilec->x0); - l_height = (l_tilec->y1 - l_tilec->y0); - l_offset_x = opj_int_ceildiv(l_image->x0, l_img_comp->dx); - l_offset_y = opj_int_ceildiv(l_image->y0, l_img_comp->dy); - l_image_width = opj_int_ceildiv(l_image->x1 - l_image->x0, l_img_comp->dx); + l_width = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0); + l_height = (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0); + l_offset_x = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); + l_offset_y = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->y0, (OPJ_INT32)l_img_comp->dy); + l_image_width = (OPJ_UINT32)opj_int_ceildiv((OPJ_INT32)l_image->x1 - (OPJ_INT32)l_image->x0, (OPJ_INT32)l_img_comp->dx); l_stride = l_image_width - l_width; - l_src_ptr = l_img_comp->data + (l_tilec->x0 - l_offset_x) + (l_tilec->y0 - l_offset_y) * l_image_width; + l_src_ptr = l_img_comp->data + ((OPJ_UINT32)l_tilec->x0 - l_offset_x) + ((OPJ_UINT32)l_tilec->y0 - l_offset_y) * l_image_width; switch (l_size_comp) { case 1: @@ -9234,7 +9693,7 @@ void opj_j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) else { for (j=0;jm_procedure_list,(opj_procedure)opj_j2k_write_qcd ); if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) { - opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_image_components ); + /* No need for COC or QCC, QCD and COD are used + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_coc ); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_all_qcc ); + */ opj_procedure_list_add_procedure(p_j2k->m_procedure_list,(opj_procedure)opj_j2k_write_tlm ); if (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == OPJ_CINEMA4K_24) { @@ -9416,7 +9878,6 @@ OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k, opj_stream_private_t *p_stream, struct opj_event_mgr * p_manager ) { - OPJ_UINT32 compno; OPJ_UINT32 l_nb_bytes_written = 0; OPJ_UINT32 l_current_nb_bytes_written; OPJ_BYTE * l_begin_data = 00; @@ -9447,6 +9908,7 @@ OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k, p_total_data_size -= l_current_nb_bytes_written; if (l_cp->m_specific_param.m_enc.m_cinema == 0) { +#if 0 for (compno = 1; compno < p_j2k->m_private_image->numcomps; compno++) { l_current_nb_bytes_written = 0; opj_j2k_write_coc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager); @@ -9460,6 +9922,7 @@ OPJ_BOOL opj_j2k_write_first_tile_part (opj_j2k_t *p_j2k, p_data += l_current_nb_bytes_written; p_total_data_size -= l_current_nb_bytes_written; } +#endif if (l_cp->tcps[p_j2k->m_current_tile_number].numpocs) { l_current_nb_bytes_written = 0; @@ -9515,6 +9978,8 @@ OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k, /*Get number of tile parts*/ tot_num_tp = opj_j2k_get_num_tp(l_cp,0,p_j2k->m_current_tile_number); + /* start writing remaining tile parts */ + ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number; for (tilepartno = 1; tilepartno < tot_num_tp ; ++tilepartno) { p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = tilepartno; l_current_nb_bytes_written = 0; @@ -9528,7 +9993,7 @@ OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k, l_nb_bytes_written += l_current_nb_bytes_written; p_data += l_current_nb_bytes_written; p_total_data_size -= l_current_nb_bytes_written; - l_part_tile_size += l_nb_bytes_written; + l_part_tile_size += l_current_nb_bytes_written; l_current_nb_bytes_written = 0; if (! opj_j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) { @@ -9538,7 +10003,7 @@ OPJ_BOOL opj_j2k_write_all_tile_parts( opj_j2k_t *p_j2k, p_data += l_current_nb_bytes_written; l_nb_bytes_written += l_current_nb_bytes_written; p_total_data_size -= l_current_nb_bytes_written; - l_part_tile_size += l_nb_bytes_written; + l_part_tile_size += l_current_nb_bytes_written; /* Writing Psot in SOT marker */ opj_write_bytes(l_begin_data + 6,l_part_tile_size,4); /* PSOT */ diff --git a/src/lib/openjp2/jp2.c b/src/lib/openjp2/jp2.c index 9fd78592..b730d5de 100644 --- a/src/lib/openjp2/jp2.c +++ b/src/lib/openjp2/jp2.c @@ -428,12 +428,10 @@ static void opj_jp2_setup_decoding_validation (opj_jp2_t *jp2); static void opj_jp2_setup_header_reading (opj_jp2_t *jp2); /* ----------------------------------------------------------------------- */ - OPJ_BOOL opj_jp2_read_boxhdr(opj_jp2_box_t *box, - OPJ_UINT32 * p_number_bytes_read, - opj_stream_private_t *cio, - opj_event_mgr_t * p_manager - ) + OPJ_UINT32 * p_number_bytes_read, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager ) { /* read header from file */ OPJ_BYTE l_data_header [8]; @@ -444,7 +442,7 @@ static void opj_jp2_setup_header_reading (opj_jp2_t *jp2); assert(p_number_bytes_read != 00); assert(p_manager != 00); - *p_number_bytes_read = opj_stream_read_data(cio,l_data_header,8,p_manager); + *p_number_bytes_read = (OPJ_UINT32)opj_stream_read_data(cio,l_data_header,8,p_manager); if (*p_number_bytes_read != 8) { return OPJ_FALSE; } @@ -452,13 +450,21 @@ static void opj_jp2_setup_header_reading (opj_jp2_t *jp2); /* process read data */ opj_read_bytes(l_data_header,&(box->length), 4); opj_read_bytes(l_data_header+4,&(box->type), 4); + + if(box->length == 0)/* last box */ + { + const OPJ_OFF_T bleft = opj_stream_get_number_byte_left(cio); + box->length = (OPJ_UINT32)bleft; + assert( (OPJ_OFF_T)box->length == bleft ); + return OPJ_TRUE; + } /* do we have a "special very large box ?" */ /* read then the XLBox */ if (box->length == 1) { OPJ_UINT32 l_xl_part_size; - OPJ_UINT32 l_nb_bytes_read = opj_stream_read_data(cio,l_data_header,8,p_manager); + OPJ_UINT32 l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(cio,l_data_header,8,p_manager); if (l_nb_bytes_read != 8) { if (l_nb_bytes_read > 0) { *p_number_bytes_read += l_nb_bytes_read; @@ -467,14 +473,15 @@ static void opj_jp2_setup_header_reading (opj_jp2_t *jp2); return OPJ_FALSE; } + *p_number_bytes_read = 16; opj_read_bytes(l_data_header,&l_xl_part_size, 4); if (l_xl_part_size != 0) { opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n"); return OPJ_FALSE; } - opj_read_bytes(l_data_header,&(box->length), 4); + opj_read_bytes(l_data_header+4,&(box->length), 4); } - return OPJ_TRUE; + return OPJ_TRUE; } #if 0 @@ -607,7 +614,7 @@ OPJ_BYTE * opj_jp2_write_bpcc( opj_jp2_t *jp2, { OPJ_UINT32 i; /* room for 8 bytes for box and 1 byte for each component */ - OPJ_INT32 l_bpcc_size = 8 + jp2->numcomps; + OPJ_UINT32 l_bpcc_size = 8 + jp2->numcomps; OPJ_BYTE * l_bpcc_data,* l_current_bpcc_ptr; /* preconditions */ @@ -747,6 +754,85 @@ void opj_jp2_free_pclr(opj_jp2_color_t *color) opj_free(color->jp2_pclr); color->jp2_pclr = NULL; } +static OPJ_BOOL opj_jp2_check_color(opj_image_t *image, opj_jp2_color_t *color, opj_event_mgr_t *p_manager) +{ + OPJ_UINT16 i; + + /* testcase 4149.pdf.SIGSEGV.cf7.3501 */ + if (color->jp2_cdef) { + opj_jp2_cdef_info_t *info = color->jp2_cdef->info; + OPJ_UINT16 n = color->jp2_cdef->n; + + for (i = 0; i < n; i++) { + if (info[i].cn >= image->numcomps) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].cn, image->numcomps); + return OPJ_FALSE; + } + if (info[i].asoc > 0 && (OPJ_UINT32)(info[i].asoc - 1) >= image->numcomps) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", info[i].asoc - 1, image->numcomps); + return OPJ_FALSE; + } + } + } + + /* testcases 451.pdf.SIGSEGV.f4c.3723, 451.pdf.SIGSEGV.5b5.3723 and + 66ea31acbb0f23a2bbc91f64d69a03f5_signal_sigsegv_13937c0_7030_5725.pdf */ + if (color->jp2_pclr && color->jp2_pclr->cmap) { + OPJ_UINT16 nr_channels = color->jp2_pclr->nr_channels; + opj_jp2_cmap_comp_t *cmap = color->jp2_pclr->cmap; + OPJ_BOOL *pcol_usage, is_sane = OPJ_TRUE; + + /* verify that all original components match an existing one */ + for (i = 0; i < nr_channels; i++) { + if (cmap[i].cmp >= image->numcomps) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid component index %d (>= %d).\n", cmap[i].cmp, image->numcomps); + is_sane = OPJ_FALSE; + } + } + + pcol_usage = opj_calloc(nr_channels, sizeof(OPJ_BOOL)); + if (!pcol_usage) { + opj_event_msg(p_manager, EVT_ERROR, "Unexpected OOM.\n"); + return OPJ_FALSE; + } + /* verify that no component is targeted more than once */ + for (i = 0; i < nr_channels; i++) { + OPJ_UINT16 pcol = cmap[i].pcol; + assert(cmap[i].mtyp == 0 || cmap[i].mtyp == 1); + if (pcol >= nr_channels) { + opj_event_msg(p_manager, EVT_ERROR, "Invalid component/palette index for direct mapping %d.\n", pcol); + is_sane = OPJ_FALSE; + } + else if (pcol_usage[pcol] && cmap[i].mtyp == 1) { + opj_event_msg(p_manager, EVT_ERROR, "Component %d is mapped twice.\n", pcol); + is_sane = OPJ_FALSE; + } + else if (cmap[i].mtyp == 0 && cmap[i].pcol != 0) { + /* I.5.3.5 PCOL: If the value of the MTYP field for this channel is 0, then + * the value of this field shall be 0. */ + opj_event_msg(p_manager, EVT_ERROR, "Direct use at #%d however pcol=%d.\n", i, pcol); + is_sane = OPJ_FALSE; + } + else + pcol_usage[pcol] = OPJ_TRUE; + } + /* verify that all components are targeted at least once */ + for (i = 0; i < nr_channels; i++) { + if (!pcol_usage[i] && cmap[i].mtyp != 0) { + opj_event_msg(p_manager, EVT_ERROR, "Component %d doesn't have a mapping.\n", i); + is_sane = OPJ_FALSE; + } + } + opj_free(pcol_usage); + if (!is_sane) { + return OPJ_FALSE; + } + } + + return OPJ_TRUE; +} + +/* file9.jp2 */ void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color) { opj_image_comp_t *old_comps, *new_comps; @@ -771,40 +857,52 @@ void opj_jp2_apply_pclr(opj_image_t *image, opj_jp2_color_t *color) for(i = 0; i < nr_channels; ++i) { pcol = cmap[i].pcol; cmp = cmap[i].cmp; - new_comps[pcol] = old_comps[cmp]; - /* Direct use */ - if(cmap[i].mtyp == 0){ - old_comps[cmp].data = NULL; continue; - } + if(cmap[i].mtyp == 0){ + assert( pcol == 0 ); + new_comps[i] = old_comps[cmp]; + } else { + assert( i == pcol ); + new_comps[pcol] = old_comps[cmp]; + } /* Palette mapping: */ - new_comps[pcol].data = (OPJ_INT32*) + new_comps[i].data = (OPJ_INT32*) opj_malloc(old_comps[cmp].w * old_comps[cmp].h * sizeof(OPJ_INT32)); - new_comps[pcol].prec = channel_size[i]; - new_comps[pcol].sgnd = channel_sign[i]; + new_comps[i].prec = channel_size[i]; + new_comps[i].sgnd = channel_sign[i]; } top_k = color->jp2_pclr->nr_entries - 1; for(i = 0; i < nr_channels; ++i) { - /* Direct use: */ - if(cmap[i].mtyp == 0) continue; - /* Palette mapping: */ cmp = cmap[i].cmp; pcol = cmap[i].pcol; src = old_comps[cmp].data; - dst = new_comps[pcol].data; + assert( src ); max = new_comps[pcol].w * new_comps[pcol].h; - for(j = 0; j < max; ++j) - { - /* The index */ - if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k; + /* Direct use: */ + if(cmap[i].mtyp == 0) { + assert( cmp == 0 ); + dst = new_comps[i].data; + assert( dst ); + for(j = 0; j < max; ++j) { + dst[j] = src[j]; + } + } + else { + assert( i == pcol ); + dst = new_comps[pcol].data; + assert( dst ); + for(j = 0; j < max; ++j) { + /* The index */ + if((k = src[j]) < 0) k = 0; else if(k > top_k) k = top_k; - /* The colour */ - dst[j] = entries[k * nr_channels + pcol]; - } + /* The colour */ + dst[j] = (OPJ_INT32)entries[k * nr_channels + pcol]; + } + } } max = image->numcomps; @@ -832,6 +930,7 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2, OPJ_UINT16 nr_entries,nr_channels; OPJ_UINT16 i, j; OPJ_UINT32 l_value; + OPJ_BYTE *orig_header_data = p_pclr_header_data; /* preconditions */ assert(p_pclr_header_data != 00); @@ -842,6 +941,9 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2, if(jp2->color.jp2_pclr) return OPJ_FALSE; + if (p_pclr_header_size < 3) + return OPJ_FALSE; + opj_read_bytes(p_pclr_header_data, &l_value , 2); /* NE */ p_pclr_header_data += 2; nr_entries = (OPJ_UINT16) l_value; @@ -850,7 +952,10 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2, ++p_pclr_header_data; nr_channels = (OPJ_UINT16) l_value; - entries = (OPJ_UINT32*) opj_malloc(nr_channels * nr_entries * sizeof(OPJ_UINT32)); + if (p_pclr_header_size < 3 + (OPJ_UINT32)nr_channels || nr_channels == 0 || nr_entries >= (OPJ_UINT32)-1 / nr_channels) + return OPJ_FALSE; + + entries = (OPJ_UINT32*) opj_malloc((size_t)nr_channels * nr_entries * sizeof(OPJ_UINT32)); if (!entries) return OPJ_FALSE; channel_size = (OPJ_BYTE*) opj_malloc(nr_channels); @@ -889,13 +994,18 @@ OPJ_BOOL opj_jp2_read_pclr( opj_jp2_t *jp2, opj_read_bytes(p_pclr_header_data, &l_value , 1); /* Bi */ ++p_pclr_header_data; - channel_size[i] = (l_value & 0x7f) + 1; - channel_sign[i] = (l_value & 0x80)? 1 : 0; + channel_size[i] = (OPJ_BYTE)((l_value & 0x7f) + 1); + channel_sign[i] = (l_value & 0x80) ? 1 : 0; } for(j = 0; j < nr_entries; ++j) { for(i = 0; i < nr_channels; ++i) { - OPJ_INT32 bytes_to_read = (channel_size[i]+7)>>3; + OPJ_UINT32 bytes_to_read = (OPJ_UINT32)((channel_size[i]+7)>>3); + + if (bytes_to_read > sizeof(OPJ_UINT32)) + bytes_to_read = sizeof(OPJ_UINT32); + if ((ptrdiff_t)p_pclr_header_size < p_pclr_header_data - orig_header_data + (ptrdiff_t)bytes_to_read) + return OPJ_FALSE; opj_read_bytes(p_pclr_header_data, &l_value , bytes_to_read); /* Cji */ p_pclr_header_data += bytes_to_read; @@ -938,6 +1048,11 @@ OPJ_BOOL opj_jp2_read_cmap( opj_jp2_t * jp2, } nr_channels = jp2->color.jp2_pclr->nr_channels; + if (p_cmap_header_size < (OPJ_UINT32)nr_channels * 4) { + opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CMAP box.\n"); + return OPJ_FALSE; + } + cmap = (opj_jp2_cmap_comp_t*) opj_malloc(nr_channels * sizeof(opj_jp2_cmap_comp_t)); if (!cmap) return OPJ_FALSE; @@ -970,13 +1085,22 @@ void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color) info = color->jp2_cdef->info; n = color->jp2_cdef->n; - for(i = 0; i < n; ++i) - { - /* WATCH: acn = asoc - 1 ! */ - if((asoc = info[i].asoc) == 0) continue; + for(i = 0; i < n; ++i) + { + /* WATCH: acn = asoc - 1 ! */ + asoc = info[i].asoc; + if(asoc == 0 || asoc == 65535) + { + continue; + } - cn = info[i].cn; - acn = asoc - 1; + cn = info[i].cn; + acn = (OPJ_UINT16)(asoc - 1); + if( cn >= image->numcomps || acn >= image->numcomps ) + { + fprintf(stderr, "cn=%d, acn=%d, numcomps=%d\n", cn, acn, image->numcomps); + continue; + } if(cn != acn) { @@ -986,9 +1110,10 @@ void opj_jp2_apply_cdef(opj_image_t *image, opj_jp2_color_t *color) memcpy(&image->comps[cn], &image->comps[acn], sizeof(opj_image_comp_t)); memcpy(&image->comps[acn], &saved, sizeof(opj_image_comp_t)); - info[i].asoc = cn + 1; - info[acn].asoc = info[acn].cn + 1; + info[i].asoc = (OPJ_UINT16)(cn + 1); + info[acn].asoc = (OPJ_UINT16)(info[acn].cn + 1); } + } if(color->jp2_cdef->info) opj_free(color->jp2_cdef->info); @@ -1017,6 +1142,11 @@ OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2, * inside a JP2 Header box.'*/ if(jp2->color.jp2_cdef) return OPJ_FALSE; + if (p_cdef_header_size < 2) { + opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n"); + return OPJ_FALSE; + } + opj_read_bytes(p_cdef_header_data,&l_value ,2); /* N */ p_cdef_header_data+= 2; @@ -1025,6 +1155,11 @@ OPJ_BOOL opj_jp2_read_cdef( opj_jp2_t * jp2, return OPJ_FALSE; } + if (p_cdef_header_size < 2 + (OPJ_UINT32)(OPJ_UINT16)l_value * 6) { + opj_event_msg(p_manager, EVT_ERROR, "Insufficient data for CDEF box.\n"); + return OPJ_FALSE; + } + cdef_info = (opj_jp2_cdef_info_t*) opj_malloc(l_value * sizeof(opj_jp2_cdef_info_t)); if (!cdef_info) return OPJ_FALSE; @@ -1092,26 +1227,32 @@ OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2, ++p_colr_header_data; if (jp2->meth == 1) { - if (p_colr_header_size != 7) { - opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n"); + if (p_colr_header_size < 7) { + opj_event_msg(p_manager, EVT_ERROR, "Bad COLR header box (bad size: %d)\n", p_colr_header_size); return OPJ_FALSE; } + if (p_colr_header_size > 7) { + /* testcase Altona_Technical_v20_x4.pdf */ + opj_event_msg(p_manager, EVT_WARNING, "Bad COLR header box (bad size: %d)\n", p_colr_header_size); + } opj_read_bytes(p_colr_header_data,&jp2->enumcs ,4); /* EnumCS */ + + jp2->color.jp2_has_colr = 1; } else if (jp2->meth == 2) { /* ICC profile */ OPJ_INT32 it_icc_value = 0; - OPJ_INT32 icc_len = p_colr_header_size - 3; + OPJ_INT32 icc_len = (OPJ_INT32)p_colr_header_size - 3; - jp2->color.icc_profile_len = icc_len; - jp2->color.icc_profile_buf = (OPJ_BYTE*) opj_malloc(icc_len); + jp2->color.icc_profile_len = (OPJ_UINT32)icc_len; + jp2->color.icc_profile_buf = (OPJ_BYTE*) opj_malloc((size_t)icc_len); if (!jp2->color.icc_profile_buf) { jp2->color.icc_profile_len = 0; return OPJ_FALSE; } - memset(jp2->color.icc_profile_buf, 0, icc_len * sizeof(OPJ_BYTE)); + memset(jp2->color.icc_profile_buf, 0, (size_t)icc_len * sizeof(OPJ_BYTE)); for (it_icc_value = 0; it_icc_value < icc_len; ++it_icc_value) { @@ -1119,14 +1260,17 @@ OPJ_BOOL opj_jp2_read_colr( opj_jp2_t *jp2, ++p_colr_header_data; jp2->color.icc_profile_buf[it_icc_value] = (OPJ_BYTE) l_value; } - + + jp2->color.jp2_has_colr = 1; } - else - opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), so we will skip the fields following the approx field.\n", jp2->meth); - - jp2->color.jp2_has_colr = 1; - - return OPJ_TRUE; + else if (jp2->meth > 2) + { + /* ISO/IEC 15444-1:2004 (E), Table I.9 ­ Legal METH values: + conforming JP2 reader shall ignore the entire Colour Specification box.*/ + opj_event_msg(p_manager, EVT_INFO, "COLR BOX meth value is not a regular value (%d), " + "so we will ignore the entire Colour Specification box. \n", jp2->meth); + } + return OPJ_TRUE; } OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2, @@ -1144,6 +1288,9 @@ OPJ_BOOL opj_jp2_decode(opj_jp2_t *jp2, } if (!jp2->ignore_pclr_cmap_cdef){ + if (!opj_jp2_check_color(p_image, &(jp2->color), p_manager)) { + return OPJ_FALSE; + } /* Set Image Color Space */ if (jp2->enumcs == 16) @@ -1188,7 +1335,7 @@ OPJ_BOOL opj_jp2_write_jp2h(opj_jp2_t *jp2, OPJ_INT32 i, l_nb_pass; /* size of data for super box*/ - OPJ_INT32 l_jp2h_size = 8; + OPJ_UINT32 l_jp2h_size = 8; OPJ_BOOL l_result = OPJ_TRUE; /* to store the data of the super box */ @@ -1415,7 +1562,8 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2, opj_event_mgr_t * p_manager) { OPJ_UINT32 i; - OPJ_INT32 depth_0, sign; + OPJ_UINT32 depth_0; + OPJ_UINT32 sign; if(!jp2 || !parameters || !image) return; @@ -1464,7 +1612,7 @@ void opj_jp2_setup_encoder( opj_jp2_t *jp2, sign = image->comps[0].sgnd; jp2->bpc = depth_0 + (sign << 7); for (i = 1; i < image->numcomps; i++) { - OPJ_INT32 depth = image->comps[i].prec - 1; + OPJ_UINT32 depth = image->comps[i].prec - 1; sign = image->comps[i].sgnd; if (depth_0 != depth) jp2->bpc = 255; @@ -1675,6 +1823,12 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2, opj_free(l_current_data); return OPJ_FALSE; } + /* testcase 1851.pdf.SIGSEGV.ce9.948 */ + else if (box.length < l_nb_bytes_read) { + opj_event_msg(p_manager, EVT_ERROR, "invalid box size %d (%x)\n", box.length, box.type); + opj_free(l_current_data); + return OPJ_FALSE; + } l_current_handler = opj_jp2_find_handler(box.type); l_current_data_size = box.length - l_nb_bytes_read; @@ -1682,7 +1836,7 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2, if (l_current_handler != 00) { if (l_current_data_size > l_last_data_size) { OPJ_BYTE* new_current_data = (OPJ_BYTE*)opj_realloc(l_current_data,l_current_data_size); - if (!l_current_data){ + if (!new_current_data) { opj_free(l_current_data); opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 box\n"); return OPJ_FALSE; @@ -1691,7 +1845,7 @@ OPJ_BOOL opj_jp2_read_header_procedure( opj_jp2_t *jp2, l_last_data_size = l_current_data_size; } - l_nb_bytes_read = opj_stream_read_data(stream,l_current_data,l_current_data_size,p_manager); + l_nb_bytes_read = (OPJ_UINT32)opj_stream_read_data(stream,l_current_data,l_current_data_size,p_manager); if (l_nb_bytes_read != l_current_data_size) { opj_event_msg(p_manager, EVT_ERROR, "Problem with reading JPEG2000 box, stream error\n"); opj_free(l_current_data); @@ -2064,11 +2218,11 @@ OPJ_BOOL opj_jp2_read_boxhdr_char( opj_jp2_box_t *box, /* process read data */ opj_read_bytes(p_data, &l_value, 4); p_data += 4; - box->length = (OPJ_INT32)(l_value); + box->length = (OPJ_UINT32)(l_value); opj_read_bytes(p_data, &l_value, 4); p_data += 4; - box->type = (OPJ_INT32)(l_value); + box->type = (OPJ_UINT32)(l_value); *p_number_bytes_read = 8; @@ -2093,7 +2247,7 @@ OPJ_BOOL opj_jp2_read_boxhdr_char( opj_jp2_box_t *box, opj_read_bytes(p_data, &l_value, 4); *p_number_bytes_read += 4; - box->length = (OPJ_INT32)(l_value); + box->length = (OPJ_UINT32)(l_value); if (box->length == 0) { opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n"); @@ -2324,6 +2478,10 @@ OPJ_BOOL opj_jp2_get_tile( opj_jp2_t *p_jp2, return OPJ_FALSE; } + if (!opj_jp2_check_color(p_image, &(p_jp2->color), p_manager)) { + return OPJ_FALSE; + } + /* Set Image Color Space */ if (p_jp2->enumcs == 16) p_image->color_space = OPJ_CLRSPC_SRGB; @@ -2551,6 +2709,7 @@ static OPJ_BOOL opj_jpip_write_cidx(opj_jp2_t *jp2, return OPJ_TRUE; } +#if 0 static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio, opj_event_mgr_t * p_manager ) { @@ -2583,8 +2742,10 @@ static void write_prxy( int offset_jp2c, int length_jp2c, int offset_idx, int le opj_stream_write_data(cio,l_data_header,4,p_manager); opj_stream_seek(cio, lenp+len,p_manager); } +#endif +#if 0 static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int length_idx, opj_stream_private_t *cio, opj_event_mgr_t * p_manager ) { @@ -2606,4 +2767,5 @@ static int write_fidx( int offset_jp2c, int length_jp2c, int offset_idx, int len return len; } +#endif #endif /* USE_JPIP */ diff --git a/src/lib/openjp2/libopenjp2.pc.cmake.in b/src/lib/openjp2/libopenjp2.pc.cmake.in index 42f33d0c..62159b00 100644 --- a/src/lib/openjp2/libopenjp2.pc.cmake.in +++ b/src/lib/openjp2/libopenjp2.pc.cmake.in @@ -10,4 +10,5 @@ Description: JPEG2000 library (Part 1 and 2) URL: http://www.openjpeg.org/ Version: @OPENJPEG_VERSION@ Libs: -L${libdir} -lopenjp2 +Libs.private: -lm Cflags: -I${includedir} diff --git a/src/lib/openjp2/mct.c b/src/lib/openjp2/mct.c index 5e933ce5..d2754dc2 100644 --- a/src/lib/openjp2/mct.c +++ b/src/lib/openjp2/mct.c @@ -230,7 +230,7 @@ OPJ_BOOL opj_mct_encode_custom( lCurrentMatrix = lCurrentData + pNbComp; for (i =0;ibp == 0xff) { mqc->bp++; - *mqc->bp = mqc->c >> 20; + *mqc->bp = (OPJ_BYTE)(mqc->c >> 20); mqc->c &= 0xfffff; mqc->ct = 7; } else { if ((mqc->c & 0x8000000) == 0) { /* ((mqc->c&0x8000000)==0) CHANGE */ mqc->bp++; - *mqc->bp = mqc->c >> 19; + *mqc->bp = (OPJ_BYTE)(mqc->c >> 19); mqc->c &= 0x7ffff; mqc->ct = 8; } else { @@ -213,12 +213,12 @@ void opj_mqc_byteout(opj_mqc_t *mqc) { if (*mqc->bp == 0xff) { mqc->c &= 0x7ffffff; mqc->bp++; - *mqc->bp = mqc->c >> 20; + *mqc->bp = (OPJ_BYTE)(mqc->c >> 20); mqc->c &= 0xfffff; mqc->ct = 7; } else { mqc->bp++; - *mqc->bp = mqc->c >> 19; + *mqc->bp = (OPJ_BYTE)(mqc->c >> 19); mqc->c &= 0x7ffff; mqc->ct = 8; } @@ -274,10 +274,10 @@ void opj_mqc_setbits(opj_mqc_t *mqc) { static INLINE OPJ_INT32 opj_mqc_mpsexchange(opj_mqc_t *const mqc) { OPJ_INT32 d; if (mqc->a < (*mqc->curctx)->qeval) { - d = 1 - (*mqc->curctx)->mps; + d = (OPJ_INT32)(1 - (*mqc->curctx)->mps); *mqc->curctx = (*mqc->curctx)->nlps; } else { - d = (*mqc->curctx)->mps; + d = (OPJ_INT32)(*mqc->curctx)->mps; *mqc->curctx = (*mqc->curctx)->nmps; } @@ -288,11 +288,11 @@ static INLINE OPJ_INT32 opj_mqc_lpsexchange(opj_mqc_t *const mqc) { OPJ_INT32 d; if (mqc->a < (*mqc->curctx)->qeval) { mqc->a = (*mqc->curctx)->qeval; - d = (*mqc->curctx)->mps; + d = (OPJ_INT32)(*mqc->curctx)->mps; *mqc->curctx = (*mqc->curctx)->nmps; } else { mqc->a = (*mqc->curctx)->qeval; - d = 1 - (*mqc->curctx)->mps; + d = (OPJ_INT32)(1 - (*mqc->curctx)->mps); *mqc->curctx = (*mqc->curctx)->nlps; } @@ -371,7 +371,11 @@ void opj_mqc_destroy(opj_mqc_t *mqc) { } OPJ_UINT32 opj_mqc_numbytes(opj_mqc_t *mqc) { - return mqc->bp - mqc->start; + const ptrdiff_t diff = mqc->bp - mqc->start; +#if 0 + assert( diff <= 0xffffffff && diff >= 0 ); /* UINT32_MAX */ +#endif + return (OPJ_UINT32)diff; } void opj_mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp) { @@ -420,7 +424,7 @@ void opj_mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 d) { mqc->c = mqc->c + (d << mqc->ct); if (mqc->ct == 0) { mqc->bp++; - *mqc->bp = mqc->c; + *mqc->bp = (OPJ_BYTE)mqc->c; mqc->ct = 8; if (*mqc->bp == 0xff) { mqc->ct = 7; @@ -437,11 +441,11 @@ OPJ_UINT32 opj_mqc_bypass_flush_enc(opj_mqc_t *mqc) { if (mqc->ct != 0) { while (mqc->ct > 0) { mqc->ct--; - mqc->c += bit_padding << mqc->ct; + mqc->c += (OPJ_UINT32)(bit_padding << mqc->ct); bit_padding = (bit_padding + 1) & 0x01; } mqc->bp++; - *mqc->bp = mqc->c; + *mqc->bp = (OPJ_BYTE)mqc->c; mqc->ct = 8; mqc->c = 0; } @@ -460,11 +464,11 @@ OPJ_UINT32 opj_mqc_restart_enc(opj_mqc_t *mqc) { OPJ_UINT32 correction = 1; /* */ - OPJ_INT32 n = 27 - 15 - mqc->ct; + OPJ_INT32 n = (OPJ_INT32)(27 - 15 - mqc->ct); mqc->c <<= mqc->ct; while (n > 0) { opj_mqc_byteout(mqc); - n -= mqc->ct; + n -= (OPJ_INT32)mqc->ct; mqc->c <<= mqc->ct; } opj_mqc_byteout(mqc); @@ -485,13 +489,13 @@ void opj_mqc_restart_init_enc(opj_mqc_t *mqc) { } void opj_mqc_erterm_enc(opj_mqc_t *mqc) { - OPJ_INT32 k = 11 - mqc->ct + 1; + OPJ_INT32 k = (OPJ_INT32)(11 - mqc->ct + 1); while (k > 0) { mqc->c <<= mqc->ct; mqc->ct = 0; opj_mqc_byteout(mqc); - k -= mqc->ct; + k -= (OPJ_INT32)mqc->ct; } if (*mqc->bp != 0xff) { @@ -514,7 +518,7 @@ OPJ_BOOL opj_mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len) { mqc->end = bp + len; mqc->bp = bp; if (len==0) mqc->c = 0xff << 16; - else mqc->c = *mqc->bp << 16; + else mqc->c = (OPJ_UINT32)(*mqc->bp << 16); #ifdef MQC_PERF_OPT /* TODO_MSD: check this option and put in experimental */ { @@ -579,7 +583,7 @@ OPJ_INT32 opj_mqc_decode(opj_mqc_t *const mqc) { d = opj_mqc_mpsexchange(mqc); opj_mqc_renormd(mqc); } else { - d = (*mqc->curctx)->mps; + d = (OPJ_INT32)(*mqc->curctx)->mps; } } @@ -594,7 +598,7 @@ void opj_mqc_resetstates(opj_mqc_t *mqc) { } void opj_mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb, OPJ_INT32 prob) { - mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)]; + mqc->ctxs[ctxno] = &mqc_states[msb + (OPJ_UINT32)(prob << 1)]; } diff --git a/src/lib/openjp2/openjpeg.c b/src/lib/openjp2/openjpeg.c index 0ed7e67a..d09f6f2c 100644 --- a/src/lib/openjp2/openjpeg.c +++ b/src/lib/openjp2/openjpeg.c @@ -30,126 +30,8 @@ #include #endif /* _WIN32 */ -#include "opj_config.h" #include "opj_includes.h" -/** - * Decompression handler. - */ -typedef struct opj_decompression -{ - /** Main header reading function handler*/ - OPJ_BOOL (*opj_read_header) ( struct opj_stream_private * cio, - void * p_codec, - opj_image_t **p_image, - struct opj_event_mgr * p_manager); - /** Decoding function */ - OPJ_BOOL (*opj_decode) ( void * p_codec, - struct opj_stream_private *p_cio, - opj_image_t *p_image, - struct opj_event_mgr * p_manager); - /** FIXME DOC */ - OPJ_BOOL (*opj_read_tile_header)( void * p_codec, - OPJ_UINT32 * p_tile_index, - OPJ_UINT32* p_data_size, - OPJ_INT32 * p_tile_x0, OPJ_INT32 * p_tile_y0, - OPJ_INT32 * p_tile_x1, OPJ_INT32 * p_tile_y1, - OPJ_UINT32 * p_nb_comps, - OPJ_BOOL * p_should_go_on, - struct opj_stream_private *p_cio, - struct opj_event_mgr * p_manager); - /** FIXME DOC */ - OPJ_BOOL (*opj_decode_tile_data)( void * p_codec, - OPJ_UINT32 p_tile_index, - OPJ_BYTE * p_data, - OPJ_UINT32 p_data_size, - struct opj_stream_private *p_cio, - struct opj_event_mgr * p_manager); - /** Reading function used after codestream if necessary */ - OPJ_BOOL (* opj_end_decompress) ( void *p_codec, - struct opj_stream_private *cio, - struct opj_event_mgr * p_manager); - /** Codec destroy function handler*/ - void (*opj_destroy) (void * p_codec); - /** Setup decoder function handler */ - void (*opj_setup_decoder) (void * p_codec, opj_dparameters_t * p_param); - /** Set decode area function handler */ - OPJ_BOOL (*opj_set_decode_area) ( void * p_codec, - opj_image_t* p_image, - OPJ_INT32 p_start_x, OPJ_INT32 p_end_x, - OPJ_INT32 p_start_y, OPJ_INT32 p_end_y, - struct opj_event_mgr * p_manager); - - /** Get tile function */ - OPJ_BOOL (*opj_get_decoded_tile) ( void *p_codec, - opj_stream_private_t *p_cio, - opj_image_t *p_image, - struct opj_event_mgr * p_manager, - OPJ_UINT32 tile_index); - - /** Set the decoded resolution factor */ - OPJ_BOOL (*opj_set_decoded_resolution_factor) ( void * p_codec, - OPJ_UINT32 res_factor, - opj_event_mgr_t * p_manager); - -}opj_decompression_t; - -/** - * Compression handler. FIXME DOC - */ -typedef struct opj_compression -{ - OPJ_BOOL (* opj_start_compress) ( void *p_codec, - struct opj_stream_private *cio, - struct opj_image * p_image, - struct opj_event_mgr * p_manager); - - OPJ_BOOL (* opj_encode) ( void * p_codec, - struct opj_stream_private *p_cio, - struct opj_event_mgr * p_manager); - - OPJ_BOOL (* opj_write_tile) ( void * p_codec, - OPJ_UINT32 p_tile_index, - OPJ_BYTE * p_data, - OPJ_UINT32 p_data_size, - struct opj_stream_private * p_cio, - struct opj_event_mgr * p_manager); - - OPJ_BOOL (* opj_end_compress) ( void * p_codec, - struct opj_stream_private *p_cio, - struct opj_event_mgr * p_manager); - - void (* opj_destroy) (void * p_codec); - - void (* opj_setup_encoder) ( void * p_codec, - opj_cparameters_t * p_param, - struct opj_image * p_image, - struct opj_event_mgr * p_manager); - -}opj_compression_t; - -/** - * Main codec handler used for compression or decompression. - */ -typedef struct opj_codec_private -{ - /** FIXME DOC */ - union - { - opj_decompression_t m_decompression; - opj_compression_t m_compression; - } m_codec_data; - /** FIXME DOC*/ - void * m_codec; - /** Event handler */ - opj_event_mgr_t m_event_mgr; - /** Flag to indicate if the codec is used to decode or encode*/ - OPJ_BOOL is_decompressor; - void (*opj_dump_codec) (void * p_codec, OPJ_INT32 info_flag, FILE* output_stream); - opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec); - opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec); -} -opj_codec_private_t; /* ---------------------------------------------------------------------- */ /* Functions to set the message handlers */ @@ -212,10 +94,10 @@ static OPJ_UINT64 opj_get_data_length_from_file (FILE * p_file) OPJ_OFF_T file_length = 0; OPJ_FSEEK(p_file, 0, SEEK_END); - file_length = (OPJ_UINT64)OPJ_FTELL(p_file); + file_length = (OPJ_OFF_T)OPJ_FTELL(p_file); OPJ_FSEEK(p_file, 0, SEEK_SET); - return file_length; + return (OPJ_UINT64)file_length; } static OPJ_SIZE_T opj_write_from_file (void * p_buffer, OPJ_SIZE_T p_nb_bytes, FILE * p_file) @@ -851,10 +733,9 @@ OPJ_BOOL OPJ_CALLCONV opj_encode(opj_codec_t *p_info, opj_stream_t *p_stream) opj_stream_private_t * l_stream = (opj_stream_private_t *) p_stream; if (! l_codec->is_decompressor) { - l_codec->m_codec_data.m_compression.opj_encode( l_codec->m_codec, + return l_codec->m_codec_data.m_compression.opj_encode( l_codec->m_codec, l_stream, &(l_codec->m_event_mgr)); - return OPJ_TRUE; } } @@ -902,8 +783,8 @@ OPJ_BOOL OPJ_CALLCONV opj_set_MCT(opj_cparameters_t *parameters, OPJ_FLOAT32 * pEncodingMatrix, OPJ_INT32 * p_dc_shift,OPJ_UINT32 pNbComp) { - OPJ_UINT32 l_matrix_size = pNbComp * pNbComp * sizeof(OPJ_FLOAT32); - OPJ_UINT32 l_dc_shift_size = pNbComp * sizeof(OPJ_INT32); + OPJ_UINT32 l_matrix_size = pNbComp * pNbComp * (OPJ_UINT32)sizeof(OPJ_FLOAT32); + OPJ_UINT32 l_dc_shift_size = pNbComp * (OPJ_UINT32)sizeof(OPJ_INT32); OPJ_UINT32 l_mct_total_size = l_matrix_size + l_dc_shift_size; /* add MCT capability */ diff --git a/src/lib/openjp2/openjpeg.h b/src/lib/openjp2/openjpeg.h index 9a2f1073..749e7d5c 100644 --- a/src/lib/openjp2/openjpeg.h +++ b/src/lib/openjp2/openjpeg.h @@ -43,14 +43,31 @@ ========================================================== */ +/* +The inline keyword is supported by C99 but not by C90. +Most compilers implement their own version of this keyword ... +*/ +#ifndef INLINE + #if defined(_MSC_VER) + #define INLINE __forceinline + #elif defined(__GNUC__) + #define INLINE __inline__ + #elif defined(__MWERKS__) + #define INLINE inline + #else + /* add other compilers here ... */ + #define INLINE + #endif /* defined() */ +#endif /* INLINE */ + /* deprecated attribute */ #ifdef __GNUC__ - #define DEPRECATED(func) func __attribute__ ((deprecated)) + #define OPJ_DEPRECATED(func) func __attribute__ ((deprecated)) #elif defined(_MSC_VER) - #define DEPRECATED(func) __declspec(deprecated) func + #define OPJ_DEPRECATED(func) __declspec(deprecated) func #else #pragma message("WARNING: You need to implement DEPRECATED for this compiler") - #define DEPRECATED(func) func + #define OPJ_DEPRECATED(func) func #endif #if defined(OPJ_STATIC) || !defined(_WIN32) @@ -143,7 +160,7 @@ typedef size_t OPJ_SIZE_T; #define OPJ_IMG_INFO 1 /**< Basic image information provided to the user */ #define OPJ_J2K_MH_INFO 2 /**< Codestream information based only on the main header */ #define OPJ_J2K_TH_INFO 4 /**< Tile information based on the current tile header */ -/*FIXME #define OPJ_J2K_CSTR_INFO 6*/ /**< */ +#define OPJ_J2K_TCH_INFO 8 /**< Tile/Component information of all tiles */ #define OPJ_J2K_MH_IND 16 /**< Codestream index based only on the main header */ #define OPJ_J2K_TH_IND 32 /**< Tile index based on the current tile */ /*FIXME #define OPJ_J2K_CSTR_IND 48*/ /**< */ @@ -193,10 +210,10 @@ typedef enum PROG_ORDER { */ typedef enum COLOR_SPACE { OPJ_CLRSPC_UNKNOWN = -1, /**< not supported by the library */ - OPJ_CLRSPC_UNSPECIFIED = 0, /**< not specified in the codestream */ + OPJ_CLRSPC_UNSPECIFIED = 0, /**< not specified in the codestream */ OPJ_CLRSPC_SRGB = 1, /**< sRGB */ OPJ_CLRSPC_GRAY = 2, /**< grayscale */ - OPJ_CLRSPC_SYCC = 3 /**< YUV */ + OPJ_CLRSPC_SYCC = 3 /**< YUV */ } OPJ_COLOR_SPACE; /** @@ -387,7 +404,8 @@ typedef struct opj_cparameters { char tcp_mct; /** Enable JPIP indexing*/ OPJ_BOOL jpip_on; - /** Naive implementation of MCT restricted to a single reversible array based encoding without offset concerning all the components. */ + /** Naive implementation of MCT restricted to a single reversible array based + encoding without offset concerning all the components. */ void * mct_data; } opj_cparameters_t; @@ -1217,7 +1235,8 @@ OPJ_API OPJ_BOOL OPJ_CALLCONV opj_set_decoded_resolution_factor(opj_codec_t *p_c * @param p_codec the jpeg2000 codec. * @param p_tile_index the index of the tile to write. At the moment, the tiles must be written from 0 to n-1 in sequence. * @param p_data pointer to the data to write. Data is arranged in sequence, data_comp0, then data_comp1, then ... NO INTERLEAVING should be set. - * @param p_data_size this value os used to make sure the data being written is correct. The size must be equal to the sum for each component of tile_width * tile_height * component_size. component_size can be 1,2 or 4 bytes, depending on the precision of the given component. + * @param p_data_size this value os used to make sure the data being written is correct. The size must be equal to the sum for each component of + * tile_width * tile_height * component_size. component_size can be 1,2 or 4 bytes, depending on the precision of the given component. * @param p_stream the stream to write data to. * * @return true if the data could be written. diff --git a/src/lib/openjp2/opj_clock.c b/src/lib/openjp2/opj_clock.c index dbbf6e0a..5f2ab9dc 100644 --- a/src/lib/openjp2/opj_clock.c +++ b/src/lib/openjp2/opj_clock.c @@ -51,9 +51,9 @@ OPJ_FLOAT64 opj_clock(void) { getrusage(0,&t); /* (2) What is the elapsed time ? - CPU time = User time + System time */ /* (2a) Get the seconds */ - procTime = t.ru_utime.tv_sec + t.ru_stime.tv_sec; + procTime = (OPJ_FLOAT64)(t.ru_utime.tv_sec + t.ru_stime.tv_sec); /* (2b) More precisely! Get the microseconds part ! */ - return ( procTime + (t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ; + return ( procTime + (OPJ_FLOAT64)(t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ; #endif } diff --git a/src/lib/openjp2/opj_codec.h b/src/lib/openjp2/opj_codec.h new file mode 100644 index 00000000..6ac0f28f --- /dev/null +++ b/src/lib/openjp2/opj_codec.h @@ -0,0 +1,160 @@ +/* + * Copyright (c) 2002-2007, Communications and Remote Sensing Laboratory, Universite catholique de Louvain (UCL), Belgium + * Copyright (c) 2002-2007, Professor Benoit Macq + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __OPJ_CODEC_H +#define __OPJ_CODEC_H +/** +@file opj_codec.h +*/ + + +/** + * Main codec handler used for compression or decompression. + */ +typedef struct opj_codec_private +{ + /** FIXME DOC */ + union + { + /** + * Decompression handler. + */ + struct opj_decompression + { + /** Main header reading function handler */ + OPJ_BOOL (*opj_read_header) ( struct opj_stream_private * cio, + void * p_codec, + opj_image_t **p_image, + struct opj_event_mgr * p_manager); + + /** Decoding function */ + OPJ_BOOL (*opj_decode) ( void * p_codec, + struct opj_stream_private * p_cio, + opj_image_t * p_image, + struct opj_event_mgr * p_manager); + + /** FIXME DOC */ + OPJ_BOOL (*opj_read_tile_header)( void * p_codec, + OPJ_UINT32 * p_tile_index, + OPJ_UINT32 * p_data_size, + OPJ_INT32 * p_tile_x0, + OPJ_INT32 * p_tile_y0, + OPJ_INT32 * p_tile_x1, + OPJ_INT32 * p_tile_y1, + OPJ_UINT32 * p_nb_comps, + OPJ_BOOL * p_should_go_on, + struct opj_stream_private * p_cio, + struct opj_event_mgr * p_manager); + + /** FIXME DOC */ + OPJ_BOOL (*opj_decode_tile_data)( void * p_codec, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + struct opj_stream_private * p_cio, + struct opj_event_mgr * p_manager); + + /** Reading function used after codestream if necessary */ + OPJ_BOOL (* opj_end_decompress) ( void *p_codec, + struct opj_stream_private * cio, + struct opj_event_mgr * p_manager); + + /** Codec destroy function handler */ + void (*opj_destroy) (void * p_codec); + + /** Setup decoder function handler */ + void (*opj_setup_decoder) ( void * p_codec, opj_dparameters_t * p_param); + + /** Set decode area function handler */ + OPJ_BOOL (*opj_set_decode_area) ( void * p_codec, + opj_image_t * p_image, + OPJ_INT32 p_start_x, + OPJ_INT32 p_end_x, + OPJ_INT32 p_start_y, + OPJ_INT32 p_end_y, + struct opj_event_mgr * p_manager); + + /** Get tile function */ + OPJ_BOOL (*opj_get_decoded_tile) ( void *p_codec, + opj_stream_private_t * p_cio, + opj_image_t *p_image, + struct opj_event_mgr * p_manager, + OPJ_UINT32 tile_index); + + /** Set the decoded resolution factor */ + OPJ_BOOL (*opj_set_decoded_resolution_factor) ( void * p_codec, + OPJ_UINT32 res_factor, + opj_event_mgr_t * p_manager); + } m_decompression; + + /** + * Compression handler. FIXME DOC + */ + struct opj_compression + { + OPJ_BOOL (* opj_start_compress) ( void *p_codec, + struct opj_stream_private * cio, + struct opj_image * p_image, + struct opj_event_mgr * p_manager); + + OPJ_BOOL (* opj_encode) ( void * p_codec, + struct opj_stream_private *p_cio, + struct opj_event_mgr * p_manager); + + OPJ_BOOL (* opj_write_tile) ( void * p_codec, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + struct opj_stream_private * p_cio, + struct opj_event_mgr * p_manager); + + OPJ_BOOL (* opj_end_compress) ( void * p_codec, + struct opj_stream_private * p_cio, + struct opj_event_mgr * p_manager); + + void (* opj_destroy) (void * p_codec); + + void (* opj_setup_encoder) ( void * p_codec, + opj_cparameters_t * p_param, + struct opj_image * p_image, + struct opj_event_mgr * p_manager); + } m_compression; + } m_codec_data; + /** FIXME DOC*/ + void * m_codec; + /** Event handler */ + opj_event_mgr_t m_event_mgr; + /** Flag to indicate if the codec is used to decode or encode*/ + OPJ_BOOL is_decompressor; + void (*opj_dump_codec) (void * p_codec, OPJ_INT32 info_flag, FILE* output_stream); + opj_codestream_info_v2_t* (*opj_get_codec_info)(void* p_codec); + opj_codestream_index_t* (*opj_get_codec_index)(void* p_codec); +} +opj_codec_private_t; + + +#endif /* __OPJ_CODEC_H */ + diff --git a/src/lib/openjp2/opj_config.h.cmake.in b/src/lib/openjp2/opj_config.h.cmake.in index 91772ef9..2f5311b8 100644 --- a/src/lib/openjp2/opj_config.h.cmake.in +++ b/src/lib/openjp2/opj_config.h.cmake.in @@ -1,41 +1,2 @@ -/* create config.h for CMake */ -#cmakedefine OPJ_HAVE_STDINT_H @HAVE_STDINT_H@ - -#define OPJ_PACKAGE_VERSION "@PACKAGE_VERSION@" - -#cmakedefine HAVE_INTTYPES_H @HAVE_INTTYPES_H@ -#cmakedefine HAVE_MEMORY_H @HAVE_MEMORY_H@ -#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@ -#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@ -#cmakedefine HAVE_STRING_H @HAVE_STRING_H@ -#cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@ -#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ -#cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@ -#cmakedefine HAVE_LIBPNG @HAVE_LIBPNG@ -#cmakedefine HAVE_PNG_H @HAVE_PNG_H@ -#cmakedefine HAVE_LIBTIFF @HAVE_LIBTIFF@ -#cmakedefine HAVE_TIFF_H @HAVE_TIFF_H@ - -#cmakedefine _LARGEFILE_SOURCE -#cmakedefine _LARGE_FILES -#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@ -#cmakedefine HAVE_FSEEKO @HAVE_FSEEKO@ - -#cmakedefine HAVE_LIBLCMS1 -#cmakedefine HAVE_LIBLCMS2 -#cmakedefine HAVE_LCMS1_H -#cmakedefine HAVE_LCMS2_H - -/* Byte order. */ -/* All compilers that support Mac OS X define either __BIG_ENDIAN__ or -__LITTLE_ENDIAN__ to match the endianness of the architecture being -compiled for. This is not necessarily the same as the architecture of the -machine doing the building. In order to support Universal Binaries on -Mac OS X, we prefer those defines to decide the endianness. -On other platforms we use the result of the TRY_RUN. */ -#if !defined(__APPLE__) -#cmakedefine OPJ_BIG_ENDIAN -#elif defined(__BIG_ENDIAN__) -# define OPJ_BIG_ENDIAN -#endif - +/* create opj_config.h for CMake */ +#cmakedefine OPJ_HAVE_STDINT_H @OPJ_HAVE_STDINT_H@ diff --git a/src/lib/openjp2/opj_config_private.h.cmake.in b/src/lib/openjp2/opj_config_private.h.cmake.in new file mode 100644 index 00000000..8a02c79d --- /dev/null +++ b/src/lib/openjp2/opj_config_private.h.cmake.in @@ -0,0 +1,31 @@ +/* create opj_config_private.h for CMake */ +#cmakedefine OPJ_HAVE_INTTYPES_H @OPJ_HAVE_INTTYPES_H@ + +#define OPJ_PACKAGE_VERSION "@PACKAGE_VERSION@" + +/* Not used by openjp2*/ +/*#cmakedefine HAVE_MEMORY_H @HAVE_MEMORY_H@*/ +/*#cmakedefine HAVE_STDLIB_H @HAVE_STDLIB_H@*/ +/*#cmakedefine HAVE_STRINGS_H @HAVE_STRINGS_H@*/ +/*#cmakedefine HAVE_STRING_H @HAVE_STRING_H@*/ +/*#cmakedefine HAVE_SYS_STAT_H @HAVE_SYS_STAT_H@*/ +/*#cmakedefine HAVE_SYS_TYPES_H @HAVE_SYS_TYPES_H@ */ +/*#cmakedefine HAVE_UNISTD_H @HAVE_UNISTD_H@*/ + +#cmakedefine _LARGEFILE_SOURCE +#cmakedefine _LARGE_FILES +#cmakedefine _FILE_OFFSET_BITS @_FILE_OFFSET_BITS@ +#cmakedefine OPJ_HAVE_FSEEKO @OPJ_HAVE_FSEEKO@ + +/* Byte order. */ +/* All compilers that support Mac OS X define either __BIG_ENDIAN__ or +__LITTLE_ENDIAN__ to match the endianness of the architecture being +compiled for. This is not necessarily the same as the architecture of the +machine doing the building. In order to support Universal Binaries on +Mac OS X, we prefer those defines to decide the endianness. +On other platforms we use the result of the TRY_RUN. */ +#if !defined(__APPLE__) +#cmakedefine OPJ_BIG_ENDIAN +#elif defined(__BIG_ENDIAN__) +# define OPJ_BIG_ENDIAN +#endif \ No newline at end of file diff --git a/src/lib/openjp2/opj_includes.h b/src/lib/openjp2/opj_includes.h index 4397149a..76380962 100644 --- a/src/lib/openjp2/opj_includes.h +++ b/src/lib/openjp2/opj_includes.h @@ -32,7 +32,7 @@ * This must be included before any system headers, * since they can react to macro defined there */ -#include "opj_config.h" +#include "opj_config_private.h" /* ========================================================== @@ -56,7 +56,7 @@ ftello() only on systems with special LFS support since some systems (e.g. FreeBSD) support a 64-bit off_t by default. */ -#if defined(HAVE_FSEEKO) +#if defined(OPJ_HAVE_FSEEKO) && !defined(fseek) # define fseek fseeko # define ftell ftello #endif @@ -102,22 +102,6 @@ #define __attribute__(x) /* __attribute__(x) */ #endif -/* -The inline keyword is supported by C99 but not by C90. -Most compilers implement their own version of this keyword ... -*/ -#ifndef INLINE - #if defined(_MSC_VER) - #define INLINE __forceinline - #elif defined(__GNUC__) - #define INLINE __inline__ - #elif defined(__MWERKS__) - #define INLINE inline - #else - /* add other compilers here ... */ - #define INLINE - #endif /* defined() */ -#endif /* INLINE */ /* Are restricted pointers available? (C99) */ #if (__STDC_VERSION__ != 199901L) @@ -129,8 +113,8 @@ Most compilers implement their own version of this keyword ... #endif #endif -/* MSVC and Borland C do not have lrintf */ -#if defined(_MSC_VER) || defined(__BORLANDC__) +/* MSVC before 2013 and Borland C do not have lrintf */ +#if defined(_MSC_VER) && (_MSC_VER < 1800) || defined(__BORLANDC__) static INLINE long lrintf(float f){ #ifdef _M_X64 return (long)((f>0.0f) ? (f + 0.5f):(f -0.5f)); @@ -185,6 +169,7 @@ static INLINE long lrintf(float f){ /* <> b; + return (OPJ_INT32)((a + (OPJ_INT64)(1 << b) - 1) >> b); } /** Divide an integer by a power of 2 and round downwards diff --git a/src/lib/openjp2/opj_inttypes.h b/src/lib/openjp2/opj_inttypes.h index d6a29263..61215137 100644 --- a/src/lib/openjp2/opj_inttypes.h +++ b/src/lib/openjp2/opj_inttypes.h @@ -26,8 +26,8 @@ #ifndef OPJ_INTTYPES_H #define OPJ_INTTYPES_H -#include "opj_config.h" -#ifdef HAVE_INTTYPES_H +#include "opj_config_private.h" +#ifdef OPJ_HAVE_INTTYPES_H #include #else #if defined(_WIN32) diff --git a/src/lib/openjp2/opj_malloc.h b/src/lib/openjp2/opj_malloc.h index aef2ee3b..95ad1472 100644 --- a/src/lib/openjp2/opj_malloc.h +++ b/src/lib/openjp2/opj_malloc.h @@ -48,8 +48,13 @@ Allocate an uninitialized memory block #ifdef ALLOC_PERF_OPT void * OPJ_CALLCONV opj_malloc(size_t size); #else +/* prevent assertion on overflow for MSVC */ +#ifdef _MSC_VER +#define opj_malloc(size) ((size_t)(size) >= (size_t)-0x100 ? NULL : malloc(size)) +#else #define opj_malloc(size) malloc(size) #endif +#endif /** Allocate a memory block with elements initialized to 0 @@ -60,8 +65,13 @@ Allocate a memory block with elements initialized to 0 #ifdef ALLOC_PERF_OPT void * OPJ_CALLCONV opj_calloc(size_t _NumOfElements, size_t _SizeOfElements); #else +/* prevent assertion on overflow for MSVC */ +#ifdef _MSC_VER +#define opj_calloc(num, size) ((size_t)(num) != 0 && (size_t)(num) >= (size_t)-0x100 / (size_t)(size) ? NULL : calloc(num, size)) +#else #define opj_calloc(num, size) calloc(num, size) #endif +#endif /** Allocate memory aligned to a 16 byte boundry @@ -139,8 +149,13 @@ Reallocate memory blocks. #ifdef ALLOC_PERF_OPT void * OPJ_CALLCONV opj_realloc(void * m, size_t s); #else +/* prevent assertion on overflow for MSVC */ +#ifdef _MSC_VER +#define opj_realloc(m, s) ((size_t)(s) >= (size_t)-0x100 ? NULL : realloc(m, s)) +#else #define opj_realloc(m, s) realloc(m, s) #endif +#endif /** Deallocates or frees a memory block. diff --git a/src/lib/openjp2/phix_manager.c b/src/lib/openjp2/phix_manager.c index b4d5a40d..8346e69d 100644 --- a/src/lib/openjp2/phix_manager.c +++ b/src/lib/openjp2/phix_manager.c @@ -52,11 +52,11 @@ int opj_write_phix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, opj_event_mgr_t * p_manager ) { OPJ_BYTE l_data_header [8]; - int len, compno, i; + OPJ_UINT32 len, compno, i; opj_jp2_box_t *box; OPJ_OFF_T lenp = 0; - box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t)); + box = (opj_jp2_box_t *)opj_calloc( (size_t)cstr_info.numcomps, sizeof(opj_jp2_box_t)); for( i=0;i<2;i++){ if (i) @@ -67,10 +67,10 @@ int opj_write_phix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, opj_write_bytes(l_data_header,JPIP_PHIX,4); /* PHIX */ opj_stream_write_data(cio,l_data_header,4,p_manager); - opj_write_manf( i, cstr_info.numcomps, box, cio, p_manager ); + opj_write_manf( (int)i, cstr_info.numcomps, box, cio, p_manager ); - for( compno=0; compnonumresolutions; resno++) { OPJ_UINT32 dx, dy; res = &comp->resolutions[resno]; - dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); - dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); + dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno)); + dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno)); pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx); pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy); } @@ -334,8 +334,8 @@ if (!pi->tp_on){ pi->poc.tx1 = pi->tx1; } for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { - for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) { for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { OPJ_UINT32 levelno; OPJ_INT32 trx0, try0; @@ -348,16 +348,16 @@ if (!pi->tp_on){ } res = &comp->resolutions[pi->resno]; levelno = comp->numresolutions - 1 - pi->resno; - trx0 = opj_int_ceildiv(pi->tx0, comp->dx << levelno); - try0 = opj_int_ceildiv(pi->ty0, comp->dy << levelno); - trx1 = opj_int_ceildiv(pi->tx1, comp->dx << levelno); - try1 = opj_int_ceildiv(pi->ty1, comp->dy << levelno); + trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno)); + try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno)); + trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno)); + try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno)); rpx = res->pdx + levelno; rpy = res->pdy + levelno; - if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){ + if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){ continue; } - if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ + if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ continue; } @@ -365,11 +365,11 @@ if (!pi->tp_on){ if ((trx0==trx1)||(try0==try1)) continue; - prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, comp->dx << levelno), res->pdx) - - opj_int_floordivpow2(trx0, res->pdx); - prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, comp->dy << levelno), res->pdy) - - opj_int_floordivpow2(try0, res->pdy); - pi->precno = prci + prcj * res->pw; + prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx) + - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx); + prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy) + - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy); + pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw); for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { @@ -404,8 +404,8 @@ OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) { for (resno = 0; resno < comp->numresolutions; resno++) { OPJ_UINT32 dx, dy; res = &comp->resolutions[resno]; - dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); - dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); + dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno)); + dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno)); pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx); pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy); } @@ -417,8 +417,8 @@ OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) { pi->poc.ty1 = pi->ty1; pi->poc.tx1 = pi->tx1; } - for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) { for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { comp = &pi->comps[pi->compno]; for (pi->resno = pi->poc.resno0; pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) { @@ -429,16 +429,16 @@ OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) { OPJ_INT32 prci, prcj; res = &comp->resolutions[pi->resno]; levelno = comp->numresolutions - 1 - pi->resno; - trx0 = opj_int_ceildiv(pi->tx0, comp->dx << levelno); - try0 = opj_int_ceildiv(pi->ty0, comp->dy << levelno); - trx1 = opj_int_ceildiv(pi->tx1, comp->dx << levelno); - try1 = opj_int_ceildiv(pi->ty1, comp->dy << levelno); + trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno)); + try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno)); + trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno)); + try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno)); rpx = res->pdx + levelno; rpy = res->pdy + levelno; - if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){ + if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){ continue; } - if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ + if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ continue; } @@ -446,11 +446,11 @@ OPJ_BOOL opj_pi_next_pcrl(opj_pi_iterator_t * pi) { if ((trx0==trx1)||(try0==try1)) continue; - prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, comp->dx << levelno), res->pdx) - - opj_int_floordivpow2(trx0, res->pdx); - prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, comp->dy << levelno), res->pdy) - - opj_int_floordivpow2(try0, res->pdy); - pi->precno = prci + prcj * res->pw; + prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx) + - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx); + prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy) + - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy); + pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw); for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { @@ -487,8 +487,8 @@ OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) { for (resno = 0; resno < comp->numresolutions; resno++) { OPJ_UINT32 dx, dy; res = &comp->resolutions[resno]; - dx = comp->dx * (1 << (res->pdx + comp->numresolutions - 1 - resno)); - dy = comp->dy * (1 << (res->pdy + comp->numresolutions - 1 - resno)); + dx = comp->dx * (1u << (res->pdx + comp->numresolutions - 1 - resno)); + dy = comp->dy * (1u << (res->pdy + comp->numresolutions - 1 - resno)); pi->dx = !pi->dx ? dx : opj_uint_min(pi->dx, dx); pi->dy = !pi->dy ? dy : opj_uint_min(pi->dy, dy); } @@ -498,8 +498,8 @@ OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) { pi->poc.ty1 = pi->ty1; pi->poc.tx1 = pi->tx1; } - for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->y = pi->poc.ty0; pi->y < pi->poc.ty1; pi->y += (OPJ_INT32)(pi->dy - (OPJ_UINT32)(pi->y % (OPJ_INT32)pi->dy))) { + for (pi->x = pi->poc.tx0; pi->x < pi->poc.tx1; pi->x += (OPJ_INT32)(pi->dx - (OPJ_UINT32)(pi->x % (OPJ_INT32)pi->dx))) { for (pi->resno = pi->poc.resno0; pi->resno < opj_uint_min(pi->poc.resno1, comp->numresolutions); pi->resno++) { OPJ_UINT32 levelno; OPJ_INT32 trx0, try0; @@ -508,16 +508,16 @@ OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) { OPJ_INT32 prci, prcj; res = &comp->resolutions[pi->resno]; levelno = comp->numresolutions - 1 - pi->resno; - trx0 = opj_int_ceildiv(pi->tx0, comp->dx << levelno); - try0 = opj_int_ceildiv(pi->ty0, comp->dy << levelno); - trx1 = opj_int_ceildiv(pi->tx1, comp->dx << levelno); - try1 = opj_int_ceildiv(pi->ty1, comp->dy << levelno); + trx0 = opj_int_ceildiv(pi->tx0, (OPJ_INT32)(comp->dx << levelno)); + try0 = opj_int_ceildiv(pi->ty0, (OPJ_INT32)(comp->dy << levelno)); + trx1 = opj_int_ceildiv(pi->tx1, (OPJ_INT32)(comp->dx << levelno)); + try1 = opj_int_ceildiv(pi->ty1, (OPJ_INT32)(comp->dy << levelno)); rpx = res->pdx + levelno; rpy = res->pdy + levelno; - if (!((pi->y % (comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){ + if (!((pi->y % (OPJ_INT32)(comp->dy << rpy) == 0) || ((pi->y == pi->ty0) && ((try0 << levelno) % (1 << rpy))))){ continue; } - if (!((pi->x % (comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ + if (!((pi->x % (OPJ_INT32)(comp->dx << rpx) == 0) || ((pi->x == pi->tx0) && ((trx0 << levelno) % (1 << rpx))))){ continue; } @@ -525,11 +525,11 @@ OPJ_BOOL opj_pi_next_cprl(opj_pi_iterator_t * pi) { if ((trx0==trx1)||(try0==try1)) continue; - prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, comp->dx << levelno), res->pdx) - - opj_int_floordivpow2(trx0, res->pdx); - prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, comp->dy << levelno), res->pdy) - - opj_int_floordivpow2(try0, res->pdy); - pi->precno = prci + prcj * res->pw; + prci = opj_int_floordivpow2(opj_int_ceildiv(pi->x, (OPJ_INT32)(comp->dx << levelno)), (OPJ_INT32)res->pdx) + - opj_int_floordivpow2(trx0, (OPJ_INT32)res->pdx); + prcj = opj_int_floordivpow2(opj_int_ceildiv(pi->y, (OPJ_INT32)(comp->dy << levelno)), (OPJ_INT32)res->pdy) + - opj_int_floordivpow2(try0, (OPJ_INT32)res->pdy); + pi->precno = (OPJ_UINT32)(prci + prcj * (OPJ_INT32)res->pw); for (pi->layno = pi->poc.layno0; pi->layno < pi->poc.layno1; pi->layno++) { index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; if (!pi->include[index]) { @@ -583,10 +583,10 @@ void opj_get_encoding_parameters( const opj_image_t *p_image, q = p_tileno / p_cp->tw; /* find extent of tile */ - *p_tx0 = opj_int_max(p_cp->tx0 + p * p_cp->tdx, p_image->x0); - *p_tx1 = opj_int_min(p_cp->tx0 + (p + 1) * p_cp->tdx, p_image->x1); - *p_ty0 = opj_int_max(p_cp->ty0 + q * p_cp->tdy, p_image->y0); - *p_ty1 = opj_int_min(p_cp->ty0 + (q + 1) * p_cp->tdy, p_image->y1); + *p_tx0 = opj_int_max((OPJ_INT32)(p_cp->tx0 + p * p_cp->tdx), (OPJ_INT32)p_image->x0); + *p_tx1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + (p + 1) * p_cp->tdx), (OPJ_INT32)p_image->x1); + *p_ty0 = opj_int_max((OPJ_INT32)(p_cp->ty0 + q * p_cp->tdy), (OPJ_INT32)p_image->y0); + *p_ty1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + (q + 1) * p_cp->tdy), (OPJ_INT32)p_image->y1); /* max precision is 0 (can only grow) */ *p_max_prec = 0; @@ -606,10 +606,10 @@ void opj_get_encoding_parameters( const opj_image_t *p_image, OPJ_UINT32 l_product; OPJ_INT32 l_tcx0, l_tcy0, l_tcx1, l_tcy1; - l_tcx0 = opj_int_ceildiv(*p_tx0, l_img_comp->dx); - l_tcy0 = opj_int_ceildiv(*p_ty0, l_img_comp->dy); - l_tcx1 = opj_int_ceildiv(*p_tx1, l_img_comp->dx); - l_tcy1 = opj_int_ceildiv(*p_ty1, l_img_comp->dy); + l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx); + l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy); + l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx); + l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy); if (l_tccp->numresolutions > *p_max_res) { *p_max_res = l_tccp->numresolutions; @@ -623,8 +623,8 @@ void opj_get_encoding_parameters( const opj_image_t *p_image, l_pdx = l_tccp->prcw[resno]; l_pdy = l_tccp->prch[resno]; - l_dx = l_img_comp->dx * (1 << (l_pdx + l_tccp->numresolutions - 1 - resno)); - l_dy = l_img_comp->dy * (1 << (l_pdy + l_tccp->numresolutions - 1 - resno)); + l_dx = l_img_comp->dx * (1u << (l_pdx + l_tccp->numresolutions - 1 - resno)); + l_dy = l_img_comp->dy * (1u << (l_pdy + l_tccp->numresolutions - 1 - resno)); /* take the minimum size for dx for each comp and resolution */ *p_dx_min = opj_uint_min(*p_dx_min, l_dx); @@ -633,19 +633,19 @@ void opj_get_encoding_parameters( const opj_image_t *p_image, /* various calculations of extents */ l_level_no = l_tccp->numresolutions - 1 - resno; - l_rx0 = opj_int_ceildivpow2(l_tcx0, l_level_no); - l_ry0 = opj_int_ceildivpow2(l_tcy0, l_level_no); - l_rx1 = opj_int_ceildivpow2(l_tcx1, l_level_no); - l_ry1 = opj_int_ceildivpow2(l_tcy1, l_level_no); + l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no); + l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no); + l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no); + l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no); - l_px0 = opj_int_floordivpow2(l_rx0, l_pdx) << l_pdx; - l_py0 = opj_int_floordivpow2(l_ry0, l_pdy) << l_pdy; - l_px1 = opj_int_ceildivpow2(l_rx1, l_pdx) << l_pdx; + l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx; + l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy; + l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx; - py1 = opj_int_ceildivpow2(l_ry1, l_pdy) << l_pdy; + py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy; - l_pw = (l_rx0==l_rx1)?0:((l_px1 - l_px0) >> l_pdx); - l_ph = (l_ry0==l_ry1)?0:((py1 - l_py0) >> l_pdy); + l_pw = (l_rx0==l_rx1)?0:(OPJ_UINT32)((l_px1 - l_px0) >> l_pdx); + l_ph = (l_ry0==l_ry1)?0:(OPJ_UINT32)((py1 - l_py0) >> l_pdy); l_product = l_pw * l_ph; @@ -702,10 +702,10 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image, q = tileno / p_cp->tw; /* here calculation of tx0, tx1, ty0, ty1, maxprec, l_dx and l_dy */ - *p_tx0 = opj_int_max(p_cp->tx0 + p * p_cp->tdx, p_image->x0); - *p_tx1 = opj_int_min(p_cp->tx0 + (p + 1) * p_cp->tdx, p_image->x1); - *p_ty0 = opj_int_max(p_cp->ty0 + q * p_cp->tdy, p_image->y0); - *p_ty1 = opj_int_min(p_cp->ty0 + (q + 1) * p_cp->tdy, p_image->y1); + *p_tx0 = opj_int_max((OPJ_INT32)(p_cp->tx0 + p * p_cp->tdx), (OPJ_INT32)p_image->x0); + *p_tx1 = opj_int_min((OPJ_INT32)(p_cp->tx0 + (p + 1) * p_cp->tdx), (OPJ_INT32)p_image->x1); + *p_ty0 = opj_int_max((OPJ_INT32)(p_cp->ty0 + q * p_cp->tdy), (OPJ_INT32)p_image->y0); + *p_ty1 = opj_int_min((OPJ_INT32)(p_cp->ty0 + (q + 1) * p_cp->tdy), (OPJ_INT32)p_image->y1); /* max precision and resolution is 0 (can only grow)*/ *p_max_prec = 0; @@ -726,10 +726,10 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image, lResolutionPtr = p_resolutions[compno]; - l_tcx0 = opj_int_ceildiv(*p_tx0, l_img_comp->dx); - l_tcy0 = opj_int_ceildiv(*p_ty0, l_img_comp->dy); - l_tcx1 = opj_int_ceildiv(*p_tx1, l_img_comp->dx); - l_tcy1 = opj_int_ceildiv(*p_ty1, l_img_comp->dy); + l_tcx0 = opj_int_ceildiv(*p_tx0, (OPJ_INT32)l_img_comp->dx); + l_tcy0 = opj_int_ceildiv(*p_ty0, (OPJ_INT32)l_img_comp->dy); + l_tcx1 = opj_int_ceildiv(*p_tx1, (OPJ_INT32)l_img_comp->dx); + l_tcy1 = opj_int_ceildiv(*p_ty1, (OPJ_INT32)l_img_comp->dy); if (l_tccp->numresolutions > *p_max_res) { *p_max_res = l_tccp->numresolutions; @@ -745,23 +745,23 @@ void opj_get_all_encoding_parameters( const opj_image_t *p_image, l_pdy = l_tccp->prch[resno]; *lResolutionPtr++ = l_pdx; *lResolutionPtr++ = l_pdy; - l_dx = l_img_comp->dx * (1 << (l_pdx + l_level_no)); - l_dy = l_img_comp->dy * (1 << (l_pdy + l_level_no)); + l_dx = l_img_comp->dx * (1u << (l_pdx + l_level_no)); + l_dy = l_img_comp->dy * (1u << (l_pdy + l_level_no)); /* take the minimum size for l_dx for each comp and resolution*/ - *p_dx_min = opj_int_min(*p_dx_min, l_dx); - *p_dy_min = opj_int_min(*p_dy_min, l_dy); + *p_dx_min = (OPJ_UINT32)opj_int_min((OPJ_INT32)*p_dx_min, (OPJ_INT32)l_dx); + *p_dy_min = (OPJ_UINT32)opj_int_min((OPJ_INT32)*p_dy_min, (OPJ_INT32)l_dy); /* various calculations of extents*/ - l_rx0 = opj_int_ceildivpow2(l_tcx0, l_level_no); - l_ry0 = opj_int_ceildivpow2(l_tcy0, l_level_no); - l_rx1 = opj_int_ceildivpow2(l_tcx1, l_level_no); - l_ry1 = opj_int_ceildivpow2(l_tcy1, l_level_no); - l_px0 = opj_int_floordivpow2(l_rx0, l_pdx) << l_pdx; - l_py0 = opj_int_floordivpow2(l_ry0, l_pdy) << l_pdy; - l_px1 = opj_int_ceildivpow2(l_rx1, l_pdx) << l_pdx; - py1 = opj_int_ceildivpow2(l_ry1, l_pdy) << l_pdy; - l_pw = (l_rx0==l_rx1)?0:((l_px1 - l_px0) >> l_pdx); - l_ph = (l_ry0==l_ry1)?0:((py1 - l_py0) >> l_pdy); + l_rx0 = opj_int_ceildivpow2(l_tcx0, (OPJ_INT32)l_level_no); + l_ry0 = opj_int_ceildivpow2(l_tcy0, (OPJ_INT32)l_level_no); + l_rx1 = opj_int_ceildivpow2(l_tcx1, (OPJ_INT32)l_level_no); + l_ry1 = opj_int_ceildivpow2(l_tcy1, (OPJ_INT32)l_level_no); + l_px0 = opj_int_floordivpow2(l_rx0, (OPJ_INT32)l_pdx) << l_pdx; + l_py0 = opj_int_floordivpow2(l_ry0, (OPJ_INT32)l_pdy) << l_pdy; + l_px1 = opj_int_ceildivpow2(l_rx1, (OPJ_INT32)l_pdx) << l_pdx; + py1 = opj_int_ceildivpow2(l_ry1, (OPJ_INT32)l_pdy) << l_pdy; + l_pw = (l_rx0==l_rx1)?0:(OPJ_UINT32)((l_px1 - l_px0) >> l_pdx); + l_ph = (l_ry0==l_ry1)?0:(OPJ_UINT32)((py1 - l_py0) >> l_pdy); *lResolutionPtr++ = l_pw; *lResolutionPtr++ = l_ph; l_product = l_pw * l_ph; @@ -890,10 +890,10 @@ void opj_pi_update_encode_poc_and_final ( opj_cp_t *p_cp, l_current_poc->prcS = 0; l_current_poc->prcE = p_max_prec; - l_current_poc->txS = p_tx0; - l_current_poc->txE = p_tx1; - l_current_poc->tyS = p_ty0; - l_current_poc->tyE = p_ty1; + l_current_poc->txS = (OPJ_UINT32)p_tx0; + l_current_poc->txE = (OPJ_UINT32)p_tx1; + l_current_poc->tyS = (OPJ_UINT32)p_ty0; + l_current_poc->tyE = (OPJ_UINT32)p_ty1; l_current_poc->dx = p_dx_min; l_current_poc->dy = p_dy_min; @@ -910,10 +910,10 @@ void opj_pi_update_encode_poc_and_final ( opj_cp_t *p_cp, l_current_poc->layS = (l_current_poc->layE > (l_current_poc-1)->layE) ? l_current_poc->layE : 0; l_current_poc->prcE = p_max_prec; - l_current_poc->txS = p_tx0; - l_current_poc->txE = p_tx1; - l_current_poc->tyS = p_ty0; - l_current_poc->tyE = p_ty1; + l_current_poc->txS = (OPJ_UINT32)p_tx0; + l_current_poc->txE = (OPJ_UINT32)p_tx1; + l_current_poc->tyS = (OPJ_UINT32)p_ty0; + l_current_poc->tyE = (OPJ_UINT32)p_ty1; l_current_poc->dx = p_dx_min; l_current_poc->dy = p_dy_min; ++ l_current_poc; @@ -965,10 +965,10 @@ void opj_pi_update_encode_not_poc ( opj_cp_t *p_cp, l_current_poc->prg = l_tcp->prg; l_current_poc->prcS = 0; l_current_poc->prcE = p_max_prec; - l_current_poc->txS = p_tx0; - l_current_poc->txE = p_tx1; - l_current_poc->tyS = p_ty0; - l_current_poc->tyE = p_ty1; + l_current_poc->txS = (OPJ_UINT32)p_tx0; + l_current_poc->txE = (OPJ_UINT32)p_tx1; + l_current_poc->tyS = (OPJ_UINT32)p_ty0; + l_current_poc->tyE = (OPJ_UINT32)p_ty1; l_current_poc->dx = p_dx_min; l_current_poc->dy = p_dy_min; ++ l_current_poc; @@ -1001,16 +1001,16 @@ void opj_pi_update_decode_poc (opj_pi_iterator_t * p_pi, l_current_poc = p_tcp->pocs; for (pino = 0;pinopoc.prg = l_current_poc->prg; + l_current_pi->poc.prg = l_current_poc->prg; /* Progression Order #0 */ l_current_pi->first = 1; - l_current_pi->poc.resno0 = l_current_poc->resno0; - l_current_pi->poc.compno0 = l_current_poc->compno0; + l_current_pi->poc.resno0 = l_current_poc->resno0; /* Resolution Level Index #0 (Start) */ + l_current_pi->poc.compno0 = l_current_poc->compno0; /* Component Index #0 (Start) */ l_current_pi->poc.layno0 = 0; l_current_pi->poc.precno0 = 0; - l_current_pi->poc.resno1 = l_current_poc->resno1; - l_current_pi->poc.compno1 = l_current_poc->compno1; - l_current_pi->poc.layno1 = l_current_poc->layno1; + l_current_pi->poc.resno1 = l_current_poc->resno1; /* Resolution Level Index #0 (End) */ + l_current_pi->poc.compno1 = l_current_poc->compno1; /* Component Index #0 (End) */ + l_current_pi->poc.layno1 = l_current_poc->layno1; /* Layer Index #0 (End) */ l_current_pi->poc.precno1 = p_max_precision; ++l_current_pi; ++l_current_poc; @@ -1557,10 +1557,10 @@ void opj_pi_create_encode( opj_pi_iterator_t *pi, pi[pino].poc.layno1 = tcp->layE; pi[pino].poc.precno0 = tcp->prcS; pi[pino].poc.precno1 = tcp->prcE; - pi[pino].poc.tx0 = tcp->txS; - pi[pino].poc.ty0 = tcp->tyS; - pi[pino].poc.tx1 = tcp->txE; - pi[pino].poc.ty1 = tcp->tyE; + pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS; + pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS; + pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE; + pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE; }else { for(i=tppos+1;i<4;i++){ switch(prog[i]){ @@ -1584,10 +1584,10 @@ void opj_pi_create_encode( opj_pi_iterator_t *pi, pi[pino].poc.precno1 = tcp->prcE; break; default: - pi[pino].poc.tx0 = tcp->txS; - pi[pino].poc.ty0 = tcp->tyS; - pi[pino].poc.tx1 = tcp->txE; - pi[pino].poc.ty1 = tcp->tyE; + pi[pino].poc.tx0 = (OPJ_INT32)tcp->txS; + pi[pino].poc.ty0 = (OPJ_INT32)tcp->tyS; + pi[pino].poc.tx1 = (OPJ_INT32)tcp->txE; + pi[pino].poc.ty1 = (OPJ_INT32)tcp->tyE; break; } break; @@ -1627,12 +1627,12 @@ void opj_pi_create_encode( opj_pi_iterator_t *pi, default: tcp->tx0_t = tcp->txS; tcp->ty0_t = tcp->tyS; - pi[pino].poc.tx0 = tcp->tx0_t; - pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx); - pi[pino].poc.ty0 = tcp->ty0_t; - pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); - tcp->tx0_t = pi[pino].poc.tx1; - tcp->ty0_t = pi[pino].poc.ty1; + pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t; + pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx - (tcp->tx0_t % tcp->dx)); + pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t; + pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy)); + tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1; + tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1; break; } break; @@ -1662,10 +1662,10 @@ void opj_pi_create_encode( opj_pi_iterator_t *pi, pi[pino].poc.precno1 = tcp->prc_t; break; default: - pi[pino].poc.tx0 = tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx); - pi[pino].poc.tx1 = tcp->tx0_t ; - pi[pino].poc.ty0 = tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy); - pi[pino].poc.ty1 = tcp->ty0_t ; + pi[pino].poc.tx0 = (OPJ_INT32)(tcp->tx0_t - tcp->dx - (tcp->tx0_t % tcp->dx)); + pi[pino].poc.tx1 = (OPJ_INT32)tcp->tx0_t ; + pi[pino].poc.ty0 = (OPJ_INT32)(tcp->ty0_t - tcp->dy - (tcp->ty0_t % tcp->dy)); + pi[pino].poc.ty1 = (OPJ_INT32)tcp->ty0_t ; break; } break; @@ -1752,29 +1752,29 @@ void opj_pi_create_encode( opj_pi_iterator_t *pi, if(tcp->ty0_t >= tcp->tyE){ if(opj_pi_check_next_level(i-1,cp,tileno,pino,prog)){ tcp->ty0_t = tcp->tyS; - pi[pino].poc.ty0 = tcp->ty0_t; - pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); - tcp->ty0_t = pi[pino].poc.ty1; + pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t; + pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy)); + tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1; incr_top=1;resetX=1; }else{ incr_top=0;resetX=0; } }else{ - pi[pino].poc.ty0 = tcp->ty0_t; - pi[pino].poc.ty1 = tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy); - tcp->ty0_t = pi[pino].poc.ty1; + pi[pino].poc.ty0 = (OPJ_INT32)tcp->ty0_t; + pi[pino].poc.ty1 = (OPJ_INT32)(tcp->ty0_t + tcp->dy - (tcp->ty0_t % tcp->dy)); + tcp->ty0_t = (OPJ_UINT32)pi[pino].poc.ty1; incr_top=0;resetX=1; } if(resetX==1){ tcp->tx0_t = tcp->txS; - pi[pino].poc.tx0 = tcp->tx0_t; - pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx); - tcp->tx0_t = pi[pino].poc.tx1; + pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t; + pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx)); + tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1; } }else{ - pi[pino].poc.tx0 = tcp->tx0_t; - pi[pino].poc.tx1 = tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx); - tcp->tx0_t = pi[pino].poc.tx1; + pi[pino].poc.tx0 = (OPJ_INT32)tcp->tx0_t; + pi[pino].poc.tx1 = (OPJ_INT32)(tcp->tx0_t + tcp->dx- (tcp->tx0_t % tcp->dx)); + tcp->tx0_t = (OPJ_UINT32)pi[pino].poc.tx1; incr_top=0; } break; diff --git a/src/lib/openjp2/ppix_manager.c b/src/lib/openjp2/ppix_manager.c index 5428df61..dff49530 100644 --- a/src/lib/openjp2/ppix_manager.c +++ b/src/lib/openjp2/ppix_manager.c @@ -60,7 +60,7 @@ int opj_write_ppix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, /* printf("cstr_info.packno %d\n", cstr_info.packno); //NMAX? */ lenp = -1; - box = (opj_jp2_box_t *)opj_calloc( cstr_info.numcomps, sizeof(opj_jp2_box_t)); + box = (opj_jp2_box_t *)opj_calloc( (size_t)cstr_info.numcomps, sizeof(opj_jp2_box_t)); for (i=0;i<2;i++){ if (i) @@ -75,7 +75,7 @@ int opj_write_ppix( int coff, opj_codestream_info_t cstr_info, OPJ_BOOL EPHused, opj_write_manf( i, cstr_info.numcomps, box, cio, p_manager); for (compno=0; compnobp - raw->start; + const ptrdiff_t diff = raw->bp - raw->start; + assert( diff <= (ptrdiff_t)0xffffffff && diff >= 0 ); /* UINT32_MAX */ + return (OPJ_UINT32)diff; } void opj_raw_init_dec(opj_raw_t *raw, OPJ_BYTE *bp, OPJ_UINT32 len) { diff --git a/src/lib/openjp2/t1.c b/src/lib/openjp2/t1.c index 6e2b557f..59a219da 100644 --- a/src/lib/openjp2/t1.c +++ b/src/lib/openjp2/t1.c @@ -62,6 +62,7 @@ static void opj_t1_enc_sigpass_step(opj_t1_t *t1, /** Decode significant pass */ +#if 0 static void opj_t1_dec_sigpass_step(opj_t1_t *t1, opj_flag_t *flagsp, OPJ_INT32 *datap, @@ -69,6 +70,7 @@ static void opj_t1_dec_sigpass_step(opj_t1_t *t1, OPJ_INT32 oneplushalf, OPJ_BYTE type, OPJ_UINT32 vsc); +#endif static INLINE void opj_t1_dec_sigpass_step_raw( opj_t1_t *t1, @@ -161,6 +163,7 @@ static void opj_t1_dec_refpass_mqc_vsc( /** Decode refinement pass */ +#if 0 static void opj_t1_dec_refpass_step(opj_t1_t *t1, opj_flag_t *flagsp, OPJ_INT32 *datap, @@ -168,6 +171,7 @@ static void opj_t1_dec_refpass_step(opj_t1_t *t1, OPJ_INT32 neghalf, OPJ_BYTE type, OPJ_UINT32 vsc); +#endif static INLINE void opj_t1_dec_refpass_step_raw( opj_t1_t *t1, @@ -367,25 +371,25 @@ void opj_t1_enc_sigpass_step( opj_t1_t *t1, opj_mqc_t *mqc = t1->mqc; /* MQC component */ - flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + flag = vsc ? (OPJ_UINT32)((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (OPJ_UINT32)(*flagsp); if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { v = opj_int_abs(*datap) & one ? 1 : 0; opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient)); /* ESSAI */ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - opj_mqc_bypass_enc(mqc, v); + opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v); } else { - opj_mqc_encode(mqc, v); + opj_mqc_encode(mqc, (OPJ_UINT32)v); } if (v) { v = *datap < 0 ? 1 : 0; - *nmsedec += opj_t1_getnmsedec_sig(opj_int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS); + *nmsedec += opj_t1_getnmsedec_sig((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS)); opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag)); /* ESSAI */ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - opj_mqc_bypass_enc(mqc, v); + opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v); } else { - opj_mqc_encode(mqc, v ^ opj_t1_getspb(flag)); + opj_mqc_encode(mqc, (OPJ_UINT32)(v ^ opj_t1_getspb((OPJ_UINT32)flag))); } - opj_t1_updateflags(flagsp, v, t1->flags_stride); + opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride); } *flagsp |= T1_VISIT; } @@ -407,9 +411,9 @@ static INLINE void opj_t1_dec_sigpass_step_raw( flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { if (opj_raw_decode(raw)) { - v = opj_raw_decode(raw); /* ESSAI */ + v = (OPJ_INT32)opj_raw_decode(raw); /* ESSAI */ *datap = v ? -oneplushalf : oneplushalf; - opj_t1_updateflags(flagsp, v, t1->flags_stride); + opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride); } *flagsp |= T1_VISIT; } @@ -428,12 +432,12 @@ INLINE void opj_t1_dec_sigpass_step_mqc( flag = *flagsp; if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient)); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient)); if (opj_mqc_decode(mqc)) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag)); - v = opj_mqc_decode(mqc) ^ opj_t1_getspb(flag); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag)); + v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag); *datap = v ? -oneplushalf : oneplushalf; - opj_t1_updateflags(flagsp, v, t1->flags_stride); + opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride); } *flagsp |= T1_VISIT; } @@ -453,12 +457,12 @@ INLINE void opj_t1_dec_sigpass_step_mqc_vsc( flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient)); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient)); if (opj_mqc_decode(mqc)) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag)); - v = opj_mqc_decode(mqc) ^ opj_t1_getspb(flag); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag)); + v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag); *datap = v ? -oneplushalf : oneplushalf; - opj_t1_updateflags(flagsp, v, t1->flags_stride); + opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride); } *flagsp |= T1_VISIT; } @@ -537,7 +541,7 @@ void opj_t1_dec_sigpass_mqc( one = 1 << bpno; half = one >> 1; oneplushalf = one | half; - for (k = 0; k < (t1->h & ~3); k += 4) { + for (k = 0; k < (t1->h & ~3u); k += 4) { for (i = 0; i < t1->w; ++i) { OPJ_INT32 *data2 = data1 + i; opj_flag_t *flags2 = flags1 + i; @@ -610,15 +614,15 @@ void opj_t1_enc_refpass_step( opj_t1_t *t1, opj_mqc_t *mqc = t1->mqc; /* MQC component */ - flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + flag = vsc ? (OPJ_UINT32)((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (OPJ_UINT32)(*flagsp); if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { - *nmsedec += opj_t1_getnmsedec_ref(opj_int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS); + *nmsedec += opj_t1_getnmsedec_ref((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS)); v = opj_int_abs(*datap) & one ? 1 : 0; opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag(flag)); /* ESSAI */ if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - opj_mqc_bypass_enc(mqc, v); + opj_mqc_bypass_enc(mqc, (OPJ_UINT32)v); } else { - opj_mqc_encode(mqc, v); + opj_mqc_encode(mqc, (OPJ_UINT32)v); } *flagsp |= T1_REFINE; } @@ -638,7 +642,7 @@ INLINE void opj_t1_dec_refpass_step_raw( flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { - v = opj_raw_decode(raw); + v = (OPJ_INT32)opj_raw_decode(raw); t = v ? poshalf : neghalf; *datap += *datap < 0 ? -t : t; *flagsp |= T1_REFINE; @@ -658,7 +662,7 @@ INLINE void opj_t1_dec_refpass_step_mqc( flag = *flagsp; if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag(flag)); /* ESSAI */ + opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag((OPJ_UINT32)flag)); /* ESSAI */ v = opj_mqc_decode(mqc); t = v ? poshalf : neghalf; *datap += *datap < 0 ? -t : t; @@ -680,7 +684,7 @@ INLINE void opj_t1_dec_refpass_step_mqc_vsc( flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag(flag)); /* ESSAI */ + opj_mqc_setcurctx(mqc, opj_t1_getctxno_mag((OPJ_UINT32)flag)); /* ESSAI */ v = opj_mqc_decode(mqc); t = v ? poshalf : neghalf; *datap += *datap < 0 ? -t : t; @@ -757,7 +761,7 @@ void opj_t1_dec_refpass_mqc( one = 1 << bpno; poshalf = one >> 1; neghalf = bpno > 0 ? -poshalf : -1; - for (k = 0; k < (t1->h & ~3); k += 4) { + for (k = 0; k < (t1->h & ~3u); k += 4) { for (i = 0; i < t1->w; ++i) { OPJ_INT32 *data2 = data1 + i; opj_flag_t *flags2 = flags1 + i; @@ -831,21 +835,21 @@ void opj_t1_enc_clnpass_step( opj_mqc_t *mqc = t1->mqc; /* MQC component */ - flag = vsc ? ((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*flagsp); + flag = vsc ? (OPJ_UINT32)((*flagsp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (OPJ_UINT32)(*flagsp); if (partial) { goto LABEL_PARTIAL; } if (!(*flagsp & (T1_SIG | T1_VISIT))) { opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient)); v = opj_int_abs(*datap) & one ? 1 : 0; - opj_mqc_encode(mqc, v); + opj_mqc_encode(mqc, (OPJ_UINT32)v); if (v) { LABEL_PARTIAL: - *nmsedec += opj_t1_getnmsedec_sig(opj_int_abs(*datap), bpno + T1_NMSEDEC_FRACBITS); + *nmsedec += opj_t1_getnmsedec_sig((OPJ_UINT32)opj_int_abs(*datap), (OPJ_UINT32)(bpno + T1_NMSEDEC_FRACBITS)); opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag)); v = *datap < 0 ? 1 : 0; - opj_mqc_encode(mqc, v ^ opj_t1_getspb(flag)); - opj_t1_updateflags(flagsp, v, t1->flags_stride); + opj_mqc_encode(mqc, (OPJ_UINT32)(v ^ opj_t1_getspb((OPJ_UINT32)flag))); + opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride); } } *flagsp &= ~T1_VISIT; @@ -864,10 +868,10 @@ static void opj_t1_dec_clnpass_step_partial( OPJ_ARG_NOT_USED(orient); flag = *flagsp; - opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag)); - v = opj_mqc_decode(mqc) ^ opj_t1_getspb(flag); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag)); + v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag); *datap = v ? -oneplushalf : oneplushalf; - opj_t1_updateflags(flagsp, v, t1->flags_stride); + opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride); *flagsp &= ~T1_VISIT; } /* VSC and BYPASS by Antonin */ @@ -884,12 +888,12 @@ static void opj_t1_dec_clnpass_step( flag = *flagsp; if (!(flag & (T1_SIG | T1_VISIT))) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient)); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient)); if (opj_mqc_decode(mqc)) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag)); - v = opj_mqc_decode(mqc) ^ opj_t1_getspb(flag); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag)); + v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag); *datap = v ? -oneplushalf : oneplushalf; - opj_t1_updateflags(flagsp, v, t1->flags_stride); + opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride); } } *flagsp &= ~T1_VISIT; @@ -913,13 +917,13 @@ static void opj_t1_dec_clnpass_step_vsc( goto LABEL_PARTIAL; } if (!(flag & (T1_SIG | T1_VISIT))) { - opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc(flag, orient)); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_zc((OPJ_UINT32)flag, (OPJ_UINT32)orient)); if (opj_mqc_decode(mqc)) { LABEL_PARTIAL: - opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc(flag)); - v = opj_mqc_decode(mqc) ^ opj_t1_getspb(flag); + opj_mqc_setcurctx(mqc, opj_t1_getctxno_sc((OPJ_UINT32)flag)); + v = opj_mqc_decode(mqc) ^ opj_t1_getspb((OPJ_UINT32)flag); *datap = v ? -oneplushalf : oneplushalf; - opj_t1_updateflags(flagsp, v, t1->flags_stride); + opj_t1_updateflags(flagsp, (OPJ_UINT32)v, t1->flags_stride); } } *flagsp &= ~T1_VISIT; @@ -1029,7 +1033,7 @@ static void opj_t1_dec_clnpass( } else { runlen = 0; } - for (j = k + runlen; j < k + 4 && j < t1->h; ++j) { + for (j = k + (OPJ_UINT32)runlen; j < k + 4 && j < t1->h; ++j) { vsc = (j == k + 3 || j == t1->h - 1) ? 1 : 0; opj_t1_dec_clnpass_step_vsc( t1, @@ -1037,7 +1041,7 @@ static void opj_t1_dec_clnpass( &t1->data[(j * t1->w) + i], orient, oneplushalf, - agg && (j == k + runlen), + agg && (j == k + (OPJ_UINT32)runlen), vsc); } } @@ -1045,7 +1049,7 @@ static void opj_t1_dec_clnpass( } else { OPJ_INT32 *data1 = t1->data; opj_flag_t *flags1 = &t1->flags[1]; - for (k = 0; k < (t1->h & ~3); k += 4) { + for (k = 0; k < (t1->h & ~3u); k += 4) { for (i = 0; i < t1->w; ++i) { OPJ_INT32 *data2 = data1 + i; opj_flag_t *flags2 = flags1 + i; @@ -1061,11 +1065,11 @@ static void opj_t1_dec_clnpass( opj_mqc_setcurctx(mqc, T1_CTXNO_UNI); runlen = opj_mqc_decode(mqc); runlen = (runlen << 1) | opj_mqc_decode(mqc); - flags2 += runlen * t1->flags_stride; - data2 += runlen * t1->w; - for (j = k + runlen; j < k + 4 && j < t1->h; ++j) { + flags2 += (OPJ_UINT32)runlen * t1->flags_stride; + data2 += (OPJ_UINT32)runlen * t1->w; + for (j = k + (OPJ_UINT32)runlen; j < k + 4 && j < t1->h; ++j) { flags2 += t1->flags_stride; - if (agg && (j == k + runlen)) { + if (agg && (j == k + (OPJ_UINT32)runlen)) { opj_t1_dec_clnpass_step_partial(t1, flags2, data2, orient, oneplushalf); } else { opj_t1_dec_clnpass_step(t1, flags2, data2, orient, oneplushalf); @@ -1256,7 +1260,7 @@ OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1, ) { OPJ_UINT32 resno, bandno, precno, cblkno; - OPJ_UINT32 tile_w = tilec->x1 - tilec->x0; + OPJ_UINT32 tile_w = (OPJ_UINT32)(tilec->x1 - tilec->x0); for (resno = 0; resno < tilec->minimum_num_resolutions; ++resno) { opj_tcd_resolution_t* res = &tilec->resolutions[resno]; @@ -1279,7 +1283,7 @@ OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1, t1, cblk, band->bandno, - tccp->roishift, + (OPJ_UINT32)tccp->roishift, tccp->cblksty)) { return OPJ_FALSE; } @@ -1315,7 +1319,7 @@ OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1, /*tiledp=(void*)&tilec->data[(y * tile_w) + x];*/ if (tccp->qmfbid == 1) { - OPJ_INT32* restrict tiledp = &tilec->data[(y * tile_w) + x]; + OPJ_INT32* restrict tiledp = &tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x]; for (j = 0; j < cblk_h; ++j) { for (i = 0; i < cblk_w; ++i) { OPJ_INT32 tmp = datap[(j * cblk_w) + i]; @@ -1323,11 +1327,11 @@ OPJ_BOOL opj_t1_decode_cblks( opj_t1_t* t1, } } } else { /* if (tccp->qmfbid == 0) */ - OPJ_FLOAT32* restrict tiledp = (OPJ_FLOAT32*) &tilec->data[(y * tile_w) + x]; + OPJ_FLOAT32* restrict tiledp = (OPJ_FLOAT32*) &tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x]; for (j = 0; j < cblk_h; ++j) { OPJ_FLOAT32* restrict tiledp2 = tiledp; for (i = 0; i < cblk_w; ++i) { - OPJ_FLOAT32 tmp = *datap * band->stepsize; + OPJ_FLOAT32 tmp = (OPJ_FLOAT32)*datap * band->stepsize; *tiledp2 = tmp; datap++; tiledp2++; @@ -1366,13 +1370,13 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1, if(!opj_t1_allocate_buffers( t1, - cblk->x1 - cblk->x0, - cblk->y1 - cblk->y0)) + (OPJ_UINT32)(cblk->x1 - cblk->x0), + (OPJ_UINT32)(cblk->y1 - cblk->y0))) { return OPJ_FALSE; } - bpno = roishift + cblk->numbps - 1; + bpno = (OPJ_INT32)(roishift + cblk->numbps - 1); passtype = 2; opj_mqc_resetstates(mqc); @@ -1401,18 +1405,18 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1, switch (passtype) { case 0: if (type == T1_TYPE_RAW) { - opj_t1_dec_sigpass_raw(t1, bpno+1, orient, cblksty); + opj_t1_dec_sigpass_raw(t1, bpno+1, (OPJ_INT32)orient, (OPJ_INT32)cblksty); } else { if (cblksty & J2K_CCP_CBLKSTY_VSC) { - opj_t1_dec_sigpass_mqc_vsc(t1, bpno+1, orient); + opj_t1_dec_sigpass_mqc_vsc(t1, bpno+1, (OPJ_INT32)orient); } else { - opj_t1_dec_sigpass_mqc(t1, bpno+1, orient); + opj_t1_dec_sigpass_mqc(t1, bpno+1, (OPJ_INT32)orient); } } break; case 1: if (type == T1_TYPE_RAW) { - opj_t1_dec_refpass_raw(t1, bpno+1, cblksty); + opj_t1_dec_refpass_raw(t1, bpno+1, (OPJ_INT32)cblksty); } else { if (cblksty & J2K_CCP_CBLKSTY_VSC) { opj_t1_dec_refpass_mqc_vsc(t1, bpno+1); @@ -1422,7 +1426,7 @@ OPJ_BOOL opj_t1_decode_cblk(opj_t1_t *t1, } break; case 2: - opj_t1_dec_clnpass(t1, bpno+1, orient, cblksty); + opj_t1_dec_clnpass(t1, bpno+1, (OPJ_INT32)orient, (OPJ_INT32)cblksty); break; } @@ -1457,7 +1461,7 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1, for (compno = 0; compno < tile->numcomps; ++compno) { opj_tcd_tilecomp_t* tilec = &tile->comps[compno]; opj_tccp_t* tccp = &tcp->tccps[compno]; - OPJ_UINT32 tile_w = tilec->x1 - tilec->x0; + OPJ_UINT32 tile_w = (OPJ_UINT32)(tilec->x1 - tilec->x0); for (resno = 0; resno < tilec->numresolutions; ++resno) { opj_tcd_resolution_t *res = &tilec->resolutions[resno]; @@ -1490,8 +1494,8 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1, if(!opj_t1_allocate_buffers( t1, - cblk->x1 - cblk->x0, - cblk->y1 - cblk->y0)) + (OPJ_UINT32)(cblk->x1 - cblk->x0), + (OPJ_UINT32)(cblk->y1 - cblk->y0))) { return OPJ_FALSE; } @@ -1500,7 +1504,7 @@ OPJ_BOOL opj_t1_encode_cblks( opj_t1_t *t1, cblk_w = t1->w; cblk_h = t1->h; - tiledp=&tilec->data[(y * tile_w) + x]; + tiledp=&tilec->data[(OPJ_UINT32)y * tile_w + (OPJ_UINT32)x]; if (tccp->qmfbid == 1) { for (j = 0; j < cblk_h; ++j) { for (i = 0; i < cblk_w; ++i) { @@ -1573,9 +1577,9 @@ void opj_t1_encode_cblk(opj_t1_t *t1, max = opj_int_max(max, tmp); } - cblk->numbps = max ? (opj_int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0; + cblk->numbps = max ? (OPJ_UINT32)((opj_int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS) : 0; - bpno = cblk->numbps - 1; + bpno = (OPJ_INT32)(cblk->numbps - 1); passtype = 2; opj_mqc_resetstates(mqc); @@ -1678,6 +1682,7 @@ void opj_t1_encode_cblk(opj_t1_t *t1, } } +#if 0 void opj_t1_dec_refpass_step( opj_t1_t *t1, opj_flag_t *flagsp, OPJ_INT32 *datap, @@ -1705,9 +1710,11 @@ void opj_t1_dec_refpass_step( opj_t1_t *t1, *flagsp |= T1_REFINE; } } /* VSC and BYPASS by Antonin */ +#endif +#if 0 void opj_t1_dec_sigpass_step( opj_t1_t *t1, opj_flag_t *flagsp, OPJ_INT32 *datap, @@ -1741,4 +1748,4 @@ void opj_t1_dec_sigpass_step( opj_t1_t *t1, *flagsp |= T1_VISIT; } } /* VSC and BYPASS by Antonin */ - +#endif diff --git a/src/lib/openjp2/t1_generate_luts.c b/src/lib/openjp2/t1_generate_luts.c index d1843248..b2944d8c 100644 --- a/src/lib/openjp2/t1_generate_luts.c +++ b/src/lib/openjp2/t1_generate_luts.c @@ -181,7 +181,8 @@ static void dump_array16(int array[],int size){ printf("0x%04x\n};\n\n", array[size]); } -int main(){ +int main(int argc, char **argv) +{ int i, j; double u, v, t; @@ -190,6 +191,7 @@ int main(){ int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS]; int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS]; int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS]; + (void)argc; (void)argv; printf("/* This file was automatically generated by t1_generate_luts.c */\n\n"); diff --git a/src/lib/openjp2/t2.c b/src/lib/openjp2/t2.c index a3cf75d9..253d14f8 100644 --- a/src/lib/openjp2/t2.c +++ b/src/lib/openjp2/t2.c @@ -311,6 +311,19 @@ OPJ_BOOL opj_t2_encode_packets( opj_t2_t* p_t2, return OPJ_TRUE; } +/* see issue 80 */ +#if 0 +#define JAS_FPRINTF fprintf +#else +/* issue 290 */ +static void opj_null_jas_fprintf(FILE* file, const char * format, ...) +{ + (void)file; + (void)format; +} +#define JAS_FPRINTF opj_null_jas_fprintf +#endif + OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2, OPJ_UINT32 p_tile_no, opj_tcd_tile_t *p_tile, @@ -354,8 +367,8 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2, for (pino = 0; pino <= l_tcp->numpocs; ++pino) { - /* if the resolution needed is to low, one dim of the tilec could be equal to zero - * and no packets are used to encode this resolution and + /* if the resolution needed is too low, one dim of the tilec could be equal to zero + * and no packets are used to decode this resolution and * l_current_pi->resno is always >= p_tile->comps[l_current_pi->compno].minimum_num_resolutions * and no l_img_comp->resno_decoded are computed */ @@ -368,7 +381,8 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2, memset(first_pass_failed, OPJ_TRUE, l_image->numcomps * sizeof(OPJ_BOOL)); while (opj_pi_next(l_current_pi)) { - + JAS_FPRINTF( stderr, "packet offset=00000166 prg=%d cmptno=%02d rlvlno=%02d prcno=%03d lyrno=%02d\n\n", + l_current_pi->poc.prg1, l_current_pi->compno, l_current_pi->resno, l_current_pi->precno, l_current_pi->layno ); if (l_tcp->num_layers_to_decode > l_current_pi->layno && l_current_pi->resno < p_tile->comps[l_current_pi->compno].minimum_num_resolutions) { @@ -441,7 +455,7 @@ OPJ_BOOL opj_t2_decode_packets( opj_t2_t *p_t2, /* don't forget to release pi */ opj_pi_destroy(l_pi,l_nb_pocs); - *p_data_read = l_current_data - p_src; + *p_data_read = (OPJ_UINT32)(l_current_data - p_src); return OPJ_TRUE; } @@ -546,8 +560,13 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, c[1] = 145; c[2] = 0; c[3] = 4; +#if 0 c[4] = (tile->packno % 65536) / 256; c[5] = (tile->packno % 65536) % 256; +#else + c[4] = (tile->packno >> 8) & 0xff; /* packno is uint32_t */ + c[5] = tile->packno & 0xff; +#endif c += 6; length -= 6; } @@ -567,7 +586,7 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, cblk = &prc->cblks.enc[cblkno]; cblk->numpasses = 0; - opj_tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps); + opj_tgt_setvalue(prc->imsbtree, cblkno, band->numbps - (OPJ_INT32)cblk->numbps); } ++band; } @@ -589,7 +608,7 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, opj_tcd_layer_t *layer = &cblk->layers[layno]; if (!cblk->numpasses && layer->numpasses) { - opj_tgt_setvalue(prc->incltree, cblkno, layno); + opj_tgt_setvalue(prc->incltree, cblkno, (OPJ_INT32)layno); } ++cblk; @@ -605,7 +624,7 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, /* cblk inclusion bits */ if (!cblk->numpasses) { - opj_tgt_encode(bio, prc->incltree, cblkno, layno + 1); + opj_tgt_encode(bio, prc->incltree, cblkno, (OPJ_INT32)(layno + 1)); } else { opj_bio_write(bio, layer->numpasses != 0, 1); } @@ -633,14 +652,15 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, len += pass->len; if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { - increment = opj_int_max(increment, opj_int_floorlog2(len) + 1 - (cblk->numlenbits + opj_int_floorlog2(nump))); + increment = (OPJ_UINT32)opj_int_max((OPJ_INT32)increment, opj_int_floorlog2((OPJ_INT32)len) + 1 + - ((OPJ_INT32)cblk->numlenbits + opj_int_floorlog2((OPJ_INT32)nump))); len = 0; nump = 0; } ++pass; } - opj_t2_putcommacode(bio, increment); + opj_t2_putcommacode(bio, (OPJ_INT32)increment); /* computation of the new Length indicator */ cblk->numlenbits += increment; @@ -652,7 +672,7 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, len += pass->len; if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { - opj_bio_write(bio, len, cblk->numlenbits + opj_int_floorlog2(nump)); + opj_bio_write(bio, (OPJ_UINT32)len, cblk->numlenbits + (OPJ_UINT32)opj_int_floorlog2((OPJ_INT32)nump)); len = 0; nump = 0; } @@ -670,7 +690,7 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, return OPJ_FALSE; /* modified to eliminate longjmp !! */ } - l_nb_bytes = opj_bio_numbytes(bio); + l_nb_bytes = (OPJ_UINT32)opj_bio_numbytes(bio); c += l_nb_bytes; length -= l_nb_bytes; @@ -734,7 +754,8 @@ OPJ_BOOL opj_t2_encode_packet( OPJ_UINT32 tileno, ++band; } - * p_data_written += (c - dest); + assert( c >= dest ); + * p_data_written += (OPJ_UINT32)(c - dest); return OPJ_TRUE; } @@ -778,7 +799,6 @@ static OPJ_BOOL opj_t2_skip_packet( opj_t2_t* p_t2, } - OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, opj_tcd_tile_t *p_tile, opj_tcp_t *p_tcp, @@ -835,8 +855,13 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, /* SOP markers */ if (p_tcp->csty & J2K_CP_CSTY_SOP) { - if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) { - /* TODO opj_event_msg(t2->cinfo->event_mgr, EVT_WARNING, "Expected SOP marker\n"); */ + if (p_max_length < 6) { + /* TODO opj_event_msg(p_t2->cinfo->event_mgr, EVT_WARNING, "Not enough space for expected SOP marker\n"); */ + printf("Not enough space for expected SOP marker\n"); + } else if ((*l_current_data) != 0xff || (*(l_current_data + 1) != 0x91)) { + /* TODO opj_event_msg(p_t2->cinfo->event_mgr, EVT_WARNING, "Expected SOP marker\n"); */ + printf("Expected SOP marker\n"); + fprintf(stderr, "Error : expected SOP marker\n"); } else { l_current_data += 6; } @@ -870,13 +895,14 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, else { /* Normal Case */ l_header_data_start = &(l_current_data); l_header_data = *l_header_data_start; - l_remaining_length = p_src_data+p_max_length-l_header_data; + l_remaining_length = (OPJ_UINT32)(p_src_data+p_max_length-l_header_data); l_modified_length_ptr = &(l_remaining_length); } opj_bio_init_dec(l_bio, l_header_data,*l_modified_length_ptr); l_present = opj_bio_read(l_bio, 1); + JAS_FPRINTF(stderr, "present=%d \n", l_present ); if (!l_present) { /* TODO MSD: no test to control the output of this function*/ opj_bio_inalign(l_bio); @@ -885,14 +911,16 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, /* EPH markers */ if (p_tcp->csty & J2K_CP_CSTY_EPH) { - if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) { - printf("Error : expected EPH marker\n"); + if (p_max_length < 2) { + fprintf(stderr, "Not enough space for expected EPH marker\n"); + } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) { + fprintf(stderr, "Error : expected EPH marker\n"); } else { l_header_data += 2; } } - l_header_length = (l_header_data - *l_header_data_start); + l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start); *l_modified_length_ptr -= l_header_length; *l_header_data_start += l_header_length; @@ -905,7 +933,7 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, /* INDEX >> */ * p_is_data_present = OPJ_FALSE; - *p_data_read = l_current_data - p_src_data; + *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data); return OPJ_TRUE; } @@ -926,7 +954,7 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, /* if cblk not yet included before --> inclusion tagtree */ if (!l_cblk->numsegs) { - l_included = opj_tgt_decode(l_bio, l_prc->incltree, cblkno, p_pi->layno + 1); + l_included = opj_tgt_decode(l_bio, l_prc->incltree, cblkno, (OPJ_INT32)(p_pi->layno + 1)); /* else one bit */ } else { @@ -937,6 +965,7 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, if (!l_included) { l_cblk->numnewpasses = 0; ++l_cblk; + JAS_FPRINTF(stderr, "included=%d \n", l_included); continue; } @@ -944,11 +973,11 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, if (!l_cblk->numsegs) { OPJ_UINT32 i = 0; - while (!opj_tgt_decode(l_bio, l_prc->imsbtree, cblkno, i)) { + while (!opj_tgt_decode(l_bio, l_prc->imsbtree, cblkno, (OPJ_INT32)i)) { ++i; } - l_cblk->numbps = l_band->numbps + 1 - i; + l_cblk->numbps = (OPJ_UINT32)l_band->numbps + 1 - i; l_cblk->numlenbits = 3; } @@ -976,13 +1005,14 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, } } } - n = l_cblk->numnewpasses; + n = (OPJ_INT32)l_cblk->numnewpasses; do { - l_cblk->segs[l_segno].numnewpasses = opj_int_min(l_cblk->segs[l_segno].maxpasses - l_cblk->segs[l_segno].numpasses, n); + l_cblk->segs[l_segno].numnewpasses = (OPJ_UINT32)opj_int_min((OPJ_INT32)(l_cblk->segs[l_segno].maxpasses - l_cblk->segs[l_segno].numpasses), n); l_cblk->segs[l_segno].newlen = opj_bio_read(l_bio, l_cblk->numlenbits + opj_uint_floorlog2(l_cblk->segs[l_segno].numnewpasses)); + JAS_FPRINTF(stderr, "included=%d numnewpasses=%d increment=%d len=%d \n", l_included, l_cblk->segs[l_segno].numnewpasses, l_increment, l_cblk->segs[l_segno].newlen ); - n -= l_cblk->segs[l_segno].numnewpasses; + n -= (OPJ_INT32)l_cblk->segs[l_segno].numnewpasses; if (n > 0) { ++l_segno; @@ -1009,14 +1039,19 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, /* EPH markers */ if (p_tcp->csty & J2K_CP_CSTY_EPH) { - if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) { + if (p_max_length < 2) { + fprintf(stderr, "Not enough space for expected EPH marker\n"); + } else if ((*l_header_data) != 0xff || (*(l_header_data + 1) != 0x92)) { /* TODO opj_event_msg(t2->cinfo->event_mgr, EVT_ERROR, "Expected EPH marker\n"); */ + fprintf(stderr, "Error : expected EPH marker\n"); } else { l_header_data += 2; } } - l_header_length = (l_header_data - *l_header_data_start); + l_header_length = (OPJ_UINT32)(l_header_data - *l_header_data_start); + JAS_FPRINTF( stderr, "hdrlen=%d \n", l_header_length ); + JAS_FPRINTF( stderr, "packet body\n"); *l_modified_length_ptr -= l_header_length; *l_header_data_start += l_header_length; @@ -1029,7 +1064,7 @@ OPJ_BOOL opj_t2_read_packet_header( opj_t2_t* p_t2, /* INDEX >> */ *p_is_data_present = OPJ_TRUE; - *p_data_read = l_current_data - p_src_data; + *p_data_read = (OPJ_UINT32)(l_current_data - p_src_data); return OPJ_TRUE; } @@ -1089,6 +1124,8 @@ OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2, do { if (l_current_data + l_seg->newlen > p_src_data + p_max_length) { + fprintf(stderr, "read: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", + l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno); return OPJ_FALSE; } @@ -1152,7 +1189,7 @@ OPJ_BOOL opj_t2_read_packet_data( opj_t2_t* p_t2, ++l_band; } - *(p_data_read) = l_current_data - p_src_data; + *(p_data_read) = (OPJ_UINT32)(l_current_data - p_src_data); return OPJ_TRUE; } @@ -1212,6 +1249,8 @@ OPJ_BOOL opj_t2_skip_packet_data( opj_t2_t* p_t2, do { if (* p_data_read + l_seg->newlen > p_max_length) { + fprintf(stderr, "skip: segment too long (%d) with max (%d) for codeblock %d (p=%d, b=%d, r=%d, c=%d)\n", + l_seg->newlen, p_max_length, cblkno, p_pi->precno, bandno, p_pi->resno, p_pi->compno); return OPJ_FALSE; } @@ -1234,6 +1273,7 @@ OPJ_BOOL opj_t2_skip_packet_data( opj_t2_t* p_t2, }; #endif /* USE_JPWL */ + JAS_FPRINTF(stderr, "p_data_read (%d) newlen (%d) \n", *p_data_read, l_seg->newlen ); *(p_data_read) += l_seg->newlen; l_seg->numpasses += l_seg->numnewpasses; diff --git a/src/lib/openjp2/tcd.c b/src/lib/openjp2/tcd.c index fc77b5e4..147bc681 100644 --- a/src/lib/openjp2/tcd.c +++ b/src/lib/openjp2/tcd.c @@ -301,7 +301,7 @@ void opj_tcd_makelayer_fixed(opj_tcd_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final) for (j = 0; j < tilec->numresolutions; j++) { for (k = 0; k < 3; k++) { matrice[i][j][k] = - (OPJ_INT32) (cp->m_specific_param.m_enc.m_matrice[i * tilec->numresolutions * 3 + j * 3 + k] + (OPJ_INT32) ((OPJ_FLOAT32)cp->m_specific_param.m_enc.m_matrice[i * tilec->numresolutions * 3 + j * 3 + k] * (OPJ_FLOAT32) (tcd->image->comps[compno].prec / 16.0)); } } @@ -320,7 +320,7 @@ void opj_tcd_makelayer_fixed(opj_tcd_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final) opj_tcd_cblk_enc_t *cblk = &prc->cblks.enc[cblkno]; opj_tcd_layer_t *layer = &cblk->layers[layno]; OPJ_UINT32 n; - OPJ_INT32 imsb = tcd->image->comps[compno].prec - cblk->numbps; /* number of bit-plan equal to zero */ + OPJ_INT32 imsb = (OPJ_INT32)(tcd->image->comps[compno].prec - cblk->numbps); /* number of bit-plan equal to zero */ /* Correction of the matrix of coefficient to include the IMSB information */ if (layno == 0) { @@ -347,12 +347,12 @@ void opj_tcd_makelayer_fixed(opj_tcd_t *tcd, OPJ_UINT32 layno, OPJ_UINT32 final) n = cblk->numpassesinlayers; if (cblk->numpassesinlayers == 0) { if (value != 0) { - n = 3 * value - 2 + cblk->numpassesinlayers; + n = 3 * (OPJ_UINT32)value - 2 + cblk->numpassesinlayers; } else { n = cblk->numpassesinlayers; } } else { - n = 3 * value + cblk->numpassesinlayers; + n = 3 * (OPJ_UINT32)value + cblk->numpassesinlayers; } layer->numpasses = n - cblk->numpassesinlayers; @@ -421,10 +421,10 @@ OPJ_BOOL opj_tcd_rateallocate( opj_tcd_t *tcd, OPJ_FLOAT64 dd, rdslope; if (passno == 0) { - dr = pass->rate; + dr = (OPJ_INT32)pass->rate; dd = pass->distortiondec; } else { - dr = pass->rate - cblk->passes[passno - 1].rate; + dr = (OPJ_INT32)(pass->rate - cblk->passes[passno - 1].rate); dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec; } @@ -580,7 +580,7 @@ OPJ_BOOL opj_tcd_init( opj_tcd_t *p_tcd, } memset(p_tcd->tcd_image->tiles,0, sizeof(opj_tcd_tile_t)); - l_tile_comp_size = p_image->numcomps * sizeof(opj_tcd_tilecomp_t); + l_tile_comp_size = p_image->numcomps * (OPJ_UINT32)sizeof(opj_tcd_tilecomp_t); p_tcd->tcd_image->tiles->comps = (opj_tcd_tilecomp_t *) opj_malloc(l_tile_comp_size); if (! p_tcd->tcd_image->tiles->comps ) { return OPJ_FALSE; @@ -659,10 +659,15 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ /*fprintf(stderr, "Tile coordinate = %d,%d\n", p, q);*/ \ \ /* 4 borders of the tile rescale on the image if necessary */ \ - l_tile->x0 = opj_int_max(l_cp->tx0 + p * l_cp->tdx, l_image->x0); \ - l_tile->y0 = opj_int_max(l_cp->ty0 + q * l_cp->tdy, l_image->y0); \ - l_tile->x1 = opj_int_min(l_cp->tx0 + (p + 1) * l_cp->tdx, l_image->x1); \ - l_tile->y1 = opj_int_min(l_cp->ty0 + (q + 1) * l_cp->tdy, l_image->y1); \ + l_tile->x0 = opj_int_max((OPJ_INT32)(l_cp->tx0 + p * l_cp->tdx), (OPJ_INT32)l_image->x0); \ + l_tile->y0 = opj_int_max((OPJ_INT32)(l_cp->ty0 + q * l_cp->tdy), (OPJ_INT32)l_image->y0); \ + l_tile->x1 = opj_int_min((OPJ_INT32)(l_cp->tx0 + (p + 1) * l_cp->tdx), (OPJ_INT32)l_image->x1); \ + l_tile->y1 = opj_int_min((OPJ_INT32)(l_cp->ty0 + (q + 1) * l_cp->tdy), (OPJ_INT32)l_image->y1); \ + /* testcase 1888.pdf.asan.35.988 */ \ + if (l_tccp->numresolutions == 0) { \ + fprintf(stderr, "tiles require at least one resolution\n"); \ + return OPJ_FALSE; \ + } \ /*fprintf(stderr, "Tile border = %d,%d,%d,%d\n", l_tile->x0, l_tile->y0,l_tile->x1,l_tile->y1);*/ \ \ /*tile->numcomps = image->numcomps; */ \ @@ -670,14 +675,14 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ /*fprintf(stderr, "compno = %d/%d\n", compno, l_tile->numcomps);*/ \ \ /* border of each l_tile component (global) */ \ - l_tilec->x0 = opj_int_ceildiv(l_tile->x0, l_image_comp->dx); \ - l_tilec->y0 = opj_int_ceildiv(l_tile->y0, l_image_comp->dy); \ - l_tilec->x1 = opj_int_ceildiv(l_tile->x1, l_image_comp->dx); \ - l_tilec->y1 = opj_int_ceildiv(l_tile->y1, l_image_comp->dy); \ + l_tilec->x0 = opj_int_ceildiv(l_tile->x0, (OPJ_INT32)l_image_comp->dx); \ + l_tilec->y0 = opj_int_ceildiv(l_tile->y0, (OPJ_INT32)l_image_comp->dy); \ + l_tilec->x1 = opj_int_ceildiv(l_tile->x1, (OPJ_INT32)l_image_comp->dx); \ + l_tilec->y1 = opj_int_ceildiv(l_tile->y1, (OPJ_INT32)l_image_comp->dy); \ /*fprintf(stderr, "\tTile compo border = %d,%d,%d,%d\n", l_tilec->x0, l_tilec->y0,l_tilec->x1,l_tilec->y1);*/ \ \ - l_data_size = (l_tilec->x1 - l_tilec->x0) \ - * (l_tilec->y1 - l_tilec->y0) * sizeof(OPJ_UINT32 );\ + l_data_size = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0) \ + * (OPJ_UINT32)(l_tilec->y1 - l_tilec->y0) * (OPJ_UINT32)sizeof(OPJ_UINT32 );\ l_tilec->numresolutions = l_tccp->numresolutions; \ if (l_tccp->numresolutions < l_cp->m_specific_param.m_dec.m_reduce) { \ l_tilec->minimum_num_resolutions = 1; \ @@ -711,7 +716,7 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ l_tilec->data_size = l_data_size; \ } \ \ - l_data_size = l_tilec->numresolutions * sizeof(opj_tcd_resolution_t); \ + l_data_size = l_tilec->numresolutions * (OPJ_UINT32)sizeof(opj_tcd_resolution_t); \ \ if (l_tilec->resolutions == 00) { \ l_tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(l_data_size); \ @@ -756,28 +761,28 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ OPJ_UINT32 cblkwidthexpn, cblkheightexpn; \ \ /* border for each resolution level (global) */ \ - l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, l_level_no); \ - l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, l_level_no); \ - l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, l_level_no); \ - l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, l_level_no); \ + l_res->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); \ + l_res->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); \ + l_res->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); \ + l_res->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); \ /*fprintf(stderr, "\t\t\tres_x0= %d, res_y0 =%d, res_x1=%d, res_y1=%d\n", l_res->x0, l_res->y0, l_res->x1, l_res->y1);*/ \ /* p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) */ \ l_pdx = l_tccp->prcw[resno]; \ l_pdy = l_tccp->prch[resno]; \ /*fprintf(stderr, "\t\t\tpdx=%d, pdy=%d\n", l_pdx, l_pdy);*/ \ /* p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) */ \ - l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, l_pdx) << l_pdx; \ - l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, l_pdy) << l_pdy; \ - l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, l_pdx) << l_pdx; \ - l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, l_pdy) << l_pdy; \ + l_tl_prc_x_start = opj_int_floordivpow2(l_res->x0, (OPJ_INT32)l_pdx) << l_pdx; \ + l_tl_prc_y_start = opj_int_floordivpow2(l_res->y0, (OPJ_INT32)l_pdy) << l_pdy; \ + l_br_prc_x_end = opj_int_ceildivpow2(l_res->x1, (OPJ_INT32)l_pdx) << l_pdx; \ + l_br_prc_y_end = opj_int_ceildivpow2(l_res->y1, (OPJ_INT32)l_pdy) << l_pdy; \ /*fprintf(stderr, "\t\t\tprc_x_start=%d, prc_y_start=%d, br_prc_x_end=%d, br_prc_y_end=%d \n", l_tl_prc_x_start, l_tl_prc_y_start, l_br_prc_x_end ,l_br_prc_y_end );*/ \ \ - l_res->pw = (l_res->x0 == l_res->x1) ? 0 : ((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx); \ - l_res->ph = (l_res->y0 == l_res->y1) ? 0 : ((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy); \ + l_res->pw = (l_res->x0 == l_res->x1) ? 0 : (OPJ_UINT32)((l_br_prc_x_end - l_tl_prc_x_start) >> l_pdx); \ + l_res->ph = (l_res->y0 == l_res->y1) ? 0 : (OPJ_UINT32)((l_br_prc_y_end - l_tl_prc_y_start) >> l_pdy); \ /*fprintf(stderr, "\t\t\tres_pw=%d, res_ph=%d\n", l_res->pw, l_res->ph );*/ \ \ l_nb_precincts = l_res->pw * l_res->ph; \ - l_nb_precinct_size = l_nb_precincts * sizeof(opj_tcd_precinct_t); \ + l_nb_precinct_size = l_nb_precincts * (OPJ_UINT32)sizeof(opj_tcd_precinct_t); \ if (resno == 0) { \ tlcbgxstart = l_tl_prc_x_start; \ tlcbgystart = l_tl_prc_y_start; \ @@ -807,29 +812,29 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ \ if (resno == 0) { \ l_band->bandno = 0 ; \ - l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, l_level_no); \ - l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, l_level_no); \ - l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, l_level_no); \ - l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, l_level_no); \ + l_band->x0 = opj_int_ceildivpow2(l_tilec->x0, (OPJ_INT32)l_level_no); \ + l_band->y0 = opj_int_ceildivpow2(l_tilec->y0, (OPJ_INT32)l_level_no); \ + l_band->x1 = opj_int_ceildivpow2(l_tilec->x1, (OPJ_INT32)l_level_no); \ + l_band->y1 = opj_int_ceildivpow2(l_tilec->y1, (OPJ_INT32)l_level_no); \ } \ else { \ l_band->bandno = bandno + 1; \ /* x0b = 1 if bandno = 1 or 3 */ \ l_x0b = l_band->bandno&1; \ /* y0b = 1 if bandno = 2 or 3 */ \ - l_y0b = (l_band->bandno)>>1; \ + l_y0b = (OPJ_INT32)((l_band->bandno)>>1); \ /* l_band border (global) */ \ - l_band->x0 = opj_int_ceildivpow2(l_tilec->x0 - (1 << l_level_no) * l_x0b, l_level_no + 1); \ - l_band->y0 = opj_int_ceildivpow2(l_tilec->y0 - (1 << l_level_no) * l_y0b, l_level_no + 1); \ - l_band->x1 = opj_int_ceildivpow2(l_tilec->x1 - (1 << l_level_no) * l_x0b, l_level_no + 1); \ - l_band->y1 = opj_int_ceildivpow2(l_tilec->y1 - (1 << l_level_no) * l_y0b, l_level_no + 1); \ + l_band->x0 = opj_int_ceildivpow2(l_tilec->x0 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1)); \ + l_band->y0 = opj_int_ceildivpow2(l_tilec->y0 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1)); \ + l_band->x1 = opj_int_ceildivpow2(l_tilec->x1 - (1 << l_level_no) * l_x0b, (OPJ_INT32)(l_level_no + 1)); \ + l_band->y1 = opj_int_ceildivpow2(l_tilec->y1 - (1 << l_level_no) * l_y0b, (OPJ_INT32)(l_level_no + 1)); \ } \ \ /** avoid an if with storing function pointer */ \ l_gain = (*l_gain_ptr) (l_band->bandno); \ - numbps = l_image_comp->prec + l_gain; \ + numbps = (OPJ_INT32)(l_image_comp->prec + l_gain); \ l_band->stepsize = (OPJ_FLOAT32)(((1.0 + l_step_size->mant / 2048.0) * pow(2.0, (OPJ_INT32) (numbps - l_step_size->expn)))) * FRACTION; \ - l_band->numbps = l_step_size->expn + l_tccp->numgbits - 1; /* WHY -1 ? */ \ + l_band->numbps = l_step_size->expn + (OPJ_INT32)l_tccp->numgbits - 1; /* WHY -1 ? */ \ \ if (! l_band->precincts) { \ l_band->precincts = (opj_tcd_precinct_t *) opj_malloc( /*3 * */ l_nb_precinct_size); \ @@ -860,8 +865,8 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ l_current_precinct = l_band->precincts; \ for (precno = 0; precno < l_nb_precincts; ++precno) { \ OPJ_INT32 tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; \ - OPJ_INT32 cbgxstart = tlcbgxstart + (precno % l_res->pw) * (1 << cbgwidthexpn); \ - OPJ_INT32 cbgystart = tlcbgystart + (precno / l_res->pw) * (1 << cbgheightexpn); \ + OPJ_INT32 cbgxstart = tlcbgxstart + (OPJ_INT32)(precno % l_res->pw) * (1 << cbgwidthexpn); \ + OPJ_INT32 cbgystart = tlcbgystart + (OPJ_INT32)(precno / l_res->pw) * (1 << cbgheightexpn); \ OPJ_INT32 cbgxend = cbgxstart + (1 << cbgwidthexpn); \ OPJ_INT32 cbgyend = cbgystart + (1 << cbgheightexpn); \ /*fprintf(stderr, "\t precno=%d; bandno=%d, resno=%d; compno=%d\n", precno, bandno , resno, compno);*/ \ @@ -876,20 +881,20 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ l_current_precinct->y1 = opj_int_min(cbgyend, l_band->y1); \ /*fprintf(stderr, "\t prc_x0=%d; prc_y0=%d, prc_x1=%d; prc_y1=%d\n",l_current_precinct->x0, l_current_precinct->y0 ,l_current_precinct->x1, l_current_precinct->y1);*/ \ \ - tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, cblkwidthexpn) << cblkwidthexpn; \ + tlcblkxstart = opj_int_floordivpow2(l_current_precinct->x0, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn; \ /*fprintf(stderr, "\t tlcblkxstart =%d\n",tlcblkxstart );*/ \ - tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, cblkheightexpn) << cblkheightexpn; \ + tlcblkystart = opj_int_floordivpow2(l_current_precinct->y0, (OPJ_INT32)cblkheightexpn) << cblkheightexpn; \ /*fprintf(stderr, "\t tlcblkystart =%d\n",tlcblkystart );*/ \ - brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1, cblkwidthexpn) << cblkwidthexpn; \ + brcblkxend = opj_int_ceildivpow2(l_current_precinct->x1, (OPJ_INT32)cblkwidthexpn) << cblkwidthexpn; \ /*fprintf(stderr, "\t brcblkxend =%d\n",brcblkxend );*/ \ - brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1, cblkheightexpn) << cblkheightexpn; \ + brcblkyend = opj_int_ceildivpow2(l_current_precinct->y1, (OPJ_INT32)cblkheightexpn) << cblkheightexpn; \ /*fprintf(stderr, "\t brcblkyend =%d\n",brcblkyend );*/ \ - l_current_precinct->cw = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; \ - l_current_precinct->ch = (brcblkyend - tlcblkystart) >> cblkheightexpn; \ + l_current_precinct->cw = (OPJ_UINT32)((brcblkxend - tlcblkxstart) >> cblkwidthexpn); \ + l_current_precinct->ch = (OPJ_UINT32)((brcblkyend - tlcblkystart) >> cblkheightexpn); \ \ l_nb_code_blocks = l_current_precinct->cw * l_current_precinct->ch; \ /*fprintf(stderr, "\t\t\t\t precinct_cw = %d x recinct_ch = %d\n",l_current_precinct->cw, l_current_precinct->ch); */ \ - l_nb_code_blocks_size = l_nb_code_blocks * sizeof(TYPE); \ + l_nb_code_blocks_size = l_nb_code_blocks * (OPJ_UINT32)sizeof(TYPE); \ \ if (! l_current_precinct->cblks.ELEMENT) { \ l_current_precinct->cblks.ELEMENT = (TYPE*) opj_malloc(l_nb_code_blocks_size); \ @@ -957,8 +962,8 @@ OPJ_BOOL FUNCTION ( opj_tcd_t *p_tcd, \ l_code_block = l_current_precinct->cblks.ELEMENT; \ \ for (cblkno = 0; cblkno < l_nb_code_blocks; ++cblkno) { \ - OPJ_INT32 cblkxstart = tlcblkxstart + (cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn); \ - OPJ_INT32 cblkystart = tlcblkystart + (cblkno / l_current_precinct->cw) * (1 << cblkheightexpn); \ + OPJ_INT32 cblkxstart = tlcblkxstart + (OPJ_INT32)(cblkno % l_current_precinct->cw) * (1 << cblkwidthexpn); \ + OPJ_INT32 cblkystart = tlcblkystart + (OPJ_INT32)(cblkno / l_current_precinct->cw) * (1 << cblkheightexpn); \ OPJ_INT32 cblkxend = cblkxstart + (1 << cblkwidthexpn); \ OPJ_INT32 cblkyend = cblkystart + (1 << cblkheightexpn); \ \ @@ -1001,7 +1006,7 @@ OPJ_BOOL opj_tcd_code_block_enc_allocate (opj_tcd_cblk_enc_t * p_code_block) { if (! p_code_block->data) { - p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE); //why +1 ? + p_code_block->data = (OPJ_BYTE*) opj_malloc(OPJ_J2K_DEFAULT_CBLK_DATA_SIZE*2); /*why +1 ?*/ if(! p_code_block->data) { return OPJ_FALSE; } @@ -1085,7 +1090,7 @@ OPJ_UINT32 opj_tcd_get_decoded_tile_size ( opj_tcd_t *p_tcd ) } l_res = l_tile_comp->resolutions + l_tile_comp->minimum_num_resolutions - 1; - l_data_size += l_size_comp * (l_res->x1 - l_res->x0) * (l_res->y1 - l_res->y0); + l_data_size += l_size_comp * (OPJ_UINT32)((l_res->x1 - l_res->x0) * (l_res->y1 - l_res->y0)); ++l_img_comp; ++l_tile_comp; } @@ -1116,14 +1121,14 @@ OPJ_BOOL opj_tcd_encode_tile( opj_tcd_t *p_tcd, for (i = 0; i < l_tilec_idx->numresolutions; i++) { opj_tcd_resolution_t *l_res_idx = &l_tilec_idx->resolutions[i]; - p_cstr_info->tile[p_tile_no].pw[i] = l_res_idx->pw; - p_cstr_info->tile[p_tile_no].ph[i] = l_res_idx->ph; + p_cstr_info->tile[p_tile_no].pw[i] = (int)l_res_idx->pw; + p_cstr_info->tile[p_tile_no].ph[i] = (int)l_res_idx->ph; l_num_packs += l_res_idx->pw * l_res_idx->ph; - p_cstr_info->tile[p_tile_no].pdx[i] = l_tccp->prcw[i]; - p_cstr_info->tile[p_tile_no].pdy[i] = l_tccp->prch[i]; + p_cstr_info->tile[p_tile_no].pdx[i] = (int)l_tccp->prcw[i]; + p_cstr_info->tile[p_tile_no].pdy[i] = (int)l_tccp->prch[i]; } - p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t*) opj_calloc(p_cstr_info->numcomps * p_cstr_info->numlayers * l_num_packs, sizeof(opj_packet_info_t)); + p_cstr_info->tile[p_tile_no].packet = (opj_packet_info_t*) opj_calloc((size_t)p_cstr_info->numcomps * (size_t)p_cstr_info->numlayers * l_num_packs, sizeof(opj_packet_info_t)); } /* << INDEX */ @@ -1286,9 +1291,9 @@ OPJ_BOOL opj_tcd_update_tile_data ( opj_tcd_t *p_tcd, l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/ l_remaining = l_img_comp->prec & 7; /* (%8) */ l_res = l_tilec->resolutions + l_img_comp->resno_decoded; - l_width = (l_res->x1 - l_res->x0); - l_height = (l_res->y1 - l_res->y0); - l_stride = (l_tilec->x1 - l_tilec->x0) - l_width; + l_width = (OPJ_UINT32)(l_res->x1 - l_res->x0); + l_height = (OPJ_UINT32)(l_res->y1 - l_res->y0); + l_stride = (OPJ_UINT32)(l_tilec->x1 - l_tilec->x0) - l_width; if (l_remaining) { ++l_size_comp; @@ -1316,7 +1321,7 @@ OPJ_BOOL opj_tcd_update_tile_data ( opj_tcd_t *p_tcd, else { for (j=0;jx1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0); + l_samples = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0)); if (l_tile->numcomps >= 3 ){ - if (l_tcp->mct == 2) { + /* testcase 1336.pdf.asan.47.376 */ + if ((l_tile->comps[0].x1 - l_tile->comps[0].x0) * (l_tile->comps[0].y1 - l_tile->comps[0].y0) < (OPJ_INT32)l_samples || + (l_tile->comps[1].x1 - l_tile->comps[1].x0) * (l_tile->comps[1].y1 - l_tile->comps[1].y0) < (OPJ_INT32)l_samples || + (l_tile->comps[2].x1 - l_tile->comps[2].x0) * (l_tile->comps[2].y1 - l_tile->comps[2].y0) < (OPJ_INT32)l_samples) { + fprintf(stderr, "Tiles don't all have the same dimension. Skip the MCT step.\n"); + return OPJ_FALSE; + } + else if (l_tcp->mct == 2) { OPJ_BYTE ** l_data; if (! l_tcp->m_mct_decoding_matrix) { @@ -1650,9 +1662,11 @@ OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd ) for (compno = 0; compno < l_tile->numcomps; compno++) { l_res = l_tile_comp->resolutions + l_img_comp->resno_decoded; - l_width = (l_res->x1 - l_res->x0); - l_height = (l_res->y1 - l_res->y0); - l_stride = (l_tile_comp->x1 - l_tile_comp->x0) - l_width; + l_width = (OPJ_UINT32)(l_res->x1 - l_res->x0); + l_height = (OPJ_UINT32)(l_res->y1 - l_res->y0); + l_stride = (OPJ_UINT32)(l_tile_comp->x1 - l_tile_comp->x0) - l_width; + + assert(l_height == 0 || l_width + l_stride <= l_tile_comp->data_size / l_height); /*MUPDF*/ if (l_img_comp->sgnd) { l_min = -(1 << (l_img_comp->prec - 1)); @@ -1678,7 +1692,7 @@ OPJ_BOOL opj_tcd_dc_level_shift_decode ( opj_tcd_t *p_tcd ) for (j=0;jm_dc_level_shift, l_min, l_max); ; + *l_current_ptr = opj_int_clamp((OPJ_INT32)lrintf(l_value) + l_tccp->m_dc_level_shift, l_min, l_max); ; ++l_current_ptr; } l_current_ptr += l_stride; @@ -1789,7 +1803,7 @@ OPJ_UINT32 opj_tcd_get_encoded_tile_size ( opj_tcd_t *p_tcd ) l_size_comp = 4; } - l_data_size += l_size_comp * (l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0); + l_data_size += l_size_comp * (OPJ_UINT32)((l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0)); ++l_img_comp; ++l_tilec; } @@ -1814,7 +1828,7 @@ OPJ_BOOL opj_tcd_dc_level_shift_encode ( opj_tcd_t *p_tcd ) for (compno = 0; compno < l_tile->numcomps; compno++) { l_current_ptr = l_tile_comp->data; - l_nb_elem = (l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0); + l_nb_elem = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0)); if (l_tccp->qmfbid == 1) { for (i = 0; i < l_nb_elem; ++i) { @@ -1841,7 +1855,7 @@ OPJ_BOOL opj_tcd_mct_encode ( opj_tcd_t *p_tcd ) { opj_tcd_tile_t * l_tile = p_tcd->tcd_image->tiles; opj_tcd_tilecomp_t * l_tile_comp = p_tcd->tcd_image->tiles->comps; - OPJ_UINT32 samples = (l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0); + OPJ_UINT32 samples = (OPJ_UINT32)((l_tile_comp->x1 - l_tile_comp->x0) * (l_tile_comp->y1 - l_tile_comp->y0)); OPJ_UINT32 i; OPJ_BYTE ** l_data = 00; opj_tcp_t * l_tcp = p_tcd->tcp; @@ -2038,7 +2052,7 @@ OPJ_BOOL opj_tcd_copy_tile_data ( opj_tcd_t *p_tcd, for (i=0;iimage->numcomps;++i) { l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/ l_remaining = l_img_comp->prec & 7; /* (%8) */ - l_nb_elem = (l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0); + l_nb_elem = (OPJ_UINT32)((l_tilec->x1 - l_tilec->x0) * (l_tilec->y1 - l_tilec->y0)); if (l_remaining) { ++l_size_comp; diff --git a/src/lib/openjp2/tgt.c b/src/lib/openjp2/tgt.c index 06930d49..44252ba7 100644 --- a/src/lib/openjp2/tgt.c +++ b/src/lib/openjp2/tgt.c @@ -53,7 +53,7 @@ opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) { tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); if(!tree) { - fprintf(stderr, "ERROR in tgt_create_v2 while allocating tree\n"); + fprintf(stderr, "ERROR in tgt_create while allocating tree\n"); return 00; } memset(tree,0,sizeof(opj_tgt_tree_t)); @@ -62,11 +62,11 @@ opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) { tree->numleafsv = numleafsv; numlvls = 0; - nplh[0] = numleafsh; - nplv[0] = numleafsv; + nplh[0] = (OPJ_INT32)numleafsh; + nplv[0] = (OPJ_INT32)numleafsv; tree->numnodes = 0; do { - n = nplh[numlvls] * nplv[numlvls]; + n = (OPJ_UINT32)(nplh[numlvls] * nplv[numlvls]); nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; tree->numnodes += n; @@ -76,18 +76,18 @@ opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) { /* ADD */ if (tree->numnodes == 0) { opj_free(tree); - fprintf(stderr, "WARNING in tgt_create_v2 tree->numnodes == 0, no tree created.\n"); + fprintf(stderr, "WARNING in tgt_create tree->numnodes == 0, no tree created.\n"); return 00; } tree->nodes = (opj_tgt_node_t*) opj_calloc(tree->numnodes, sizeof(opj_tgt_node_t)); if(!tree->nodes) { - fprintf(stderr, "ERROR in tgt_create_v2 while allocating node of the tree\n"); + fprintf(stderr, "ERROR in tgt_create while allocating node of the tree\n"); opj_free(tree); return 00; } memset(tree->nodes,0,tree->numnodes * sizeof(opj_tgt_node_t)); - tree->nodes_size = tree->numnodes * sizeof(opj_tgt_node_t); + tree->nodes_size = tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t); node = tree->nodes; l_parent_node = &tree->nodes[tree->numleafsh * tree->numleafsv]; @@ -119,7 +119,7 @@ opj_tgt_tree_t *opj_tgt_create(OPJ_UINT32 numleafsh, OPJ_UINT32 numleafsv) { } /** - * Reinitialises a tag-tree from an exixting one. (V2 framevork) + * Reinitialises a tag-tree from an existing one. * * @param p_tree the tree to reinitialize. * @param p_num_leafs_h the width of the array of leafs of the tree @@ -148,12 +148,12 @@ opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, O p_tree->numleafsv = p_num_leafs_v; l_num_levels = 0; - l_nplh[0] = p_num_leafs_h; - l_nplv[0] = p_num_leafs_v; + l_nplh[0] = (OPJ_INT32)p_num_leafs_h; + l_nplv[0] = (OPJ_INT32)p_num_leafs_v; p_tree->numnodes = 0; do { - n = l_nplh[l_num_levels] * l_nplv[l_num_levels]; + n = (OPJ_UINT32)(l_nplh[l_num_levels] * l_nplv[l_num_levels]); l_nplh[l_num_levels + 1] = (l_nplh[l_num_levels] + 1) / 2; l_nplv[l_num_levels + 1] = (l_nplv[l_num_levels] + 1) / 2; p_tree->numnodes += n; @@ -166,7 +166,7 @@ opj_tgt_tree_t *opj_tgt_init(opj_tgt_tree_t * p_tree,OPJ_UINT32 p_num_leafs_h, O opj_tgt_destroy(p_tree); return 00; } - l_node_size = p_tree->numnodes * sizeof(opj_tgt_node_t); + l_node_size = p_tree->numnodes * (OPJ_UINT32)sizeof(opj_tgt_node_t); if (l_node_size > p_tree->nodes_size) { opj_tgt_node_t* new_nodes = (opj_tgt_node_t*) opj_realloc(p_tree->nodes, l_node_size); diff --git a/src/lib/openjp2/thix_manager.c b/src/lib/openjp2/thix_manager.c index 229676ef..e3ebf110 100644 --- a/src/lib/openjp2/thix_manager.c +++ b/src/lib/openjp2/thix_manager.c @@ -48,7 +48,7 @@ int opj_write_thix( int coff, opj_codestream_info_t cstr_info, opj_stream_privat OPJ_OFF_T lenp; lenp = 0; - box = (opj_jp2_box_t *)opj_calloc( cstr_info.tw*cstr_info.th, sizeof(opj_jp2_box_t)); + box = (opj_jp2_box_t *)opj_calloc( (size_t)(cstr_info.tw*cstr_info.th), sizeof(opj_jp2_box_t)); for ( i = 0; i < 2 ; i++ ){ if (i) @@ -62,7 +62,7 @@ int opj_write_thix( int coff, opj_codestream_info_t cstr_info, opj_stream_privat opj_write_manf( i, cstr_info.tw*cstr_info.th, box, cio, p_manager); for (tileno = 0; tileno < cstr_info.tw*cstr_info.th; tileno++){ - box[tileno].length = opj_write_tilemhix( coff, cstr_info, tileno, cio,p_manager); + box[tileno].length = (OPJ_UINT32)opj_write_tilemhix( coff, cstr_info, tileno, cio,p_manager); box[tileno].type = JPIP_MHIX; } @@ -76,7 +76,7 @@ int opj_write_thix( int coff, opj_codestream_info_t cstr_info, opj_stream_privat opj_free(box); - return len; + return (int)len; } /* @@ -107,7 +107,7 @@ int opj_write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, o tile = cstr_info.tile[tileno]; tp = tile.tp[0]; - opj_write_bytes(l_data_header,tp.tp_end_header-tp.tp_start_pos+1, 8); /* TLEN */ + opj_write_bytes(l_data_header,(OPJ_UINT32)(tp.tp_end_header-tp.tp_start_pos+1), 8); /* TLEN */ opj_stream_write_data(cio,l_data_header,8,p_manager); marker = cstr_info.tile[tileno].marker; @@ -118,7 +118,7 @@ int opj_write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, o opj_stream_write_data(cio,l_data_header,4,p_manager); opj_write_bytes( l_data_header, (OPJ_UINT32)(marker[i].pos-coff), 8); opj_stream_write_data(cio,l_data_header,8,p_manager); - opj_write_bytes( l_data_header, marker[i].len, 2); + opj_write_bytes( l_data_header, (OPJ_UINT32)marker[i].len, 2); opj_stream_write_data(cio,l_data_header,2,p_manager); } @@ -130,5 +130,5 @@ int opj_write_tilemhix( int coff, opj_codestream_info_t cstr_info, int tileno, o opj_stream_write_data(cio,l_data_header,4,p_manager); opj_stream_seek(cio, lenp+len,p_manager); - return len; + return (int)len; } diff --git a/src/lib/openjp2/tpix_manager.c b/src/lib/openjp2/tpix_manager.c index 429f5089..5e440e1e 100644 --- a/src/lib/openjp2/tpix_manager.c +++ b/src/lib/openjp2/tpix_manager.c @@ -80,7 +80,7 @@ int opj_write_tpix( int coff, opj_stream_write_data(cio,l_data_header,4,p_manager); opj_stream_seek(cio, lenp+len,p_manager); - return len; + return (int)len; } int opj_write_tpixfaix( int coff, @@ -92,15 +92,15 @@ int opj_write_tpixfaix( int coff, { OPJ_UINT32 len; OPJ_OFF_T lenp; - int i, j; - int Aux; - int num_max_tile_parts; - int size_of_coding; /* 4 or 8 */ + OPJ_UINT32 i, j; + OPJ_UINT32 Aux; + OPJ_UINT32 num_max_tile_parts; + OPJ_UINT32 size_of_coding; /* 4 or 8 */ opj_tp_info_t tp; OPJ_BYTE l_data_header [8]; - int version; + OPJ_UINT32 version; - num_max_tile_parts = get_num_max_tile_parts( cstr_info); + num_max_tile_parts = (OPJ_UINT32)get_num_max_tile_parts( cstr_info); if( j2klen > pow( 2, 32)){ size_of_coding = 8; @@ -120,24 +120,24 @@ int opj_write_tpixfaix( int coff, opj_write_bytes(l_data_header,num_max_tile_parts,size_of_coding); /* NMAX */ opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager); - opj_write_bytes(l_data_header,cstr_info.tw*cstr_info.th,size_of_coding); /* M */ + opj_write_bytes(l_data_header,(OPJ_UINT32)(cstr_info.tw*cstr_info.th),size_of_coding); /* M */ opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager); - for (i = 0; i < cstr_info.tw*cstr_info.th; i++) + for (i = 0; i < (OPJ_UINT32)(cstr_info.tw*cstr_info.th); i++) { - for (j = 0; j < cstr_info.tile[i].num_tps; j++) + for (j = 0; j < (OPJ_UINT32)cstr_info.tile[i].num_tps; j++) { tp = cstr_info.tile[i].tp[j]; - opj_write_bytes(l_data_header,tp.tp_start_pos-coff,size_of_coding); /* start position */ + opj_write_bytes(l_data_header,(OPJ_UINT32)(tp.tp_start_pos-coff),size_of_coding); /* start position */ opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager); - opj_write_bytes(l_data_header,tp.tp_end_pos-tp.tp_start_pos+1,size_of_coding); /* length */ + opj_write_bytes(l_data_header,(OPJ_UINT32)(tp.tp_end_pos-tp.tp_start_pos+1),size_of_coding); /* length */ opj_stream_write_data(cio,l_data_header,size_of_coding,p_manager); if (version & 0x02) { if( cstr_info.tile[i].num_tps == 1 && cstr_info.numdecompos[compno] > 1) - Aux = cstr_info.numdecompos[compno] + 1; + Aux = (OPJ_UINT32)(cstr_info.numdecompos[compno] + 1); else Aux = j + 1; @@ -171,7 +171,7 @@ int opj_write_tpixfaix( int coff, opj_stream_write_data(cio,l_data_header,4,p_manager); opj_stream_seek(cio, lenp+len,p_manager); - return len; + return (int)len; } int get_num_max_tile_parts( opj_codestream_info_t cstr_info) diff --git a/src/lib/openjp3d/bio.c b/src/lib/openjp3d/bio.c old mode 100755 new mode 100644 index bc3b1138..57e909b9 --- a/src/lib/openjp3d/bio.c +++ b/src/lib/openjp3d/bio.c @@ -1,189 +1,189 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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 "opj_includes.h" - -/** @defgroup BIO BIO - Individual bit input-output stream */ -/*@{*/ - -/** @name Local static functions */ -/*@{*/ - -/** -Write a bit -@param bio BIO handle -@param b Bit to write (0 or 1) -*/ -static void bio_putbit(opj_bio_t *bio, int b); -/** -Read a bit -@param bio BIO handle -@return Returns the read bit -*/ -static int bio_getbit(opj_bio_t *bio); -/** -Write a byte -@param bio BIO handle -@return Returns 0 if successful, returns 1 otherwise -*/ -static int bio_byteout(opj_bio_t *bio); -/** -Read a byte -@param bio BIO handle -@return Returns 0 if successful, returns 1 otherwise -*/ -static int bio_bytein(opj_bio_t *bio); - -/*@}*/ - -/*@}*/ - - -/* -========================================================== - local functions -========================================================== -*/ - -static int bio_byteout(opj_bio_t *bio) { - bio->buf = (bio->buf << 8) & 0xffff; - bio->ct = bio->buf == 0xff00 ? 7 : 8; - if (bio->bp >= bio->end) { - return 1; - } - *bio->bp++ = bio->buf >> 8; - return 0; -} - -static int bio_bytein(opj_bio_t *bio) { - bio->buf = (bio->buf << 8) & 0xffff; - bio->ct = bio->buf == 0xff00 ? 7 : 8; - if (bio->bp >= bio->end) { - return 1; - } - bio->buf |= *bio->bp++; - return 0; -} - -static void bio_putbit(opj_bio_t *bio, int b) { - if (bio->ct == 0) { - bio_byteout(bio); - } - bio->ct--; - bio->buf |= b << bio->ct; -} - -/* MOD antonin */ -static int bio_getbit(opj_bio_t *bio) { -/* DOM */ - if (bio->ct == 0) { - bio_bytein(bio); - } - bio->ct--; - return (bio->buf >> bio->ct) & 1; -} - -/* -========================================================== - Bit Input/Output interface -========================================================== -*/ - -opj_bio_t* bio_create() { - opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t)); - return bio; -} - -void bio_destroy(opj_bio_t *bio) { - if(bio) { - opj_free(bio); - } -} - -int bio_numbytes(opj_bio_t *bio) { - return (bio->bp - bio->start); -} - -void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) { - bio->start = bp; - bio->end = bp + len; - bio->bp = bp; - bio->buf = 0; - bio->ct = 8; -} - -void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) { - bio->start = bp; - bio->end = bp + len; - bio->bp = bp; - bio->buf = 0; - bio->ct = 0; -} - -void bio_write(opj_bio_t *bio, int v, int n) { - int i; - for (i = n - 1; i >= 0; i--) { - bio_putbit(bio, (v >> i) & 1); - } -} - -int bio_read(opj_bio_t *bio, int n) { - int i, v; - v = 0; - for (i = n - 1; i >= 0; i--) { - v += bio_getbit(bio) << i; - } - return v; -} - -int bio_flush(opj_bio_t *bio) { - bio->ct = 0; - if (bio_byteout(bio)) { - return 1; - } - if (bio->ct == 7) { - bio->ct = 0; - if (bio_byteout(bio)) { - return 1; - } - } - return 0; -} - -int bio_inalign(opj_bio_t *bio) { - bio->ct = 0; - if ((bio->buf & 0xff) == 0xff) { - if (bio_bytein(bio)) { - return 1; - } - bio->ct = 0; - } - return 0; -} +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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 "opj_includes.h" + +/** @defgroup BIO BIO - Individual bit input-output stream */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +/** +Write a bit +@param bio BIO handle +@param b Bit to write (0 or 1) +*/ +static void bio_putbit(opj_bio_t *bio, int b); +/** +Read a bit +@param bio BIO handle +@return Returns the read bit +*/ +static int bio_getbit(opj_bio_t *bio); +/** +Write a byte +@param bio BIO handle +@return Returns 0 if successful, returns 1 otherwise +*/ +static int bio_byteout(opj_bio_t *bio); +/** +Read a byte +@param bio BIO handle +@return Returns 0 if successful, returns 1 otherwise +*/ +static int bio_bytein(opj_bio_t *bio); + +/*@}*/ + +/*@}*/ + + +/* +========================================================== + local functions +========================================================== +*/ + +static int bio_byteout(opj_bio_t *bio) { + bio->buf = (bio->buf << 8) & 0xffff; + bio->ct = bio->buf == 0xff00 ? 7 : 8; + if (bio->bp >= bio->end) { + return 1; + } + *bio->bp++ = bio->buf >> 8; + return 0; +} + +static int bio_bytein(opj_bio_t *bio) { + bio->buf = (bio->buf << 8) & 0xffff; + bio->ct = bio->buf == 0xff00 ? 7 : 8; + if (bio->bp >= bio->end) { + return 1; + } + bio->buf |= *bio->bp++; + return 0; +} + +static void bio_putbit(opj_bio_t *bio, int b) { + if (bio->ct == 0) { + bio_byteout(bio); + } + bio->ct--; + bio->buf |= b << bio->ct; +} + +/* MOD antonin */ +static int bio_getbit(opj_bio_t *bio) { +/* DOM */ + if (bio->ct == 0) { + bio_bytein(bio); + } + bio->ct--; + return (bio->buf >> bio->ct) & 1; +} + +/* +========================================================== + Bit Input/Output interface +========================================================== +*/ + +opj_bio_t* bio_create() { + opj_bio_t *bio = (opj_bio_t*)opj_malloc(sizeof(opj_bio_t)); + return bio; +} + +void bio_destroy(opj_bio_t *bio) { + if(bio) { + opj_free(bio); + } +} + +int bio_numbytes(opj_bio_t *bio) { + return (bio->bp - bio->start); +} + +void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) { + bio->start = bp; + bio->end = bp + len; + bio->bp = bp; + bio->buf = 0; + bio->ct = 8; +} + +void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) { + bio->start = bp; + bio->end = bp + len; + bio->bp = bp; + bio->buf = 0; + bio->ct = 0; +} + +void bio_write(opj_bio_t *bio, int v, int n) { + int i; + for (i = n - 1; i >= 0; i--) { + bio_putbit(bio, (v >> i) & 1); + } +} + +int bio_read(opj_bio_t *bio, int n) { + int i, v; + v = 0; + for (i = n - 1; i >= 0; i--) { + v += bio_getbit(bio) << i; + } + return v; +} + +int bio_flush(opj_bio_t *bio) { + bio->ct = 0; + if (bio_byteout(bio)) { + return 1; + } + if (bio->ct == 7) { + bio->ct = 0; + if (bio_byteout(bio)) { + return 1; + } + } + return 0; +} + +int bio_inalign(opj_bio_t *bio) { + bio->ct = 0; + if ((bio->buf & 0xff) == 0xff) { + if (bio_bytein(bio)) { + return 1; + } + bio->ct = 0; + } + return 0; +} diff --git a/src/lib/openjp3d/bio.h b/src/lib/openjp3d/bio.h old mode 100755 new mode 100644 index 2c91342f..183eb0a1 --- a/src/lib/openjp3d/bio.h +++ b/src/lib/openjp3d/bio.h @@ -1,132 +1,132 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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. - */ - -#ifndef __BIO_H -#define __BIO_H -/** -@file bio.h -@brief Implementation of an individual bit input-output (BIO) - -The functions in BIO.C have for goal to realize an individual bit input - output. -*/ - -/** @defgroup BIO BIO - Individual bit input-output stream */ -/*@{*/ - -/** -Individual bit input-output stream (BIO) -*/ -typedef struct opj_bio { -/** pointer to the start of the buffer */ - unsigned char *start; -/** pointer to the end of the buffer */ - unsigned char *end; -/** pointer to the present position in the buffer */ - unsigned char *bp; -/** temporary place where each byte is read or written */ - unsigned int buf; -/** coder : number of bits free to write. decoder : number of bits read */ - int ct; -} opj_bio_t; - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Create a new BIO handle -@return Returns a new BIO handle if successful, returns NULL otherwise -*/ -opj_bio_t* bio_create(void); -/** -Destroy a previously created BIO handle -@param bio BIO handle to destroy -*/ -void bio_destroy(opj_bio_t *bio); -/** -Number of bytes written. -@param bio BIO handle -@return Returns the number of bytes written -*/ -int bio_numbytes(opj_bio_t *bio); -/** -Init encoder -@param bio BIO handle -@param bp Output buffer -@param len Output buffer length -*/ -void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len); -/** -Init decoder -@param bio BIO handle -@param bp Input buffer -@param len Input buffer length -*/ -void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len); -/** -Write bits -@param bio BIO handle -@param v Value of bits -@param n Number of bits to write -*/ -void bio_write(opj_bio_t *bio, int v, int n); -/** -Read bits -@param bio BIO handle -@param n Number of bits to read -@return Returns the corresponding read number -*/ -int bio_read(opj_bio_t *bio, int n); -/** -Flush bits -@param bio BIO handle -@return Returns 1 if successful, returns 0 otherwise -*/ -int bio_flush(opj_bio_t *bio); -/** -Passes the ending bits (coming from flushing) -@param bio BIO handle -@return Returns 1 if successful, returns 0 otherwise -*/ -int bio_inalign(opj_bio_t *bio); -/** -Read a bit -@param bio BIO handle -@return Returns the read bit -*/ -/* MOD antonin */ -/*int bio_getbit(opj_bio_t *bio);*/ -/* DOM */ -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __BIO_H */ - +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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. + */ + +#ifndef __BIO_H +#define __BIO_H +/** +@file bio.h +@brief Implementation of an individual bit input-output (BIO) + +The functions in BIO.C have for goal to realize an individual bit input - output. +*/ + +/** @defgroup BIO BIO - Individual bit input-output stream */ +/*@{*/ + +/** +Individual bit input-output stream (BIO) +*/ +typedef struct opj_bio { +/** pointer to the start of the buffer */ + unsigned char *start; +/** pointer to the end of the buffer */ + unsigned char *end; +/** pointer to the present position in the buffer */ + unsigned char *bp; +/** temporary place where each byte is read or written */ + unsigned int buf; +/** coder : number of bits free to write. decoder : number of bits read */ + int ct; +} opj_bio_t; + +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new BIO handle +@return Returns a new BIO handle if successful, returns NULL otherwise +*/ +opj_bio_t* bio_create(void); +/** +Destroy a previously created BIO handle +@param bio BIO handle to destroy +*/ +void bio_destroy(opj_bio_t *bio); +/** +Number of bytes written. +@param bio BIO handle +@return Returns the number of bytes written +*/ +int bio_numbytes(opj_bio_t *bio); +/** +Init encoder +@param bio BIO handle +@param bp Output buffer +@param len Output buffer length +*/ +void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len); +/** +Init decoder +@param bio BIO handle +@param bp Input buffer +@param len Input buffer length +*/ +void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len); +/** +Write bits +@param bio BIO handle +@param v Value of bits +@param n Number of bits to write +*/ +void bio_write(opj_bio_t *bio, int v, int n); +/** +Read bits +@param bio BIO handle +@param n Number of bits to read +@return Returns the corresponding read number +*/ +int bio_read(opj_bio_t *bio, int n); +/** +Flush bits +@param bio BIO handle +@return Returns 1 if successful, returns 0 otherwise +*/ +int bio_flush(opj_bio_t *bio); +/** +Passes the ending bits (coming from flushing) +@param bio BIO handle +@return Returns 1 if successful, returns 0 otherwise +*/ +int bio_inalign(opj_bio_t *bio); +/** +Read a bit +@param bio BIO handle +@return Returns the read bit +*/ +/* MOD antonin */ +/*int bio_getbit(opj_bio_t *bio);*/ +/* DOM */ +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __BIO_H */ + diff --git a/src/lib/openjp3d/cio.c b/src/lib/openjp3d/cio.c old mode 100755 new mode 100644 index 4e99c847..7b2c5e4e --- a/src/lib/openjp3d/cio.c +++ b/src/lib/openjp3d/cio.c @@ -1,217 +1,218 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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 "opj_includes.h" - -/* ----------------------------------------------------------------------- */ - -opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length) { - opj_cp_t *cp = NULL; - opj_cio_t *cio = (opj_cio_t*)opj_malloc(sizeof(opj_cio_t)); - if(!cio) return NULL; - cio->cinfo = cinfo; - if(buffer && length) { - /* wrap a user buffer containing the encoded image */ - cio->openmode = OPJ_STREAM_READ; - cio->buffer = buffer; - cio->length = length; - } - else if(!buffer && !length && cinfo) { - /* allocate a buffer for the encoded image */ - cio->openmode = OPJ_STREAM_WRITE; - switch(cinfo->codec_format) { - case CODEC_J3D: - case CODEC_J2K: - cp = ((opj_j3d_t*)cinfo->j3d_handle)->cp; - break; - default: - opj_free(cio); - return NULL; - } - cio->length = cp->tdx * cp->tdy * cp->tdz * cp->tw * cp->th * cp->tl * 4; - cio->buffer = (unsigned char *)opj_malloc(cio->length); - if(!cio->buffer) { - opj_free(cio); - return NULL; - } - } - else { - opj_free(cio); - return NULL; - } - - /* Initialize byte IO */ - cio->start = cio->buffer; - cio->end = cio->buffer + cio->length; - cio->bp = cio->buffer; - - return cio; -} - -void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio) { - if(cio) { - if(cio->openmode == OPJ_STREAM_WRITE) { - /* destroy the allocated buffer */ - opj_free(cio->buffer); - } - /* destroy the cio */ - opj_free(cio); - } -} - - -/* ----------------------------------------------------------------------- */ - -/* - * Get position in byte stream. - */ -int OPJ_CALLCONV cio_tell(opj_cio_t *cio) { - return cio->bp - cio->start; -} - -/* - * Set position in byte stream. - * - * pos : position, in number of bytes, from the beginning of the stream - */ -void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) { - cio->bp = cio->start + pos; -} - -/* - * Number of bytes left before the end of the stream. - */ -int cio_numbytesleft(opj_cio_t *cio) { - return cio->end - cio->bp; -} - -/* - * Get pointer to the current position in the stream. - */ -unsigned char *cio_getbp(opj_cio_t *cio) { - return cio->bp; -} - -/* - * Write a byte. - */ -static bool cio_byteout(opj_cio_t *cio, unsigned char v) { - if (cio->bp >= cio->end) { - opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n"); - return false; - } - *cio->bp++ = v; - return true; -} - -/* - * Read a byte. - */ -static unsigned char cio_bytein(opj_cio_t *cio) { - if (cio->bp >= cio->end) { - opj_event_msg(cio->cinfo, EVT_ERROR, "read error\n"); - return 0; - } - return *cio->bp++; -} - -/* - * Write some bytes. - * - * v : value to write - * n : number of bytes to write - */ -unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n) { - int i; - for (i = n - 1; i >= 0; i--) { - if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) ) - return 0; - } - return n; -} - -/* - * Read some bytes. - * - * n : number of bytes to read - * - * return : value of the n bytes read - */ -unsigned int cio_read(opj_cio_t *cio, int n) { - int i; - unsigned int v; - v = 0; - for (i = n - 1; i >= 0; i--) { - v += cio_bytein(cio) << (i << 3); - } - return v; -} - -/* - * Skip some bytes. - * - * n : number of bytes to skip - */ -void cio_skip(opj_cio_t *cio, int n) { - cio->bp += n; -} - -/* - * Write some bytes. - * - * v : value to write - * n : number of bytes to write - */ -int cio_write_int(opj_cio_t *cio, int v, int n) { - int i; - for (i = n - 1; i >= 0; i--) { - if( !cio_byteout(cio, (char) ((v >> (i << 3)) & 0xff)) ) - return 0; - } - return n; -} - -/* - * Read some bytes. - * - * n : number of bytes to read - * - * return : value of the n bytes read - */ -int cio_read_int(opj_cio_t *cio, int n) { - int i; - int v; - v = 0; - for (i = n - 1; i >= 0; i--) { - v += cio_bytein(cio) << (i << 3); - } - return v; -} - +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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 "opj_includes.h" + +/* ----------------------------------------------------------------------- */ + +opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length) { + opj_cp_t *cp = NULL; + opj_cio_t *cio = (opj_cio_t*)opj_malloc(sizeof(opj_cio_t)); + if(!cio) return NULL; + cio->cinfo = cinfo; + if(buffer && length) { + /* wrap a user buffer containing the encoded image */ + cio->openmode = OPJ_STREAM_READ; + cio->buffer = buffer; + cio->length = length; + } + else if(!buffer && !length && cinfo) { + /* allocate a buffer for the encoded image */ + cio->openmode = OPJ_STREAM_WRITE; + switch(cinfo->codec_format) { + case CODEC_J3D: + case CODEC_J2K: + cp = ((opj_j3d_t*)cinfo->j3d_handle)->cp; + break; + default: + opj_free(cio); + return NULL; + } + cio->length = cp->tdx * cp->tdy * cp->tdz * cp->tw * cp->th * cp->tl * 4; + cio->buffer = (unsigned char *)opj_malloc(cio->length); + if(!cio->buffer) { + opj_event_msg(cio->cinfo, EVT_ERROR, "Error allocating memory for compressed bitstream\n"); + opj_free(cio); + return NULL; + } + } + else { + opj_free(cio); + return NULL; + } + + /* Initialize byte IO */ + cio->start = cio->buffer; + cio->end = cio->buffer + cio->length; + cio->bp = cio->buffer; + + return cio; +} + +void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio) { + if(cio) { + if(cio->openmode == OPJ_STREAM_WRITE) { + /* destroy the allocated buffer */ + opj_free(cio->buffer); + } + /* destroy the cio */ + opj_free(cio); + } +} + + +/* ----------------------------------------------------------------------- */ + +/* + * Get position in byte stream. + */ +int OPJ_CALLCONV cio_tell(opj_cio_t *cio) { + return cio->bp - cio->start; +} + +/* + * Set position in byte stream. + * + * pos : position, in number of bytes, from the beginning of the stream + */ +void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos) { + cio->bp = cio->start + pos; +} + +/* + * Number of bytes left before the end of the stream. + */ +int cio_numbytesleft(opj_cio_t *cio) { + return cio->end - cio->bp; +} + +/* + * Get pointer to the current position in the stream. + */ +unsigned char *cio_getbp(opj_cio_t *cio) { + return cio->bp; +} + +/* + * Write a byte. + */ +static bool cio_byteout(opj_cio_t *cio, unsigned char v) { + if (cio->bp >= cio->end) { + opj_event_msg(cio->cinfo, EVT_ERROR, "write error\n"); + return false; + } + *cio->bp++ = v; + return true; +} + +/* + * Read a byte. + */ +static unsigned char cio_bytein(opj_cio_t *cio) { + if (cio->bp >= cio->end) { + opj_event_msg(cio->cinfo, EVT_ERROR, "read error\n"); + return 0; + } + return *cio->bp++; +} + +/* + * Write some bytes. + * + * v : value to write + * n : number of bytes to write + */ +unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n) { + int i; + for (i = n - 1; i >= 0; i--) { + if( !cio_byteout(cio, (unsigned char) ((v >> (i << 3)) & 0xff)) ) + return 0; + } + return n; +} + +/* + * Read some bytes. + * + * n : number of bytes to read + * + * return : value of the n bytes read + */ +unsigned int cio_read(opj_cio_t *cio, int n) { + int i; + unsigned int v; + v = 0; + for (i = n - 1; i >= 0; i--) { + v += cio_bytein(cio) << (i << 3); + } + return v; +} + +/* + * Skip some bytes. + * + * n : number of bytes to skip + */ +void cio_skip(opj_cio_t *cio, int n) { + cio->bp += n; +} + +/* + * Write some bytes. + * + * v : value to write + * n : number of bytes to write + */ +int cio_write_int(opj_cio_t *cio, int v, int n) { + int i; + for (i = n - 1; i >= 0; i--) { + if( !cio_byteout(cio, (char) ((v >> (i << 3)) & 0xff)) ) + return 0; + } + return n; +} + +/* + * Read some bytes. + * + * n : number of bytes to read + * + * return : value of the n bytes read + */ +int cio_read_int(opj_cio_t *cio, int n) { + int i; + int v; + v = 0; + for (i = n - 1; i >= 0; i--) { + v += cio_bytein(cio) << (i << 3); + } + return v; +} + diff --git a/src/lib/openjp3d/cio.h b/src/lib/openjp3d/cio.h old mode 100755 new mode 100644 index b7b0c416..aee5b330 --- a/src/lib/openjp3d/cio.h +++ b/src/lib/openjp3d/cio.h @@ -1,100 +1,100 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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. - */ - -#ifndef __CIO_H -#define __CIO_H -/** -@file cio.h -@brief Implementation of a byte input-output process (CIO) - -The functions in CIO.C have for goal to realize a byte input / output process. -*/ - -/** @defgroup CIO CIO - byte input-output stream */ -/*@{*/ - -/** @name Funciones generales (see also openjp3d.h) */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Number of bytes left before the end of the stream -@param cio CIO handle -@return Returns the number of bytes before the end of the stream -*/ -int cio_numbytesleft(opj_cio_t *cio); -/** -Get pointer to the current position in the stream -@param cio CIO handle -@return Returns a pointer to the current position -*/ -unsigned char *cio_getbp(opj_cio_t *cio); -/** -Write some bytes -@param cio CIO handle -@param v Value to write -@param n Number of bytes to write -@return Returns the number of bytes written or 0 if an error occured -*/ -unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n); -/** -Read some bytes -@param cio CIO handle -@param n Number of bytes to read -@return Returns the value of the n bytes read -*/ -unsigned int cio_read(opj_cio_t *cio, int n); -/** -Skip some bytes -@param cio CIO handle -@param n Number of bytes to skip -*/ -void cio_skip(opj_cio_t *cio, int n); -/** -Write some bytes -@param cio CIO handle -@param v Signed integer value to write -@param n Number of bytes to write -@return Returns the number of bytes written or 0 if an error occured -*/ -int cio_write_int(opj_cio_t *cio, int v, int n); -/** -Read some bytes -@param cio CIO handle -@param n Number of bytes to read -@return Returns the value of the n bytes read -*/ -int cio_read_int(opj_cio_t *cio, int n); -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __CIO_H */ - +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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. + */ + +#ifndef __CIO_H +#define __CIO_H +/** +@file cio.h +@brief Implementation of a byte input-output process (CIO) + +The functions in CIO.C have for goal to realize a byte input / output process. +*/ + +/** @defgroup CIO CIO - byte input-output stream */ +/*@{*/ + +/** @name Funciones generales (see also openjp3d.h) */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Number of bytes left before the end of the stream +@param cio CIO handle +@return Returns the number of bytes before the end of the stream +*/ +int cio_numbytesleft(opj_cio_t *cio); +/** +Get pointer to the current position in the stream +@param cio CIO handle +@return Returns a pointer to the current position +*/ +unsigned char *cio_getbp(opj_cio_t *cio); +/** +Write some bytes +@param cio CIO handle +@param v Value to write +@param n Number of bytes to write +@return Returns the number of bytes written or 0 if an error occured +*/ +unsigned int cio_write(opj_cio_t *cio, unsigned int v, int n); +/** +Read some bytes +@param cio CIO handle +@param n Number of bytes to read +@return Returns the value of the n bytes read +*/ +unsigned int cio_read(opj_cio_t *cio, int n); +/** +Skip some bytes +@param cio CIO handle +@param n Number of bytes to skip +*/ +void cio_skip(opj_cio_t *cio, int n); +/** +Write some bytes +@param cio CIO handle +@param v Signed integer value to write +@param n Number of bytes to write +@return Returns the number of bytes written or 0 if an error occured +*/ +int cio_write_int(opj_cio_t *cio, int v, int n); +/** +Read some bytes +@param cio CIO handle +@param n Number of bytes to read +@return Returns the value of the n bytes read +*/ +int cio_read_int(opj_cio_t *cio, int n); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __CIO_H */ + diff --git a/src/lib/openjp3d/dwt.c b/src/lib/openjp3d/dwt.c old mode 100755 new mode 100644 index 6078ec1a..3d15d893 --- a/src/lib/openjp3d/dwt.c +++ b/src/lib/openjp3d/dwt.c @@ -58,7 +58,7 @@ /** @name Local static functions */ /*@{*/ -unsigned int ops; +/*unsigned int ops;*/ /** Forward lazy transform (horizontal) */ @@ -668,7 +668,7 @@ void dwt_encode(opj_tcd_tilecomp_t * tilec, int dwtid[3]) { int *bj = NULL; int *cj = NULL; - ops = 0; + /*ops = 0;*/ memset(flagnorm,0,8000*sizeof(int)); w = tilec->x1-tilec->x0; diff --git a/src/lib/openjp3d/dwt.h b/src/lib/openjp3d/dwt.h old mode 100755 new mode 100644 index 3fa781b1..9ad6237c --- a/src/lib/openjp3d/dwt.h +++ b/src/lib/openjp3d/dwt.h @@ -1,101 +1,101 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __DWT_H -#define __DWT_H -/** -@file dwt.h -@brief Implementation of a discrete wavelet transform (DWT) - -The functions in DWT.C have for goal to realize forward and inverse discret wavelet -transform with filter 5-3 (reversible) and filter 9-7 (irreversible). The functions in -DWT.C are used by some function in TCD.C. -*/ - -/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ -/*@{*/ - -/** -DCCS-LIWT properties -*/ - - -typedef struct opj_wtfilt { - double *LPS; - int lenLPS; - double *HPS; - int lenHPS; -} opj_wtfilt_t; -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Forward 5-3 wavelet tranform in 3-D. -Apply a reversible DWT transform to a component of an volume. -@param tilec Tile component information (current tile) -@param dwtid Number of identification of wavelet kernel(s) used in DWT in each direction -*/ -void dwt_encode(opj_tcd_tilecomp_t * tilec, int dwtid[3]); -/** -Inverse 5-3 wavelet tranform in 3-D. -Apply a reversible inverse DWT transform to a component of an volume. -@param tilec Tile component information (current tile) -@param stops Number of decoded resolution levels in each dimension -@param dwtid Number of identification of wavelet kernel(s) used in DWT in each dimension -*/ -void dwt_decode(opj_tcd_tilecomp_t * tilec, int stops[3], int dwtid[3]); -/* ----------------------------------------------------------------------- */ -/** -Get the gain of a subband for the reversible 3-D DWT. -@param orient Number that identifies the subband (0->LLL, 1->HLL, 2->LHL, 3->HHL, 4->LLH, 5->HLH, 6->LHH, 7->HHH) -@param reversible Wavelet transformation type -@return Returns 0 if orient = 0, returns 1 if orient = 1,2 or 4, returns 2 if orient = 3,5 or 6, returns 3 otherwise -*/ -int dwt_getgain(int orient, int reversible); -/** -Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT or irreversible 9-7 in 3-D. -@param orient Band of the wavelet function -@param level Levels of the wavelet function in X,Y,Z axis -@param dwtid Wavelet transformation identifier -@return Returns the norm of the wavelet function -*/ -double dwt_getnorm(int orient, int level[3], int dwtid[3]); -/* ----------------------------------------------------------------------- */ -/** -Calcula el valor del escalón de cuantificación correspondiente a cada subbanda. -@param tccp Tile component coding parameters -@param prec Precision of data -*/ -void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec); -/*@}*/ -/*@}*/ - -#endif /* __DWT_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __DWT_H +#define __DWT_H +/** +@file dwt.h +@brief Implementation of a discrete wavelet transform (DWT) + +The functions in DWT.C have for goal to realize forward and inverse discret wavelet +transform with filter 5-3 (reversible) and filter 9-7 (irreversible). The functions in +DWT.C are used by some function in TCD.C. +*/ + +/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ +/*@{*/ + +/** +DCCS-LIWT properties +*/ + + +typedef struct opj_wtfilt { + double *LPS; + int lenLPS; + double *HPS; + int lenHPS; +} opj_wtfilt_t; +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Forward 5-3 wavelet tranform in 3-D. +Apply a reversible DWT transform to a component of an volume. +@param tilec Tile component information (current tile) +@param dwtid Number of identification of wavelet kernel(s) used in DWT in each direction +*/ +void dwt_encode(opj_tcd_tilecomp_t * tilec, int dwtid[3]); +/** +Inverse 5-3 wavelet tranform in 3-D. +Apply a reversible inverse DWT transform to a component of an volume. +@param tilec Tile component information (current tile) +@param stops Number of decoded resolution levels in each dimension +@param dwtid Number of identification of wavelet kernel(s) used in DWT in each dimension +*/ +void dwt_decode(opj_tcd_tilecomp_t * tilec, int stops[3], int dwtid[3]); +/* ----------------------------------------------------------------------- */ +/** +Get the gain of a subband for the reversible 3-D DWT. +@param orient Number that identifies the subband (0->LLL, 1->HLL, 2->LHL, 3->HHL, 4->LLH, 5->HLH, 6->LHH, 7->HHH) +@param reversible Wavelet transformation type +@return Returns 0 if orient = 0, returns 1 if orient = 1,2 or 4, returns 2 if orient = 3,5 or 6, returns 3 otherwise +*/ +int dwt_getgain(int orient, int reversible); +/** +Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT or irreversible 9-7 in 3-D. +@param orient Band of the wavelet function +@param level Levels of the wavelet function in X,Y,Z axis +@param dwtid Wavelet transformation identifier +@return Returns the norm of the wavelet function +*/ +double dwt_getnorm(int orient, int level[3], int dwtid[3]); +/* ----------------------------------------------------------------------- */ +/** +Calcula el valor del escalón de cuantificación correspondiente a cada subbanda. +@param tccp Tile component coding parameters +@param prec Precision of data +*/ +void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec); +/*@}*/ +/*@}*/ + +#endif /* __DWT_H */ diff --git a/src/lib/openjp3d/event.c b/src/lib/openjp3d/event.c old mode 100755 new mode 100644 index 4c86c332..f9e4da0e --- a/src/lib/openjp3d/event.c +++ b/src/lib/openjp3d/event.c @@ -1,181 +1,181 @@ -/* - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * 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" - -/* ========================================================== -// Utility functions -// ==========================================================*/ - -#ifndef _WIN32 -static char* -i2a(unsigned i, char *a, unsigned r) { - if (i/r > 0) a = i2a(i/r,a,r); - *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r]; - return a+1; -} - -/** - Transforms integer i into an ascii string and stores the result in a; - string is encoded in the base indicated by r. - @param i Number to be converted - @param a String result - @param r Base of value; must be in the range 2 - 36 - @return Returns a -*/ -static char * -_itoa(int i, char *a, int r) { - r = ((r < 2) || (r > 36)) ? 10 : r; - if(i < 0) { - *a = '-'; - *i2a(-i, a+1, r) = 0; - } - else *i2a(i, a, r) = 0; - return a; -} - -#endif /* !_WIN32 */ - -/* ----------------------------------------------------------------------- */ - -opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) { - if(cinfo) { - opj_event_mgr_t *previous = cinfo->event_mgr; - cinfo->event_mgr = event_mgr; - cinfo->client_data = context; - return previous; - } - - return NULL; -} - -bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) { -#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */ - opj_msg_callback msg_handler = NULL; - - opj_event_mgr_t *event_mgr = cinfo->event_mgr; - if(event_mgr != NULL) { - switch(event_type) { - case EVT_ERROR: - msg_handler = event_mgr->error_handler; - break; - case EVT_WARNING: - msg_handler = event_mgr->warning_handler; - break; - case EVT_INFO: - msg_handler = event_mgr->info_handler; - break; - default: - break; - } - if(msg_handler == NULL) { - return false; - } - } else { - return false; - } - - if ((fmt != NULL) && (event_mgr != NULL)) { - va_list arg; - int str_length, i, j; - char message[MSG_SIZE]; - memset(message, 0, MSG_SIZE); - /* initialize the optional parameter list */ - va_start(arg, fmt); - /* check the length of the format string */ - str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt); - /* parse the format string and put the result in 'message' */ - for (i = 0, j = 0; i < str_length; ++i) { - if (fmt[i] == '%') { - if (i + 1 < str_length) { - switch(tolower(fmt[i + 1])) { - case '%' : - message[j++] = '%'; - break; - case 'o' : /* octal numbers */ - { - char tmp[16]; - _itoa(va_arg(arg, int), tmp, 8); - strcat(message, tmp); - j += strlen(tmp); - ++i; - break; - } - case 'i' : /* decimal numbers */ - case 'd' : - { - char tmp[16]; - _itoa(va_arg(arg, int), tmp, 10); - strcat(message, tmp); - j += strlen(tmp); - ++i; - break; - } - case 'x' : /* hexadecimal numbers */ - { - char tmp[16]; - _itoa(va_arg(arg, int), tmp, 16); - strcat(message, tmp); - j += strlen(tmp); - ++i; - break; - } - case 's' : /* strings */ - { - char *tmp = va_arg(arg, char*); - strcat(message, tmp); - j += strlen(tmp); - ++i; - break; - } - case 'f' : /* floats */ - { - char tmp[16]; - double value = va_arg(arg, double); - sprintf(tmp, "%f", value); - strcat(message, tmp); - j += strlen(tmp); - ++i; - break; - } - }; - } else { - message[j++] = fmt[i]; - } - } else { - message[j++] = fmt[i]; - }; - } - /* deinitialize the optional parameter list */ - va_end(arg); - - /* output the message to the user program */ - msg_handler(message, cinfo->client_data); - } - - return true; -} - +/* + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * 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" + +/* ========================================================== +// Utility functions +// ==========================================================*/ + +#ifndef _WIN32 +static char* +i2a(unsigned i, char *a, unsigned r) { + if (i/r > 0) a = i2a(i/r,a,r); + *a = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i%r]; + return a+1; +} + +/** + Transforms integer i into an ascii string and stores the result in a; + string is encoded in the base indicated by r. + @param i Number to be converted + @param a String result + @param r Base of value; must be in the range 2 - 36 + @return Returns a +*/ +static char * +_itoa(int i, char *a, int r) { + r = ((r < 2) || (r > 36)) ? 10 : r; + if(i < 0) { + *a = '-'; + *i2a(-i, a+1, r) = 0; + } + else *i2a(i, a, r) = 0; + return a; +} + +#endif /* !_WIN32 */ + +/* ----------------------------------------------------------------------- */ + +opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context) { + if(cinfo) { + opj_event_mgr_t *previous = cinfo->event_mgr; + cinfo->event_mgr = event_mgr; + cinfo->client_data = context; + return previous; + } + + return NULL; +} + +bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) { +#define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */ + opj_msg_callback msg_handler = NULL; + + opj_event_mgr_t *event_mgr = cinfo->event_mgr; + if(event_mgr != NULL) { + switch(event_type) { + case EVT_ERROR: + msg_handler = event_mgr->error_handler; + break; + case EVT_WARNING: + msg_handler = event_mgr->warning_handler; + break; + case EVT_INFO: + msg_handler = event_mgr->info_handler; + break; + default: + break; + } + if(msg_handler == NULL) { + return false; + } + } else { + return false; + } + + if ((fmt != NULL) && (event_mgr != NULL)) { + va_list arg; + int str_length, i, j; + char message[MSG_SIZE]; + memset(message, 0, MSG_SIZE); + /* initialize the optional parameter list */ + va_start(arg, fmt); + /* check the length of the format string */ + str_length = (strlen(fmt) > MSG_SIZE) ? MSG_SIZE : strlen(fmt); + /* parse the format string and put the result in 'message' */ + for (i = 0, j = 0; i < str_length; ++i) { + if (fmt[i] == '%') { + if (i + 1 < str_length) { + switch(tolower(fmt[i + 1])) { + case '%' : + message[j++] = '%'; + break; + case 'o' : /* octal numbers */ + { + char tmp[16]; + _itoa(va_arg(arg, int), tmp, 8); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + case 'i' : /* decimal numbers */ + case 'd' : + { + char tmp[16]; + _itoa(va_arg(arg, int), tmp, 10); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + case 'x' : /* hexadecimal numbers */ + { + char tmp[16]; + _itoa(va_arg(arg, int), tmp, 16); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + case 's' : /* strings */ + { + char *tmp = va_arg(arg, char*); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + case 'f' : /* floats */ + { + char tmp[16]; + double value = va_arg(arg, double); + sprintf(tmp, "%f", value); + strcat(message, tmp); + j += strlen(tmp); + ++i; + break; + } + }; + } else { + message[j++] = fmt[i]; + } + } else { + message[j++] = fmt[i]; + }; + } + /* deinitialize the optional parameter list */ + va_end(arg); + + /* output the message to the user program */ + msg_handler(message, cinfo->client_data); + } + + return true; +} + diff --git a/src/lib/openjp3d/event.h b/src/lib/openjp3d/event.h old mode 100755 new mode 100644 index 8f45452b..4b803b56 --- a/src/lib/openjp3d/event.h +++ b/src/lib/openjp3d/event.h @@ -1,58 +1,58 @@ -/* - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __EVENT_H -#define __EVENT_H -/** -@file event.h -@brief Implementation of a event callback system - -The functions in EVENT.C have for goal to send output messages (errors, warnings, debug) to the user. -*/ - -#define EVT_ERROR 1 /**< Error event type */ -#define EVT_WARNING 2 /**< Warning event type */ -#define EVT_INFO 4 /**< Debug event type */ - -/** @defgroup EVENT EVENT - Implementation of a event callback system */ -/*@{*/ - -/** @name Funciones generales (see also openjp3d.h) */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Write formatted data to a string and send the string to a user callback. -@param cinfo Codec context info -@param event_type Event type or callback to use to send the message -@param fmt Format-control string (plus optionnal arguments) -@return Returns true if successful, returns false otherwise -*/ -bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...); -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __EVENT_H */ +/* + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __EVENT_H +#define __EVENT_H +/** +@file event.h +@brief Implementation of a event callback system + +The functions in EVENT.C have for goal to send output messages (errors, warnings, debug) to the user. +*/ + +#define EVT_ERROR 1 /**< Error event type */ +#define EVT_WARNING 2 /**< Warning event type */ +#define EVT_INFO 4 /**< Debug event type */ + +/** @defgroup EVENT EVENT - Implementation of a event callback system */ +/*@{*/ + +/** @name Funciones generales (see also openjp3d.h) */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Write formatted data to a string and send the string to a user callback. +@param cinfo Codec context info +@param event_type Event type or callback to use to send the message +@param fmt Format-control string (plus optionnal arguments) +@return Returns true if successful, returns false otherwise +*/ +bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __EVENT_H */ diff --git a/src/lib/openjp3d/fix.h b/src/lib/openjp3d/fix.h old mode 100755 new mode 100644 diff --git a/src/lib/openjp3d/int.h b/src/lib/openjp3d/int.h old mode 100755 new mode 100644 diff --git a/src/lib/openjp3d/jp3d.c b/src/lib/openjp3d/jp3d.c old mode 100755 new mode 100644 index 593cda82..1b940e70 --- a/src/lib/openjp3d/jp3d.c +++ b/src/lib/openjp3d/jp3d.c @@ -1,2333 +1,2355 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain - * 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" - -/** @defgroup J3D J3D - JPEG-2000 PART 10 codestream reader/writer */ -/*@{*/ - -/** @name Funciones locales */ -/*@{*/ - -/** -Write the SOC marker (Start Of Codestream) -@param j3d J3D handle -*/ -static void j3d_write_soc(opj_j3d_t *j3d); -/** -Read the SOC marker (Start of Codestream) -@param j3d J3D handle -*/ -static void j3d_read_soc(opj_j3d_t *j3d); -/** -Write the SIZ marker (2D volume and tile size) -@param j3d J3D handle -*/ -static void j3d_write_siz(opj_j3d_t *j3d); -/** -Read the SIZ marker (2D volume and tile size) -@param j3d J3D handle -*/ -static void j3d_read_siz(opj_j3d_t *j3d); -/** -Write the ZSI marker (3rd volume and tile size) -@param j3d J3D handle -*/ -static void j3d_write_zsi(opj_j3d_t *j3d); -/** -Read the ZSI marker (3rd volume and tile size) -@param j3d J3D handle -*/ -static void j3d_read_zsi(opj_j3d_t *j3d); -/** -Write the COM marker (comment) -@param j3d J3D handle -*/ -static void j3d_write_com(opj_j3d_t *j3d); -/** -Read the COM marker (comment) -@param j3d J3D handle -*/ -static void j3d_read_com(opj_j3d_t *j3d); -/** -Write the value concerning the specified component in the marker COD and COC -@param j3d J3D handle -@param compno Number of the component concerned by the information written -*/ -static void j3d_write_cox(opj_j3d_t *j3d, int compno); -/** -Read the value concerning the specified component in the marker COD and COC -@param j3d J3D handle -@param compno Number of the component concerned by the information read -*/ -static void j3d_read_cox(opj_j3d_t *j3d, int compno); -/** -Write the COD marker (coding style default) -@param j3d J3D handle -*/ -static void j3d_write_cod(opj_j3d_t *j3d); -/** -Read the COD marker (coding style default) -@param j3d J3D handle -*/ -static void j3d_read_cod(opj_j3d_t *j3d); -/** -Write the COC marker (coding style component) -@param j3d J3D handle -@param compno Number of the component concerned by the information written -*/ -static void j3d_write_coc(opj_j3d_t *j3d, int compno); -/** -Read the COC marker (coding style component) -@param j3d J3D handle -*/ -static void j3d_read_coc(opj_j3d_t *j3d); -/** -Write the value concerning the specified component in the marker QCD and QCC -@param j3d J3D handle -@param compno Number of the component concerned by the information written -*/ -static void j3d_write_qcx(opj_j3d_t *j3d, int compno); -/** -Read the value concerning the specified component in the marker QCD and QCC -@param j3d J3D handle -@param compno Number of the component concern by the information read -@param len Length of the information in the QCX part of the marker QCD/QCC -*/ -static void j3d_read_qcx(opj_j3d_t *j3d, int compno, int len); -/** -Write the QCD marker (quantization default) -@param j3d J3D handle -*/ -static void j3d_write_qcd(opj_j3d_t *j3d); -/** -Read the QCD marker (quantization default) -@param j3d J3D handle -*/ -static void j3d_read_qcd(opj_j3d_t *j3d); -/** -Write the QCC marker (quantization component) -@param j3d J3D handle -@param compno Number of the component concerned by the information written -*/ -static void j3d_write_qcc(opj_j3d_t *j3d, int compno); -/** -Read the QCC marker (quantization component) -@param j3d J3D handle -*/ -static void j3d_read_qcc(opj_j3d_t *j3d); -/** -Write the POC marker (progression order change) -@param j3d J3D handle -*/ -static void j3d_write_poc(opj_j3d_t *j3d); -/** -Read the POC marker (progression order change) -@param j3d J3D handle -*/ -static void j3d_read_poc(opj_j3d_t *j3d); -/** -Read the CRG marker (component registration) -@param j3d J3D handle -*/ -static void j3d_read_crg(opj_j3d_t *j3d); -/** -Read the TLM marker (tile-part lengths) -@param j3d J3D handle -*/ -static void j3d_read_tlm(opj_j3d_t *j3d); -/** -Read the PLM marker (packet length, main header) -@param j3d J3D handle -*/ -static void j3d_read_plm(opj_j3d_t *j3d); -/** -Read the PLT marker (packet length, tile-part header) -@param j3d J3D handle -*/ -static void j3d_read_plt(opj_j3d_t *j3d); -/** -Read the PPM marker (packet packet headers, main header) -@param j3d J3D handle -*/ -static void j3d_read_ppm(opj_j3d_t *j3d); -/** -Read the PPT marker (packet packet headers, tile-part header) -@param j3d J3D handle -*/ -static void j3d_read_ppt(opj_j3d_t *j3d); -/** -Write the SOT marker (start of tile-part) -@param j3d J3D handle -*/ -static void j3d_write_sot(opj_j3d_t *j3d); -/** -Read the SOT marker (start of tile-part) -@param j3d J3D handle -*/ -static void j3d_read_sot(opj_j3d_t *j3d); -/** -Write the SOD marker (start of data) -@param j3d J3D handle -@param tile_coder Pointer to a TCD handle -*/ -static void j3d_write_sod(opj_j3d_t *j3d, void *tile_coder); -/** -Read the SOD marker (start of data) -@param j3d J3D handle -*/ -static void j3d_read_sod(opj_j3d_t *j3d); -/** -Write the RGN marker (region-of-interest) -@param j3d J3D handle -@param compno Number of the component concerned by the information written -@param tileno Number of the tile concerned by the information written -*/ -static void j3d_write_rgn(opj_j3d_t *j3d, int compno, int tileno); -/** -Read the RGN marker (region-of-interest) -@param j3d J3D handle -*/ -static void j3d_read_rgn(opj_j3d_t *j3d); -/** -Write the EOC marker (end of codestream) -@param j3d J3D handle -*/ -static void j3d_write_eoc(opj_j3d_t *j3d); -/** -Read the EOC marker (end of codestream) -@param j3d J3D handle -*/ -static void j3d_read_eoc(opj_j3d_t *j3d); -/** -Read an unknown marker -@param j3d J3D handle -*/ -static void j3d_read_unk(opj_j3d_t *j3d); -/** -Write the CAP marker (extended capabilities) -@param j3d J3D handle -*/ -static void j3d_write_cap(opj_j3d_t *j3d); -/** -Read the CAP marker (extended capabilities) -@param j3d J3D handle -*/ -static void j3d_read_cap(opj_j3d_t *j3d); -/** -Write the DCO marker (Variable DC offset) -@param j3d J3D handle -*/ -static void j3d_write_dco(opj_j3d_t *j3d); -/** -Read the DCO marker (Variable DC offset) -@param j3d J3D handle -*/ -static void j3d_read_dco(opj_j3d_t *j3d); -/** -Write the ATK marker (arbitrary transformation kernel) -@param j3d J3D handle -*/ -static void j3d_write_atk(opj_j3d_t *j3d); -/** -Read the ATK marker (arbitrary transformation kernel) -@param j3d J3D handle -*/ -static void j3d_read_atk(opj_j3d_t *j3d); -/** -Write the CBD marker (component bit depth definition) -@param j3d J3D handle -*/ -static void j3d_write_cbd(opj_j3d_t *j3d); -/** -Read the CBD marker (component bit depth definition) -@param j3d J3D handle -*/ -static void j3d_read_cbd(opj_j3d_t *j3d); -/** -Write the MCT marker (multiple component transfomation definition) -@param j3d J3D handle -*/ -static void j3d_write_mct(opj_j3d_t *j3d); -/** -Read the MCT marker (multiple component transfomation definition) -@param j3d J3D handle -*/ -static void j3d_read_mct(opj_j3d_t *j3d); -/** -Write the MCC marker (multiple component transfomation collection) -@param j3d J3D handle -*/ -static void j3d_write_mcc(opj_j3d_t *j3d); -/** -Read the MCC marker (multiple component transfomation collection) -@param j3d J3D handle -*/ -static void j3d_read_mcc(opj_j3d_t *j3d); -/** -Write the MCO marker (multiple component transfomation ordering) -@param j3d J3D handle -*/ -static void j3d_write_mco(opj_j3d_t *j3d); -/** -Read the MCO marker (multiple component transfomation ordering) -@param j3d J3D handle -*/ -static void j3d_read_mco(opj_j3d_t *j3d); -/** -Write the NLT marker (non-linearity point transformation) -@param j3d J3D handle -*/ -static void j3d_write_nlt(opj_j3d_t *j3d); -/** -Read the NLT marker (non-linearity point transformation) -@param j3d J3D handle -*/ -static void j3d_read_nlt(opj_j3d_t *j3d); -/*@}*/ - -/* ----------------------------------------------------------------------- */ - -static void j3d_dump_volume(FILE *fd, opj_volume_t * vol) { - int compno; - fprintf(fd, "volume {\n"); - fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", vol->x0, vol->y0, vol->z0,vol->x1, vol->y1, vol->z1); - fprintf(fd, " numcomps=%d\n", vol->numcomps); - for (compno = 0; compno < vol->numcomps; compno++) { - opj_volume_comp_t *comp = &vol->comps[compno]; - fprintf(fd, " comp %d {\n", compno); - fprintf(fd, " dx=%d, dy=%d, dz=%d\n", comp->dx, comp->dy, comp->dz); - fprintf(fd, " prec=%d\n", comp->prec); - fprintf(fd, " sgnd=%d\n", comp->sgnd); - fprintf(fd, " }\n"); - } - fprintf(fd, "}\n"); -} - -static void j3d_dump_cp(FILE *fd, opj_volume_t * vol, opj_cp_t * cp) { - int tileno, compno, layno, bandno, resno, numbands; - fprintf(fd, "coding parameters {\n"); - fprintf(fd, " tx0=%d, ty0=%d, tz0=%d\n", cp->tx0, cp->ty0, cp->tz0); - fprintf(fd, " tdx=%d, tdy=%d, tdz=%d\n", cp->tdx, cp->tdy, cp->tdz); - fprintf(fd, " tw=%d, th=%d, tl=%d\n", cp->tw, cp->th, cp->tl); - fprintf(fd, " transform format: %d\n", cp->transform_format); - fprintf(fd, " encoding format: %d\n", cp->encoding_format); - for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) { - opj_tcp_t *tcp = &cp->tcps[tileno]; - fprintf(fd, " tile %d {\n", tileno); - fprintf(fd, " csty=%x\n", tcp->csty); - fprintf(fd, " prg=%d\n", tcp->prg); - fprintf(fd, " numlayers=%d\n", tcp->numlayers); - fprintf(fd, " mct=%d\n", tcp->mct); - fprintf(fd, " rates="); - for (layno = 0; layno < tcp->numlayers; layno++) { - fprintf(fd, "%f ", tcp->rates[layno]); - } - fprintf(fd, "\n"); - fprintf(fd, " first=%d\n", tcp->first); - for (compno = 0; compno < vol->numcomps; compno++) { - opj_tccp_t *tccp = &tcp->tccps[compno]; - fprintf(fd, " comp %d {\n", compno); - fprintf(fd, " csty=%x\n", tccp->csty); - fprintf(fd, " numresx=%d, numresy=%d, numresz=%d\n", tccp->numresolution[0], tccp->numresolution[1], tccp->numresolution[2]); - fprintf(fd, " cblkw=%d, cblkh=%d, cblkl=%d\n", tccp->cblk[0], tccp->cblk[1], tccp->cblk[2]); - fprintf(fd, " cblksty=%x\n", tccp->cblksty); - fprintf(fd, " qntsty=%d\n", tccp->qntsty); - fprintf(fd, " numgbits=%d\n", tccp->numgbits); - fprintf(fd, " roishift=%d\n", tccp->roishift); - fprintf(fd, " reversible=%d\n", tccp->reversible); - fprintf(fd, " dwtidx=%d dwtidy=%d dwtidz=%d\n", tccp->dwtid[0], tccp->dwtid[1], tccp->dwtid[2]); - if (tccp->atk != NULL) { - fprintf(fd, " atk.index=%d\n", tccp->atk->index); - fprintf(fd, " atk.coeff_typ=%d\n", tccp->atk->coeff_typ); - fprintf(fd, " atk.filt_cat=%d\n", tccp->atk->filt_cat); - fprintf(fd, " atk.exten=%d\n", tccp->atk->exten); - fprintf(fd, " atk.minit=%d\n", tccp->atk->minit); - fprintf(fd, " atk.wt_typ=%d\n", tccp->atk->wt_typ); - } - fprintf(fd, " stepsizes of bands="); - numbands = (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) ? 1 : - ( (cp->transform_format == TRF_2D_DWT) ? (tccp->numresolution[0] * 3 - 2) : - (tccp->numresolution[0] * 7 - 6) - 4 *(tccp->numresolution[0] - tccp->numresolution[2]) ); - for (bandno = 0; bandno < numbands; bandno++) { - fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant,tccp->stepsizes[bandno].expn); - } - fprintf(fd, "\n"); - - if (tccp->csty & J3D_CCP_CSTY_PRT) { - fprintf(fd, " prcw="); - for (resno = 0; resno < tccp->numresolution[0]; resno++) { - fprintf(fd, "%d ", tccp->prctsiz[0][resno]); - } - fprintf(fd, "\n"); - fprintf(fd, " prch="); - for (resno = 0; resno < tccp->numresolution[0]; resno++) { - fprintf(fd, "%d ", tccp->prctsiz[1][resno]); - } - fprintf(fd, "\n"); - fprintf(fd, " prcl="); - for (resno = 0; resno < tccp->numresolution[0]; resno++) { - fprintf(fd, "%d ", tccp->prctsiz[2][resno]); - } - fprintf(fd, "\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, "}\n"); -} - -/* ----------------------------------------------------------------------- -Extended capabilities -------------------------------------------------------------------------*/ - -static void j3d_write_cap(opj_j3d_t *j3d){ - int len,lenp; - - opj_cio_t *cio = j3d->cio; - cio_write(cio, J3D_MS_CAP, 2); /* CAP */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio,J3D_CAP_10, 4); - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lsiz */ - cio_seek(cio, lenp + len); - -} -static void j3d_read_cap(opj_j3d_t *j3d){ - int len, Cap; - opj_cio_t *cio = j3d->cio; - /*cio_read(cio, 2); CAP */ - len = cio_read(cio, 2); - Cap = cio_read(cio, 4); -} -static void j3d_write_zsi(opj_j3d_t *j3d) { - int i; - int lenp, len; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - opj_cp_t *cp = j3d->cp; - - cio_write(cio, J3D_MS_ZSI, 2); /* ZSI */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, volume->z1, 4); /* Zsiz */ - cio_write(cio, volume->z0, 4); /* Z0siz */ - cio_write(cio, cp->tdz, 4); /* ZTsiz */ - cio_write(cio, cp->tz0, 4); /* ZT0siz */ - for (i = 0; i < volume->numcomps; i++) { - cio_write(cio, volume->comps[i].dz, 1); /* ZRsiz_i */ - } - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lsiz */ - cio_seek(cio, lenp + len); -} - -static void j3d_read_zsi(opj_j3d_t *j3d) { - int len, i; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - opj_cp_t *cp = j3d->cp; - - len = cio_read(cio, 2); /* Lsiz */ - volume->z1 = cio_read(cio, 4); /* Zsiz */ - volume->z0 = cio_read(cio, 4); /* Z0siz */ - cp->tdz = cio_read(cio, 4); /* ZTsiz */ - cp->tz0 = cio_read(cio, 4); /* ZT0siz */ - for (i = 0; i < volume->numcomps; i++) { - volume->comps[i].dz = cio_read(cio, 1); /* ZRsiz_i */ - } - - /*Initialization of volume*/ - cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx); - cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy); - cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz); - cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t)); - cp->tileno = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int)); - cp->tileno_size = 0; - - for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) { - cp->tcps[i].POC = 0; - cp->tcps[i].numpocs = 0; - cp->tcps[i].first = 1; - } - - /* Initialization for PPM marker (Packets header)*/ - cp->ppm = 0; - cp->ppm_data = NULL; - cp->ppm_data_first = NULL; - cp->ppm_previous = 0; - cp->ppm_store = 0; - - j3d->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps); - for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) { - cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps); - } - j3d->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(unsigned char *)); - j3d->tile_len = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int)); - j3d->state = J3D_STATE_MH; - -} -static void j3d_write_dco(opj_j3d_t *j3d){ - int lenp, len, i; - int dcotype; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - opj_cp_t *cp = j3d->cp; - - dcotype = 1; /* Offsets are 16bit signed integers Table A21 15444-2 */ - cio_write(cio, J3D_MS_DCO, 2); /* DCO */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, dcotype, 1); - if (dcotype == 0) { - for (i = 0; i < volume->numcomps; i++) - cio_write(cio, volume->comps[i].dcoffset, 1); /* SPdco_i */ - } else if (dcotype == 1) { - for (i = 0; i < volume->numcomps; i++){ - cio_write(cio, volume->comps[i].dcoffset, 1); /* SPdco_i */ - opj_event_msg(j3d->cinfo, EVT_INFO, "dcotype %d DCO %d \n",dcotype,volume->comps[i].dcoffset); - } - } - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Ldco */ - cio_seek(cio, lenp + len); - -} -static void j3d_read_dco(opj_j3d_t *j3d){ - int len, i; - int dcotype; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - opj_cp_t *cp = j3d->cp; - - len = cio_read(cio, 2); /* Lsiz */ - dcotype = cio_read(cio, 1); /*offset 8bit unsigned / 16bit signed integers*/ - if (dcotype == 0) { - for (i = 0; i < volume->numcomps; i++) { - volume->comps[i].dcoffset = cio_read(cio, 1); - if (volume->comps[i].dcoffset > 128) - volume->comps[i].dcoffset = volume->comps[i].dcoffset - 256; - } - } else if (dcotype == 1) { - for (i = 0; i < volume->numcomps; i++) { - volume->comps[i].dcoffset = cio_read(cio, 1); - if (volume->comps[i].dcoffset > 128) - volume->comps[i].dcoffset = volume->comps[i].dcoffset - 256; - } - } - -} -static void j3d_write_atk(opj_j3d_t *j3d){ - int lenp, len, s, k; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - opj_atk_t *atk = j3d->cp->tcps->tccps->atk; - - cio_write(cio, J3D_MS_ATK, 2); /* ATK */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, atk->index + (atk->coeff_typ << 8) + (atk->filt_cat << 11) - + (atk->wt_typ << 12) + (atk->minit << 13) + (atk->exten << 14), 2); /* Satk */ - if (atk->wt_typ == J3D_ATK_IRR) - cio_write(cio,(unsigned int) (atk->Katk * 8192.0), 1 << atk->coeff_typ); - cio_write(cio, atk->Natk, 1); - for (s = 0; s < atk->Natk; s++){ - if (atk->filt_cat == J3D_ATK_ARB) - cio_write(cio, atk->Oatk[s], 1); - if (atk->wt_typ == J3D_ATK_REV){ - cio_write(cio, atk->Eatk[s], 1); - cio_write(cio, atk->Batk[s], 1); - } - cio_write(cio, atk->LCatk[s], 1); - for (k = 0; k < atk->LCatk[s]; k++) - cio_write(cio,(unsigned int) (atk->Aatk[s][k] * 8192.0), 1 << atk->coeff_typ); - } - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Latk */ - cio_seek(cio, lenp + len); -} -static void j3d_read_atk(opj_j3d_t *j3d){ - int len, i, Satk, k; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - opj_cp_t *cp = j3d->cp; - opj_atk_t *atk = cp->tcps->tccps->atk; - - len = cio_read(cio, 2); /* Latk */ - Satk = cio_read(cio, 2); - atk->index = Satk & 0x00ff; - atk->coeff_typ = Satk >> 8 & 0x0007; - atk->filt_cat = Satk >> 11 & 0x0001; - atk->wt_typ = Satk >> 12 & 0x0001; - atk->minit = Satk >> 13 & 0x0001; - atk->exten = Satk >> 14 & 0x0001; - if (atk->wt_typ == J3D_ATK_IRR) - atk->Katk = ((double) cio_read(cio, 1 << atk->coeff_typ) / 8192.0); - atk->Natk = cio_read(cio, 1); - for (i = 0; i < atk->Natk; i++) { - if (atk->filt_cat == J3D_ATK_ARB) - atk->Oatk[i] = cio_read(cio, 1); - if (atk->wt_typ == J3D_ATK_REV){ - atk->Eatk[i] = cio_read(cio, 1); - atk->Batk[i] = cio_read(cio, 1); - } - atk->LCatk[i] = cio_read(cio, 1); - for (k = 0; k < atk->LCatk[i]; k++) - atk->Aatk[i][k] = ((double) cio_read(cio, 1 << atk->coeff_typ) / 8192.0); - } -} -static void j3d_write_cbd(opj_j3d_t *j3d){ -} -static void j3d_read_cbd(opj_j3d_t *j3d){ -} -static void j3d_write_mct(opj_j3d_t *j3d){ -} -static void j3d_read_mct(opj_j3d_t *j3d){ -} -static void j3d_write_mcc(opj_j3d_t *j3d){ -} -static void j3d_read_mcc(opj_j3d_t *j3d){ -} -static void j3d_write_mco(opj_j3d_t *j3d){ -} -static void j3d_read_mco(opj_j3d_t *j3d){ -} -static void j3d_write_nlt(opj_j3d_t *j3d){ -} -static void j3d_read_nlt(opj_j3d_t *j3d){ -} -/* ----------------------------------------------------------------------- -15444-1 codestream syntax -------------------------------------------------------------------------*/ -static void j3d_write_soc(opj_j3d_t *j3d) { - opj_cio_t *cio = j3d->cio; - cio_write(cio, J3D_MS_SOC, 2); -} - -static void j3d_read_soc(opj_j3d_t *j3d) { - j3d->state = J3D_STATE_MHSIZ; -} - -static void j3d_write_siz(opj_j3d_t *j3d) { - int i; - int lenp, len; - int Rsiz; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - opj_cp_t *cp = j3d->cp; - - cio_write(cio, J3D_MS_SIZ, 2); /* SIZ */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - /*cio_write(cio, 0, 2);*/ /* Rsiz (capabilities of 15444-1 only) */ - Rsiz = J3D_RSIZ_DCO | J3D_RSIZ_ATK; /** | J3D_RSIZ_MCT | J3D_RSIZ_NONLT (not implemented yet)*/ - cio_write(cio, Rsiz, 2); /* capabilities of WDv5.2*/ - cio_write(cio, volume->x1, 4); /* Xsiz */ - cio_write(cio, volume->y1, 4); /* Ysiz */ - cio_write(cio, volume->x0, 4); /* X0siz */ - cio_write(cio, volume->y0, 4); /* Y0siz */ - cio_write(cio, cp->tdx, 4); /* XTsiz */ - cio_write(cio, cp->tdy, 4); /* YTsiz */ - cio_write(cio, cp->tx0, 4); /* XT0siz */ - cio_write(cio, cp->ty0, 4); /* YT0siz */ - cio_write(cio, volume->numcomps, 2); /* Csiz */ - for (i = 0; i < volume->numcomps; i++) { - cio_write(cio, volume->comps[i].prec - 1 + (volume->comps[i].sgnd << 7), 1); /* Ssiz_i */ - cio_write(cio, volume->comps[i].dx, 1); /* XRsiz_i */ - cio_write(cio, volume->comps[i].dy, 1); /* YRsiz_i */ - } - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lsiz */ - cio_seek(cio, lenp + len); -} - -static void j3d_read_siz(opj_j3d_t *j3d) { - int len, i; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - opj_cp_t *cp = j3d->cp; - - len = cio_read(cio, 2); /* Lsiz */ - cp->rsiz = cio_read(cio, 2); /* Rsiz (capabilities) */ - volume->x1 = cio_read(cio, 4); /* Xsiz */ - volume->y1 = cio_read(cio, 4); /* Ysiz */ - volume->x0 = cio_read(cio, 4); /* X0siz */ - volume->y0 = cio_read(cio, 4); /* Y0siz */ - cp->tdx = cio_read(cio, 4); /* XTsiz */ - cp->tdy = cio_read(cio, 4); /* YTsiz */ - cp->tx0 = cio_read(cio, 4); /* XT0siz */ - cp->ty0 = cio_read(cio, 4); /* YT0siz */ - - volume->numcomps = cio_read(cio, 2); /* Csiz */ - volume->comps = (opj_volume_comp_t *) opj_malloc(volume->numcomps * sizeof(opj_volume_comp_t)); - for (i = 0; i < volume->numcomps; i++) { - int tmp, j; - tmp = cio_read(cio, 1); /* Ssiz_i */ - volume->comps[i].prec = (tmp & 0x7f) + 1; - volume->comps[i].sgnd = tmp >> 7; - volume->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */ - volume->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */ - for (j = 0; j < 3; j++) { - volume->comps[i].resno_decoded[j] = 0; /* number of resolution decoded */ - volume->comps[i].factor[j] = 0; /* reducing factor per component */ - } - } - - if (j3d->cinfo->codec_format == CODEC_J2K){ - volume->z1 = 1; - volume->z0 = 0; - volume->numslices = 1; - cp->tdz = 1; - cp->tz0 = 0; - for (i = 0; i < volume->numcomps; i++) - volume->comps[i].dz = 1; - - /*Initialization of volume*/ - cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx); - cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy); - cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz); - cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t)); - cp->tileno = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int)); - cp->tileno_size = 0; - - for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) { - cp->tcps[i].POC = 0; - cp->tcps[i].numpocs = 0; - cp->tcps[i].first = 1; - } - - /* Initialization for PPM marker (Packets header)*/ - cp->ppm = 0; - cp->ppm_data = NULL; - cp->ppm_data_first = NULL; - cp->ppm_previous = 0; - cp->ppm_store = 0; - - j3d->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps); - for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) { - cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps); - } - j3d->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(unsigned char *)); - j3d->tile_len = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int)); - j3d->state = J3D_STATE_MH; - } -} - - - -static void j3d_write_com(opj_j3d_t *j3d) { - unsigned int i; - int lenp, len; - - opj_cio_t *cio = j3d->cio; - - cio_write(cio, J3D_MS_COM, 2); - lenp = cio_tell(cio); - cio_skip(cio, 2); - /*cio_write(cio, 0, 2);*/ - cio_write(cio, j3d->cp->transform_format,1); - cio_write(cio, j3d->cp->encoding_format,1); - /*opj_event_msg(j3d->cinfo, EVT_INFO, "TRF %D ENCOD %d\n",j3d->cp->transform_format,j3d->cp->encoding_format);*/ - if (j3d->cp->comment != NULL) { - char *comment = j3d->cp->comment; - for (i = 0; i < strlen(comment); i++) { - cio_write(cio, comment[i], 1); - } - } - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); - cio_seek(cio, lenp + len); -} - -static void j3d_read_com(opj_j3d_t *j3d) { - int len; - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); - - j3d->cp->transform_format = (OPJ_TRANSFORM) cio_read(cio, 1); - j3d->cp->encoding_format = (OPJ_ENTROPY_CODING) cio_read(cio, 1); - /*opj_event_msg(j3d->cinfo, EVT_INFO, "TRF %D ENCOD %d\n",j3d->cp->transform_format,j3d->cp->encoding_format);*/ - - cio_skip(cio, len - 4); /*posible comments*/ -} - -static void j3d_write_cox(opj_j3d_t *j3d, int compno) { - int i; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = &cp->tcps[j3d->curtileno]; - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_cio_t *cio = j3d->cio; - - cio_write(cio, tccp->numresolution[0] - 1, 1); /* SPcox (D) No of decomposition levels in x-axis*/ - if (j3d->cinfo->codec_format == CODEC_J3D) { - cio_write(cio, tccp->numresolution[1] - 1, 1); /* SPcox (E) No of decomposition levels in y-axis*/ - cio_write(cio, tccp->numresolution[2] - 1, 1); /* SPcox (F) No of decomposition levels in z-axis*/ - } - /* (cblkw - 2) + (cblkh - 2) + (cblkl - 2) <= 18*/ - cio_write(cio, tccp->cblk[0] - 2, 1); /* SPcox (G) Cblk width entre 10 y 2 (8 y 0)*/ - cio_write(cio, tccp->cblk[1] - 2, 1); /* SPcox (H) Cblk height*/ - if (j3d->cinfo->codec_format == CODEC_J3D) { - cio_write(cio, tccp->cblk[2] - 2, 1); /* SPcox (I) Cblk depth*/ - } - cio_write(cio, tccp->cblksty, 1); /* SPcox (J) Cblk style*/ - cio_write(cio, tccp->dwtid[0], 1); /* SPcox (K) WT in x-axis 15444-2 Table A10*/ - if (j3d->cinfo->codec_format == CODEC_J3D) { - cio_write(cio, tccp->dwtid[1], 1); /* SPcox (L) WT in y-axis 15444-2 Table A10*/ - cio_write(cio, tccp->dwtid[2], 1); /* SPcox (M) WT in z-axis 15444-2 Table A10*/ - } - - if (tccp->csty & J3D_CCP_CSTY_PRT) { - for (i = 0; i < tccp->numresolution[0]; i++) { - if (i < tccp->numresolution[2]) - cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4) + (tccp->prctsiz[2][i] << 8), 2); /* SPcox (N_i) Table A9*/ - else - if (j3d->cinfo->codec_format == CODEC_J3D) - cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4), 2); /* SPcox (N_i) Table A9*/ - else - cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4), 1); /* SPcox (N_i) Table A9*/ } - } -} - -static void j3d_read_cox(opj_j3d_t *j3d, int compno) { - int i; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_cio_t *cio = j3d->cio; - - tccp->numresolution[0] = cio_read(cio, 1) + 1; /* SPcox (D) No of decomposition levels in x-axis*/ - if (j3d->cinfo->codec_format == CODEC_J3D) { - tccp->numresolution[1] = cio_read(cio, 1) + 1; /* SPcox (E) No of decomposition levels in y-axis*/ - tccp->numresolution[2] = cio_read(cio, 1) + 1; /* SPcox (F) No of decomposition levels in z-axis*/ - }else if (j3d->cinfo->codec_format == CODEC_J2K) { - tccp->numresolution[1] = tccp->numresolution[0]; - tccp->numresolution[2] = 1; - } - /* check the reduce value */ - cp->reduce[0] = int_min((tccp->numresolution[0])-1, cp->reduce[0]); - cp->reduce[1] = int_min((tccp->numresolution[1])-1, cp->reduce[1]); - cp->reduce[2] = int_min((tccp->numresolution[2])-1, cp->reduce[2]); - - tccp->cblk[0] = cio_read(cio, 1) + 2; /* SPcox (G) */ - tccp->cblk[1] = cio_read(cio, 1) + 2; /* SPcox (H) */ - if (j3d->cinfo->codec_format == CODEC_J3D) - tccp->cblk[2] = cio_read(cio, 1) + 2; /* SPcox (I) */ - else - tccp->cblk[2] = tccp->cblk[0]; - - tccp->cblksty = cio_read(cio, 1); /* SPcox (J) */ - tccp->dwtid[0] = cio_read(cio, 1); /* SPcox (K) */ - if (j3d->cinfo->codec_format == CODEC_J3D) { - tccp->dwtid[1] = cio_read(cio, 1); /* SPcox (L) */ - tccp->dwtid[2] = cio_read(cio, 1); /* SPcox (M) */ - }else{ - tccp->dwtid[1] = tccp->dwtid[0]; /* SPcox (L) */ - tccp->dwtid[2] = tccp->dwtid[0]; /* SPcox (M) */ - } - tccp->reversible = (tccp->dwtid[0]>=1 && tccp->dwtid[1]>=1 && tccp->dwtid[2]>=1); /*TODO: only valid for irreversible 9x7 WTs*/ - if (tccp->csty & J3D_CP_CSTY_PRT) { - for (i = 0; i < tccp->numresolution[0]; i++) { - int tmp = cio_read(cio, 2); /* SPcox (N_i) */ - tccp->prctsiz[0][i] = tmp & 0xf; - tccp->prctsiz[1][i] = tmp >> 4; - tccp->prctsiz[2][i] = tmp >> 8; - } - } -} - -static void j3d_write_cod(opj_j3d_t *j3d) { - opj_cp_t *cp = NULL; - opj_tcp_t *tcp = NULL; - int lenp, len; - - opj_cio_t *cio = j3d->cio; - - cio_write(cio, J3D_MS_COD, 2); /* COD */ - - lenp = cio_tell(cio); - cio_skip(cio, 2); - - cp = j3d->cp; - tcp = &cp->tcps[j3d->curtileno]; - - /* Scod : Table A-4*/ - cio_write(cio, tcp->csty, 1); /* Scod : Coding style parameters */ - /* SGcod : Table A-5*/ - cio_write(cio, tcp->prg, 1); /* SGcod (A) : Progression order */ - cio_write(cio, tcp->numlayers, 2); /* SGcod (B) : No of layers */ - cio_write(cio, tcp->mct, 1); /* SGcod (C) : Multiple component transformation usage */ - /* SPcod : Table A-6*/ - j3d_write_cox(j3d, 0); - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lcod */ - cio_seek(cio, lenp + len); -} - -static void j3d_read_cod(opj_j3d_t *j3d) { - int len, i, pos; - - opj_cio_t *cio = j3d->cio; - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; - opj_volume_t *volume = j3d->volume; - - /* Lcod */ - len = cio_read(cio, 2); - /* Scod : Table A-4*/ - tcp->csty = cio_read(cio, 1); - /* SGcod : Table A-5*/ - tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); - tcp->numlayers = cio_read(cio, 2); - tcp->mct = cio_read(cio, 1); - - pos = cio_tell(cio); - for (i = 0; i < volume->numcomps; i++) { - tcp->tccps[i].csty = tcp->csty & J3D_CP_CSTY_PRT; - cio_seek(cio, pos); - j3d_read_cox(j3d, i); - } -} - -static void j3d_write_coc(opj_j3d_t *j3d, int compno) { - int lenp, len; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = &cp->tcps[j3d->curtileno]; - opj_volume_t *volume = j3d->volume; - opj_cio_t *cio = j3d->cio; - - cio_write(cio, J3D_MS_COC, 2); /* COC */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, compno, volume->numcomps <= 256 ? 1 : 2); /* Ccoc */ - cio_write(cio, tcp->tccps[compno].csty, 1); /* Scoc */ - - j3d_write_cox(j3d, compno); - - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lcoc */ - cio_seek(cio, lenp + len); -} - -static void j3d_read_coc(opj_j3d_t *j3d) { - int len, compno; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; - opj_volume_t *volume = j3d->volume; - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); /* Lcoc */ - compno = cio_read(cio, volume->numcomps <= 256 ? 1 : 2); /* Ccoc */ - tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */ - j3d_read_cox(j3d, compno); -} - -static void j3d_write_qcx(opj_j3d_t *j3d, int compno) { - int bandno, numbands; - int expn, mant; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = &cp->tcps[j3d->curtileno]; - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_cio_t *cio = j3d->cio; - - cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1); /* Sqcx : Table A28 de 15444-1*/ - - if (j3d->cinfo->codec_format == CODEC_J2K) - numbands = tccp->qntsty == J3D_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolution[0] * 3 - 2; - else if (j3d->cinfo->codec_format == CODEC_J3D) { - int diff = tccp->numresolution[0] - tccp->numresolution[2]; - numbands = (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) ? 1 : (tccp->numresolution[0] * 7 - 6) - 4 *diff; /* SIQNT vs. SEQNT */ - } - - for (bandno = 0; bandno < numbands; bandno++) { - expn = tccp->stepsizes[bandno].expn; - mant = tccp->stepsizes[bandno].mant; - - if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) { - cio_write(cio, expn << 3, 1); /* SPqcx_i */ - } else { - cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */ - } - } -} - -static void j3d_read_qcx(opj_j3d_t *j3d, int compno, int len) { - int tmp; - int bandno, numbands; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_cio_t *cio = j3d->cio; - - tmp = cio_read(cio, 1); /* Sqcx */ - tccp->qntsty = tmp & 0x1f; - tccp->numgbits = tmp >> 5; - - /*Numbands = 1 si SIQNT - len - 1 si NOQNT - (len - 1) / 2 si SEQNT */ - numbands = tccp->qntsty == J3D_CCP_QNTSTY_SIQNT ? 1 : ((tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2); - - for (bandno = 0; bandno < numbands; bandno++) { - int expn, mant; - if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) { - expn = cio_read(cio, 1) >> 3; /* SPqcx_i */ - mant = 0; - } else { - tmp = cio_read(cio, 2); /* SPqcx_i */ - expn = tmp >> 11; - mant = tmp & 0x7ff; - } - tccp->stepsizes[bandno].expn = expn; - tccp->stepsizes[bandno].mant = mant; - } - - /* Add Antonin : if scalar_derived -> compute other stepsizes */ - if (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) { - for (bandno = 1; bandno < J3D_MAXBANDS; bandno++) { - int numbands = (cp->transform_format==TRF_2D_DWT) ? 3 : 7; - tccp->stepsizes[bandno].expn = tccp->stepsizes[0].expn - ((bandno - 1) / numbands); - tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant; - } - } - /* ddA */ -} - -static void j3d_write_qcd(opj_j3d_t *j3d) { - int lenp, len; - - opj_cio_t *cio = j3d->cio; - - cio_write(cio, J3D_MS_QCD, 2); /* QCD */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - j3d_write_qcx(j3d, 0); /* Sqcd*/ - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lqcd */ - cio_seek(cio, lenp + len); -} - -static void j3d_read_qcd(opj_j3d_t *j3d) { - int len, i, pos; - - opj_cio_t *cio = j3d->cio; - opj_volume_t *volume = j3d->volume; - - len = cio_read(cio, 2); /* Lqcd */ - pos = cio_tell(cio); - for (i = 0; i < volume->numcomps; i++) { - cio_seek(cio, pos); - j3d_read_qcx(j3d, i, len - 2); - } -} - -static void j3d_write_qcc(opj_j3d_t *j3d, int compno) { - int lenp, len; - - opj_cio_t *cio = j3d->cio; - - cio_write(cio, J3D_MS_QCC, 2); /* QCC */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, compno, j3d->volume->numcomps <= 256 ? 1 : 2); /* Cqcc */ - j3d_write_qcx(j3d, compno); - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lqcc */ - cio_seek(cio, lenp + len); -} - -static void j3d_read_qcc(opj_j3d_t *j3d) { - int len, compno; - int numcomp = j3d->volume->numcomps; - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); /* Lqcc */ - compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */ - j3d_read_qcx(j3d, compno, len - 2 - (numcomp <= 256 ? 1 : 2)); -} - -static void j3d_write_poc(opj_j3d_t *j3d) { - int len, numpchgs, i; - - int numcomps = j3d->volume->numcomps; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = &cp->tcps[j3d->curtileno]; - opj_tccp_t *tccp = &tcp->tccps[0]; - opj_cio_t *cio = j3d->cio; - - numpchgs = tcp->numpocs; - cio_write(cio, J3D_MS_POC, 2); /* POC */ - len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs; - cio_write(cio, len, 2); /* Lpoc */ - for (i = 0; i < numpchgs; i++) { - opj_poc_t *poc = &tcp->pocs[i]; - cio_write(cio, poc->resno0, 1); /* RSpoc_i */ - cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2)); /* CSpoc_i */ - cio_write(cio, poc->layno1, 2); /* LYEpoc_i */ - poc->layno1 = int_min(poc->layno1, tcp->numlayers); - cio_write(cio, poc->resno1, 1); /* REpoc_i */ - poc->resno1 = int_min(poc->resno1, tccp->numresolution[0]); - cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2)); /* CEpoc_i */ - poc->compno1 = int_min(poc->compno1, numcomps); - cio_write(cio, poc->prg, 1); /* Ppoc_i */ - } -} - -static void j3d_read_poc(opj_j3d_t *j3d) { - int len, numpchgs, i, old_poc; - - int numcomps = j3d->volume->numcomps; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; - opj_tccp_t *tccp = &tcp->tccps[0]; - opj_cio_t *cio = j3d->cio; - - old_poc = tcp->POC ? tcp->numpocs + 1 : 0; - tcp->POC = 1; - len = cio_read(cio, 2); /* Lpoc */ - numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2)); - - for (i = old_poc; i < numpchgs + old_poc; i++) { - opj_poc_t *poc; - poc = &tcp->pocs[i]; - poc->resno0 = cio_read(cio, 1); /* RSpoc_i */ - poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2); /* CSpoc_i */ - poc->layno1 = int_min(cio_read(cio, 2), (unsigned int) tcp->numlayers); /* LYEpoc_i */ - poc->resno1 = int_min(cio_read(cio, 1), (unsigned int) tccp->numresolution[0]); /* REpoc_i */ - poc->compno1 = int_min( - cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps); /* CEpoc_i */ - poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* Ppoc_i */ - } - - tcp->numpocs = numpchgs + old_poc - 1; -} - -static void j3d_read_crg(opj_j3d_t *j3d) { - int len, i, Xcrg_i, Ycrg_i, Zcrg_i; - - opj_cio_t *cio = j3d->cio; - int numcomps = j3d->volume->numcomps; - - len = cio_read(cio, 2); /* Lcrg */ - for (i = 0; i < numcomps; i++) { - Xcrg_i = cio_read(cio, 2); /* Xcrg_i */ - Ycrg_i = cio_read(cio, 2); /* Ycrg_i */ - Zcrg_i = cio_read(cio, 2); /* Zcrg_i */ - } -} - -static void j3d_read_tlm(opj_j3d_t *j3d) { - int len, Ztlm, Stlm, ST, SP, tile_tlm, i; - long int Ttlm_i, Ptlm_i; - - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); /* Ltlm */ - Ztlm = cio_read(cio, 1); /* Ztlm */ - Stlm = cio_read(cio, 1); /* Stlm */ - ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02); - SP = (Stlm >> 6) & 0x01; - tile_tlm = (len - 4) / ((SP + 1) * 2 + ST); - for (i = 0; i < tile_tlm; i++) { - Ttlm_i = cio_read(cio, ST); /* Ttlm_i */ - Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */ - } -} - -static void j3d_read_plm(opj_j3d_t *j3d) { - int len, i, Zplm, Nplm, add, packet_len = 0; - - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); /* Lplm */ - Zplm = cio_read(cio, 1); /* Zplm */ - len -= 3; - while (len > 0) { - Nplm = cio_read(cio, 4); /* Nplm */ - len -= 4; - for (i = Nplm; i > 0; i--) { - add = cio_read(cio, 1); - len--; - packet_len = (packet_len << 7) + add; /* Iplm_ij */ - if ((add & 0x80) == 0) { - /* New packet */ - packet_len = 0; - } - if (len <= 0) - break; - } - } -} - -static void j3d_read_plt(opj_j3d_t *j3d) { - int len, i, Zplt, packet_len = 0, add; - - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); /* Lplt */ - Zplt = cio_read(cio, 1); /* Zplt */ - for (i = len - 3; i > 0; i--) { - add = cio_read(cio, 1); - packet_len = (packet_len << 7) + add; /* Iplt_i */ - if ((add & 0x80) == 0) { - /* New packet */ - packet_len = 0; - } - } -} - -static void j3d_read_ppm(opj_j3d_t *j3d) { - int len, Z_ppm, i, j; - int N_ppm; - - opj_cp_t *cp = j3d->cp; - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); - cp->ppm = 1; - - Z_ppm = cio_read(cio, 1); /* Z_ppm */ - len -= 3; - while (len > 0) { - if (cp->ppm_previous == 0) { - N_ppm = cio_read(cio, 4); /* N_ppm */ - len -= 4; - } else { - N_ppm = cp->ppm_previous; - } - j = cp->ppm_store; - if (Z_ppm == 0) { /* First PPM marker */ - cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char)); - cp->ppm_data_first = cp->ppm_data; - cp->ppm_len = N_ppm; - } else { /* NON-first PPM marker */ - cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data, (N_ppm + cp->ppm_store) * sizeof(unsigned char)); - cp->ppm_data_first = cp->ppm_data; - cp->ppm_len = N_ppm + cp->ppm_store; - } - for (i = N_ppm; i > 0; i--) { /* Read packet header */ - cp->ppm_data[j] = cio_read(cio, 1); - j++; - len--; - if (len == 0) - break; /* Case of non-finished packet header in present marker but finished in next one */ - } - cp->ppm_previous = i - 1; - cp->ppm_store = j; - } -} - -static void j3d_read_ppt(opj_j3d_t *j3d) { - int len, Z_ppt, i, j = 0; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = cp->tcps + j3d->curtileno; - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); - Z_ppt = cio_read(cio, 1); - tcp->ppt = 1; - if (Z_ppt == 0) { /* First PPT marker */ - tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char)); - tcp->ppt_data_first = tcp->ppt_data; - tcp->ppt_store = 0; - tcp->ppt_len = len - 3; - } else { /* NON-first PPT marker */ - tcp->ppt_data = (unsigned char *) opj_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char)); - tcp->ppt_data_first = tcp->ppt_data; - tcp->ppt_len = len - 3 + tcp->ppt_store; - } - j = tcp->ppt_store; - for (i = len - 3; i > 0; i--) { - tcp->ppt_data[j] = cio_read(cio, 1); - j++; - } - tcp->ppt_store = j; -} - -static void j3d_write_sot(opj_j3d_t *j3d) { - int lenp, len; - - opj_cio_t *cio = j3d->cio; - - j3d->sot_start = cio_tell(cio); - cio_write(cio, J3D_MS_SOT, 2); /* SOT */ - lenp = cio_tell(cio); - cio_skip(cio, 2); /* Lsot (further) */ - cio_write(cio, j3d->curtileno, 2); /* Isot */ - cio_skip(cio, 4); /* Psot (further in j3d_write_sod) */ - cio_write(cio, 0, 1); /* TPsot */ - cio_write(cio, 1, 1); /* TNsot (no of tile-parts of this tile in this codestream)*/ - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lsot */ - cio_seek(cio, lenp + len); -} - -static void j3d_read_sot(opj_j3d_t *j3d) { - int len, tileno, totlen, partno, numparts, i; - opj_tcp_t *tcp = NULL; - char status = 0; - - opj_cp_t *cp = j3d->cp; - opj_cio_t *cio = j3d->cio; - - len = cio_read(cio, 2); - tileno = cio_read(cio, 2); - - if (cp->tileno_size == 0) { - cp->tileno[cp->tileno_size] = tileno; - cp->tileno_size++; - } else { - i = 0; - while (i < cp->tileno_size && status == 0) { - status = cp->tileno[i] == tileno ? 1 : 0; - i++; - } - if (status == 0) { - cp->tileno[cp->tileno_size] = tileno; - cp->tileno_size++; - } - } - - totlen = cio_read(cio, 4); - if (!totlen) - totlen = cio_numbytesleft(cio) + 8; - - partno = cio_read(cio, 1); - numparts = cio_read(cio, 1); - - j3d->curtileno = tileno; - j3d->eot = cio_getbp(cio) - 12 + totlen; - j3d->state = J3D_STATE_TPH; - tcp = &cp->tcps[j3d->curtileno]; - - if (tcp->first == 1) { - - /* Initialization PPT */ - opj_tccp_t *tmp = tcp->tccps; - memcpy(tcp, j3d->default_tcp, sizeof(opj_tcp_t)); - tcp->ppt = 0; - tcp->ppt_data = NULL; - tcp->ppt_data_first = NULL; - tcp->tccps = tmp; - - for (i = 0; i < j3d->volume->numcomps; i++) { - tcp->tccps[i] = j3d->default_tcp->tccps[i]; - } - cp->tcps[j3d->curtileno].first = 0; - } -} - -static void j3d_write_sod(opj_j3d_t *j3d, void *tile_coder) { - int l, layno; - int totlen; - opj_tcp_t *tcp = NULL; - opj_volume_info_t *volume_info = NULL; - - opj_tcd_t *tcd = (opj_tcd_t*)tile_coder; /* cast is needed because of conflicts in header inclusions */ - opj_cp_t *cp = j3d->cp; - opj_cio_t *cio = j3d->cio; - - cio_write(cio, J3D_MS_SOD, 2); - if (j3d->curtileno == 0) { - j3d->sod_start = cio_tell(cio) + j3d->pos_correction; - } - - /* INDEX >> */ - volume_info = j3d->volume_info; - if (volume_info && volume_info->index_on) { - volume_info->tile[j3d->curtileno].end_header = cio_tell(cio) + j3d->pos_correction - 1; - } - /* << INDEX */ - - tcp = &cp->tcps[j3d->curtileno]; - for (layno = 0; layno < tcp->numlayers; layno++) { - tcp->rates[layno] -= tcp->rates[layno] ? (j3d->sod_start / (cp->th * cp->tw * cp->tl)) : 0; - } - - if(volume_info) { - volume_info->num = 0; - } - - l = tcd_encode_tile(tcd, j3d->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, volume_info); - - /* Writing Psot in SOT marker */ - totlen = cio_tell(cio) + l - j3d->sot_start; - cio_seek(cio, j3d->sot_start + 6); - cio_write(cio, totlen, 4); - cio_seek(cio, j3d->sot_start + totlen); -} - -static void j3d_read_sod(opj_j3d_t *j3d) { - int len, truncate = 0, i; - unsigned char *data = NULL, *data_ptr = NULL; - - opj_cio_t *cio = j3d->cio; - int curtileno = j3d->curtileno; - - len = int_min(j3d->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1); - - if (len == cio_numbytesleft(cio) + 1) { - truncate = 1; /* Case of a truncate codestream */ - } - - data = (unsigned char *) opj_malloc((j3d->tile_len[curtileno] + len) * sizeof(unsigned char)); - - for (i = 0; i < j3d->tile_len[curtileno]; i++) { - data[i] = j3d->tile_data[curtileno][i]; - } - - data_ptr = data + j3d->tile_len[curtileno]; - for (i = 0; i < len; i++) { - data_ptr[i] = cio_read(cio, 1); - } - - j3d->tile_len[curtileno] += len; - opj_free(j3d->tile_data[curtileno]); - j3d->tile_data[curtileno] = data; - - if (!truncate) { - j3d->state = J3D_STATE_TPHSOT; - } else { - j3d->state = J3D_STATE_NEOC; /* RAJOUTE !! */ - } -} - -static void j3d_write_rgn(opj_j3d_t *j3d, int compno, int tileno) { - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = &cp->tcps[tileno]; - opj_cio_t *cio = j3d->cio; - int numcomps = j3d->volume->numcomps; - - cio_write(cio, J3D_MS_RGN, 2); /* RGN */ - cio_write(cio, numcomps <= 256 ? 5 : 6, 2); /* Lrgn */ - cio_write(cio, compno, numcomps <= 256 ? 1 : 2); /* Crgn */ - cio_write(cio, 0, 1); /* Srgn */ - cio_write(cio, tcp->tccps[compno].roishift, 1); /* SPrgn */ -} - -static void j3d_read_rgn(opj_j3d_t *j3d) { - int len, compno, roisty; - - opj_cp_t *cp = j3d->cp; - opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; - opj_cio_t *cio = j3d->cio; - int numcomps = j3d->volume->numcomps; - - len = cio_read(cio, 2); /* Lrgn */ - compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */ - roisty = cio_read(cio, 1); /* Srgn */ - tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */ -} - -static void j3d_write_eoc(opj_j3d_t *j3d) { - opj_cio_t *cio = j3d->cio; - /* opj_event_msg(j3d->cinfo, "%.8x: EOC\n", cio_tell(cio) + j3d->pos_correction); */ - cio_write(cio, J3D_MS_EOC, 2); -} - -static void j3d_read_eoc(opj_j3d_t *j3d) { - int i, tileno; - -#ifndef NO_PACKETS_DECODING - opj_tcd_t *tcd = tcd_create(j3d->cinfo); - tcd_malloc_decode(tcd, j3d->volume, j3d->cp); - /*j3d_dump_volume(stdout, tcd->volume); - j3d_dump_cp(stdout, tcd->volume, tcd->cp);*/ - for (i = 0; i < j3d->cp->tileno_size; i++) { - tileno = j3d->cp->tileno[i]; - /*opj_event_msg(j3d->cinfo, EVT_INFO, "tcd_decode_tile \n");*/ - tcd_decode_tile(tcd, j3d->tile_data[tileno], j3d->tile_len[tileno], tileno); - opj_free(j3d->tile_data[tileno]); - j3d->tile_data[tileno] = NULL; - } - tcd_free_decode(tcd); - tcd_destroy(tcd); -#else - for (i = 0; i < j3d->cp->tileno_size; i++) { - tileno = j3d->cp->tileno[i]; - opj_free(j3d->tile_data[tileno]); - j3d->tile_data[tileno] = NULL; - } -#endif - - j3d->state = J3D_STATE_MT; -} - -static void j3d_read_unk(opj_j3d_t *j3d) { - opj_event_msg(j3d->cinfo, EVT_WARNING, "Unknown marker\n"); -} - -static opj_atk_t atk_info_wt[] = { - {0, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1.230174104, 4, {0}, {0}, {0}, {1,1,1,1}, {-1.586134342059924, -0.052980118572961, 0.882911075530934, 0.443506852043971}},/* WT 9-7 IRR*/ - {1, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {1,2}, {1,2}, {1,1}, {-1.0,1.0}},/* WT 5-3 REV*/ - {2, 0, J3D_ATK_ARB, J3D_ATK_REV, 0, J3D_ATK_CON, 0, 2, {0,0}, {0,1}, {0,1}, {1,1}, {{-1.0},{1.0}}}, /* WT 2-2 REV*/ - {3, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-1}, {0,1,2}, {0,1,2}, {1,1,3}, {{-1.0},{1.0},{1.0,0.0,-1.0}}}, /* WT 2-6 REV*/ - {4, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-2}, {0,1,6}, {0,1,32}, {1,1,5}, {{-1},{1},{-3.0,22.0,0.0,-22.0,3.0}}}, /* WT 2-10 REV*/ - {5, 1, J3D_ATK_ARB, J3D_ATK_IRR, 1, J3D_ATK_WS, 1, 7, {0}, {0}, {0}, {1,1,2,1,2,1,3},{{-1},{1.58613434206},{-0.460348209828, 0.460348209828},{0.25},{0.374213867768,-0.374213867768},{-1.33613434206},{0.29306717103,0,-0.29306717103}}}, /* WT 6-10 IRR*/ - {6, 1, J3D_ATK_ARB, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 11, {0}, {0}, {0}, {1,1,2,1,2,1,2,1,2,1,5},{{-1},{0,99715069105},{-1.00573127827, 1.00573127827},{-0.27040357631},{2.20509972343, -2.20509972343},{0.08059995736}, - {-1.62682532350, 1.62682532350},{0.52040357631},{0.60404664250, -0.60404664250},{-0.82775064841},{-0.06615812964, 0.29402137720, 0, -0.29402137720, 0.06615812964}}}, /* WT 10-18 IRR*/ - {7, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 2, {0}, {0}, {0}, {1,1}, {-0.5, 0.25}}, /* WT 5-3 IRR*/ - {8, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {4,4}, {8,8}, {2,2}, {{-9,1},{5,-1}}} /* WT 13-7 REV*/ -}; - -typedef struct opj_dec_mstabent { - /** marker value */ - int id; - /** value of the state when the marker can appear */ - int states; - /** action linked to the marker */ - void (*handler) (opj_j3d_t *j3d); -} opj_dec_mstabent_t; - -opj_dec_mstabent_t j3d_dec_mstab[] = { - {J3D_MS_SOC, J3D_STATE_MHSOC, j3d_read_soc}, - {J3D_MS_SOT, J3D_STATE_MH | J3D_STATE_TPHSOT, j3d_read_sot}, - {J3D_MS_SOD, J3D_STATE_TPH, j3d_read_sod}, - {J3D_MS_EOC, J3D_STATE_TPHSOT, j3d_read_eoc}, - {J3D_MS_CAP, J3D_STATE_MHSIZ, j3d_read_cap}, - {J3D_MS_SIZ, J3D_STATE_MHSIZ, j3d_read_siz}, - {J3D_MS_ZSI, J3D_STATE_MHSIZ, j3d_read_zsi}, - {J3D_MS_COD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_cod}, - {J3D_MS_COC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_coc}, - {J3D_MS_RGN, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_rgn}, - {J3D_MS_QCD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_qcd}, - {J3D_MS_QCC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_qcc}, - {J3D_MS_POC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_poc}, - {J3D_MS_TLM, J3D_STATE_MH, j3d_read_tlm}, - {J3D_MS_PLM, J3D_STATE_MH, j3d_read_plm}, - {J3D_MS_PLT, J3D_STATE_TPH, j3d_read_plt}, - {J3D_MS_PPM, J3D_STATE_MH, j3d_read_ppm}, - {J3D_MS_PPT, J3D_STATE_TPH, j3d_read_ppt}, - {J3D_MS_SOP, 0, 0}, - {J3D_MS_CRG, J3D_STATE_MH, j3d_read_crg}, - {J3D_MS_COM, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_com}, - {J3D_MS_DCO, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_dco}, - {J3D_MS_ATK, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_atk}, - {0, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_unk} - /*, -->must define the j3d_read functions - {J3D_MS_CBD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_cbd}, - {J3D_MS_MCT, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mct}, - {J3D_MS_MCC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mcc}, - {J3D_MS_MCO, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mco}, - {J3D_MS_NLT, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_nlt}, - {J3D_MS_VMS, J3D_STATE_MH, j3d_read_vms}, - {J3D_MS_DFS, J3D_STATE_MH, j3d_read_dfs}, - {J3D_MS_ADS, J3D_STATE_MH, j3d_read_ads}, - {J3D_MS_QPD, J3D_STATE_MH, j3d_read_qpd}, - {J3D_MS_QPC, J3D_STATE_TPH, j3d_read_qpc}*/ -}; - -/** -Read the lookup table containing all the marker, status and action -@param id Marker value -*/ -static opj_dec_mstabent_t *j3d_dec_mstab_lookup(int id) { - opj_dec_mstabent_t *e; - for (e = j3d_dec_mstab; e->id != 0; e++) { - if (e->id == id) { - break; - } - } - return e; -} - -/* ----------------------------------------------------------------------- */ -/* J3D / JPT decoder interface */ -/* ----------------------------------------------------------------------- */ - -opj_j3d_t* j3d_create_decompress(opj_common_ptr cinfo) { - opj_j3d_t *j3d = (opj_j3d_t*)opj_malloc(sizeof(opj_j3d_t)); - if(j3d) { - j3d->cinfo = cinfo; - j3d->default_tcp = (opj_tcp_t*)opj_malloc(sizeof(opj_tcp_t)); - if(!j3d->default_tcp) { - opj_free(j3d); - return NULL; - } - } - return j3d; -} - -void j3d_destroy_decompress(opj_j3d_t *j3d) { - int i = 0; - - if(j3d->tile_len != NULL) { - opj_free(j3d->tile_len); - } - if(j3d->tile_data != NULL) { - opj_free(j3d->tile_data); - } - if(j3d->default_tcp != NULL) { - opj_tcp_t *default_tcp = j3d->default_tcp; - if(default_tcp->ppt_data_first != NULL) { - opj_free(default_tcp->ppt_data_first); - } - if(j3d->default_tcp->tccps != NULL) { - opj_free(j3d->default_tcp->tccps); - } - opj_free(j3d->default_tcp); - } - if(j3d->cp != NULL) { - opj_cp_t *cp = j3d->cp; - if(cp->tcps != NULL) { - for(i = 0; i < cp->tw * cp->th * cp->tl; i++) { - if(cp->tcps[i].ppt_data_first != NULL) { - opj_free(cp->tcps[i].ppt_data_first); - } - if(cp->tcps[i].tccps != NULL) { - opj_free(cp->tcps[i].tccps); - } - } - opj_free(cp->tcps); - } - if(cp->ppm_data_first != NULL) { - opj_free(cp->ppm_data_first); - } - if(cp->tileno != NULL) { - opj_free(cp->tileno); - } - if(cp->comment != NULL) { - opj_free(cp->comment); - } - - opj_free(cp); - } - - opj_free(j3d); -} - -void j3d_setup_decoder(opj_j3d_t *j3d, opj_dparameters_t *parameters) { - if(j3d && parameters) { - /* create and initialize the coding parameters structure */ - opj_cp_t *cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); - cp->reduce[0] = parameters->cp_reduce[0]; - cp->reduce[1] = parameters->cp_reduce[1]; - cp->reduce[2] = parameters->cp_reduce[2]; - cp->layer = parameters->cp_layer; - cp->bigendian = parameters->bigendian; - - - cp->encoding_format = ENCOD_2EB; - cp->transform_format = TRF_2D_DWT; - - /* keep a link to cp so that we can destroy it later in j3d_destroy_decompress */ - j3d->cp = cp; - } -} - -opj_volume_t* j3d_decode(opj_j3d_t *j3d, opj_cio_t *cio) { - opj_volume_t *volume = NULL; - - opj_common_ptr cinfo = j3d->cinfo; - - j3d->cio = cio; - - /* create an empty volume */ - volume = (opj_volume_t*)opj_malloc(sizeof(opj_volume_t)); - j3d->volume = volume; - - j3d->state = J3D_STATE_MHSOC; - - for (;;) { - opj_dec_mstabent_t *e; - int id = cio_read(cio, 2); - if (id >> 8 != 0xff) { - opj_volume_destroy(volume); - opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); - return 0; - } - e = j3d_dec_mstab_lookup(id); - /*opj_event_msg(cinfo, EVT_INFO, "MARKER %x PREVSTATE %d E->STATE %d\n",e->id,j3d->state,e->states);*/ - if (!(j3d->state & e->states)) { - opj_volume_destroy(volume); - opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); - return 0; - } - if (e->handler) { - (*e->handler)(j3d); - } - /*opj_event_msg(cinfo, EVT_INFO, "POSTSTATE %d\n",j3d->state);*/ - if (j3d->state == J3D_STATE_MT) { - break; - } - if (j3d->state == J3D_STATE_NEOC) { - break; - } - } - if (j3d->state == J3D_STATE_NEOC) { - j3d_read_eoc(j3d); - } - - if (j3d->state != J3D_STATE_MT) { - opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); - } - - return volume; -} - -/* ----------------------------------------------------------------------- */ -/* J3D encoder interface */ -/* ----------------------------------------------------------------------- */ - -opj_j3d_t* j3d_create_compress(opj_common_ptr cinfo) { - opj_j3d_t *j3d = (opj_j3d_t*)opj_malloc(sizeof(opj_j3d_t)); - if(j3d) { - j3d->cinfo = cinfo; - } - return j3d; -} - -void j3d_destroy_compress(opj_j3d_t *j3d) { - int tileno; - - if(!j3d) return; - - if(j3d->volume_info != NULL) { - opj_volume_info_t *volume_info = j3d->volume_info; - if (volume_info->index_on && j3d->cp) { - opj_cp_t *cp = j3d->cp; - for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { - opj_tile_info_t *tile_info = &volume_info->tile[tileno]; - opj_free(tile_info->thresh); - opj_free(tile_info->packet); - } - opj_free(volume_info->tile); - } - opj_free(volume_info); - } - if(j3d->cp != NULL) { - opj_cp_t *cp = j3d->cp; - - if(cp->comment) { - opj_free(cp->comment); - } - if(cp->matrice) { - opj_free(cp->matrice); - } - for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { - opj_free(cp->tcps[tileno].tccps); - } - opj_free(cp->tcps); - opj_free(cp); - } - - opj_free(j3d); -} - -void j3d_setup_encoder(opj_j3d_t *j3d, opj_cparameters_t *parameters, opj_volume_t *volume) { - int i, j, tileno, numpocs_tile; - opj_cp_t *cp = NULL; - - if(!j3d || !parameters || ! volume) { - return; - } - - /* create and initialize the coding parameters structure */ - cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); - - /* keep a link to cp so that we can destroy it later in j3d_destroy_compress */ - j3d->cp = cp; - - /* set default values for cp */ - cp->tw = 1; - cp->th = 1; - cp->tl = 1; - - /* copy user encoding parameters */ - cp->disto_alloc = parameters->cp_disto_alloc; - cp->fixed_alloc = parameters->cp_fixed_alloc; - cp->fixed_quality = parameters->cp_fixed_quality; - - /* transform and coding method */ - cp->transform_format = parameters->transform_format; - cp->encoding_format = parameters->encoding_format; - - /* mod fixed_quality */ - if(parameters->cp_matrice) { - size_t array_size = parameters->tcp_numlayers * 3 * parameters->numresolution[0] * sizeof(int); - cp->matrice = (int *) opj_malloc(array_size); - memcpy(cp->matrice, parameters->cp_matrice, array_size); - } - - /* creation of an index file ? */ - cp->index_on = parameters->index_on; - if(cp->index_on) { - j3d->volume_info = (opj_volume_info_t*)opj_malloc(sizeof(opj_volume_info_t)); - } - - /* tiles */ - cp->tdx = parameters->cp_tdx; - cp->tdy = parameters->cp_tdy; - cp->tdz = parameters->cp_tdz; - /* tile offset */ - cp->tx0 = parameters->cp_tx0; - cp->ty0 = parameters->cp_ty0; - cp->tz0 = parameters->cp_tz0; - /* comment string */ - if(parameters->cp_comment) { - cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1); - if(cp->comment) { - strcpy(cp->comment, parameters->cp_comment); - } - } - - /*calculate other encoding parameters*/ - if (parameters->tile_size_on) { - cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx); - cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy); - cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz); - } else { - cp->tdx = volume->x1 - cp->tx0; - cp->tdy = volume->y1 - cp->ty0; - cp->tdz = volume->z1 - cp->tz0; - } - - /* initialize the multiple tiles */ - /* ---------------------------- */ - cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t)); - - for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) { - opj_tcp_t *tcp = &cp->tcps[tileno]; - tcp->numlayers = parameters->tcp_numlayers; - for (j = 0; j < tcp->numlayers; j++) { - if (cp->fixed_quality) { /* add fixed_quality */ - tcp->distoratio[j] = parameters->tcp_distoratio[j]; - } else { - tcp->rates[j] = parameters->tcp_rates[j]; - } - } - tcp->csty = parameters->csty; - tcp->prg = parameters->prog_order; - tcp->mct = volume->numcomps == 3 ? 1 : 0; - - numpocs_tile = 0; - tcp->POC = 0; - if (parameters->numpocs) { - /* initialisation of POC */ - tcp->POC = 1; - for (i = 0; i < parameters->numpocs; i++) { - if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) { - opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile]; - tcp_poc->resno0 = parameters->POC[numpocs_tile].resno0; - tcp_poc->compno0 = parameters->POC[numpocs_tile].compno0; - tcp_poc->layno1 = parameters->POC[numpocs_tile].layno1; - tcp_poc->resno1 = parameters->POC[numpocs_tile].resno1; - tcp_poc->compno1 = parameters->POC[numpocs_tile].compno1; - tcp_poc->prg = parameters->POC[numpocs_tile].prg; - tcp_poc->tile = parameters->POC[numpocs_tile].tile; - numpocs_tile++; - } - } - } - tcp->numpocs = numpocs_tile; - - tcp->tccps = (opj_tccp_t *) opj_malloc(volume->numcomps * sizeof(opj_tccp_t)); - - for (i = 0; i < volume->numcomps; i++) { - opj_tccp_t *tccp = &tcp->tccps[i]; - tccp->csty = parameters->csty & J3D_CCP_CSTY_PRT; /* 0 => standard precint || 1 => custom-defined precinct */ - tccp->numresolution[0] = parameters->numresolution[0]; - tccp->numresolution[1] = parameters->numresolution[1]; - tccp->numresolution[2] = parameters->numresolution[2]; - assert (parameters->cblock_init[0] <= T1_MAXCBLKW); - assert (parameters->cblock_init[0] >= T1_MINCBLKW); - assert (parameters->cblock_init[1] <= T1_MAXCBLKH); - assert (parameters->cblock_init[1] >= T1_MINCBLKH); - assert (parameters->cblock_init[2] <= T1_MAXCBLKD); - assert (parameters->cblock_init[2] >= T1_MINCBLKD); - tccp->cblk[0] = int_floorlog2(parameters->cblock_init[0]); - tccp->cblk[1] = int_floorlog2(parameters->cblock_init[1]); - tccp->cblk[2] = int_floorlog2(parameters->cblock_init[2]); - assert (tccp->cblk[0]+tccp->cblk[1]+tccp->cblk[1] <= T1_MAXWHD); - tccp->cblksty = parameters->mode; /*Codeblock style --> Table A.19 (default 0)*/ - - /*ATK / transform */ - tccp->reversible = parameters->irreversible ? 0 : 1; /* 0 => DWT 9-7 || 1 => DWT 5-3 */ - for (j = 0; j < 3; j++) { - tccp->dwtid[j] = parameters->irreversible ? 0 : 1; /* 0 => DWT 9-7 || 1 => DWT 5-3 */ - } - - /* Quantification: SEQNT (Scalar Expounded, value for each subband) / NOQNT (no quant)*/ - tccp->qntsty = parameters->irreversible ? J3D_CCP_QNTSTY_SEQNT : J3D_CCP_QNTSTY_NOQNT; - tccp->numgbits = 2; - if (i == parameters->roi_compno) { - tccp->roishift = parameters->roi_shift; - } else { - tccp->roishift = 0; - } - /* Custom defined precints */ - if (parameters->csty & J3D_CCP_CSTY_PRT) { - int k; - for (k = 0; k < 3; k++) { - int p = 0; - for (j = tccp->numresolution[k] - 1; j >= 0; j--) { - if (p < parameters->res_spec) {/* p < number of precinct size specifications */ - if (parameters->prct_init[k][p] < 1) { - tccp->prctsiz[k][j] = 1; - } else { - tccp->prctsiz[k][j] = int_floorlog2(parameters->prct_init[k][p]); - } - } else { - int res_spec = parameters->res_spec; - int size_prct = parameters->prct_init[k][res_spec - 1] >> (p - (res_spec - 1)); - if (size_prct < 1) { - tccp->prctsiz[k][j] = 1; - } else { - tccp->prctsiz[k][j] = int_floorlog2(size_prct); - } - } - } - p++; - } - } else { - int k; - for (k = 0; k < 3; k++) { - for (j = 0; j < tccp->numresolution[k]; j++) { - tccp->prctsiz[k][j] = 15; - } - } - } - /*Calcular stepsize for each subband (if NOQNT -->stepsize = 1.0)*/ - dwt_calc_explicit_stepsizes(tccp, volume->comps[i].prec); - } - } -} - -/** -Create an index file -@param j3d -@param cio -@param volume_info -@param index Index filename -@return Returns 1 if successful, returns 0 otherwise -*/ -static int j3d_create_index(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_info_t *volume_info, char *index) { - - int tileno, compno, layno, resno, precno, pack_nb, x, y, z; - FILE *stream = NULL; - double total_disto = 0; - - volume_info->codestream_size = cio_tell(cio) + j3d->pos_correction; /* Correction 14/4/03 suite rmq de Patrick */ - - stream = fopen(index, "w"); - if (!stream) { - opj_event_msg(j3d->cinfo, EVT_ERROR, "failed to open %s for writing\n", index); - return 0; - } - - fprintf(stream, "w %d\t h %d\t l %d\n", volume_info->volume_w, volume_info->volume_h, volume_info->volume_l); - fprintf(stream, "TRASNFORM\t%d\n", volume_info->transform_format); - fprintf(stream, "ENTROPY CODING\t%d\n", volume_info->encoding_format); - fprintf(stream, "PROG\t%d\n", volume_info->prog); - fprintf(stream, "TILE\tx %d y %d z %d\n", volume_info->tile_x, volume_info->tile_y, volume_info->tile_z); - fprintf(stream, "NOTILE\tx %d y %d z %d\n", volume_info->tw, volume_info->th, volume_info->tl); - fprintf(stream, "COMPONENTS\t%d\n", volume_info->comp); - fprintf(stream, "LAYER\t%d\n", volume_info->layer); - fprintf(stream, "RESOLUTIONS\tx %d y %d z %d\n", volume_info->decomposition[0], volume_info->decomposition[1], volume_info->decomposition[2]); - - fprintf(stream, "Precint sizes for each resolution:\n"); - for (resno = volume_info->decomposition[0]; resno >= 0; resno--) { - fprintf(stream, "Resno %d \t [%d,%d,%d] \n", resno, - (1 << volume_info->tile[0].prctsiz[0][resno]), (1 << volume_info->tile[0].prctsiz[0][resno]), (1 << volume_info->tile[0].prctsiz[2][resno])); /* based on tile 0 */ - } - fprintf(stream, "HEADER_END\t%d\n", volume_info->main_head_end); - fprintf(stream, "CODESTREAM\t%d\n", volume_info->codestream_size); - fprintf(stream, "Num_tile Start_pos End_header End_pos Distotile Nbpix Ratio\n"); - for (tileno = 0; tileno < (volume_info->tw * volume_info->th * volume_info->tl); tileno++) { - fprintf(stream, "%4d\t%9d\t%9d\t%9d\t%9e\t%9d\t%9e\n", - volume_info->tile[tileno].num_tile, - volume_info->tile[tileno].start_pos, - volume_info->tile[tileno].end_header, - volume_info->tile[tileno].end_pos, - volume_info->tile[tileno].distotile, volume_info->tile[tileno].nbpix, - volume_info->tile[tileno].distotile / volume_info->tile[tileno].nbpix); - } - - for (tileno = 0; tileno < (volume_info->tw * volume_info->th * volume_info->tl); tileno++) { - int start_pos, end_pos; - double disto = 0; - pack_nb = 0; - if (volume_info->prog == LRCP) { /* LRCP */ - fprintf(stream, "pack_nb tileno layno resno compno precno start_pos end_pos disto\n"); - for (layno = 0; layno < volume_info->layer; layno++) { - for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { - for (compno = 0; compno < volume_info->comp; compno++) { - int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno]; - for (precno = 0; precno < prec_max; precno++) { - start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; - end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; - disto = volume_info->tile[tileno].packet[pack_nb].disto; - fprintf(stream, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n",pack_nb, tileno, layno, resno, compno, precno, start_pos, end_pos, disto); - total_disto += disto; - pack_nb++; - } - } - } - } - } /* LRCP */ - else if (volume_info->prog == RLCP) { /* RLCP */ - /* - fprintf(stream, "pack_nb tileno resno layno compno precno start_pos end_pos disto"); - */ - for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { - for (layno = 0; layno < volume_info->layer; layno++) { - for (compno = 0; compno < volume_info->comp; compno++) { - int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno]* volume_info->tile[tileno].prctno[2][resno]; - for (precno = 0; precno < prec_max; precno++) { - start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; - end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; - disto = volume_info->tile[tileno].packet[pack_nb].disto; - fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %8e\n", - pack_nb, tileno, resno, layno, compno, precno, start_pos, end_pos, disto); - total_disto += disto; - pack_nb++; - } - } - } - } - } /* RLCP */ - else if (volume_info->prog == RPCL) { /* RPCL */ - /* - fprintf(stream, "\npack_nb tileno resno precno compno layno start_pos end_pos disto\n"); - */ - for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { - /* I suppose components have same XRsiz, YRsiz */ - /*int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x;*/ - /*int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y;*/ - int x0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_x; - int y0 = volume_info->tile_Oy + (int)floor( (float)tileno/(float)volume_info->th ) * volume_info->tile_y; - int z0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tl ) * volume_info->tile_z; - int x1 = x0 + volume_info->tile_x; - int y1 = y0 + volume_info->tile_y; - int z1 = z0 + volume_info->tile_z; - for(z = z0; z < z1; z++) { - for(y = y0; y < y1; y++) { - for(x = x0; x < x1; x++) { - for (compno = 0; compno < volume_info->comp; compno++) { - int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno]; - for (precno = 0; precno < prec_max; precno++) { - int pcnx = volume_info->tile[tileno].prctno[0][resno]; - int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno ); - int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno ); - int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno ); - int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; - int precno_y = (int) floor( (float)precno/(float)pcnx ); - if (precno_y*pcy == y ) { - if (precno_x*pcx == x ) { - for (layno = 0; layno < volume_info->layer; layno++) { - start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; - end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; - disto = volume_info->tile[tileno].packet[pack_nb].disto; - fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %8e\n", - pack_nb, tileno, resno, precno, compno, layno, start_pos, end_pos, disto); - total_disto += disto; - pack_nb++; - } - } - } - } /* precno */ - } /* compno */ - } /* x = x0..x1 */ - } /* y = y0..y1 */ - } /* z = z0..z1 */ - } /* resno */ - } /* RPCL */ - else if (volume_info->prog == PCRL) { /* PCRL */ - /* I suppose components have same XRsiz, YRsiz */ - int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x; - int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y; - int z0 = volume_info->tile_Oz + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_z; - int x1 = x0 + volume_info->tile_x; - int y1 = y0 + volume_info->tile_y; - int z1 = z0 + volume_info->tile_z; - /* - fprintf(stream, "\npack_nb tileno precno compno resno layno start_pos end_pos disto\n"); - */ - for(z = z0; z < z1; z++) { - for(y = y0; y < y1; y++) { - for(x = x0; x < x1; x++) { - for (compno = 0; compno < volume_info->comp; compno++) { - for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { - int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno]; - for (precno = 0; precno < prec_max; precno++) { - int pcnx = volume_info->tile[tileno].prctno[0][resno]; - int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno ); - int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno ); - int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno ); - int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; - int precno_y = (int) floor( (float)precno/(float)pcnx ); - int precno_z = (int) floor( (float)precno/(float)pcnx ); - if (precno_z*pcz == z ) { - if (precno_y*pcy == y ) { - if (precno_x*pcx == x ) { - for (layno = 0; layno < volume_info->layer; layno++) { - start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; - end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; - disto = volume_info->tile[tileno].packet[pack_nb].disto; - fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n", - pack_nb, tileno, precno, compno, resno, layno, start_pos, end_pos, disto); - total_disto += disto; - pack_nb++; - } - } - } - } - } /* precno */ - } /* resno */ - } /* compno */ - } /* x = x0..x1 */ - } /* y = y0..y1 */ - } - } /* PCRL */ - else { /* CPRL */ - /* - fprintf(stream, "\npack_nb tileno compno precno resno layno start_pos end_pos disto\n"); - */ - for (compno = 0; compno < volume_info->comp; compno++) { - /* I suppose components have same XRsiz, YRsiz */ - int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x; - int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y; - int z0 = volume_info->tile_Oz + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_z; - int x1 = x0 + volume_info->tile_x; - int y1 = y0 + volume_info->tile_y; - int z1 = z0 + volume_info->tile_z; - for(z = z0; z < z1; z++) { - for(y = y0; y < y1; y++) { - for(x = x0; x < x1; x++) { - for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { - int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno]; - for (precno = 0; precno < prec_max; precno++) { - int pcnx = volume_info->tile[tileno].prctno[0][resno]; - int pcny = volume_info->tile[tileno].prctno[1][resno]; - int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno ); - int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno ); - int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno ); - int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; - int precno_y = (int) floor( (float)precno/(float)pcnx ); - int precno_z = 0; /*???*/ - if (precno_z*pcz == z ) { - if (precno_y*pcy == y ) { - if (precno_x*pcx == x ) { - for (layno = 0; layno < volume_info->layer; layno++) { - start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; - end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; - disto = volume_info->tile[tileno].packet[pack_nb].disto; - fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n", - pack_nb, tileno, compno, precno, resno, layno, start_pos, end_pos, disto); - total_disto += disto; - pack_nb++; - } - } - } - } - } /* precno */ - } /* resno */ - } /* x = x0..x1 */ - } /* y = y0..y1 */ - } /* z = z0..z1 */ - } /* comno */ - } /* CPRL */ - } /* tileno */ - - fprintf(stream, "SE_MAX\t%8e\n", volume_info->D_max); /* SE max */ - fprintf(stream, "SE_TOTAL\t%.8e\n", total_disto); /* SE totale */ - - - fclose(stream); - - return 1; -} - -bool j3d_encode(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_t *volume, char *index) { - int tileno, compno; - opj_volume_info_t *volume_info = NULL; - opj_cp_t *cp = NULL; - opj_tcd_t *tcd = NULL; /* TCD component */ - - j3d->cio = cio; - j3d->volume = volume; - cp = j3d->cp; - - /*j3d_dump_volume(stdout, volume); - j3d_dump_cp(stdout, volume, cp);*/ - - /* INDEX >> */ - volume_info = j3d->volume_info; - if (volume_info && cp->index_on) { - volume_info->index_on = cp->index_on; - volume_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tile_info_t)); - volume_info->volume_w = volume->x1 - volume->x0; - volume_info->volume_h = volume->y1 - volume->y0; - volume_info->volume_l = volume->z1 - volume->z0; - volume_info->prog = (&cp->tcps[0])->prg; - volume_info->tw = cp->tw; - volume_info->th = cp->th; - volume_info->tl = cp->tl; - volume_info->tile_x = cp->tdx; /* new version parser */ - volume_info->tile_y = cp->tdy; /* new version parser */ - volume_info->tile_z = cp->tdz; /* new version parser */ - volume_info->tile_Ox = cp->tx0; /* new version parser */ - volume_info->tile_Oy = cp->ty0; /* new version parser */ - volume_info->tile_Oz = cp->tz0; /* new version parser */ - volume_info->transform_format = cp->transform_format; - volume_info->encoding_format = cp->encoding_format; - volume_info->comp = volume->numcomps; - volume_info->layer = (&cp->tcps[0])->numlayers; - volume_info->decomposition[0] = (&cp->tcps[0])->tccps->numresolution[0] - 1; - volume_info->decomposition[1] = (&cp->tcps[0])->tccps->numresolution[1] - 1; - volume_info->decomposition[2] = (&cp->tcps[0])->tccps->numresolution[2] - 1; - volume_info->D_max = 0; /* ADD Marcela */ - } - /* << INDEX */ - - j3d_write_soc(j3d); - j3d_write_siz(j3d); - if (j3d->cinfo->codec_format == CODEC_J3D) { - j3d_write_cap(j3d); - j3d_write_zsi(j3d); - } - j3d_write_cod(j3d); - j3d_write_qcd(j3d); - for (compno = 0; compno < volume->numcomps; compno++) { - opj_tcp_t *tcp = &cp->tcps[0]; - if (tcp->tccps[compno].roishift) - j3d_write_rgn(j3d, compno, 0); - } - /*Optional 15444-2 markers*/ - if (j3d->cp->tcps->tccps[0].atk != NULL) - j3d_write_atk(j3d); - if (j3d->volume->comps[0].dcoffset != 0) - j3d_write_dco(j3d); - - if (j3d->cp->transform_format != TRF_2D_DWT || j3d->cp->encoding_format != ENCOD_2EB) - j3d_write_com(j3d); - - /* INDEX >> */ - if(volume_info && volume_info->index_on) { - volume_info->main_head_end = cio_tell(cio) - 1; - } - /* << INDEX */ - - /* create the tile encoder */ - tcd = tcd_create(j3d->cinfo); - - /* encode each tile */ - for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) { - opj_event_msg(j3d->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th * cp->tl); - - j3d->curtileno = tileno; - - /* initialisation before tile encoding */ - if (tileno == 0) { - tcd_malloc_encode(tcd, volume, cp, j3d->curtileno); - } else { - tcd_init_encode(tcd, volume, cp, j3d->curtileno); - } - - /* INDEX >> */ - if(volume_info && volume_info->index_on) { - volume_info->tile[j3d->curtileno].num_tile = j3d->curtileno; - volume_info->tile[j3d->curtileno].start_pos = cio_tell(cio) + j3d->pos_correction; - } - /* << INDEX */ - - j3d_write_sot(j3d); - - for (compno = 1; compno < volume->numcomps; compno++) { - j3d_write_coc(j3d, compno); - j3d_write_qcc(j3d, compno); - } - - if (cp->tcps[tileno].numpocs) { - j3d_write_poc(j3d); - } - j3d_write_sod(j3d, tcd); /*--> tcd_encode_tile*/ - - /* INDEX >> */ - if(volume_info && volume_info->index_on) { - volume_info->tile[j3d->curtileno].end_pos = cio_tell(cio) + j3d->pos_correction - 1; - } - /* << INDEX */ - } - - /* destroy the tile encoder */ - tcd_free_encode(tcd); - tcd_destroy(tcd); - - j3d_write_eoc(j3d); - - /* Creation of the index file */ - if(volume_info && volume_info->index_on) { - if(!j3d_create_index(j3d, cio, volume_info, index)) { - opj_event_msg(j3d->cinfo, EVT_ERROR, "failed to create index file %s\n", index); - return false; - } - } - - return true; -} - -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain + * 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" + +/** @defgroup J3D J3D - JPEG-2000 PART 10 codestream reader/writer */ +/*@{*/ + +/** @name Funciones locales */ +/*@{*/ + +/** +Write the SOC marker (Start Of Codestream) +@param j3d J3D handle +*/ +static void j3d_write_soc(opj_j3d_t *j3d); +/** +Read the SOC marker (Start of Codestream) +@param j3d J3D handle +*/ +static void j3d_read_soc(opj_j3d_t *j3d); +/** +Write the SIZ marker (2D volume and tile size) +@param j3d J3D handle +*/ +static void j3d_write_siz(opj_j3d_t *j3d); +/** +Read the SIZ marker (2D volume and tile size) +@param j3d J3D handle +*/ +static void j3d_read_siz(opj_j3d_t *j3d); +/** +Write the NSI marker (3rd volume and tile size) +@param j3d J3D handle +*/ +static void j3d_write_nsi(opj_j3d_t *j3d); +/** +Read the NSI marker (3rd volume and tile size) +@param j3d J3D handle +*/ +static void j3d_read_nsi(opj_j3d_t *j3d); +/** +Write the COM marker (comment) +@param j3d J3D handle +*/ +static void j3d_write_com(opj_j3d_t *j3d); +/** +Read the COM marker (comment) +@param j3d J3D handle +*/ +static void j3d_read_com(opj_j3d_t *j3d); +/** +Write the value concerning the specified component in the marker COD and COC +@param j3d J3D handle +@param compno Number of the component concerned by the information written +*/ +static void j3d_write_cox(opj_j3d_t *j3d, int compno); +/** +Read the value concerning the specified component in the marker COD and COC +@param j3d J3D handle +@param compno Number of the component concerned by the information read +*/ +static void j3d_read_cox(opj_j3d_t *j3d, int compno); +/** +Write the COD marker (coding style default) +@param j3d J3D handle +*/ +static void j3d_write_cod(opj_j3d_t *j3d); +/** +Read the COD marker (coding style default) +@param j3d J3D handle +*/ +static void j3d_read_cod(opj_j3d_t *j3d); +/** +Write the COC marker (coding style component) +@param j3d J3D handle +@param compno Number of the component concerned by the information written +*/ +static void j3d_write_coc(opj_j3d_t *j3d, int compno); +/** +Read the COC marker (coding style component) +@param j3d J3D handle +*/ +static void j3d_read_coc(opj_j3d_t *j3d); +/** +Write the value concerning the specified component in the marker QCD and QCC +@param j3d J3D handle +@param compno Number of the component concerned by the information written +*/ +static void j3d_write_qcx(opj_j3d_t *j3d, int compno); +/** +Read the value concerning the specified component in the marker QCD and QCC +@param j3d J3D handle +@param compno Number of the component concern by the information read +@param len Length of the information in the QCX part of the marker QCD/QCC +*/ +static void j3d_read_qcx(opj_j3d_t *j3d, int compno, int len); +/** +Write the QCD marker (quantization default) +@param j3d J3D handle +*/ +static void j3d_write_qcd(opj_j3d_t *j3d); +/** +Read the QCD marker (quantization default) +@param j3d J3D handle +*/ +static void j3d_read_qcd(opj_j3d_t *j3d); +/** +Write the QCC marker (quantization component) +@param j3d J3D handle +@param compno Number of the component concerned by the information written +*/ +static void j3d_write_qcc(opj_j3d_t *j3d, int compno); +/** +Read the QCC marker (quantization component) +@param j3d J3D handle +*/ +static void j3d_read_qcc(opj_j3d_t *j3d); +/** +Write the POC marker (progression order change) +@param j3d J3D handle +*/ +static void j3d_write_poc(opj_j3d_t *j3d); +/** +Read the POC marker (progression order change) +@param j3d J3D handle +*/ +static void j3d_read_poc(opj_j3d_t *j3d); +/** +Read the CRG marker (component registration) +@param j3d J3D handle +*/ +static void j3d_read_crg(opj_j3d_t *j3d); +/** +Read the TLM marker (tile-part lengths) +@param j3d J3D handle +*/ +static void j3d_read_tlm(opj_j3d_t *j3d); +/** +Read the PLM marker (packet length, main header) +@param j3d J3D handle +*/ +static void j3d_read_plm(opj_j3d_t *j3d); +/** +Read the PLT marker (packet length, tile-part header) +@param j3d J3D handle +*/ +static void j3d_read_plt(opj_j3d_t *j3d); +/** +Read the PPM marker (packet packet headers, main header) +@param j3d J3D handle +*/ +static void j3d_read_ppm(opj_j3d_t *j3d); +/** +Read the PPT marker (packet packet headers, tile-part header) +@param j3d J3D handle +*/ +static void j3d_read_ppt(opj_j3d_t *j3d); +/** +Write the SOT marker (start of tile-part) +@param j3d J3D handle +*/ +static void j3d_write_sot(opj_j3d_t *j3d); +/** +Read the SOT marker (start of tile-part) +@param j3d J3D handle +*/ +static void j3d_read_sot(opj_j3d_t *j3d); +/** +Write the SOD marker (start of data) +@param j3d J3D handle +@param tile_coder Pointer to a TCD handle +*/ +static void j3d_write_sod(opj_j3d_t *j3d, void *tile_coder); +/** +Read the SOD marker (start of data) +@param j3d J3D handle +*/ +static void j3d_read_sod(opj_j3d_t *j3d); +/** +Write the RGN marker (region-of-interest) +@param j3d J3D handle +@param compno Number of the component concerned by the information written +@param tileno Number of the tile concerned by the information written +*/ +static void j3d_write_rgn(opj_j3d_t *j3d, int compno, int tileno); +/** +Read the RGN marker (region-of-interest) +@param j3d J3D handle +*/ +static void j3d_read_rgn(opj_j3d_t *j3d); +/** +Write the EOC marker (end of codestream) +@param j3d J3D handle +*/ +static void j3d_write_eoc(opj_j3d_t *j3d); +/** +Read the EOC marker (end of codestream) +@param j3d J3D handle +*/ +static void j3d_read_eoc(opj_j3d_t *j3d); +/** +Read an unknown marker +@param j3d J3D handle +*/ +static void j3d_read_unk(opj_j3d_t *j3d); +/** +Write the CAP marker (extended capabilities) +@param j3d J3D handle +*/ +static void j3d_write_cap(opj_j3d_t *j3d); +/** +Read the CAP marker (extended capabilities) +@param j3d J3D handle +*/ +static void j3d_read_cap(opj_j3d_t *j3d); +/** +Write the DCO marker (Variable DC offset) +@param j3d J3D handle +*/ +static void j3d_write_dco(opj_j3d_t *j3d); +/** +Read the DCO marker (Variable DC offset) +@param j3d J3D handle +*/ +static void j3d_read_dco(opj_j3d_t *j3d); +/** +Write the ATK marker (arbitrary transformation kernel) +@param j3d J3D handle +*/ +static void j3d_write_atk(opj_j3d_t *j3d); +/** +Read the ATK marker (arbitrary transformation kernel) +@param j3d J3D handle +*/ +static void j3d_read_atk(opj_j3d_t *j3d); +/** +Write the CBD marker (component bit depth definition) +@param j3d J3D handle +*/ +static void j3d_write_cbd(opj_j3d_t *j3d); +/** +Read the CBD marker (component bit depth definition) +@param j3d J3D handle +*/ +static void j3d_read_cbd(opj_j3d_t *j3d); +/** +Write the MCT marker (multiple component transfomation definition) +@param j3d J3D handle +*/ +static void j3d_write_mct(opj_j3d_t *j3d); +/** +Read the MCT marker (multiple component transfomation definition) +@param j3d J3D handle +*/ +static void j3d_read_mct(opj_j3d_t *j3d); +/** +Write the MCC marker (multiple component transfomation collection) +@param j3d J3D handle +*/ +static void j3d_write_mcc(opj_j3d_t *j3d); +/** +Read the MCC marker (multiple component transfomation collection) +@param j3d J3D handle +*/ +static void j3d_read_mcc(opj_j3d_t *j3d); +/** +Write the MCO marker (multiple component transfomation ordering) +@param j3d J3D handle +*/ +static void j3d_write_mco(opj_j3d_t *j3d); +/** +Read the MCO marker (multiple component transfomation ordering) +@param j3d J3D handle +*/ +static void j3d_read_mco(opj_j3d_t *j3d); +/** +Write the NLT marker (non-linearity point transformation) +@param j3d J3D handle +*/ +static void j3d_write_nlt(opj_j3d_t *j3d); +/** +Read the NLT marker (non-linearity point transformation) +@param j3d J3D handle +*/ +static void j3d_read_nlt(opj_j3d_t *j3d); +/*@}*/ + +/* ----------------------------------------------------------------------- */ + +static void j3d_dump_volume(FILE *fd, opj_volume_t * vol) { + int compno; + fprintf(fd, "volume {\n"); + fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", vol->x0, vol->y0, vol->z0,vol->x1, vol->y1, vol->z1); + fprintf(fd, " numcomps=%d\n", vol->numcomps); + for (compno = 0; compno < vol->numcomps; compno++) { + opj_volume_comp_t *comp = &vol->comps[compno]; + fprintf(fd, " comp %d {\n", compno); + fprintf(fd, " dx=%d, dy=%d, dz=%d\n", comp->dx, comp->dy, comp->dz); + fprintf(fd, " prec=%d\n", comp->prec); + fprintf(fd, " sgnd=%d\n", comp->sgnd); + fprintf(fd, " }\n"); + } + fprintf(fd, "}\n"); +} + +static void j3d_dump_cp(FILE *fd, opj_volume_t * vol, opj_cp_t * cp) { + int tileno, compno, layno, bandno, resno, numbands; + fprintf(fd, "coding parameters {\n"); + fprintf(fd, " tx0=%d, ty0=%d, tz0=%d\n", cp->tx0, cp->ty0, cp->tz0); + fprintf(fd, " tdx=%d, tdy=%d, tdz=%d\n", cp->tdx, cp->tdy, cp->tdz); + fprintf(fd, " tw=%d, th=%d, tl=%d\n", cp->tw, cp->th, cp->tl); + fprintf(fd, " transform format: %d\n", cp->transform_format); + fprintf(fd, " encoding format: %d\n", cp->encoding_format); + for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) { + opj_tcp_t *tcp = &cp->tcps[tileno]; + fprintf(fd, " tile %d {\n", tileno); + fprintf(fd, " csty=%x\n", tcp->csty); + fprintf(fd, " prg=%d\n", tcp->prg); + fprintf(fd, " numlayers=%d\n", tcp->numlayers); + fprintf(fd, " mct=%d\n", tcp->mct); + fprintf(fd, " rates="); + for (layno = 0; layno < tcp->numlayers; layno++) { + fprintf(fd, "%f ", tcp->rates[layno]); + } + fprintf(fd, "\n"); + fprintf(fd, " first=%d\n", tcp->first); + for (compno = 0; compno < vol->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + fprintf(fd, " comp %d {\n", compno); + fprintf(fd, " csty=%x\n", tccp->csty); + fprintf(fd, " numresx=%d, numresy=%d, numresz=%d\n", tccp->numresolution[0], tccp->numresolution[1], tccp->numresolution[2]); + fprintf(fd, " cblkw=%d, cblkh=%d, cblkl=%d\n", tccp->cblk[0], tccp->cblk[1], tccp->cblk[2]); + fprintf(fd, " cblksty=%x\n", tccp->cblksty); + fprintf(fd, " qntsty=%d\n", tccp->qntsty); + fprintf(fd, " numgbits=%d\n", tccp->numgbits); + fprintf(fd, " roishift=%d\n", tccp->roishift); + fprintf(fd, " reversible=%d\n", tccp->reversible); + fprintf(fd, " dwtidx=%d dwtidy=%d dwtidz=%d\n", tccp->dwtid[0], tccp->dwtid[1], tccp->dwtid[2]); + if (tccp->atk != NULL) { + fprintf(fd, " atk.index=%d\n", tccp->atk->index); + fprintf(fd, " atk.coeff_typ=%d\n", tccp->atk->coeff_typ); + fprintf(fd, " atk.filt_cat=%d\n", tccp->atk->filt_cat); + fprintf(fd, " atk.exten=%d\n", tccp->atk->exten); + fprintf(fd, " atk.minit=%d\n", tccp->atk->minit); + fprintf(fd, " atk.wt_typ=%d\n", tccp->atk->wt_typ); + } + fprintf(fd, " stepsizes of bands="); + numbands = (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) ? 1 : + ( (cp->transform_format == TRF_2D_DWT) ? (tccp->numresolution[0] * 3 - 2) : + (tccp->numresolution[0] * 7 - 6) - 4 *(tccp->numresolution[0] - tccp->numresolution[2]) ); + for (bandno = 0; bandno < numbands; bandno++) { + fprintf(fd, "(%d,%d) ", tccp->stepsizes[bandno].mant,tccp->stepsizes[bandno].expn); + } + fprintf(fd, "\n"); + + if (tccp->csty & J3D_CCP_CSTY_PRT) { + fprintf(fd, " prcw="); + for (resno = 0; resno < tccp->numresolution[0]; resno++) { + fprintf(fd, "%d ", tccp->prctsiz[0][resno]); + } + fprintf(fd, "\n"); + fprintf(fd, " prch="); + for (resno = 0; resno < tccp->numresolution[0]; resno++) { + fprintf(fd, "%d ", tccp->prctsiz[1][resno]); + } + fprintf(fd, "\n"); + fprintf(fd, " prcl="); + for (resno = 0; resno < tccp->numresolution[0]; resno++) { + fprintf(fd, "%d ", tccp->prctsiz[2][resno]); + } + fprintf(fd, "\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, "}\n"); +} + +/* ----------------------------------------------------------------------- +Extended capabilities +------------------------------------------------------------------------*/ + +static void j3d_write_cap(opj_j3d_t *j3d){ + int len,lenp; + + opj_cio_t *cio = j3d->cio; + cio_write(cio, J3D_MS_CAP, 2); /* CAP */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio,J3D_CAP_10, 4); + if( J3D_CAP_10 ) + { + cio_write(cio, 0x0, 2); + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lsiz */ + cio_seek(cio, lenp + len); + +} +static void j3d_read_cap(opj_j3d_t *j3d){ + int len, Cap; + opj_cio_t *cio = j3d->cio; + /*cio_read(cio, 2); CAP */ + len = cio_read(cio, 2); + Cap = cio_read(cio, 4); + if(Cap) { + cio_read(cio, 2); + } + assert( len == 2 + 4 + 2 ); +} +static void j3d_write_nsi(opj_j3d_t *j3d) { + int i; + int lenp, len; + int ndim = 3; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + opj_cp_t *cp = j3d->cp; + + cio_write(cio, J3D_MS_NSI, 2); /* NSI */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, ndim, 1); /* Ndim */ + cio_write(cio, volume->z1, 4); /* Zsiz */ + cio_write(cio, volume->z0, 4); /* Z0siz */ + cio_write(cio, cp->tdz, 4); /* ZTsiz */ + cio_write(cio, cp->tz0, 4); /* ZT0siz */ + for (i = 0; i < volume->numcomps; i++) { + cio_write(cio, volume->comps[i].dz, 1); /* ZRsiz_i */ + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lsiz */ + cio_seek(cio, lenp + len); +} + +static void j3d_read_nsi(opj_j3d_t *j3d) { + int ndim; + int len, i; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + opj_cp_t *cp = j3d->cp; + + len = cio_read(cio, 2); /* Lnsi */ + ndim = cio_read(cio, 1); /* Ndim */ + assert( ndim == 3 ); + volume->z1 = cio_read(cio, 4); /* Zsiz */ + volume->z0 = cio_read(cio, 4); /* Z0siz */ + cp->tdz = cio_read(cio, 4); /* ZTsiz */ + cp->tz0 = cio_read(cio, 4); /* ZT0siz */ + for (i = 0; i < volume->numcomps; i++) { + volume->comps[i].dz = cio_read(cio, 1); /* ZRsiz_i */ + } + + /*Initialization of volume*/ + cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx); + cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy); + cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz); + cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t)); + cp->tileno = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int)); + cp->tileno_size = 0; + + for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) { + cp->tcps[i].POC = 0; + cp->tcps[i].numpocs = 0; + cp->tcps[i].first = 1; + } + + /* Initialization for PPM marker (Packets header)*/ + cp->ppm = 0; + cp->ppm_data = NULL; + cp->ppm_data_first = NULL; + cp->ppm_previous = 0; + cp->ppm_store = 0; + + j3d->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps); + for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) { + cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps); + } + j3d->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(unsigned char *)); + j3d->tile_len = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int)); + j3d->state = J3D_STATE_MH; + +} +static void j3d_write_dco(opj_j3d_t *j3d){ + int lenp, len, i; + int dcotype; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + opj_cp_t *cp = j3d->cp; + + dcotype = 1; /* Offsets are 16bit signed integers Table A21 15444-2 */ + cio_write(cio, J3D_MS_DCO, 2); /* DCO */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, dcotype, 1); + if (dcotype == 0) { + for (i = 0; i < volume->numcomps; i++) + cio_write(cio, volume->comps[i].dcoffset, 1); /* SPdco_i */ + } else if (dcotype == 1) { + for (i = 0; i < volume->numcomps; i++){ + cio_write(cio, volume->comps[i].dcoffset, 1); /* SPdco_i */ + opj_event_msg(j3d->cinfo, EVT_INFO, "dcotype %d DCO %d \n",dcotype,volume->comps[i].dcoffset); + } + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Ldco */ + cio_seek(cio, lenp + len); + +} +static void j3d_read_dco(opj_j3d_t *j3d){ + int len, i; + int dcotype; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + opj_cp_t *cp = j3d->cp; + + len = cio_read(cio, 2); /* Lsiz */ + dcotype = cio_read(cio, 1); /*offset 8bit unsigned / 16bit signed integers*/ + if (dcotype == 0) { + for (i = 0; i < volume->numcomps; i++) { + volume->comps[i].dcoffset = cio_read(cio, 1); + if (volume->comps[i].dcoffset > 128) + volume->comps[i].dcoffset = volume->comps[i].dcoffset - 256; + } + } else if (dcotype == 1) { + for (i = 0; i < volume->numcomps; i++) { + volume->comps[i].dcoffset = cio_read(cio, 1); + if (volume->comps[i].dcoffset > 128) + volume->comps[i].dcoffset = volume->comps[i].dcoffset - 256; + } + } + +} +static void j3d_write_atk(opj_j3d_t *j3d){ + int lenp, len, s, k; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + opj_atk_t *atk = j3d->cp->tcps->tccps->atk; + + cio_write(cio, J3D_MS_ATK, 2); /* ATK */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, atk->index + (atk->coeff_typ << 8) + (atk->filt_cat << 11) + + (atk->wt_typ << 12) + (atk->minit << 13) + (atk->exten << 14), 2); /* Satk */ + if (atk->wt_typ == J3D_ATK_IRR) + cio_write(cio,(unsigned int) (atk->Katk * 8192.0), 1 << atk->coeff_typ); + cio_write(cio, atk->Natk, 1); + for (s = 0; s < atk->Natk; s++){ + if (atk->filt_cat == J3D_ATK_ARB) + cio_write(cio, atk->Oatk[s], 1); + if (atk->wt_typ == J3D_ATK_REV){ + cio_write(cio, atk->Eatk[s], 1); + cio_write(cio, atk->Batk[s], 1); + } + cio_write(cio, atk->LCatk[s], 1); + for (k = 0; k < atk->LCatk[s]; k++) + cio_write(cio,(unsigned int) (atk->Aatk[s][k] * 8192.0), 1 << atk->coeff_typ); + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Latk */ + cio_seek(cio, lenp + len); +} +static void j3d_read_atk(opj_j3d_t *j3d){ + int len, i, Satk, k; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + opj_cp_t *cp = j3d->cp; + opj_atk_t *atk = cp->tcps->tccps->atk; + + len = cio_read(cio, 2); /* Latk */ + Satk = cio_read(cio, 2); + atk->index = Satk & 0x00ff; + atk->coeff_typ = Satk >> 8 & 0x0007; + atk->filt_cat = Satk >> 11 & 0x0001; + atk->wt_typ = Satk >> 12 & 0x0001; + atk->minit = Satk >> 13 & 0x0001; + atk->exten = Satk >> 14 & 0x0001; + if (atk->wt_typ == J3D_ATK_IRR) + atk->Katk = ((double) cio_read(cio, 1 << atk->coeff_typ) / 8192.0); + atk->Natk = cio_read(cio, 1); + for (i = 0; i < atk->Natk; i++) { + if (atk->filt_cat == J3D_ATK_ARB) + atk->Oatk[i] = cio_read(cio, 1); + if (atk->wt_typ == J3D_ATK_REV){ + atk->Eatk[i] = cio_read(cio, 1); + atk->Batk[i] = cio_read(cio, 1); + } + atk->LCatk[i] = cio_read(cio, 1); + for (k = 0; k < atk->LCatk[i]; k++) + atk->Aatk[i][k] = ((double) cio_read(cio, 1 << atk->coeff_typ) / 8192.0); + } +} +static void j3d_write_cbd(opj_j3d_t *j3d){ +} +static void j3d_read_cbd(opj_j3d_t *j3d){ +} +static void j3d_write_mct(opj_j3d_t *j3d){ +} +static void j3d_read_mct(opj_j3d_t *j3d){ +} +static void j3d_write_mcc(opj_j3d_t *j3d){ +} +static void j3d_read_mcc(opj_j3d_t *j3d){ +} +static void j3d_write_mco(opj_j3d_t *j3d){ +} +static void j3d_read_mco(opj_j3d_t *j3d){ +} +static void j3d_write_nlt(opj_j3d_t *j3d){ +} +static void j3d_read_nlt(opj_j3d_t *j3d){ +} +/* ----------------------------------------------------------------------- +15444-1 codestream syntax +------------------------------------------------------------------------*/ +static void j3d_write_soc(opj_j3d_t *j3d) { + opj_cio_t *cio = j3d->cio; + cio_write(cio, J3D_MS_SOC, 2); +} + +static void j3d_read_soc(opj_j3d_t *j3d) { + j3d->state = J3D_STATE_MHSIZ; +} + +static void j3d_write_siz(opj_j3d_t *j3d) { + int i; + int lenp, len; + int Rsiz; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + opj_cp_t *cp = j3d->cp; + + cio_write(cio, J3D_MS_SIZ, 2); /* SIZ */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + /*cio_write(cio, 0, 2);*/ /* Rsiz (capabilities of 15444-1 only) */ + Rsiz = J3D_RSIZ_DCO | J3D_RSIZ_ATK; /** | J3D_RSIZ_MCT | J3D_RSIZ_NONLT (not implemented yet)*/ + cio_write(cio, Rsiz, 2); /* capabilities of WDv5.2*/ + cio_write(cio, volume->x1, 4); /* Xsiz */ + cio_write(cio, volume->y1, 4); /* Ysiz */ + cio_write(cio, volume->x0, 4); /* X0siz */ + cio_write(cio, volume->y0, 4); /* Y0siz */ + cio_write(cio, cp->tdx, 4); /* XTsiz */ + cio_write(cio, cp->tdy, 4); /* YTsiz */ + cio_write(cio, cp->tx0, 4); /* XT0siz */ + cio_write(cio, cp->ty0, 4); /* YT0siz */ + cio_write(cio, volume->numcomps, 2); /* Csiz */ + for (i = 0; i < volume->numcomps; i++) { + cio_write(cio, volume->comps[i].prec - 1 + (volume->comps[i].sgnd << 7), 1); /* Ssiz_i */ + cio_write(cio, volume->comps[i].dx, 1); /* XRsiz_i */ + cio_write(cio, volume->comps[i].dy, 1); /* YRsiz_i */ + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lsiz */ + cio_seek(cio, lenp + len); +} + +static void j3d_read_siz(opj_j3d_t *j3d) { + int len, i; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + opj_cp_t *cp = j3d->cp; + + len = cio_read(cio, 2); /* Lsiz */ + cp->rsiz = cio_read(cio, 2); /* Rsiz (capabilities) */ + volume->x1 = cio_read(cio, 4); /* Xsiz */ + volume->y1 = cio_read(cio, 4); /* Ysiz */ + volume->x0 = cio_read(cio, 4); /* X0siz */ + volume->y0 = cio_read(cio, 4); /* Y0siz */ + cp->tdx = cio_read(cio, 4); /* XTsiz */ + cp->tdy = cio_read(cio, 4); /* YTsiz */ + cp->tx0 = cio_read(cio, 4); /* XT0siz */ + cp->ty0 = cio_read(cio, 4); /* YT0siz */ + + volume->numcomps = cio_read(cio, 2); /* Csiz */ + volume->comps = (opj_volume_comp_t *) opj_malloc(volume->numcomps * sizeof(opj_volume_comp_t)); + for (i = 0; i < volume->numcomps; i++) { + int tmp, j; + tmp = cio_read(cio, 1); /* Ssiz_i */ + volume->comps[i].prec = (tmp & 0x7f) + 1; + volume->comps[i].sgnd = tmp >> 7; + volume->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */ + volume->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */ + for (j = 0; j < 3; j++) { + volume->comps[i].resno_decoded[j] = 0; /* number of resolution decoded */ + volume->comps[i].factor[j] = 0; /* reducing factor per component */ + } + } + + if (j3d->cinfo->codec_format == CODEC_J2K){ + volume->z1 = 1; + volume->z0 = 0; + volume->numslices = 1; + cp->tdz = 1; + cp->tz0 = 0; + for (i = 0; i < volume->numcomps; i++) + volume->comps[i].dz = 1; + + /*Initialization of volume*/ + cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx); + cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy); + cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz); + cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t)); + cp->tileno = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int)); + cp->tileno_size = 0; + + for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) { + cp->tcps[i].POC = 0; + cp->tcps[i].numpocs = 0; + cp->tcps[i].first = 1; + } + + /* Initialization for PPM marker (Packets header)*/ + cp->ppm = 0; + cp->ppm_data = NULL; + cp->ppm_data_first = NULL; + cp->ppm_previous = 0; + cp->ppm_store = 0; + + j3d->default_tcp->tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps); + for (i = 0; i < cp->tw * cp->th * cp->tl ; i++) { + cp->tcps[i].tccps = (opj_tccp_t *) opj_malloc(sizeof(opj_tccp_t) * volume->numcomps); + } + j3d->tile_data = (unsigned char **) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(unsigned char *)); + j3d->tile_len = (int *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(int)); + j3d->state = J3D_STATE_MH; + } +} + + + +static void j3d_write_com(opj_j3d_t *j3d) { + unsigned int i; + int lenp, len; + + opj_cio_t *cio = j3d->cio; + + cio_write(cio, J3D_MS_COM, 2); + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, 1, 2); + /*opj_event_msg(j3d->cinfo, EVT_INFO, "TRF %D ENCOD %d\n",j3d->cp->transform_format,j3d->cp->encoding_format);*/ + if (j3d->cp->comment != NULL) { + char *comment = j3d->cp->comment; + for (i = 0; i < strlen(comment); i++) { + cio_write(cio, comment[i], 1); + } + } + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); + cio_seek(cio, lenp + len); +} + +static void j3d_read_com(opj_j3d_t *j3d) { + int len; + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); + cio_read(cio, 2); // read registration + + /*opj_event_msg(j3d->cinfo, EVT_INFO, "TRF %D ENCOD %d\n",j3d->cp->transform_format,j3d->cp->encoding_format);*/ + + cio_skip(cio, len - 4); /*posible comments*/ +} + +static void j3d_write_cox(opj_j3d_t *j3d, int compno) { + int i; + int shift = 2; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = &cp->tcps[j3d->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j3d->cio; + + cio_write(cio, tccp->numresolution[0] - 1, 1); /* SPcox (D) No of decomposition levels in x-axis*/ + if (j3d->cinfo->codec_format == CODEC_J3D) { + cio_write(cio, tccp->numresolution[1] - 1, 1); /* SPcox (E) No of decomposition levels in y-axis*/ + cio_write(cio, tccp->numresolution[2] - 1, 1); /* SPcox (F) No of decomposition levels in z-axis*/ + } + if (j3d->cinfo->codec_format == CODEC_J3D) { + /* Table A.7 */ + shift = 0; + } + /* (cblkw - 2) + (cblkh - 2) + (cblkl - 2) <= 18*/ + cio_write(cio, tccp->cblk[0] - shift, 1); /* SPcox (G) Cblk width entre 10 y 2 (8 y 0)*/ + cio_write(cio, tccp->cblk[1] - shift, 1); /* SPcox (H) Cblk height*/ + if (j3d->cinfo->codec_format == CODEC_J3D) { + cio_write(cio, tccp->cblk[2] - shift, 1); /* SPcox (I) Cblk depth*/ + } + cio_write(cio, tccp->cblksty, 1); /* SPcox (J) Cblk style*/ + cio_write(cio, tccp->dwtid[0], 1); /* SPcox (K) WT in x-axis 15444-2 Table A10*/ + if (j3d->cinfo->codec_format == CODEC_J3D) { + cio_write(cio, tccp->dwtid[1], 1); /* SPcox (L) WT in y-axis 15444-2 Table A10*/ + cio_write(cio, tccp->dwtid[2], 1); /* SPcox (M) WT in z-axis 15444-2 Table A10*/ + } + + if (tccp->csty & J3D_CCP_CSTY_PRT) { + for (i = 0; i < tccp->numresolution[0]; i++) { + if (i < tccp->numresolution[2]) + cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4) + (tccp->prctsiz[2][i] << 8), 2); /* SPcox (N_i) Table A9*/ + else + if (j3d->cinfo->codec_format == CODEC_J3D) + cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4), 2); /* SPcox (N_i) Table A9*/ + else + cio_write(cio, tccp->prctsiz[0][i] + (tccp->prctsiz[1][i] << 4), 1); /* SPcox (N_i) Table A9*/ } + } +} + +static void j3d_read_cox(opj_j3d_t *j3d, int compno) { + int i; + int shift = 2; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j3d->cio; + + tccp->numresolution[0] = cio_read(cio, 1) + 1; /* SPcox (D) No of decomposition levels in x-axis*/ + if (j3d->cinfo->codec_format == CODEC_J3D) { + tccp->numresolution[1] = cio_read(cio, 1) + 1; /* SPcox (E) No of decomposition levels in y-axis*/ + tccp->numresolution[2] = cio_read(cio, 1) + 1; /* SPcox (F) No of decomposition levels in z-axis*/ + }else if (j3d->cinfo->codec_format == CODEC_J2K) { + tccp->numresolution[1] = tccp->numresolution[0]; + tccp->numresolution[2] = 1; + } + /* check the reduce value */ + cp->reduce[0] = int_min((tccp->numresolution[0])-1, cp->reduce[0]); + cp->reduce[1] = int_min((tccp->numresolution[1])-1, cp->reduce[1]); + cp->reduce[2] = int_min((tccp->numresolution[2])-1, cp->reduce[2]); + + if (j3d->cinfo->codec_format == CODEC_J3D) { + /* Table A.7 */ + shift = 0; + } + tccp->cblk[0] = cio_read(cio, 1) + shift; /* SPcox (G) */ + tccp->cblk[1] = cio_read(cio, 1) + shift; /* SPcox (H) */ + if (j3d->cinfo->codec_format == CODEC_J3D) + tccp->cblk[2] = cio_read(cio, 1) + shift; /* SPcox (I) */ + else + tccp->cblk[2] = tccp->cblk[0]; + + tccp->cblksty = cio_read(cio, 1); /* SPcox (J) */ + tccp->dwtid[0] = cio_read(cio, 1); /* SPcox (K) */ + if (j3d->cinfo->codec_format == CODEC_J3D) { + tccp->dwtid[1] = cio_read(cio, 1); /* SPcox (L) */ + tccp->dwtid[2] = cio_read(cio, 1); /* SPcox (M) */ + }else{ + tccp->dwtid[1] = tccp->dwtid[0]; /* SPcox (L) */ + tccp->dwtid[2] = tccp->dwtid[0]; /* SPcox (M) */ + } + tccp->reversible = (tccp->dwtid[0]>=1 && tccp->dwtid[1]>=1 && tccp->dwtid[2]>=1); /*TODO: only valid for irreversible 9x7 WTs*/ + if (tccp->csty & J3D_CP_CSTY_PRT) { + for (i = 0; i < tccp->numresolution[0]; i++) { + int tmp = cio_read(cio, 2); /* SPcox (N_i) */ + tccp->prctsiz[0][i] = tmp & 0xf; + tccp->prctsiz[1][i] = tmp >> 4; + tccp->prctsiz[2][i] = tmp >> 8; + } + } +} + +static void j3d_write_cod(opj_j3d_t *j3d) { + opj_cp_t *cp = NULL; + opj_tcp_t *tcp = NULL; + int lenp, len; + + opj_cio_t *cio = j3d->cio; + + cio_write(cio, J3D_MS_COD, 2); /* COD */ + + lenp = cio_tell(cio); + cio_skip(cio, 2); + + cp = j3d->cp; + tcp = &cp->tcps[j3d->curtileno]; + + /* Scod : Table A-4*/ + cio_write(cio, tcp->csty, 1); /* Scod : Coding style parameters */ + /* SGcod : Table A-5*/ + cio_write(cio, tcp->prg, 1); /* SGcod (A) : Progression order */ + cio_write(cio, tcp->numlayers, 2); /* SGcod (B) : No of layers */ + cio_write(cio, tcp->mct, 1); /* SGcod (C) : Multiple component transformation usage */ + /* SPcod : Table A-6*/ + j3d_write_cox(j3d, 0); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lcod */ + cio_seek(cio, lenp + len); +} + +static void j3d_read_cod(opj_j3d_t *j3d) { + int len, i, pos; + + opj_cio_t *cio = j3d->cio; + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; + opj_volume_t *volume = j3d->volume; + + /* Lcod */ + len = cio_read(cio, 2); + /* Scod : Table A-4*/ + tcp->csty = cio_read(cio, 1); + /* SGcod : Table A-5*/ + tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); + tcp->numlayers = cio_read(cio, 2); + tcp->mct = cio_read(cio, 1); + + pos = cio_tell(cio); + for (i = 0; i < volume->numcomps; i++) { + tcp->tccps[i].csty = tcp->csty & J3D_CP_CSTY_PRT; + cio_seek(cio, pos); + j3d_read_cox(j3d, i); + } +} + +static void j3d_write_coc(opj_j3d_t *j3d, int compno) { + int lenp, len; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = &cp->tcps[j3d->curtileno]; + opj_volume_t *volume = j3d->volume; + opj_cio_t *cio = j3d->cio; + + cio_write(cio, J3D_MS_COC, 2); /* COC */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, compno, volume->numcomps <= 256 ? 1 : 2); /* Ccoc */ + cio_write(cio, tcp->tccps[compno].csty, 1); /* Scoc */ + + j3d_write_cox(j3d, compno); + + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lcoc */ + cio_seek(cio, lenp + len); +} + +static void j3d_read_coc(opj_j3d_t *j3d) { + int len, compno; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; + opj_volume_t *volume = j3d->volume; + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); /* Lcoc */ + compno = cio_read(cio, volume->numcomps <= 256 ? 1 : 2); /* Ccoc */ + tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */ + j3d_read_cox(j3d, compno); +} + +static void j3d_write_qcx(opj_j3d_t *j3d, int compno) { + int bandno, numbands; + int expn, mant; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = &cp->tcps[j3d->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j3d->cio; + + cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1); /* Sqcx : Table A28 de 15444-1*/ + + if (j3d->cinfo->codec_format == CODEC_J2K) + numbands = tccp->qntsty == J3D_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolution[0] * 3 - 2; + else if (j3d->cinfo->codec_format == CODEC_J3D) { + int diff = tccp->numresolution[0] - tccp->numresolution[2]; + numbands = (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) ? 1 : (tccp->numresolution[0] * 7 - 6) - 4 *diff; /* SIQNT vs. SEQNT */ + } + + for (bandno = 0; bandno < numbands; bandno++) { + expn = tccp->stepsizes[bandno].expn; + mant = tccp->stepsizes[bandno].mant; + + if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) { + cio_write(cio, expn << 3, 1); /* SPqcx_i */ + } else { + cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */ + } + } +} + +static void j3d_read_qcx(opj_j3d_t *j3d, int compno, int len) { + int tmp; + int bandno, numbands; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_cio_t *cio = j3d->cio; + + tmp = cio_read(cio, 1); /* Sqcx */ + tccp->qntsty = tmp & 0x1f; + tccp->numgbits = tmp >> 5; + + /*Numbands = 1 si SIQNT + len - 1 si NOQNT + (len - 1) / 2 si SEQNT */ + numbands = tccp->qntsty == J3D_CCP_QNTSTY_SIQNT ? 1 : ((tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2); + + for (bandno = 0; bandno < numbands; bandno++) { + int expn, mant; + if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) { + expn = cio_read(cio, 1) >> 3; /* SPqcx_i */ + mant = 0; + } else { + tmp = cio_read(cio, 2); /* SPqcx_i */ + expn = tmp >> 11; + mant = tmp & 0x7ff; + } + tccp->stepsizes[bandno].expn = expn; + tccp->stepsizes[bandno].mant = mant; + } + + /* Add Antonin : if scalar_derived -> compute other stepsizes */ + if (tccp->qntsty == J3D_CCP_QNTSTY_SIQNT) { + for (bandno = 1; bandno < J3D_MAXBANDS; bandno++) { + int numbands = (cp->transform_format==TRF_2D_DWT) ? 3 : 7; + tccp->stepsizes[bandno].expn = tccp->stepsizes[0].expn - ((bandno - 1) / numbands); + tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant; + } + } + /* ddA */ +} + +static void j3d_write_qcd(opj_j3d_t *j3d) { + int lenp, len; + + opj_cio_t *cio = j3d->cio; + + cio_write(cio, J3D_MS_QCD, 2); /* QCD */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + j3d_write_qcx(j3d, 0); /* Sqcd*/ + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lqcd */ + cio_seek(cio, lenp + len); +} + +static void j3d_read_qcd(opj_j3d_t *j3d) { + int len, i, pos; + + opj_cio_t *cio = j3d->cio; + opj_volume_t *volume = j3d->volume; + + len = cio_read(cio, 2); /* Lqcd */ + pos = cio_tell(cio); + for (i = 0; i < volume->numcomps; i++) { + cio_seek(cio, pos); + j3d_read_qcx(j3d, i, len - 2); + } +} + +static void j3d_write_qcc(opj_j3d_t *j3d, int compno) { + int lenp, len; + + opj_cio_t *cio = j3d->cio; + + cio_write(cio, J3D_MS_QCC, 2); /* QCC */ + lenp = cio_tell(cio); + cio_skip(cio, 2); + cio_write(cio, compno, j3d->volume->numcomps <= 256 ? 1 : 2); /* Cqcc */ + j3d_write_qcx(j3d, compno); + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lqcc */ + cio_seek(cio, lenp + len); +} + +static void j3d_read_qcc(opj_j3d_t *j3d) { + int len, compno; + int numcomp = j3d->volume->numcomps; + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); /* Lqcc */ + compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */ + j3d_read_qcx(j3d, compno, len - 2 - (numcomp <= 256 ? 1 : 2)); +} + +static void j3d_write_poc(opj_j3d_t *j3d) { + int len, numpchgs, i; + + int numcomps = j3d->volume->numcomps; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = &cp->tcps[j3d->curtileno]; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_cio_t *cio = j3d->cio; + + numpchgs = tcp->numpocs; + cio_write(cio, J3D_MS_POC, 2); /* POC */ + len = 2 + (5 + 2 * (numcomps <= 256 ? 1 : 2)) * numpchgs; + cio_write(cio, len, 2); /* Lpoc */ + for (i = 0; i < numpchgs; i++) { + opj_poc_t *poc = &tcp->pocs[i]; + cio_write(cio, poc->resno0, 1); /* RSpoc_i */ + cio_write(cio, poc->compno0, (numcomps <= 256 ? 1 : 2)); /* CSpoc_i */ + cio_write(cio, poc->layno1, 2); /* LYEpoc_i */ + poc->layno1 = int_min(poc->layno1, tcp->numlayers); + cio_write(cio, poc->resno1, 1); /* REpoc_i */ + poc->resno1 = int_min(poc->resno1, tccp->numresolution[0]); + cio_write(cio, poc->compno1, (numcomps <= 256 ? 1 : 2)); /* CEpoc_i */ + poc->compno1 = int_min(poc->compno1, numcomps); + cio_write(cio, poc->prg, 1); /* Ppoc_i */ + } +} + +static void j3d_read_poc(opj_j3d_t *j3d) { + int len, numpchgs, i, old_poc; + + int numcomps = j3d->volume->numcomps; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_cio_t *cio = j3d->cio; + + old_poc = tcp->POC ? tcp->numpocs + 1 : 0; + tcp->POC = 1; + len = cio_read(cio, 2); /* Lpoc */ + numpchgs = (len - 2) / (5 + 2 * (numcomps <= 256 ? 1 : 2)); + + for (i = old_poc; i < numpchgs + old_poc; i++) { + opj_poc_t *poc; + poc = &tcp->pocs[i]; + poc->resno0 = cio_read(cio, 1); /* RSpoc_i */ + poc->compno0 = cio_read(cio, numcomps <= 256 ? 1 : 2); /* CSpoc_i */ + poc->layno1 = int_min(cio_read(cio, 2), (unsigned int) tcp->numlayers); /* LYEpoc_i */ + poc->resno1 = int_min(cio_read(cio, 1), (unsigned int) tccp->numresolution[0]); /* REpoc_i */ + poc->compno1 = int_min( + cio_read(cio, numcomps <= 256 ? 1 : 2), (unsigned int) numcomps); /* CEpoc_i */ + poc->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* Ppoc_i */ + } + + tcp->numpocs = numpchgs + old_poc - 1; +} + +static void j3d_read_crg(opj_j3d_t *j3d) { + int len, i, Xcrg_i, Ycrg_i, Zcrg_i; + + opj_cio_t *cio = j3d->cio; + int numcomps = j3d->volume->numcomps; + + len = cio_read(cio, 2); /* Lcrg */ + for (i = 0; i < numcomps; i++) { + Xcrg_i = cio_read(cio, 2); /* Xcrg_i */ + Ycrg_i = cio_read(cio, 2); /* Ycrg_i */ + Zcrg_i = cio_read(cio, 2); /* Zcrg_i */ + } +} + +static void j3d_read_tlm(opj_j3d_t *j3d) { + int len, Ztlm, Stlm, ST, SP, tile_tlm, i; + long int Ttlm_i, Ptlm_i; + + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); /* Ltlm */ + Ztlm = cio_read(cio, 1); /* Ztlm */ + Stlm = cio_read(cio, 1); /* Stlm */ + ST = ((Stlm >> 4) & 0x01) + ((Stlm >> 4) & 0x02); + SP = (Stlm >> 6) & 0x01; + tile_tlm = (len - 4) / ((SP + 1) * 2 + ST); + for (i = 0; i < tile_tlm; i++) { + Ttlm_i = cio_read(cio, ST); /* Ttlm_i */ + Ptlm_i = cio_read(cio, SP ? 4 : 2); /* Ptlm_i */ + } +} + +static void j3d_read_plm(opj_j3d_t *j3d) { + int len, i, Zplm, Nplm, add, packet_len = 0; + + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); /* Lplm */ + Zplm = cio_read(cio, 1); /* Zplm */ + len -= 3; + while (len > 0) { + Nplm = cio_read(cio, 4); /* Nplm */ + len -= 4; + for (i = Nplm; i > 0; i--) { + add = cio_read(cio, 1); + len--; + packet_len = (packet_len << 7) + add; /* Iplm_ij */ + if ((add & 0x80) == 0) { + /* New packet */ + packet_len = 0; + } + if (len <= 0) + break; + } + } +} + +static void j3d_read_plt(opj_j3d_t *j3d) { + int len, i, Zplt, packet_len = 0, add; + + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); /* Lplt */ + Zplt = cio_read(cio, 1); /* Zplt */ + for (i = len - 3; i > 0; i--) { + add = cio_read(cio, 1); + packet_len = (packet_len << 7) + add; /* Iplt_i */ + if ((add & 0x80) == 0) { + /* New packet */ + packet_len = 0; + } + } +} + +static void j3d_read_ppm(opj_j3d_t *j3d) { + int len, Z_ppm, i, j; + int N_ppm; + + opj_cp_t *cp = j3d->cp; + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); + cp->ppm = 1; + + Z_ppm = cio_read(cio, 1); /* Z_ppm */ + len -= 3; + while (len > 0) { + if (cp->ppm_previous == 0) { + N_ppm = cio_read(cio, 4); /* N_ppm */ + len -= 4; + } else { + N_ppm = cp->ppm_previous; + } + j = cp->ppm_store; + if (Z_ppm == 0) { /* First PPM marker */ + cp->ppm_data = (unsigned char *) opj_malloc(N_ppm * sizeof(unsigned char)); + cp->ppm_data_first = cp->ppm_data; + cp->ppm_len = N_ppm; + } else { /* NON-first PPM marker */ + cp->ppm_data = (unsigned char *) opj_realloc(cp->ppm_data, (N_ppm + cp->ppm_store) * sizeof(unsigned char)); + cp->ppm_data_first = cp->ppm_data; + cp->ppm_len = N_ppm + cp->ppm_store; + } + for (i = N_ppm; i > 0; i--) { /* Read packet header */ + cp->ppm_data[j] = cio_read(cio, 1); + j++; + len--; + if (len == 0) + break; /* Case of non-finished packet header in present marker but finished in next one */ + } + cp->ppm_previous = i - 1; + cp->ppm_store = j; + } +} + +static void j3d_read_ppt(opj_j3d_t *j3d) { + int len, Z_ppt, i, j = 0; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = cp->tcps + j3d->curtileno; + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); + Z_ppt = cio_read(cio, 1); + tcp->ppt = 1; + if (Z_ppt == 0) { /* First PPT marker */ + tcp->ppt_data = (unsigned char *) opj_malloc((len - 3) * sizeof(unsigned char)); + tcp->ppt_data_first = tcp->ppt_data; + tcp->ppt_store = 0; + tcp->ppt_len = len - 3; + } else { /* NON-first PPT marker */ + tcp->ppt_data = (unsigned char *) opj_realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char)); + tcp->ppt_data_first = tcp->ppt_data; + tcp->ppt_len = len - 3 + tcp->ppt_store; + } + j = tcp->ppt_store; + for (i = len - 3; i > 0; i--) { + tcp->ppt_data[j] = cio_read(cio, 1); + j++; + } + tcp->ppt_store = j; +} + +static void j3d_write_sot(opj_j3d_t *j3d) { + int lenp, len; + + opj_cio_t *cio = j3d->cio; + + j3d->sot_start = cio_tell(cio); + cio_write(cio, J3D_MS_SOT, 2); /* SOT */ + lenp = cio_tell(cio); + cio_skip(cio, 2); /* Lsot (further) */ + cio_write(cio, j3d->curtileno, 2); /* Isot */ + cio_skip(cio, 4); /* Psot (further in j3d_write_sod) */ + cio_write(cio, 0, 1); /* TPsot */ + cio_write(cio, 1, 1); /* TNsot (no of tile-parts of this tile in this codestream)*/ + len = cio_tell(cio) - lenp; + cio_seek(cio, lenp); + cio_write(cio, len, 2); /* Lsot */ + cio_seek(cio, lenp + len); +} + +static void j3d_read_sot(opj_j3d_t *j3d) { + int len, tileno, totlen, partno, numparts, i; + opj_tcp_t *tcp = NULL; + char status = 0; + + opj_cp_t *cp = j3d->cp; + opj_cio_t *cio = j3d->cio; + + len = cio_read(cio, 2); + tileno = cio_read(cio, 2); + + if (cp->tileno_size == 0) { + cp->tileno[cp->tileno_size] = tileno; + cp->tileno_size++; + } else { + i = 0; + while (i < cp->tileno_size && status == 0) { + status = cp->tileno[i] == tileno ? 1 : 0; + i++; + } + if (status == 0) { + cp->tileno[cp->tileno_size] = tileno; + cp->tileno_size++; + } + } + + totlen = cio_read(cio, 4); + if (!totlen) + totlen = cio_numbytesleft(cio) + 8; + + partno = cio_read(cio, 1); + numparts = cio_read(cio, 1); + + j3d->curtileno = tileno; + j3d->eot = cio_getbp(cio) - 12 + totlen; + j3d->state = J3D_STATE_TPH; + tcp = &cp->tcps[j3d->curtileno]; + + if (tcp->first == 1) { + + /* Initialization PPT */ + opj_tccp_t *tmp = tcp->tccps; + memcpy(tcp, j3d->default_tcp, sizeof(opj_tcp_t)); + tcp->ppt = 0; + tcp->ppt_data = NULL; + tcp->ppt_data_first = NULL; + tcp->tccps = tmp; + + for (i = 0; i < j3d->volume->numcomps; i++) { + tcp->tccps[i] = j3d->default_tcp->tccps[i]; + } + cp->tcps[j3d->curtileno].first = 0; + } +} + +static void j3d_write_sod(opj_j3d_t *j3d, void *tile_coder) { + int l, layno; + int totlen; + opj_tcp_t *tcp = NULL; + opj_volume_info_t *volume_info = NULL; + + opj_tcd_t *tcd = (opj_tcd_t*)tile_coder; /* cast is needed because of conflicts in header inclusions */ + opj_cp_t *cp = j3d->cp; + opj_cio_t *cio = j3d->cio; + + cio_write(cio, J3D_MS_SOD, 2); + if (j3d->curtileno == 0) { + j3d->sod_start = cio_tell(cio) + j3d->pos_correction; + } + + /* INDEX >> */ + volume_info = j3d->volume_info; + if (volume_info && volume_info->index_on) { + volume_info->tile[j3d->curtileno].end_header = cio_tell(cio) + j3d->pos_correction - 1; + } + /* << INDEX */ + + tcp = &cp->tcps[j3d->curtileno]; + for (layno = 0; layno < tcp->numlayers; layno++) { + tcp->rates[layno] -= tcp->rates[layno] ? (j3d->sod_start / (cp->th * cp->tw * cp->tl)) : 0; + } + + if(volume_info) { + volume_info->num = 0; + } + + l = tcd_encode_tile(tcd, j3d->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, volume_info); + + /* Writing Psot in SOT marker */ + totlen = cio_tell(cio) + l - j3d->sot_start; + cio_seek(cio, j3d->sot_start + 6); + cio_write(cio, totlen, 4); + cio_seek(cio, j3d->sot_start + totlen); +} + +static void j3d_read_sod(opj_j3d_t *j3d) { + int len, truncate = 0, i; + unsigned char *data = NULL, *data_ptr = NULL; + + opj_cio_t *cio = j3d->cio; + int curtileno = j3d->curtileno; + + len = int_min(j3d->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1); + + if (len == cio_numbytesleft(cio) + 1) { + truncate = 1; /* Case of a truncate codestream */ + } + + data = (unsigned char *) opj_malloc((j3d->tile_len[curtileno] + len) * sizeof(unsigned char)); + + for (i = 0; i < j3d->tile_len[curtileno]; i++) { + data[i] = j3d->tile_data[curtileno][i]; + } + + data_ptr = data + j3d->tile_len[curtileno]; + for (i = 0; i < len; i++) { + data_ptr[i] = cio_read(cio, 1); + } + + j3d->tile_len[curtileno] += len; + opj_free(j3d->tile_data[curtileno]); + j3d->tile_data[curtileno] = data; + + if (!truncate) { + j3d->state = J3D_STATE_TPHSOT; + } else { + j3d->state = J3D_STATE_NEOC; /* RAJOUTE !! */ + } +} + +static void j3d_write_rgn(opj_j3d_t *j3d, int compno, int tileno) { + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = &cp->tcps[tileno]; + opj_cio_t *cio = j3d->cio; + int numcomps = j3d->volume->numcomps; + + cio_write(cio, J3D_MS_RGN, 2); /* RGN */ + cio_write(cio, numcomps <= 256 ? 5 : 6, 2); /* Lrgn */ + cio_write(cio, compno, numcomps <= 256 ? 1 : 2); /* Crgn */ + cio_write(cio, 0, 1); /* Srgn */ + cio_write(cio, tcp->tccps[compno].roishift, 1); /* SPrgn */ +} + +static void j3d_read_rgn(opj_j3d_t *j3d) { + int len, compno, roisty; + + opj_cp_t *cp = j3d->cp; + opj_tcp_t *tcp = j3d->state == J3D_STATE_TPH ? &cp->tcps[j3d->curtileno] : j3d->default_tcp; + opj_cio_t *cio = j3d->cio; + int numcomps = j3d->volume->numcomps; + + len = cio_read(cio, 2); /* Lrgn */ + compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */ + roisty = cio_read(cio, 1); /* Srgn */ + tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */ +} + +static void j3d_write_eoc(opj_j3d_t *j3d) { + opj_cio_t *cio = j3d->cio; + /* opj_event_msg(j3d->cinfo, "%.8x: EOC\n", cio_tell(cio) + j3d->pos_correction); */ + cio_write(cio, J3D_MS_EOC, 2); +} + +static void j3d_read_eoc(opj_j3d_t *j3d) { + int i, tileno; + +#ifndef NO_PACKETS_DECODING + opj_tcd_t *tcd = tcd_create(j3d->cinfo); + tcd_malloc_decode(tcd, j3d->volume, j3d->cp); + /*j3d_dump_volume(stdout, tcd->volume); + j3d_dump_cp(stdout, tcd->volume, tcd->cp);*/ + for (i = 0; i < j3d->cp->tileno_size; i++) { + tileno = j3d->cp->tileno[i]; + /*opj_event_msg(j3d->cinfo, EVT_INFO, "tcd_decode_tile \n");*/ + tcd_decode_tile(tcd, j3d->tile_data[tileno], j3d->tile_len[tileno], tileno); + opj_free(j3d->tile_data[tileno]); + j3d->tile_data[tileno] = NULL; + } + tcd_free_decode(tcd); + tcd_destroy(tcd); +#else + for (i = 0; i < j3d->cp->tileno_size; i++) { + tileno = j3d->cp->tileno[i]; + opj_free(j3d->tile_data[tileno]); + j3d->tile_data[tileno] = NULL; + } +#endif + + j3d->state = J3D_STATE_MT; +} + +static void j3d_read_unk(opj_j3d_t *j3d) { + opj_event_msg(j3d->cinfo, EVT_WARNING, "Unknown marker\n"); +} + +static opj_atk_t atk_info_wt[] = { + {0, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1.230174104, 4, {0}, {0}, {0}, {1,1,1,1}, {-1.586134342059924, -0.052980118572961, 0.882911075530934, 0.443506852043971}},/* WT 9-7 IRR*/ + {1, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {1,2}, {1,2}, {1,1}, {-1.0,1.0}},/* WT 5-3 REV*/ + {2, 0, J3D_ATK_ARB, J3D_ATK_REV, 0, J3D_ATK_CON, 0, 2, {0,0}, {0,1}, {0,1}, {1,1}, {{-1.0},{1.0}}}, /* WT 2-2 REV*/ + {3, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-1}, {0,1,2}, {0,1,2}, {1,1,3}, {{-1.0},{1.0},{1.0,0.0,-1.0}}}, /* WT 2-6 REV*/ + {4, 0, J3D_ATK_ARB, J3D_ATK_REV, 1, J3D_ATK_CON, 0, 3, {0,0,-2}, {0,1,6}, {0,1,32}, {1,1,5}, {{-1},{1},{-3.0,22.0,0.0,-22.0,3.0}}}, /* WT 2-10 REV*/ + {5, 1, J3D_ATK_ARB, J3D_ATK_IRR, 1, J3D_ATK_WS, 1, 7, {0}, {0}, {0}, {1,1,2,1,2,1,3},{{-1},{1.58613434206},{-0.460348209828, 0.460348209828},{0.25},{0.374213867768,-0.374213867768},{-1.33613434206},{0.29306717103,0,-0.29306717103}}}, /* WT 6-10 IRR*/ + {6, 1, J3D_ATK_ARB, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 11, {0}, {0}, {0}, {1,1,2,1,2,1,2,1,2,1,5},{{-1},{0,99715069105},{-1.00573127827, 1.00573127827},{-0.27040357631},{2.20509972343, -2.20509972343},{0.08059995736}, + {-1.62682532350, 1.62682532350},{0.52040357631},{0.60404664250, -0.60404664250},{-0.82775064841},{-0.06615812964, 0.29402137720, 0, -0.29402137720, 0.06615812964}}}, /* WT 10-18 IRR*/ + {7, 1, J3D_ATK_WS, J3D_ATK_IRR, 0, J3D_ATK_WS, 1, 2, {0}, {0}, {0}, {1,1}, {-0.5, 0.25}}, /* WT 5-3 IRR*/ + {8, 0, J3D_ATK_WS, J3D_ATK_REV, 0, J3D_ATK_WS, 0, 2, {0}, {4,4}, {8,8}, {2,2}, {{-9,1},{5,-1}}} /* WT 13-7 REV*/ +}; + +typedef struct opj_dec_mstabent { + /** marker value */ + int id; + /** value of the state when the marker can appear */ + int states; + /** action linked to the marker */ + void (*handler) (opj_j3d_t *j3d); +} opj_dec_mstabent_t; + +opj_dec_mstabent_t j3d_dec_mstab[] = { + {J3D_MS_SOC, J3D_STATE_MHSOC, j3d_read_soc}, + {J3D_MS_SOT, J3D_STATE_MH | J3D_STATE_TPHSOT, j3d_read_sot}, + {J3D_MS_SOD, J3D_STATE_TPH, j3d_read_sod}, + {J3D_MS_EOC, J3D_STATE_TPHSOT, j3d_read_eoc}, + {J3D_MS_CAP, J3D_STATE_MHSIZ, j3d_read_cap}, + {J3D_MS_SIZ, J3D_STATE_MHSIZ, j3d_read_siz}, + {J3D_MS_NSI, J3D_STATE_MHSIZ, j3d_read_nsi}, + {J3D_MS_COD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_cod}, + {J3D_MS_COC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_coc}, + {J3D_MS_RGN, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_rgn}, + {J3D_MS_QCD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_qcd}, + {J3D_MS_QCC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_qcc}, + {J3D_MS_POC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_poc}, + {J3D_MS_TLM, J3D_STATE_MH, j3d_read_tlm}, + {J3D_MS_PLM, J3D_STATE_MH, j3d_read_plm}, + {J3D_MS_PLT, J3D_STATE_TPH, j3d_read_plt}, + {J3D_MS_PPM, J3D_STATE_MH, j3d_read_ppm}, + {J3D_MS_PPT, J3D_STATE_TPH, j3d_read_ppt}, + {J3D_MS_SOP, 0, 0}, + {J3D_MS_CRG, J3D_STATE_MH, j3d_read_crg}, + {J3D_MS_COM, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_com}, + {J3D_MS_DCO, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_dco}, + {J3D_MS_ATK, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_atk}, + {0, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_unk} + /*, -->must define the j3d_read functions + {J3D_MS_CBD, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_cbd}, + {J3D_MS_MCT, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mct}, + {J3D_MS_MCC, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mcc}, + {J3D_MS_MCO, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_mco}, + {J3D_MS_NLT, J3D_STATE_MH | J3D_STATE_TPH, j3d_read_nlt}, + {J3D_MS_VMS, J3D_STATE_MH, j3d_read_vms}, + {J3D_MS_DFS, J3D_STATE_MH, j3d_read_dfs}, + {J3D_MS_ADS, J3D_STATE_MH, j3d_read_ads}, + {J3D_MS_QPD, J3D_STATE_MH, j3d_read_qpd}, + {J3D_MS_QPC, J3D_STATE_TPH, j3d_read_qpc}*/ +}; + +/** +Read the lookup table containing all the marker, status and action +@param id Marker value +*/ +static opj_dec_mstabent_t *j3d_dec_mstab_lookup(int id) { + opj_dec_mstabent_t *e; + for (e = j3d_dec_mstab; e->id != 0; e++) { + if (e->id == id) { + break; + } + } + return e; +} + +/* ----------------------------------------------------------------------- */ +/* J3D / JPT decoder interface */ +/* ----------------------------------------------------------------------- */ + +opj_j3d_t* j3d_create_decompress(opj_common_ptr cinfo) { + opj_j3d_t *j3d = (opj_j3d_t*)opj_malloc(sizeof(opj_j3d_t)); + if(j3d) { + j3d->cinfo = cinfo; + j3d->default_tcp = (opj_tcp_t*)opj_malloc(sizeof(opj_tcp_t)); + if(!j3d->default_tcp) { + opj_free(j3d); + return NULL; + } + } + return j3d; +} + +void j3d_destroy_decompress(opj_j3d_t *j3d) { + int i = 0; + + if(j3d->tile_len != NULL) { + opj_free(j3d->tile_len); + } + if(j3d->tile_data != NULL) { + opj_free(j3d->tile_data); + } + if(j3d->default_tcp != NULL) { + opj_tcp_t *default_tcp = j3d->default_tcp; + if(default_tcp->ppt_data_first != NULL) { + opj_free(default_tcp->ppt_data_first); + } + if(j3d->default_tcp->tccps != NULL) { + opj_free(j3d->default_tcp->tccps); + } + opj_free(j3d->default_tcp); + } + if(j3d->cp != NULL) { + opj_cp_t *cp = j3d->cp; + if(cp->tcps != NULL) { + for(i = 0; i < cp->tw * cp->th * cp->tl; i++) { + if(cp->tcps[i].ppt_data_first != NULL) { + opj_free(cp->tcps[i].ppt_data_first); + } + if(cp->tcps[i].tccps != NULL) { + opj_free(cp->tcps[i].tccps); + } + } + opj_free(cp->tcps); + } + if(cp->ppm_data_first != NULL) { + opj_free(cp->ppm_data_first); + } + if(cp->tileno != NULL) { + opj_free(cp->tileno); + } + if(cp->comment != NULL) { + opj_free(cp->comment); + } + + opj_free(cp); + } + + opj_free(j3d); +} + +void j3d_setup_decoder(opj_j3d_t *j3d, opj_dparameters_t *parameters) { + if(j3d && parameters) { + /* create and initialize the coding parameters structure */ + opj_cp_t *cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); + cp->reduce[0] = parameters->cp_reduce[0]; + cp->reduce[1] = parameters->cp_reduce[1]; + cp->reduce[2] = parameters->cp_reduce[2]; + cp->layer = parameters->cp_layer; + cp->bigendian = parameters->bigendian; + + /* MM: Settings of the following two member variables would take + place during j3d_read_com. FIXME */ + cp->encoding_format = ENCOD_3EB; + cp->transform_format = TRF_2D_DWT; + + /* keep a link to cp so that we can destroy it later in j3d_destroy_decompress */ + j3d->cp = cp; + } +} + +opj_volume_t* j3d_decode(opj_j3d_t *j3d, opj_cio_t *cio) { + opj_volume_t *volume = NULL; + + opj_common_ptr cinfo = j3d->cinfo; + + j3d->cio = cio; + + /* create an empty volume */ + volume = (opj_volume_t*)opj_malloc(sizeof(opj_volume_t)); + j3d->volume = volume; + + j3d->state = J3D_STATE_MHSOC; + + for (;;) { + opj_dec_mstabent_t *e; + int id = cio_read(cio, 2); + if (id >> 8 != 0xff) { + opj_volume_destroy(volume); + opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); + return 0; + } + e = j3d_dec_mstab_lookup(id); + /*opj_event_msg(cinfo, EVT_INFO, "MARKER %x PREVSTATE %d E->STATE %d\n",e->id,j3d->state,e->states);*/ + if (!(j3d->state & e->states)) { + opj_volume_destroy(volume); + opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); + return 0; + } + if (e->handler) { + (*e->handler)(j3d); + } + /*opj_event_msg(cinfo, EVT_INFO, "POSTSTATE %d\n",j3d->state);*/ + if (j3d->state == J3D_STATE_MT) { + break; + } + if (j3d->state == J3D_STATE_NEOC) { + break; + } + } + if (j3d->state == J3D_STATE_NEOC) { + j3d_read_eoc(j3d); + } + + if (j3d->state != J3D_STATE_MT) { + opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); + } + + return volume; +} + +/* ----------------------------------------------------------------------- */ +/* J3D encoder interface */ +/* ----------------------------------------------------------------------- */ + +opj_j3d_t* j3d_create_compress(opj_common_ptr cinfo) { + opj_j3d_t *j3d = (opj_j3d_t*)opj_malloc(sizeof(opj_j3d_t)); + if(j3d) { + j3d->cinfo = cinfo; + } + return j3d; +} + +void j3d_destroy_compress(opj_j3d_t *j3d) { + int tileno; + + if(!j3d) return; + + if(j3d->volume_info != NULL) { + opj_volume_info_t *volume_info = j3d->volume_info; + if (volume_info->index_on && j3d->cp) { + opj_cp_t *cp = j3d->cp; + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_tile_info_t *tile_info = &volume_info->tile[tileno]; + opj_free(tile_info->thresh); + opj_free(tile_info->packet); + } + opj_free(volume_info->tile); + } + opj_free(volume_info); + } + if(j3d->cp != NULL) { + opj_cp_t *cp = j3d->cp; + + if(cp->comment) { + opj_free(cp->comment); + } + if(cp->matrice) { + opj_free(cp->matrice); + } + for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { + opj_free(cp->tcps[tileno].tccps); + } + opj_free(cp->tcps); + opj_free(cp); + } + + opj_free(j3d); +} + +void j3d_setup_encoder(opj_j3d_t *j3d, opj_cparameters_t *parameters, opj_volume_t *volume) { + int i, j, tileno, numpocs_tile; + opj_cp_t *cp = NULL; + + if(!j3d || !parameters || ! volume) { + return; + } + + /* create and initialize the coding parameters structure */ + cp = (opj_cp_t*)opj_malloc(sizeof(opj_cp_t)); + + /* keep a link to cp so that we can destroy it later in j3d_destroy_compress */ + j3d->cp = cp; + + /* set default values for cp */ + cp->tw = 1; + cp->th = 1; + cp->tl = 1; + + /* copy user encoding parameters */ + cp->disto_alloc = parameters->cp_disto_alloc; + cp->fixed_alloc = parameters->cp_fixed_alloc; + cp->fixed_quality = parameters->cp_fixed_quality; + + /* transform and coding method */ + cp->transform_format = parameters->transform_format; + cp->encoding_format = parameters->encoding_format; + + /* mod fixed_quality */ + if(parameters->cp_matrice) { + size_t array_size = parameters->tcp_numlayers * 3 * parameters->numresolution[0] * sizeof(int); + cp->matrice = (int *) opj_malloc(array_size); + memcpy(cp->matrice, parameters->cp_matrice, array_size); + } + + /* creation of an index file ? */ + cp->index_on = parameters->index_on; + if(cp->index_on) { + j3d->volume_info = (opj_volume_info_t*)opj_malloc(sizeof(opj_volume_info_t)); + } + + /* tiles */ + cp->tdx = parameters->cp_tdx; + cp->tdy = parameters->cp_tdy; + cp->tdz = parameters->cp_tdz; + /* tile offset */ + cp->tx0 = parameters->cp_tx0; + cp->ty0 = parameters->cp_ty0; + cp->tz0 = parameters->cp_tz0; + /* comment string */ + if(parameters->cp_comment) { + cp->comment = (char*)opj_malloc(strlen(parameters->cp_comment) + 1); + if(cp->comment) { + strcpy(cp->comment, parameters->cp_comment); + } + } + + /*calculate other encoding parameters*/ + if (parameters->tile_size_on) { + cp->tw = int_ceildiv(volume->x1 - cp->tx0, cp->tdx); + cp->th = int_ceildiv(volume->y1 - cp->ty0, cp->tdy); + cp->tl = int_ceildiv(volume->z1 - cp->tz0, cp->tdz); + } else { + cp->tdx = volume->x1 - cp->tx0; + cp->tdy = volume->y1 - cp->ty0; + cp->tdz = volume->z1 - cp->tz0; + } + + /* initialize the multiple tiles */ + /* ---------------------------- */ + cp->tcps = (opj_tcp_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcp_t)); + + for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) { + opj_tcp_t *tcp = &cp->tcps[tileno]; + tcp->numlayers = parameters->tcp_numlayers; + for (j = 0; j < tcp->numlayers; j++) { + if (cp->fixed_quality) { /* add fixed_quality */ + tcp->distoratio[j] = parameters->tcp_distoratio[j]; + } else { + tcp->rates[j] = parameters->tcp_rates[j]; + } + } + tcp->csty = parameters->csty; + tcp->prg = parameters->prog_order; + tcp->mct = volume->numcomps == 3 ? 1 : 0; + + numpocs_tile = 0; + tcp->POC = 0; + if (parameters->numpocs) { + /* initialisation of POC */ + tcp->POC = 1; + for (i = 0; i < parameters->numpocs; i++) { + if((tileno == parameters->POC[i].tile - 1) || (parameters->POC[i].tile == -1)) { + opj_poc_t *tcp_poc = &tcp->pocs[numpocs_tile]; + tcp_poc->resno0 = parameters->POC[numpocs_tile].resno0; + tcp_poc->compno0 = parameters->POC[numpocs_tile].compno0; + tcp_poc->layno1 = parameters->POC[numpocs_tile].layno1; + tcp_poc->resno1 = parameters->POC[numpocs_tile].resno1; + tcp_poc->compno1 = parameters->POC[numpocs_tile].compno1; + tcp_poc->prg = parameters->POC[numpocs_tile].prg; + tcp_poc->tile = parameters->POC[numpocs_tile].tile; + numpocs_tile++; + } + } + } + tcp->numpocs = numpocs_tile; + + tcp->tccps = (opj_tccp_t *) opj_malloc(volume->numcomps * sizeof(opj_tccp_t)); + + for (i = 0; i < volume->numcomps; i++) { + opj_tccp_t *tccp = &tcp->tccps[i]; + tccp->csty = parameters->csty & J3D_CCP_CSTY_PRT; /* 0 => standard precint || 1 => custom-defined precinct */ + tccp->numresolution[0] = parameters->numresolution[0]; + tccp->numresolution[1] = parameters->numresolution[1]; + tccp->numresolution[2] = parameters->numresolution[2]; + assert (parameters->cblock_init[0] <= T1_MAXCBLKW); + assert (parameters->cblock_init[0] >= T1_MINCBLKW); + assert (parameters->cblock_init[1] <= T1_MAXCBLKH); + assert (parameters->cblock_init[1] >= T1_MINCBLKH); + assert (parameters->cblock_init[2] <= T1_MAXCBLKD); + assert (parameters->cblock_init[2] >= T1_MINCBLKD); + tccp->cblk[0] = int_floorlog2(parameters->cblock_init[0]); + tccp->cblk[1] = int_floorlog2(parameters->cblock_init[1]); + tccp->cblk[2] = int_floorlog2(parameters->cblock_init[2]); + assert (tccp->cblk[0]+tccp->cblk[1]+tccp->cblk[1] <= T1_MAXWHD); + tccp->cblksty = parameters->mode; /*Codeblock style --> Table A.19 (default 0)*/ + + /*ATK / transform */ + tccp->reversible = parameters->irreversible ? 0 : 1; /* 0 => DWT 9-7 || 1 => DWT 5-3 */ + for (j = 0; j < 3; j++) { + tccp->dwtid[j] = parameters->irreversible ? 0 : 1; /* 0 => DWT 9-7 || 1 => DWT 5-3 */ + } + + /* Quantification: SEQNT (Scalar Expounded, value for each subband) / NOQNT (no quant)*/ + tccp->qntsty = parameters->irreversible ? J3D_CCP_QNTSTY_SEQNT : J3D_CCP_QNTSTY_NOQNT; + tccp->numgbits = 2; + if (i == parameters->roi_compno) { + tccp->roishift = parameters->roi_shift; + } else { + tccp->roishift = 0; + } + /* Custom defined precints */ + if (parameters->csty & J3D_CCP_CSTY_PRT) { + int k; + for (k = 0; k < 3; k++) { + int p = 0; + for (j = tccp->numresolution[k] - 1; j >= 0; j--) { + if (p < parameters->res_spec) {/* p < number of precinct size specifications */ + if (parameters->prct_init[k][p] < 1) { + tccp->prctsiz[k][j] = 1; + } else { + tccp->prctsiz[k][j] = int_floorlog2(parameters->prct_init[k][p]); + } + } else { + int res_spec = parameters->res_spec; + int size_prct = parameters->prct_init[k][res_spec - 1] >> (p - (res_spec - 1)); + if (size_prct < 1) { + tccp->prctsiz[k][j] = 1; + } else { + tccp->prctsiz[k][j] = int_floorlog2(size_prct); + } + } + } + p++; + } + } else { + int k; + for (k = 0; k < 3; k++) { + for (j = 0; j < tccp->numresolution[k]; j++) { + tccp->prctsiz[k][j] = 15; + } + } + } + /*Calcular stepsize for each subband (if NOQNT -->stepsize = 1.0)*/ + dwt_calc_explicit_stepsizes(tccp, volume->comps[i].prec); + } + } +} + +/** +Create an index file +@param j3d +@param cio +@param volume_info +@param index Index filename +@return Returns 1 if successful, returns 0 otherwise +*/ +static int j3d_create_index(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_info_t *volume_info, char *index) { + + int tileno, compno, layno, resno, precno, pack_nb, x, y, z; + FILE *stream = NULL; + double total_disto = 0; + + volume_info->codestream_size = cio_tell(cio) + j3d->pos_correction; /* Correction 14/4/03 suite rmq de Patrick */ + + stream = fopen(index, "w"); + if (!stream) { + opj_event_msg(j3d->cinfo, EVT_ERROR, "failed to open %s for writing\n", index); + return 0; + } + + fprintf(stream, "w %d\t h %d\t l %d\n", volume_info->volume_w, volume_info->volume_h, volume_info->volume_l); + fprintf(stream, "TRASNFORM\t%d\n", volume_info->transform_format); + fprintf(stream, "ENTROPY CODING\t%d\n", volume_info->encoding_format); + fprintf(stream, "PROG\t%d\n", volume_info->prog); + fprintf(stream, "TILE\tx %d y %d z %d\n", volume_info->tile_x, volume_info->tile_y, volume_info->tile_z); + fprintf(stream, "NOTILE\tx %d y %d z %d\n", volume_info->tw, volume_info->th, volume_info->tl); + fprintf(stream, "COMPONENTS\t%d\n", volume_info->comp); + fprintf(stream, "LAYER\t%d\n", volume_info->layer); + fprintf(stream, "RESOLUTIONS\tx %d y %d z %d\n", volume_info->decomposition[0], volume_info->decomposition[1], volume_info->decomposition[2]); + + fprintf(stream, "Precint sizes for each resolution:\n"); + for (resno = volume_info->decomposition[0]; resno >= 0; resno--) { + fprintf(stream, "Resno %d \t [%d,%d,%d] \n", resno, + (1 << volume_info->tile[0].prctsiz[0][resno]), (1 << volume_info->tile[0].prctsiz[0][resno]), (1 << volume_info->tile[0].prctsiz[2][resno])); /* based on tile 0 */ + } + fprintf(stream, "HEADER_END\t%d\n", volume_info->main_head_end); + fprintf(stream, "CODESTREAM\t%d\n", volume_info->codestream_size); + fprintf(stream, "Num_tile Start_pos End_header End_pos Distotile Nbpix Ratio\n"); + for (tileno = 0; tileno < (volume_info->tw * volume_info->th * volume_info->tl); tileno++) { + fprintf(stream, "%4d\t%9d\t%9d\t%9d\t%9e\t%9d\t%9e\n", + volume_info->tile[tileno].num_tile, + volume_info->tile[tileno].start_pos, + volume_info->tile[tileno].end_header, + volume_info->tile[tileno].end_pos, + volume_info->tile[tileno].distotile, volume_info->tile[tileno].nbpix, + volume_info->tile[tileno].distotile / volume_info->tile[tileno].nbpix); + } + + for (tileno = 0; tileno < (volume_info->tw * volume_info->th * volume_info->tl); tileno++) { + int start_pos, end_pos; + double disto = 0; + pack_nb = 0; + if (volume_info->prog == LRCP) { /* LRCP */ + fprintf(stream, "pack_nb tileno layno resno compno precno start_pos end_pos disto\n"); + for (layno = 0; layno < volume_info->layer; layno++) { + for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { + for (compno = 0; compno < volume_info->comp; compno++) { + int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno]; + for (precno = 0; precno < prec_max; precno++) { + start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; + disto = volume_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %7d %5d %6d %6d %9d %9d %8e\n",pack_nb, tileno, layno, resno, compno, precno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } + } /* LRCP */ + else if (volume_info->prog == RLCP) { /* RLCP */ + /* + fprintf(stream, "pack_nb tileno resno layno compno precno start_pos end_pos disto"); + */ + for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { + for (layno = 0; layno < volume_info->layer; layno++) { + for (compno = 0; compno < volume_info->comp; compno++) { + int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno]* volume_info->tile[tileno].prctno[2][resno]; + for (precno = 0; precno < prec_max; precno++) { + start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; + disto = volume_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %5d %7d %6d %6d %9d %9d %8e\n", + pack_nb, tileno, resno, layno, compno, precno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } + } /* RLCP */ + else if (volume_info->prog == RPCL) { /* RPCL */ + /* + fprintf(stream, "\npack_nb tileno resno precno compno layno start_pos end_pos disto\n"); + */ + for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { + /* I suppose components have same XRsiz, YRsiz */ + /*int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x;*/ + /*int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y;*/ + int x0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_x; + int y0 = volume_info->tile_Oy + (int)floor( (float)tileno/(float)volume_info->th ) * volume_info->tile_y; + int z0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tl ) * volume_info->tile_z; + int x1 = x0 + volume_info->tile_x; + int y1 = y0 + volume_info->tile_y; + int z1 = z0 + volume_info->tile_z; + for(z = z0; z < z1; z++) { + for(y = y0; y < y1; y++) { + for(x = x0; x < x1; x++) { + for (compno = 0; compno < volume_info->comp; compno++) { + int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = volume_info->tile[tileno].prctno[0][resno]; + int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno ); + int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno ); + int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + if (precno_y*pcy == y ) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < volume_info->layer; layno++) { + start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; + disto = volume_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %5d %6d %6d %7d %9d %9d %8e\n", + pack_nb, tileno, resno, precno, compno, layno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } /* precno */ + } /* compno */ + } /* x = x0..x1 */ + } /* y = y0..y1 */ + } /* z = z0..z1 */ + } /* resno */ + } /* RPCL */ + else if (volume_info->prog == PCRL) { /* PCRL */ + /* I suppose components have same XRsiz, YRsiz */ + int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x; + int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y; + int z0 = volume_info->tile_Oz + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_z; + int x1 = x0 + volume_info->tile_x; + int y1 = y0 + volume_info->tile_y; + int z1 = z0 + volume_info->tile_z; + /* + fprintf(stream, "\npack_nb tileno precno compno resno layno start_pos end_pos disto\n"); + */ + for(z = z0; z < z1; z++) { + for(y = y0; y < y1; y++) { + for(x = x0; x < x1; x++) { + for (compno = 0; compno < volume_info->comp; compno++) { + for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { + int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = volume_info->tile[tileno].prctno[0][resno]; + int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno ); + int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno ); + int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + int precno_z = (int) floor( (float)precno/(float)pcnx ); + if (precno_z*pcz == z ) { + if (precno_y*pcy == y ) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < volume_info->layer; layno++) { + start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; + disto = volume_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n", + pack_nb, tileno, precno, compno, resno, layno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } + } /* precno */ + } /* resno */ + } /* compno */ + } /* x = x0..x1 */ + } /* y = y0..y1 */ + } + } /* PCRL */ + else { /* CPRL */ + /* + fprintf(stream, "\npack_nb tileno compno precno resno layno start_pos end_pos disto\n"); + */ + for (compno = 0; compno < volume_info->comp; compno++) { + /* I suppose components have same XRsiz, YRsiz */ + int x0 = volume_info->tile_Ox + tileno - (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tw * volume_info->tile_x; + int y0 = volume_info->tile_Ox + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_y; + int z0 = volume_info->tile_Oz + (int)floor( (float)tileno/(float)volume_info->tw ) * volume_info->tile_z; + int x1 = x0 + volume_info->tile_x; + int y1 = y0 + volume_info->tile_y; + int z1 = z0 + volume_info->tile_z; + for(z = z0; z < z1; z++) { + for(y = y0; y < y1; y++) { + for(x = x0; x < x1; x++) { + for (resno = 0; resno < volume_info->decomposition[0] + 1; resno++) { + int prec_max = volume_info->tile[tileno].prctno[0][resno] * volume_info->tile[tileno].prctno[1][resno] * volume_info->tile[tileno].prctno[2][resno]; + for (precno = 0; precno < prec_max; precno++) { + int pcnx = volume_info->tile[tileno].prctno[0][resno]; + int pcny = volume_info->tile[tileno].prctno[1][resno]; + int pcx = (int) pow( 2, volume_info->tile[tileno].prctsiz[0][resno] + volume_info->decomposition[0] - resno ); + int pcy = (int) pow( 2, volume_info->tile[tileno].prctsiz[1][resno] + volume_info->decomposition[1] - resno ); + int pcz = (int) pow( 2, volume_info->tile[tileno].prctsiz[2][resno] + volume_info->decomposition[2] - resno ); + int precno_x = precno - (int) floor( (float)precno/(float)pcnx ) * pcnx; + int precno_y = (int) floor( (float)precno/(float)pcnx ); + int precno_z = 0; /*???*/ + if (precno_z*pcz == z ) { + if (precno_y*pcy == y ) { + if (precno_x*pcx == x ) { + for (layno = 0; layno < volume_info->layer; layno++) { + start_pos = volume_info->tile[tileno].packet[pack_nb].start_pos; + end_pos = volume_info->tile[tileno].packet[pack_nb].end_pos; + disto = volume_info->tile[tileno].packet[pack_nb].disto; + fprintf(stream, "%4d %6d %6d %6d %5d %7d %9d %9d %8e\n", + pack_nb, tileno, compno, precno, resno, layno, start_pos, end_pos, disto); + total_disto += disto; + pack_nb++; + } + } + } + } + } /* precno */ + } /* resno */ + } /* x = x0..x1 */ + } /* y = y0..y1 */ + } /* z = z0..z1 */ + } /* comno */ + } /* CPRL */ + } /* tileno */ + + fprintf(stream, "SE_MAX\t%8e\n", volume_info->D_max); /* SE max */ + fprintf(stream, "SE_TOTAL\t%.8e\n", total_disto); /* SE totale */ + + + fclose(stream); + + return 1; +} + +bool j3d_encode(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_t *volume, char *index) { + int tileno, compno; + opj_volume_info_t *volume_info = NULL; + opj_cp_t *cp = NULL; + opj_tcd_t *tcd = NULL; /* TCD component */ + + j3d->cio = cio; + j3d->volume = volume; + cp = j3d->cp; + + /*j3d_dump_volume(stdout, volume); + j3d_dump_cp(stdout, volume, cp);*/ + + /* INDEX >> */ + volume_info = j3d->volume_info; + if (volume_info && cp->index_on) { + volume_info->index_on = cp->index_on; + volume_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tile_info_t)); + volume_info->volume_w = volume->x1 - volume->x0; + volume_info->volume_h = volume->y1 - volume->y0; + volume_info->volume_l = volume->z1 - volume->z0; + volume_info->prog = (&cp->tcps[0])->prg; + volume_info->tw = cp->tw; + volume_info->th = cp->th; + volume_info->tl = cp->tl; + volume_info->tile_x = cp->tdx; /* new version parser */ + volume_info->tile_y = cp->tdy; /* new version parser */ + volume_info->tile_z = cp->tdz; /* new version parser */ + volume_info->tile_Ox = cp->tx0; /* new version parser */ + volume_info->tile_Oy = cp->ty0; /* new version parser */ + volume_info->tile_Oz = cp->tz0; /* new version parser */ + volume_info->transform_format = cp->transform_format; + volume_info->encoding_format = cp->encoding_format; + volume_info->comp = volume->numcomps; + volume_info->layer = (&cp->tcps[0])->numlayers; + volume_info->decomposition[0] = (&cp->tcps[0])->tccps->numresolution[0] - 1; + volume_info->decomposition[1] = (&cp->tcps[0])->tccps->numresolution[1] - 1; + volume_info->decomposition[2] = (&cp->tcps[0])->tccps->numresolution[2] - 1; + volume_info->D_max = 0; /* ADD Marcela */ + } + /* << INDEX */ + + j3d_write_soc(j3d); + j3d_write_siz(j3d); + if (j3d->cinfo->codec_format == CODEC_J3D) { + j3d_write_cap(j3d); + j3d_write_nsi(j3d); + } + + /*if (j3d->cp->transform_format != TRF_2D_DWT || j3d->cp->encoding_format != ENCOD_2EB)*/ + j3d_write_com(j3d); + + j3d_write_cod(j3d); + j3d_write_qcd(j3d); + for (compno = 0; compno < volume->numcomps; compno++) { + opj_tcp_t *tcp = &cp->tcps[0]; + if (tcp->tccps[compno].roishift) + j3d_write_rgn(j3d, compno, 0); + } + /*Optional 15444-2 markers*/ + if (j3d->cp->tcps->tccps[0].atk != NULL) + j3d_write_atk(j3d); + if (j3d->volume->comps[0].dcoffset != 0) + j3d_write_dco(j3d); + + /* INDEX >> */ + if(volume_info && volume_info->index_on) { + volume_info->main_head_end = cio_tell(cio) - 1; + } + /* << INDEX */ + + /* create the tile encoder */ + tcd = tcd_create(j3d->cinfo); + + /* encode each tile */ + for (tileno = 0; tileno < cp->tw * cp->th * cp->tl; tileno++) { + opj_event_msg(j3d->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th * cp->tl); + + j3d->curtileno = tileno; + + /* initialisation before tile encoding */ + if (tileno == 0) { + tcd_malloc_encode(tcd, volume, cp, j3d->curtileno); + } else { + tcd_init_encode(tcd, volume, cp, j3d->curtileno); + } + + /* INDEX >> */ + if(volume_info && volume_info->index_on) { + volume_info->tile[j3d->curtileno].num_tile = j3d->curtileno; + volume_info->tile[j3d->curtileno].start_pos = cio_tell(cio) + j3d->pos_correction; + } + /* << INDEX */ + + j3d_write_sot(j3d); + + for (compno = 1; compno < volume->numcomps; compno++) { + j3d_write_coc(j3d, compno); + j3d_write_qcc(j3d, compno); + } + + if (cp->tcps[tileno].numpocs) { + j3d_write_poc(j3d); + } + j3d_write_sod(j3d, tcd); /*--> tcd_encode_tile*/ + + /* INDEX >> */ + if(volume_info && volume_info->index_on) { + volume_info->tile[j3d->curtileno].end_pos = cio_tell(cio) + j3d->pos_correction - 1; + } + /* << INDEX */ + } + + /* destroy the tile encoder */ + tcd_free_encode(tcd); + tcd_destroy(tcd); + + j3d_write_eoc(j3d); + + /* Creation of the index file */ + if(volume_info && volume_info->index_on) { + if(!j3d_create_index(j3d, cio, volume_info, index)) { + opj_event_msg(j3d->cinfo, EVT_ERROR, "failed to create index file %s\n", index); + return false; + } + } + + return true; +} + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + diff --git a/src/lib/openjp3d/jp3d.h b/src/lib/openjp3d/jp3d.h old mode 100755 new mode 100644 index e9ecf131..d54e21dc --- a/src/lib/openjp3d/jp3d.h +++ b/src/lib/openjp3d/jp3d.h @@ -1,518 +1,518 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __J3D_H -#define __J3D_H -/** -@file jp3d.h -@brief The JPEG-2000 Codestream Reader/Writer (J3D) - -The functions in J3D.C have for goal to read/write the several parts of the codestream: markers and data. -*/ - -/** @defgroup J3D J3D - JPEG-2000 PART 10 codestream reader/writer */ -/*@{*/ - -#define J3D_CP_CSTY_PRT 0x01 -#define J3D_CP_CSTY_SOP 0x02 -#define J3D_CP_CSTY_EPH 0x04 -#define J3D_CCP_CSTY_PRT 0x01 -/** Table A-8 */ -#define J3D_CCP_CBLKSTY_LAZY 0x01 /* Selective arithmetic coding bypass */ -#define J3D_CCP_CBLKSTY_RESET 0x02 /* Reset context probabilities on coding pass boundaries */ -#define J3D_CCP_CBLKSTY_TERMALL 0x04 /* Termination on each coding pass */ -#define J3D_CCP_CBLKSTY_VSC 0x08 /* Vertically causal context, add also hook for switching off and on 3D context models */ -#define J3D_CCP_CBLKSTY_PTERM 0x10 /* Predictable termination */ -#define J3D_CCP_CBLKSTY_SEGSYM 0x20 /* Segmentation symbols are used */ -#define J3D_CCP_CBLKSTY_3DCTXT 0x40 /* 3D context models (3D-EBCOT) vs 2D context models */ - -#define J3D_CCP_QNTSTY_NOQNT 0 /* Quantization style : no quantization */ -#define J3D_CCP_QNTSTY_SIQNT 1 /* Quantization style : scalar derived (values signalled only in LLL subband) */ -#define J3D_CCP_QNTSTY_SEQNT 2 /* Quantization style : scalar expounded (values signalled for each subband) */ - -/* ----------------------------------------------------------------------- */ - -#define J3D_MS_SOC 0xff4f /**< SOC marker value */ -#define J3D_MS_SOT 0xff90 /**< SOT marker value */ -#define J3D_MS_SOD 0xff93 /**< SOD marker value */ -#define J3D_MS_EOC 0xffd9 /**< EOC marker value */ -#define J3D_MS_CAP 0xff50 /**< CAP marker value */ -#define J3D_MS_SIZ 0xff51 /**< SIZ marker value */ -#define J3D_MS_ZSI 0xff54 /**< ZSI marker value */ -#define J3D_MS_COD 0xff52 /**< COD marker value */ -#define J3D_MS_COC 0xff53 /**< COC marker value */ -#define J3D_MS_RGN 0xff5e /**< RGN marker value */ -#define J3D_MS_QCD 0xff5c /**< QCD marker value */ -#define J3D_MS_QCC 0xff5d /**< QCC marker value */ -#define J3D_MS_POC 0xff5f /**< POC marker value */ -#define J3D_MS_TLM 0xff55 /**< TLM marker value */ -#define J3D_MS_PLM 0xff57 /**< PLM marker value */ -#define J3D_MS_PLT 0xff58 /**< PLT marker value */ -#define J3D_MS_PPM 0xff60 /**< PPM marker value */ -#define J3D_MS_PPT 0xff61 /**< PPT marker value */ -#define J3D_MS_SOP 0xff91 /**< SOP marker value */ -#define J3D_MS_EPH 0xff92 /**< EPH marker value */ -#define J3D_MS_CRG 0xff63 /**< CRG marker value */ -#define J3D_MS_COM 0xff64 /**< COM marker value */ -/*15444-2*/ -#define J3D_MS_DCO 0xff70 /**< DCO marker value */ -#define J3D_MS_VMS 0xff71 /**< VMS marker value */ -#define J3D_MS_DFS 0xff72 /**< DFS marker value */ -#define J3D_MS_ADS 0xff73 /**< ADS marker value */ -#define J3D_MS_ATK 0xff79 /**< ATK marker value */ -#define J3D_MS_CBD 0xff78 /**< CBD marker value */ -#define J3D_MS_MCT 0xff74 /**< MCT marker value */ -#define J3D_MS_MCC 0xff75 /**< MCC marker value */ -#define J3D_MS_MCO 0xff77 /**< MCO marker value */ -#define J3D_MS_NLT 0xff76 /**< NLT marker value */ -#define J3D_MS_QPD 0xff5a /**< QPD marker value */ -#define J3D_MS_QPC 0xff5b /**< QPC marker value */ - -/* ----------------------------------------------------------------------- */ -/* Capability RSIZ parameter, extended */ -#define J3D_RSIZ_BASIC 0x0000 - -#define J3D_RSIZ_DCO 0x8001 /* Required */ -#define J3D_RSIZ_VSQNT 0x8002 -#define J3D_RSIZ_TCQNT 0x8004 -#define J3D_RSIZ_VMASK 0x8008 -#define J3D_RSIZ_SSOVL 0x8010 -#define J3D_RSIZ_ADECS 0x8020 -#define J3D_RSIZ_ATK 0x8040 /*Required*/ -#define J3D_RSIZ_SSYMK 0x8080 -#define J3D_RSIZ_MCT 0x8100 /*Not compatible with DCO*/ -#define J3D_RSIZ_NLT 0x8200 /*Required*/ -#define J3D_RSIZ_ASHAP 0x8400 -#define J3D_RSIZ_PRQNT 0x8800 - -#define J3D_CAP_10 0x00400000 -/* Arbitrary transformation kernel, 15444-2 */ -#define J3D_ATK_IRR 0 -#define J3D_ATK_REV 1 -#define J3D_ATK_ARB 0 -#define J3D_ATK_WS 1 -#define J3D_ATK_CON 0 -/* ----------------------------------------------------------------------- */ - -/** -Values that specify the status of the decoding process when decoding the main header. -These values may be combined with a | operator. -*/ -typedef enum J3D_STATUS { - /**< a SOC marker is expected */ - J3D_STATE_MHSOC = 0x0001, - /**< a SIZ marker is expected */ - J3D_STATE_MHSIZ = 0x0002, - /**< the decoding process is in the main header */ - J3D_STATE_MH = 0x0004, - /**< the decoding process is in a tile part header and expects a SOT marker */ - J3D_STATE_TPHSOT = 0x0008, - /**< the decoding process is in a tile part header */ - J3D_STATE_TPH = 0x0010, - /**< the EOC marker has just been read */ - J3D_STATE_MT = 0x0020, - /**< the decoding process must not expect a EOC marker because the codestream is truncated */ - J3D_STATE_NEOC = 0x0040 -} J3D_STATUS; - - - -/** -Arbitrary transformation kernel -*/ -typedef struct opj_atk { -/** index of wavelet kernel */ - int index; -/** Numerical type of scaling factor and lifting step parameters */ - int coeff_typ; -/** Wavelet filter category */ - int filt_cat; -/** Wavelet transformation type (REV/IRR) */ - int wt_typ; -/** Initial odd/even subsequence */ - int minit; -/** Boundary extension method (constant CON / whole-sample symmetric WS) */ - int exten; -/** Scaling factor. Only for wt_typ=IRR */ - double Katk; -/** Number of lifting steps */ - int Natk; -/** Offset for lifting step s. Only for filt_cat=ARB */ - int Oatk[256]; -/** Base 2 scaling exponent for lifting step s. Only for wt_typ=REV */ - int Eatk[256]; -/** Additive residue for lifting step s. Only for wt_typ=REV */ - int Batk[256]; -/** Number of lifting coefficients signaled for lifting step s */ - int LCatk[256]; -/** Lifting coefficient k for lifting step s */ - double Aatk[256][256]; -} opj_atk_t; - - -/** -Quantization stepsize -*/ -typedef struct opj_stepsize { -/** exponent */ - int expn; -/** mantissa */ - int mant; -} opj_stepsize_t; - -/** -Tile-component coding parameters -*/ -typedef struct opj_tccp { - /** coding style */ - int csty; - /** number of resolutions of x, y and z-axis */ - int numresolution[3]; - /** code-blocks width height & depth*/ - int cblk[3]; - /** code-block coding style */ - int cblksty; - /** 0: no ATK (only 9-7 or 5-3) 1: ATK defined WT*/ - int atk_wt[3]; - /** Arbitrary transformation kernel (15444-2)*/ - opj_atk_t *atk; - /** DWT identifier for x, y and z-axis (0:WT9-7 1:WT5-3 >1:WT-atk->index) */ - int dwtid[3]; - /** reversible/irreversible wavelet transfomation (0:irrev 1:reversible)*/ - int reversible; - /** quantisation style */ - int qntsty; - /** stepsizes used for quantization */ - opj_stepsize_t stepsizes[J3D_MAXBANDS]; - /** number of guard bits. Table A28 de 15444-1*/ - int numgbits; - /** Region Of Interest shift */ - int roishift; - /** precinct width heigth & depth*/ - int prctsiz[3][J3D_MAXRLVLS]; -} opj_tccp_t; - -/** -Tile coding parameters : coding/decoding parameters common to all tiles -(information like COD, COC in main header) -*/ -typedef struct opj_tcp { -/** 1 : first part-tile of a tile */ - int first; - /** coding style */ - int csty; - /** progression order */ - OPJ_PROG_ORDER prg; - /** number of layers */ - int numlayers; - /** multi-component transform identifier */ - int mct; - /** rates of layers */ - float rates[100]; - /** number of progression order changes */ - int numpocs; - /** indicates if a POC marker has been used O:NO, 1:YES */ - int POC; - /** progression order changes */ - opj_poc_t pocs[J3D_MAXRLVLS - 1]; - /** add fixed_quality */ - float distoratio[100]; - /** tile-component coding parameters */ - opj_tccp_t *tccps; -/** packet header store there for futur use in t2_decode_packet */ - unsigned char *ppt_data; - /** pointer remaining on the first byte of the first header if ppt is used */ - unsigned char *ppt_data_first; - /** If ppt == 1 --> there was a PPT marker for the present tile */ - int ppt; - /** used in case of multiple marker PPT (number of info already stored) */ - int ppt_store; - int ppt_len; -} opj_tcp_t; - -/** -Coding parameters -*/ -typedef struct opj_cp { -/** transform format 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */ - OPJ_TRANSFORM transform_format; - /** entropy coding format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI*/ - OPJ_ENTROPY_CODING encoding_format; - /** allocation by rate/distortion */ - int disto_alloc; - /** allocation by fixed layer */ - int fixed_alloc; - /** add fixed_quality */ - int fixed_quality; - /** Rsiz: capabilities */ - int rsiz; - /** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, volume is decoded to the full resolution */ - int reduce[3]; - /** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ - int layer; - /** 0 = no index || 1 = index */ - int index_on; - /** Big-Endian/Little-endian order */ - int bigendian; - /** XTOsiz */ - int tx0; - /** YTOsiz */ - int ty0; - /** ZTOsiz */ - int tz0; - /** XTsiz */ - int tdx; - /** YTsiz */ - int tdy; - /** ZTsiz */ - int tdz; - /** comment for coding */ - char *comment; - /** number of tiles in width, heigth and depth */ - int tw; - int th; - int tl; - /** ID number of the tiles present in the codestream */ - int *tileno; - /** size of the vector tileno */ - int tileno_size; - /** tile coding parameters */ - opj_tcp_t *tcps; - /** fixed layer */ - int *matrice; - - /** packet header store there for futur use in t2_decode_packet */ - unsigned char *ppm_data; - /** pointer remaining on the first byte of the first header if ppm is used */ - unsigned char *ppm_data_first; - /** if ppm == 1 --> there was a PPM marker for the present tile */ - int ppm; - /** use in case of multiple marker PPM (number of info already store) */ - int ppm_store; - /** use in case of multiple marker PPM (case on non-finished previous info) */ - int ppm_previous; - int ppm_len; -} opj_cp_t; - -/** -Information concerning a packet inside tile -*/ -typedef struct opj_packet_info { - /** start position */ - int start_pos; - /** end position */ - int end_pos; - /** distorsion introduced */ - double disto; -} opj_packet_info_t; - -/** -Index structure : information regarding tiles inside volume -*/ -typedef struct opj_tile_info { - /** value of thresh for each layer by tile cfr. Marcela */ - double *thresh; - /** number of tile */ - int num_tile; - /** start position */ - int start_pos; - /** end position of the header */ - int end_header; - /** end position */ - int end_pos; - /** precinct number for each resolution level (width, heigth and depth) */ - int prctno[3][J3D_MAXRLVLS]; - /** precinct size (in power of 2), in X for each resolution level */ - int prctsiz[3][J3D_MAXRLVLS]; - /** information concerning packets inside tile */ - opj_packet_info_t *packet; - - /** add fixed_quality */ - int nbpix; - /** add fixed_quality */ - double distotile; -} opj_tile_info_t; - -/** -Index structure -*/ -typedef struct opj_volume_info { - - /** transform format 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */ - OPJ_TRANSFORM transform_format; - /** output file format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI*/ - OPJ_ENTROPY_CODING encoding_format; /** 0 = no index || 1 = index */ - int index_on; - /** 0 = wt 9-7 || 1 = wt 5-3 || >=2 wt atk defined */ - int dwtid[3]; - /** maximum distortion reduction on the whole volume (add for Marcela) */ - double D_max; - /** packet number */ - int num; - /** writing the packet in the index with t2_encode_packets */ - int index_write; - /** volume width, height and depth */ - int volume_w; - int volume_h; - int volume_l; - /** progression order */ - OPJ_PROG_ORDER prog; - /** tile size in x, y and z */ - int tile_x; - int tile_y; - int tile_z; - /** tile origin in x, y and z */ - int tile_Ox; - int tile_Oy; - int tile_Oz; - /** number of tiles in X, Y and Z */ - int tw; - int th; - int tl; - /** component numbers */ - int comp; - /** number of layer */ - int layer; - /** number of decomposition in X, Y and Z*/ - int decomposition[3]; - /** DC offset (15444-2) */ - int dcoffset; - /** main header position */ - int main_head_end; - /** codestream's size */ - int codestream_size; - /** information regarding tiles inside volume */ - opj_tile_info_t *tile; -} opj_volume_info_t; - -/** -JPEG-2000 codestream reader/writer -*/ -typedef struct opj_j3d { - /** codec context */ - opj_common_ptr cinfo; - /** locate in which part of the codestream the decoder is (main header, tile header, end) */ - int state; - /** number of the tile curently concern by coding/decoding */ - int curtileno; - /** locate the position of the end of the tile in the codestream, used to detect a truncated codestream (in j3d_read_sod) */ - unsigned char *eot; - /** locate the start position of the SOT marker of the current coded tile: */ - int sot_start; - /* after encoding the tile, a jump (in j3d_write_sod) is done to the SOT marker to store the value of its length. */ - int sod_start; - /** as the J3D-file is written in several parts during encoding, it enables to make the right correction in position return by cio_tell */ - int pos_correction; - /** array used to store the data of each tile */ - unsigned char **tile_data; - /** array used to store the length of each tile */ - int *tile_len; - - /** decompression only : store decoding parameters common to all tiles */ - opj_tcp_t *default_tcp; - /** pointer to the encoded / decoded volume */ - opj_volume_t *volume; - /** pointer to the coding parameters */ - opj_cp_t *cp; - /** helper used to write the index file */ - opj_volume_info_t *volume_info; - /** pointer to the byte i/o stream */ - opj_cio_t *cio; -} opj_j3d_t; - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Creates a J3D decompression structure -@param cinfo Codec context info -@return Returns a handle to a J3D decompressor if successful, returns NULL otherwise -*/ -opj_j3d_t* j3d_create_decompress(opj_common_ptr cinfo); -/** -Destroy a J3D decompressor handle -@param j3d J3D decompressor handle to destroy -*/ -void j3d_destroy_decompress(opj_j3d_t *j3d); -/** -Setup the decoder decoding parameters using user parameters. -Decoding parameters are returned in j3d->cp. -@param j3d J3D decompressor handle -@param parameters decompression parameters -*/ -void j3d_setup_decoder(opj_j3d_t *j3d, opj_dparameters_t *parameters); -/** -Decode an volume from a JPEG-2000 codestream -@param j3d J3D decompressor handle -@param cio Input buffer stream -@return Returns a decoded volume if successful, returns NULL otherwise -*/ -opj_volume_t* j3d_decode(opj_j3d_t *j3d, opj_cio_t *cio); -/** -Decode an volume form a JPT-stream (JPEG 2000, JPIP) -@param j3d J3D decompressor handle -@param cio Input buffer stream -@return Returns a decoded volume if successful, returns NULL otherwise -*/ -opj_volume_t* j3d_decode_jpt_stream(opj_j3d_t *j3d, opj_cio_t *cio); -/** -Creates a J3D compression structure -@param cinfo Codec context info -@return Returns a handle to a J3D compressor if successful, returns NULL otherwise -*/ -opj_j3d_t* j3d_create_compress(opj_common_ptr cinfo); -/** -Destroy a J3D compressor handle -@param j3d J3D compressor handle to destroy -*/ -void j3d_destroy_compress(opj_j3d_t *j3d); -/** -Setup the encoder parameters using the current volume and using user parameters. -Coding parameters are returned in j3d->cp. -@param j3d J3D compressor handle -@param parameters compression parameters -@param volume input filled volume -*/ -void j3d_setup_encoder(opj_j3d_t *j3d, opj_cparameters_t *parameters, opj_volume_t *volume); -/** -Encode an volume into a JPEG-2000 codestream -@param j3d J3D compressor handle -@param cio Output buffer stream -@param volume Volume to encode -@param index Name of the index file if required, NULL otherwise -@return Returns true if successful, returns false otherwise -*/ -bool j3d_encode(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_t *volume, char *index); -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __J3D_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __J3D_H +#define __J3D_H +/** +@file jp3d.h +@brief The JPEG-2000 Codestream Reader/Writer (J3D) + +The functions in J3D.C have for goal to read/write the several parts of the codestream: markers and data. +*/ + +/** @defgroup J3D J3D - JPEG-2000 PART 10 codestream reader/writer */ +/*@{*/ + +#define J3D_CP_CSTY_PRT 0x01 +#define J3D_CP_CSTY_SOP 0x02 +#define J3D_CP_CSTY_EPH 0x04 +#define J3D_CCP_CSTY_PRT 0x01 +/** Table A-8 */ +#define J3D_CCP_CBLKSTY_LAZY 0x01 /* Selective arithmetic coding bypass */ +#define J3D_CCP_CBLKSTY_RESET 0x02 /* Reset context probabilities on coding pass boundaries */ +#define J3D_CCP_CBLKSTY_TERMALL 0x04 /* Termination on each coding pass */ +#define J3D_CCP_CBLKSTY_VSC 0x08 /* Vertically causal context, add also hook for switching off and on 3D context models */ +#define J3D_CCP_CBLKSTY_PTERM 0x10 /* Predictable termination */ +#define J3D_CCP_CBLKSTY_SEGSYM 0x20 /* Segmentation symbols are used */ +#define J3D_CCP_CBLKSTY_3DCTXT 0x40 /* 3D context models (3D-EBCOT) vs 2D context models */ + +#define J3D_CCP_QNTSTY_NOQNT 0 /* Quantization style : no quantization */ +#define J3D_CCP_QNTSTY_SIQNT 1 /* Quantization style : scalar derived (values signalled only in LLL subband) */ +#define J3D_CCP_QNTSTY_SEQNT 2 /* Quantization style : scalar expounded (values signalled for each subband) */ + +/* ----------------------------------------------------------------------- */ + +#define J3D_MS_SOC 0xff4f /**< SOC marker value */ +#define J3D_MS_SOT 0xff90 /**< SOT marker value */ +#define J3D_MS_SOD 0xff93 /**< SOD marker value */ +#define J3D_MS_EOC 0xffd9 /**< EOC marker value */ +#define J3D_MS_CAP 0xff50 /**< CAP marker value */ +#define J3D_MS_SIZ 0xff51 /**< SIZ marker value */ +#define J3D_MS_NSI 0xff54 /**< NSI marker value */ +#define J3D_MS_COD 0xff52 /**< COD marker value */ +#define J3D_MS_COC 0xff53 /**< COC marker value */ +#define J3D_MS_RGN 0xff5e /**< RGN marker value */ +#define J3D_MS_QCD 0xff5c /**< QCD marker value */ +#define J3D_MS_QCC 0xff5d /**< QCC marker value */ +#define J3D_MS_POC 0xff5f /**< POC marker value */ +#define J3D_MS_TLM 0xff55 /**< TLM marker value */ +#define J3D_MS_PLM 0xff57 /**< PLM marker value */ +#define J3D_MS_PLT 0xff58 /**< PLT marker value */ +#define J3D_MS_PPM 0xff60 /**< PPM marker value */ +#define J3D_MS_PPT 0xff61 /**< PPT marker value */ +#define J3D_MS_SOP 0xff91 /**< SOP marker value */ +#define J3D_MS_EPH 0xff92 /**< EPH marker value */ +#define J3D_MS_CRG 0xff63 /**< CRG marker value */ +#define J3D_MS_COM 0xff64 /**< COM marker value */ +/*15444-2*/ +#define J3D_MS_DCO 0xff70 /**< DCO marker value */ +#define J3D_MS_VMS 0xff71 /**< VMS marker value */ +#define J3D_MS_DFS 0xff72 /**< DFS marker value */ +#define J3D_MS_ADS 0xff73 /**< ADS marker value */ +#define J3D_MS_ATK 0xff79 /**< ATK marker value */ +#define J3D_MS_CBD 0xff78 /**< CBD marker value */ +#define J3D_MS_MCT 0xff74 /**< MCT marker value */ +#define J3D_MS_MCC 0xff75 /**< MCC marker value */ +#define J3D_MS_MCO 0xff77 /**< MCO marker value */ +#define J3D_MS_NLT 0xff76 /**< NLT marker value */ +#define J3D_MS_QPD 0xff5a /**< QPD marker value */ +#define J3D_MS_QPC 0xff5b /**< QPC marker value */ + +/* ----------------------------------------------------------------------- */ +/* Capability RSIZ parameter, extended */ +#define J3D_RSIZ_BASIC 0x0000 + +#define J3D_RSIZ_DCO 0x8001 /* Required */ +#define J3D_RSIZ_VSQNT 0x8002 +#define J3D_RSIZ_TCQNT 0x8004 +#define J3D_RSIZ_VMASK 0x8008 +#define J3D_RSIZ_SSOVL 0x8010 +#define J3D_RSIZ_ADECS 0x8020 +#define J3D_RSIZ_ATK 0x8040 /*Required*/ +#define J3D_RSIZ_SSYMK 0x8080 +#define J3D_RSIZ_MCT 0x8100 /*Not compatible with DCO*/ +#define J3D_RSIZ_NLT 0x8200 /*Required*/ +#define J3D_RSIZ_ASHAP 0x8400 +#define J3D_RSIZ_PRQNT 0x8800 + +#define J3D_CAP_10 0x00400000 +/* Arbitrary transformation kernel, 15444-2 */ +#define J3D_ATK_IRR 0 +#define J3D_ATK_REV 1 +#define J3D_ATK_ARB 0 +#define J3D_ATK_WS 1 +#define J3D_ATK_CON 0 +/* ----------------------------------------------------------------------- */ + +/** +Values that specify the status of the decoding process when decoding the main header. +These values may be combined with a | operator. +*/ +typedef enum J3D_STATUS { + /**< a SOC marker is expected */ + J3D_STATE_MHSOC = 0x0001, + /**< a SIZ marker is expected */ + J3D_STATE_MHSIZ = 0x0002, + /**< the decoding process is in the main header */ + J3D_STATE_MH = 0x0004, + /**< the decoding process is in a tile part header and expects a SOT marker */ + J3D_STATE_TPHSOT = 0x0008, + /**< the decoding process is in a tile part header */ + J3D_STATE_TPH = 0x0010, + /**< the EOC marker has just been read */ + J3D_STATE_MT = 0x0020, + /**< the decoding process must not expect a EOC marker because the codestream is truncated */ + J3D_STATE_NEOC = 0x0040 +} J3D_STATUS; + + + +/** +Arbitrary transformation kernel +*/ +typedef struct opj_atk { +/** index of wavelet kernel */ + int index; +/** Numerical type of scaling factor and lifting step parameters */ + int coeff_typ; +/** Wavelet filter category */ + int filt_cat; +/** Wavelet transformation type (REV/IRR) */ + int wt_typ; +/** Initial odd/even subsequence */ + int minit; +/** Boundary extension method (constant CON / whole-sample symmetric WS) */ + int exten; +/** Scaling factor. Only for wt_typ=IRR */ + double Katk; +/** Number of lifting steps */ + int Natk; +/** Offset for lifting step s. Only for filt_cat=ARB */ + int Oatk[256]; +/** Base 2 scaling exponent for lifting step s. Only for wt_typ=REV */ + int Eatk[256]; +/** Additive residue for lifting step s. Only for wt_typ=REV */ + int Batk[256]; +/** Number of lifting coefficients signaled for lifting step s */ + int LCatk[256]; +/** Lifting coefficient k for lifting step s */ + double Aatk[256][256]; +} opj_atk_t; + + +/** +Quantization stepsize +*/ +typedef struct opj_stepsize { +/** exponent */ + int expn; +/** mantissa */ + int mant; +} opj_stepsize_t; + +/** +Tile-component coding parameters +*/ +typedef struct opj_tccp { + /** coding style */ + int csty; + /** number of resolutions of x, y and z-axis */ + int numresolution[3]; + /** code-blocks width height & depth*/ + int cblk[3]; + /** code-block coding style */ + int cblksty; + /** 0: no ATK (only 9-7 or 5-3) 1: ATK defined WT*/ + int atk_wt[3]; + /** Arbitrary transformation kernel (15444-2)*/ + opj_atk_t *atk; + /** DWT identifier for x, y and z-axis (0:WT9-7 1:WT5-3 >1:WT-atk->index) */ + int dwtid[3]; + /** reversible/irreversible wavelet transfomation (0:irrev 1:reversible)*/ + int reversible; + /** quantisation style */ + int qntsty; + /** stepsizes used for quantization */ + opj_stepsize_t stepsizes[J3D_MAXBANDS]; + /** number of guard bits. Table A28 de 15444-1*/ + int numgbits; + /** Region Of Interest shift */ + int roishift; + /** precinct width heigth & depth*/ + int prctsiz[3][J3D_MAXRLVLS]; +} opj_tccp_t; + +/** +Tile coding parameters : coding/decoding parameters common to all tiles +(information like COD, COC in main header) +*/ +typedef struct opj_tcp { +/** 1 : first part-tile of a tile */ + int first; + /** coding style */ + int csty; + /** progression order */ + OPJ_PROG_ORDER prg; + /** number of layers */ + int numlayers; + /** multi-component transform identifier */ + int mct; + /** rates of layers */ + float rates[100]; + /** number of progression order changes */ + int numpocs; + /** indicates if a POC marker has been used O:NO, 1:YES */ + int POC; + /** progression order changes */ + opj_poc_t pocs[J3D_MAXRLVLS - 1]; + /** add fixed_quality */ + float distoratio[100]; + /** tile-component coding parameters */ + opj_tccp_t *tccps; +/** packet header store there for futur use in t2_decode_packet */ + unsigned char *ppt_data; + /** pointer remaining on the first byte of the first header if ppt is used */ + unsigned char *ppt_data_first; + /** If ppt == 1 --> there was a PPT marker for the present tile */ + int ppt; + /** used in case of multiple marker PPT (number of info already stored) */ + int ppt_store; + int ppt_len; +} opj_tcp_t; + +/** +Coding parameters +*/ +typedef struct opj_cp { +/** transform format 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */ + OPJ_TRANSFORM transform_format; + /** entropy coding format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI*/ + OPJ_ENTROPY_CODING encoding_format; + /** allocation by rate/distortion */ + int disto_alloc; + /** allocation by fixed layer */ + int fixed_alloc; + /** add fixed_quality */ + int fixed_quality; + /** Rsiz: capabilities */ + int rsiz; + /** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, volume is decoded to the full resolution */ + int reduce[3]; + /** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ + int layer; + /** 0 = no index || 1 = index */ + int index_on; + /** Big-Endian/Little-endian order */ + int bigendian; + /** XTOsiz */ + int tx0; + /** YTOsiz */ + int ty0; + /** ZTOsiz */ + int tz0; + /** XTsiz */ + int tdx; + /** YTsiz */ + int tdy; + /** ZTsiz */ + int tdz; + /** comment for coding */ + char *comment; + /** number of tiles in width, heigth and depth */ + int tw; + int th; + int tl; + /** ID number of the tiles present in the codestream */ + int *tileno; + /** size of the vector tileno */ + int tileno_size; + /** tile coding parameters */ + opj_tcp_t *tcps; + /** fixed layer */ + int *matrice; + + /** packet header store there for futur use in t2_decode_packet */ + unsigned char *ppm_data; + /** pointer remaining on the first byte of the first header if ppm is used */ + unsigned char *ppm_data_first; + /** if ppm == 1 --> there was a PPM marker for the present tile */ + int ppm; + /** use in case of multiple marker PPM (number of info already store) */ + int ppm_store; + /** use in case of multiple marker PPM (case on non-finished previous info) */ + int ppm_previous; + int ppm_len; +} opj_cp_t; + +/** +Information concerning a packet inside tile +*/ +typedef struct opj_packet_info { + /** start position */ + int start_pos; + /** end position */ + int end_pos; + /** distorsion introduced */ + double disto; +} opj_packet_info_t; + +/** +Index structure : information regarding tiles inside volume +*/ +typedef struct opj_tile_info { + /** value of thresh for each layer by tile cfr. Marcela */ + double *thresh; + /** number of tile */ + int num_tile; + /** start position */ + int start_pos; + /** end position of the header */ + int end_header; + /** end position */ + int end_pos; + /** precinct number for each resolution level (width, heigth and depth) */ + int prctno[3][J3D_MAXRLVLS]; + /** precinct size (in power of 2), in X for each resolution level */ + int prctsiz[3][J3D_MAXRLVLS]; + /** information concerning packets inside tile */ + opj_packet_info_t *packet; + + /** add fixed_quality */ + int nbpix; + /** add fixed_quality */ + double distotile; +} opj_tile_info_t; + +/** +Index structure +*/ +typedef struct opj_volume_info { + + /** transform format 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */ + OPJ_TRANSFORM transform_format; + /** output file format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI*/ + OPJ_ENTROPY_CODING encoding_format; /** 0 = no index || 1 = index */ + int index_on; + /** 0 = wt 9-7 || 1 = wt 5-3 || >=2 wt atk defined */ + int dwtid[3]; + /** maximum distortion reduction on the whole volume (add for Marcela) */ + double D_max; + /** packet number */ + int num; + /** writing the packet in the index with t2_encode_packets */ + int index_write; + /** volume width, height and depth */ + int volume_w; + int volume_h; + int volume_l; + /** progression order */ + OPJ_PROG_ORDER prog; + /** tile size in x, y and z */ + int tile_x; + int tile_y; + int tile_z; + /** tile origin in x, y and z */ + int tile_Ox; + int tile_Oy; + int tile_Oz; + /** number of tiles in X, Y and Z */ + int tw; + int th; + int tl; + /** component numbers */ + int comp; + /** number of layer */ + int layer; + /** number of decomposition in X, Y and Z*/ + int decomposition[3]; + /** DC offset (15444-2) */ + int dcoffset; + /** main header position */ + int main_head_end; + /** codestream's size */ + int codestream_size; + /** information regarding tiles inside volume */ + opj_tile_info_t *tile; +} opj_volume_info_t; + +/** +JPEG-2000 codestream reader/writer +*/ +typedef struct opj_j3d { + /** codec context */ + opj_common_ptr cinfo; + /** locate in which part of the codestream the decoder is (main header, tile header, end) */ + int state; + /** number of the tile curently concern by coding/decoding */ + int curtileno; + /** locate the position of the end of the tile in the codestream, used to detect a truncated codestream (in j3d_read_sod) */ + unsigned char *eot; + /** locate the start position of the SOT marker of the current coded tile: */ + int sot_start; + /* after encoding the tile, a jump (in j3d_write_sod) is done to the SOT marker to store the value of its length. */ + int sod_start; + /** as the J3D-file is written in several parts during encoding, it enables to make the right correction in position return by cio_tell */ + int pos_correction; + /** array used to store the data of each tile */ + unsigned char **tile_data; + /** array used to store the length of each tile */ + int *tile_len; + + /** decompression only : store decoding parameters common to all tiles */ + opj_tcp_t *default_tcp; + /** pointer to the encoded / decoded volume */ + opj_volume_t *volume; + /** pointer to the coding parameters */ + opj_cp_t *cp; + /** helper used to write the index file */ + opj_volume_info_t *volume_info; + /** pointer to the byte i/o stream */ + opj_cio_t *cio; +} opj_j3d_t; + +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Creates a J3D decompression structure +@param cinfo Codec context info +@return Returns a handle to a J3D decompressor if successful, returns NULL otherwise +*/ +opj_j3d_t* j3d_create_decompress(opj_common_ptr cinfo); +/** +Destroy a J3D decompressor handle +@param j3d J3D decompressor handle to destroy +*/ +void j3d_destroy_decompress(opj_j3d_t *j3d); +/** +Setup the decoder decoding parameters using user parameters. +Decoding parameters are returned in j3d->cp. +@param j3d J3D decompressor handle +@param parameters decompression parameters +*/ +void j3d_setup_decoder(opj_j3d_t *j3d, opj_dparameters_t *parameters); +/** +Decode an volume from a JPEG-2000 codestream +@param j3d J3D decompressor handle +@param cio Input buffer stream +@return Returns a decoded volume if successful, returns NULL otherwise +*/ +opj_volume_t* j3d_decode(opj_j3d_t *j3d, opj_cio_t *cio); +/** +Decode an volume form a JPT-stream (JPEG 2000, JPIP) +@param j3d J3D decompressor handle +@param cio Input buffer stream +@return Returns a decoded volume if successful, returns NULL otherwise +*/ +opj_volume_t* j3d_decode_jpt_stream(opj_j3d_t *j3d, opj_cio_t *cio); +/** +Creates a J3D compression structure +@param cinfo Codec context info +@return Returns a handle to a J3D compressor if successful, returns NULL otherwise +*/ +opj_j3d_t* j3d_create_compress(opj_common_ptr cinfo); +/** +Destroy a J3D compressor handle +@param j3d J3D compressor handle to destroy +*/ +void j3d_destroy_compress(opj_j3d_t *j3d); +/** +Setup the encoder parameters using the current volume and using user parameters. +Coding parameters are returned in j3d->cp. +@param j3d J3D compressor handle +@param parameters compression parameters +@param volume input filled volume +*/ +void j3d_setup_encoder(opj_j3d_t *j3d, opj_cparameters_t *parameters, opj_volume_t *volume); +/** +Encode an volume into a JPEG-2000 codestream +@param j3d J3D compressor handle +@param cio Output buffer stream +@param volume Volume to encode +@param index Name of the index file if required, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +bool j3d_encode(opj_j3d_t *j3d, opj_cio_t *cio, opj_volume_t *volume, char *index); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __J3D_H */ diff --git a/src/lib/openjp3d/jp3d_lib.c b/src/lib/openjp3d/jp3d_lib.c old mode 100755 new mode 100644 index 4445e859..d63a9b0d --- a/src/lib/openjp3d/jp3d_lib.c +++ b/src/lib/openjp3d/jp3d_lib.c @@ -1,76 +1,76 @@ -/* - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef _WIN32 -#include -#else -#include -#include -#include -#endif /* _WIN32 */ -#include "opj_includes.h" - -double opj_clock() { -#ifdef _WIN32 - /* WIN32: use QueryPerformance (very accurate) */ - LARGE_INTEGER freq , t ; - /* freq is the clock speed of the CPU */ - QueryPerformanceFrequency(&freq) ; - /* cout << "freq = " << ((double) freq.QuadPart) << endl; */ - /* t is the high resolution performance counter (see MSDN) */ - QueryPerformanceCounter ( & t ) ; - return ( t.QuadPart /(double) freq.QuadPart ) ; -#else - /* Unix or Linux: use resource usage */ - struct rusage t; - double procTime; - /* (1) Get the rusage data structure at this moment (man getrusage) */ - getrusage(0,&t); - /* (2) What is the elapsed time ? - CPU time = User time + System time */ - /* (2a) Get the seconds */ - procTime = t.ru_utime.tv_sec + t.ru_stime.tv_sec; - /* (2b) More precisely! Get the microseconds part ! */ - return ( procTime + (t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ; -#endif /* _WIN32 */ -} - -void* opj_malloc( size_t size ) { - void *memblock = malloc(size); - if(memblock) { - memset(memblock, 0, size); - } - return memblock; -} - -void* opj_realloc( void *memblock, size_t size ) { - return realloc(memblock, size); -} - -void opj_free( void *memblock ) { - free(memblock); -} - - +/* + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _WIN32 +#include +#else +#include +#include +#include +#endif /* _WIN32 */ +#include "opj_includes.h" + +double opj_clock() { +#ifdef _WIN32 + /* WIN32: use QueryPerformance (very accurate) */ + LARGE_INTEGER freq , t ; + /* freq is the clock speed of the CPU */ + QueryPerformanceFrequency(&freq) ; + /* cout << "freq = " << ((double) freq.QuadPart) << endl; */ + /* t is the high resolution performance counter (see MSDN) */ + QueryPerformanceCounter ( & t ) ; + return ( t.QuadPart /(double) freq.QuadPart ) ; +#else + /* Unix or Linux: use resource usage */ + struct rusage t; + double procTime; + /* (1) Get the rusage data structure at this moment (man getrusage) */ + getrusage(0,&t); + /* (2) What is the elapsed time ? - CPU time = User time + System time */ + /* (2a) Get the seconds */ + procTime = t.ru_utime.tv_sec + t.ru_stime.tv_sec; + /* (2b) More precisely! Get the microseconds part ! */ + return ( procTime + (t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ; +#endif /* _WIN32 */ +} + +void* opj_malloc( size_t size ) { + void *memblock = malloc(size); + if(memblock) { + memset(memblock, 0, size); + } + return memblock; +} + +void* opj_realloc( void *memblock, size_t size ) { + return realloc(memblock, size); +} + +void opj_free( void *memblock ) { + free(memblock); +} + + diff --git a/src/lib/openjp3d/jp3d_lib.h b/src/lib/openjp3d/jp3d_lib.h old mode 100755 new mode 100644 index dae43275..1b910ae3 --- a/src/lib/openjp3d/jp3d_lib.h +++ b/src/lib/openjp3d/jp3d_lib.h @@ -1,75 +1,75 @@ -/* - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __J3D_LIB_H -#define __J3D_LIB_H -/** -@file jp3d_lib.h -@brief Internal functions - -The functions in JP3D_LIB.C are internal utilities mainly used for memory management. -*/ - -/** @defgroup MISC MISC - Miscellaneous internal functions */ -/*@{*/ - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ - -/** -Difference in successive opj_clock() calls tells you the elapsed time -@return Returns time in seconds -*/ -double opj_clock(void); - -/** -Allocate a memory block with elements initialized to 0 -@param size Bytes to allocate -@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available -*/ -void* opj_malloc( size_t size ); - -/** -Reallocate memory blocks. -@param memblock Pointer to previously allocated memory block -@param size New size in bytes -@return Returns a void pointer to the reallocated (and possibly moved) memory block -*/ -void* opj_realloc( void *memblock, size_t size ); - -/** -Deallocates or frees a memory block. -@param memblock Previously allocated memory block to be freed -*/ -void opj_free( void *memblock ); - -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __J3D_LIB_H */ - +/* + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __J3D_LIB_H +#define __J3D_LIB_H +/** +@file jp3d_lib.h +@brief Internal functions + +The functions in JP3D_LIB.C are internal utilities mainly used for memory management. +*/ + +/** @defgroup MISC MISC - Miscellaneous internal functions */ +/*@{*/ + +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +/** +Difference in successive opj_clock() calls tells you the elapsed time +@return Returns time in seconds +*/ +double opj_clock(void); + +/** +Allocate a memory block with elements initialized to 0 +@param size Bytes to allocate +@return Returns a void pointer to the allocated space, or NULL if there is insufficient memory available +*/ +void* opj_malloc( size_t size ); + +/** +Reallocate memory blocks. +@param memblock Pointer to previously allocated memory block +@param size New size in bytes +@return Returns a void pointer to the reallocated (and possibly moved) memory block +*/ +void* opj_realloc( void *memblock, size_t size ); + +/** +Deallocates or frees a memory block. +@param memblock Previously allocated memory block to be freed +*/ +void opj_free( void *memblock ); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __J3D_LIB_H */ + diff --git a/src/lib/openjp3d/mct.c b/src/lib/openjp3d/mct.c old mode 100755 new mode 100644 index e915e390..ccccdbc4 --- a/src/lib/openjp3d/mct.c +++ b/src/lib/openjp3d/mct.c @@ -1,131 +1,131 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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 "opj_includes.h" - -/* */ -/* This table contains the norms of the basis function of the reversible MCT. */ -/* */ -static const double mct_norms[3] = { 1.732, .8292, .8292 }; - -/* */ -/* This table contains the norms of the basis function of the irreversible MCT. */ -/* */ -static const double mct_norms_real[3] = { 1.732, 1.805, 1.573 }; - -/* */ -/* Foward reversible MCT. */ -/* */ -void mct_encode(int *c0, int *c1, int *c2, int n) { - int i; - for (i = 0; i < n; i++) { - int r, g, b, y, u, v; - r = c0[i]; - g = c1[i]; - b = c2[i]; - y = (r + (g << 1) + b) >> 2; - u = b - g; - v = r - g; - c0[i] = y; - c1[i] = u; - c2[i] = v; - } -} - -/* */ -/* Inverse reversible MCT. */ -/* */ -void mct_decode(int *c0, int *c1, int *c2, int n) { - int i; - for (i = 0; i < n; i++) { - int y, u, v, r, g, b; - y = c0[i]; - u = c1[i]; - v = c2[i]; - g = y - ((u + v) >> 2); - r = v + g; - b = u + g; - c0[i] = r; - c1[i] = g; - c2[i] = b; - } -} - -/* */ -/* Get norm of basis function of reversible MCT. */ -/* */ -double mct_getnorm(int compno) { - return mct_norms[compno]; -} - -/* */ -/* Foward irreversible MCT. */ -/* */ -void mct_encode_real(int *c0, int *c1, int *c2, int n) { - int i; - for (i = 0; i < n; i++) { - int r, g, b, y, u, v; - r = c0[i]; - g = c1[i]; - b = c2[i]; - y = fix_mul(r, 2449) + fix_mul(g, 4809) + fix_mul(b, 934); - u = -fix_mul(r, 1382) - fix_mul(g, 2714) + fix_mul(b, 4096); - v = fix_mul(r, 4096) - fix_mul(g, 3430) - fix_mul(b, 666); - c0[i] = y; - c1[i] = u; - c2[i] = v; - } -} - -/* */ -/* Inverse irreversible MCT. */ -/* */ -void mct_decode_real(int *c0, int *c1, int *c2, int n) { - int i; - for (i = 0; i < n; i++) { - int y, u, v, r, g, b; - y = c0[i]; - u = c1[i]; - v = c2[i]; - r = y + fix_mul(v, 11485); - g = y - fix_mul(u, 2819) - fix_mul(v, 5850); - b = y + fix_mul(u, 14516); - c0[i] = r; - c1[i] = g; - c2[i] = b; - } -} - -/* */ -/* Get norm of basis function of irreversible MCT. */ -/* */ -double mct_getnorm_real(int compno) { - return mct_norms_real[compno]; -} +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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 "opj_includes.h" + +/* */ +/* This table contains the norms of the basis function of the reversible MCT. */ +/* */ +static const double mct_norms[3] = { 1.732, .8292, .8292 }; + +/* */ +/* This table contains the norms of the basis function of the irreversible MCT. */ +/* */ +static const double mct_norms_real[3] = { 1.732, 1.805, 1.573 }; + +/* */ +/* Foward reversible MCT. */ +/* */ +void mct_encode(int *c0, int *c1, int *c2, int n) { + int i; + for (i = 0; i < n; i++) { + int r, g, b, y, u, v; + r = c0[i]; + g = c1[i]; + b = c2[i]; + y = (r + (g << 1) + b) >> 2; + u = b - g; + v = r - g; + c0[i] = y; + c1[i] = u; + c2[i] = v; + } +} + +/* */ +/* Inverse reversible MCT. */ +/* */ +void mct_decode(int *c0, int *c1, int *c2, int n) { + int i; + for (i = 0; i < n; i++) { + int y, u, v, r, g, b; + y = c0[i]; + u = c1[i]; + v = c2[i]; + g = y - ((u + v) >> 2); + r = v + g; + b = u + g; + c0[i] = r; + c1[i] = g; + c2[i] = b; + } +} + +/* */ +/* Get norm of basis function of reversible MCT. */ +/* */ +double mct_getnorm(int compno) { + return mct_norms[compno]; +} + +/* */ +/* Foward irreversible MCT. */ +/* */ +void mct_encode_real(int *c0, int *c1, int *c2, int n) { + int i; + for (i = 0; i < n; i++) { + int r, g, b, y, u, v; + r = c0[i]; + g = c1[i]; + b = c2[i]; + y = fix_mul(r, 2449) + fix_mul(g, 4809) + fix_mul(b, 934); + u = -fix_mul(r, 1382) - fix_mul(g, 2714) + fix_mul(b, 4096); + v = fix_mul(r, 4096) - fix_mul(g, 3430) - fix_mul(b, 666); + c0[i] = y; + c1[i] = u; + c2[i] = v; + } +} + +/* */ +/* Inverse irreversible MCT. */ +/* */ +void mct_decode_real(int *c0, int *c1, int *c2, int n) { + int i; + for (i = 0; i < n; i++) { + int y, u, v, r, g, b; + y = c0[i]; + u = c1[i]; + v = c2[i]; + r = y + fix_mul(v, 11485); + g = y - fix_mul(u, 2819) - fix_mul(v, 5850); + b = y + fix_mul(u, 14516); + c0[i] = r; + c1[i] = g; + c2[i] = b; + } +} + +/* */ +/* Get norm of basis function of irreversible MCT. */ +/* */ +double mct_getnorm_real(int compno) { + return mct_norms_real[compno]; +} diff --git a/src/lib/openjp3d/mct.h b/src/lib/openjp3d/mct.h old mode 100755 new mode 100644 index 0b8edb7b..e843aec9 --- a/src/lib/openjp3d/mct.h +++ b/src/lib/openjp3d/mct.h @@ -1,97 +1,97 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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. - */ - -#ifndef __MCT_H -#define __MCT_H -/** -@file mct.h -@brief Implementation of a multi-component transforms (MCT) - -The functions in MCT.C have for goal to realize reversible and irreversible multicomponent -transform. The functions in MCT.C are used by some function in TCD.C. -*/ - -/** @defgroup MCT MCT - Implementation of a multi-component transform */ -/*@{*/ - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Apply a reversible multi-component transform to an image -@param c0 Samples for red component -@param c1 Samples for green component -@param c2 Samples blue component -@param n Number of samples for each component -*/ -void mct_encode(int *c0, int *c1, int *c2, int n); -/** -Apply a reversible multi-component inverse transform to an image -@param c0 Samples for luminance component -@param c1 Samples for red chrominance component -@param c2 Samples for blue chrominance component -@param n Number of samples for each component -*/ -void mct_decode(int *c0, int *c1, int *c2, int n); -/** -Get norm of the basis function used for the reversible multi-component transform -@param compno Number of the component (0->Y, 1->U, 2->V) -@return -*/ -double mct_getnorm(int compno); - -/** -Apply an irreversible multi-component transform to an image -@param c0 Samples for red component -@param c1 Samples for green component -@param c2 Samples blue component -@param n Number of samples for each component -*/ -void mct_encode_real(int *c0, int *c1, int *c2, int n); -/** -Apply an irreversible multi-component inverse transform to an image -@param c0 Samples for luminance component -@param c1 Samples for red chrominance component -@param c2 Samples for blue chrominance component -@param n Number of samples for each component -*/ -void mct_decode_real(int *c0, int *c1, int *c2, int n); -/** -Get norm of the basis function used for the irreversible multi-component transform -@param compno Number of the component (0->Y, 1->U, 2->V) -@return -*/ -double mct_getnorm_real(int compno); -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __MCT_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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. + */ + +#ifndef __MCT_H +#define __MCT_H +/** +@file mct.h +@brief Implementation of a multi-component transforms (MCT) + +The functions in MCT.C have for goal to realize reversible and irreversible multicomponent +transform. The functions in MCT.C are used by some function in TCD.C. +*/ + +/** @defgroup MCT MCT - Implementation of a multi-component transform */ +/*@{*/ + +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Apply a reversible multi-component transform to an image +@param c0 Samples for red component +@param c1 Samples for green component +@param c2 Samples blue component +@param n Number of samples for each component +*/ +void mct_encode(int *c0, int *c1, int *c2, int n); +/** +Apply a reversible multi-component inverse transform to an image +@param c0 Samples for luminance component +@param c1 Samples for red chrominance component +@param c2 Samples for blue chrominance component +@param n Number of samples for each component +*/ +void mct_decode(int *c0, int *c1, int *c2, int n); +/** +Get norm of the basis function used for the reversible multi-component transform +@param compno Number of the component (0->Y, 1->U, 2->V) +@return +*/ +double mct_getnorm(int compno); + +/** +Apply an irreversible multi-component transform to an image +@param c0 Samples for red component +@param c1 Samples for green component +@param c2 Samples blue component +@param n Number of samples for each component +*/ +void mct_encode_real(int *c0, int *c1, int *c2, int n); +/** +Apply an irreversible multi-component inverse transform to an image +@param c0 Samples for luminance component +@param c1 Samples for red chrominance component +@param c2 Samples for blue chrominance component +@param n Number of samples for each component +*/ +void mct_decode_real(int *c0, int *c1, int *c2, int n); +/** +Get norm of the basis function used for the irreversible multi-component transform +@param compno Number of the component (0->Y, 1->U, 2->V) +@return +*/ +double mct_getnorm_real(int compno); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __MCT_H */ diff --git a/src/lib/openjp3d/mqc.c b/src/lib/openjp3d/mqc.c old mode 100755 new mode 100644 index 12ac90d6..874b7340 --- a/src/lib/openjp3d/mqc.c +++ b/src/lib/openjp3d/mqc.c @@ -1,548 +1,548 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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 "opj_includes.h" - -/** @defgroup MQC MQC - Implementation of an MQ-Coder */ -/*@{*/ - -/** @name Local static functions */ -/*@{*/ - -/** -Output a byte, doing bit-stuffing if necessary. -After a 0xff byte, the next byte must be smaller than 0x90. -@param mqc MQC handle -*/ -static void mqc_byteout(opj_mqc_t *mqc); -/** -Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000 -@param mqc MQC handle -*/ -static void mqc_renorme(opj_mqc_t *mqc); -/** -Encode the most probable symbol -@param mqc MQC handle -*/ -static void mqc_codemps(opj_mqc_t *mqc); -/** -Encode the most least symbol -@param mqc MQC handle -*/ -static void mqc_codelps(opj_mqc_t *mqc); -/** -Fill mqc->c with 1's for flushing -@param mqc MQC handle -*/ -static void mqc_setbits(opj_mqc_t *mqc); -/** -Exchange MPS with LPS -@param mqc MQC handle -@return -*/ -static int mqc_mpsexchange(opj_mqc_t *mqc); -/** -Exchange LPS with MPS -@param mqc MQC handle -@return -*/ -static int mqc_lpsexchange(opj_mqc_t *mqc); -/** -Input a byte -@param mqc MQC handle -*/ -static void mqc_bytein(opj_mqc_t *mqc); -/** -Renormalize mqc->a and mqc->c while decoding -@param mqc MQC handle -*/ -static void mqc_renormd(opj_mqc_t *mqc); - -/*@}*/ - -/*@}*/ - -/* */ -/* This array defines all the possible states for a context. */ -/* */ -static opj_mqc_state_t mqc_states[47 * 2] = { - {0x5601, 0, &mqc_states[2], &mqc_states[3]}, - {0x5601, 1, &mqc_states[3], &mqc_states[2]}, - {0x3401, 0, &mqc_states[4], &mqc_states[12]}, - {0x3401, 1, &mqc_states[5], &mqc_states[13]}, - {0x1801, 0, &mqc_states[6], &mqc_states[18]}, - {0x1801, 1, &mqc_states[7], &mqc_states[19]}, - {0x0ac1, 0, &mqc_states[8], &mqc_states[24]}, - {0x0ac1, 1, &mqc_states[9], &mqc_states[25]}, - {0x0521, 0, &mqc_states[10], &mqc_states[58]}, - {0x0521, 1, &mqc_states[11], &mqc_states[59]}, - {0x0221, 0, &mqc_states[76], &mqc_states[66]}, - {0x0221, 1, &mqc_states[77], &mqc_states[67]}, - {0x5601, 0, &mqc_states[14], &mqc_states[13]}, - {0x5601, 1, &mqc_states[15], &mqc_states[12]}, - {0x5401, 0, &mqc_states[16], &mqc_states[28]}, - {0x5401, 1, &mqc_states[17], &mqc_states[29]}, - {0x4801, 0, &mqc_states[18], &mqc_states[28]}, - {0x4801, 1, &mqc_states[19], &mqc_states[29]}, - {0x3801, 0, &mqc_states[20], &mqc_states[28]}, - {0x3801, 1, &mqc_states[21], &mqc_states[29]}, - {0x3001, 0, &mqc_states[22], &mqc_states[34]}, - {0x3001, 1, &mqc_states[23], &mqc_states[35]}, - {0x2401, 0, &mqc_states[24], &mqc_states[36]}, - {0x2401, 1, &mqc_states[25], &mqc_states[37]}, - {0x1c01, 0, &mqc_states[26], &mqc_states[40]}, - {0x1c01, 1, &mqc_states[27], &mqc_states[41]}, - {0x1601, 0, &mqc_states[58], &mqc_states[42]}, - {0x1601, 1, &mqc_states[59], &mqc_states[43]}, - {0x5601, 0, &mqc_states[30], &mqc_states[29]}, - {0x5601, 1, &mqc_states[31], &mqc_states[28]}, - {0x5401, 0, &mqc_states[32], &mqc_states[28]}, - {0x5401, 1, &mqc_states[33], &mqc_states[29]}, - {0x5101, 0, &mqc_states[34], &mqc_states[30]}, - {0x5101, 1, &mqc_states[35], &mqc_states[31]}, - {0x4801, 0, &mqc_states[36], &mqc_states[32]}, - {0x4801, 1, &mqc_states[37], &mqc_states[33]}, - {0x3801, 0, &mqc_states[38], &mqc_states[34]}, - {0x3801, 1, &mqc_states[39], &mqc_states[35]}, - {0x3401, 0, &mqc_states[40], &mqc_states[36]}, - {0x3401, 1, &mqc_states[41], &mqc_states[37]}, - {0x3001, 0, &mqc_states[42], &mqc_states[38]}, - {0x3001, 1, &mqc_states[43], &mqc_states[39]}, - {0x2801, 0, &mqc_states[44], &mqc_states[38]}, - {0x2801, 1, &mqc_states[45], &mqc_states[39]}, - {0x2401, 0, &mqc_states[46], &mqc_states[40]}, - {0x2401, 1, &mqc_states[47], &mqc_states[41]}, - {0x2201, 0, &mqc_states[48], &mqc_states[42]}, - {0x2201, 1, &mqc_states[49], &mqc_states[43]}, - {0x1c01, 0, &mqc_states[50], &mqc_states[44]}, - {0x1c01, 1, &mqc_states[51], &mqc_states[45]}, - {0x1801, 0, &mqc_states[52], &mqc_states[46]}, - {0x1801, 1, &mqc_states[53], &mqc_states[47]}, - {0x1601, 0, &mqc_states[54], &mqc_states[48]}, - {0x1601, 1, &mqc_states[55], &mqc_states[49]}, - {0x1401, 0, &mqc_states[56], &mqc_states[50]}, - {0x1401, 1, &mqc_states[57], &mqc_states[51]}, - {0x1201, 0, &mqc_states[58], &mqc_states[52]}, - {0x1201, 1, &mqc_states[59], &mqc_states[53]}, - {0x1101, 0, &mqc_states[60], &mqc_states[54]}, - {0x1101, 1, &mqc_states[61], &mqc_states[55]}, - {0x0ac1, 0, &mqc_states[62], &mqc_states[56]}, - {0x0ac1, 1, &mqc_states[63], &mqc_states[57]}, - {0x09c1, 0, &mqc_states[64], &mqc_states[58]}, - {0x09c1, 1, &mqc_states[65], &mqc_states[59]}, - {0x08a1, 0, &mqc_states[66], &mqc_states[60]}, - {0x08a1, 1, &mqc_states[67], &mqc_states[61]}, - {0x0521, 0, &mqc_states[68], &mqc_states[62]}, - {0x0521, 1, &mqc_states[69], &mqc_states[63]}, - {0x0441, 0, &mqc_states[70], &mqc_states[64]}, - {0x0441, 1, &mqc_states[71], &mqc_states[65]}, - {0x02a1, 0, &mqc_states[72], &mqc_states[66]}, - {0x02a1, 1, &mqc_states[73], &mqc_states[67]}, - {0x0221, 0, &mqc_states[74], &mqc_states[68]}, - {0x0221, 1, &mqc_states[75], &mqc_states[69]}, - {0x0141, 0, &mqc_states[76], &mqc_states[70]}, - {0x0141, 1, &mqc_states[77], &mqc_states[71]}, - {0x0111, 0, &mqc_states[78], &mqc_states[72]}, - {0x0111, 1, &mqc_states[79], &mqc_states[73]}, - {0x0085, 0, &mqc_states[80], &mqc_states[74]}, - {0x0085, 1, &mqc_states[81], &mqc_states[75]}, - {0x0049, 0, &mqc_states[82], &mqc_states[76]}, - {0x0049, 1, &mqc_states[83], &mqc_states[77]}, - {0x0025, 0, &mqc_states[84], &mqc_states[78]}, - {0x0025, 1, &mqc_states[85], &mqc_states[79]}, - {0x0015, 0, &mqc_states[86], &mqc_states[80]}, - {0x0015, 1, &mqc_states[87], &mqc_states[81]}, - {0x0009, 0, &mqc_states[88], &mqc_states[82]}, - {0x0009, 1, &mqc_states[89], &mqc_states[83]}, - {0x0005, 0, &mqc_states[90], &mqc_states[84]}, - {0x0005, 1, &mqc_states[91], &mqc_states[85]}, - {0x0001, 0, &mqc_states[90], &mqc_states[86]}, - {0x0001, 1, &mqc_states[91], &mqc_states[87]}, - {0x5601, 0, &mqc_states[92], &mqc_states[92]}, - {0x5601, 1, &mqc_states[93], &mqc_states[93]}, -}; - -/* -========================================================== - local functions -========================================================== -*/ - -static void mqc_byteout(opj_mqc_t *mqc) { - if (*mqc->bp == 0xff) { - mqc->bp++; - *mqc->bp = mqc->c >> 20; - mqc->c &= 0xfffff; - mqc->ct = 7; - } else { - if ((mqc->c & 0x8000000) == 0) { /* ((mqc->c&0x8000000)==0) CHANGE */ - mqc->bp++; - *mqc->bp = mqc->c >> 19; - mqc->c &= 0x7ffff; - mqc->ct = 8; - } else { - (*mqc->bp)++; - if (*mqc->bp == 0xff) { - mqc->c &= 0x7ffffff; - mqc->bp++; - *mqc->bp = mqc->c >> 20; - mqc->c &= 0xfffff; - mqc->ct = 7; - } else { - mqc->bp++; - *mqc->bp = mqc->c >> 19; - mqc->c &= 0x7ffff; - mqc->ct = 8; - } - } - } -} - -static void mqc_renorme(opj_mqc_t *mqc) { - do { - mqc->a <<= 1; - mqc->c <<= 1; - mqc->ct--; - if (mqc->ct == 0) { - mqc_byteout(mqc); - } - } while ((mqc->a & 0x8000) == 0); -} - -static void mqc_codemps(opj_mqc_t *mqc) { - mqc->a -= (*mqc->curctx)->qeval; - if ((mqc->a & 0x8000) == 0) { - if (mqc->a < (*mqc->curctx)->qeval) { - mqc->a = (*mqc->curctx)->qeval; - } else { - mqc->c += (*mqc->curctx)->qeval; - } - *mqc->curctx = (*mqc->curctx)->nmps; - mqc_renorme(mqc); - } else { - mqc->c += (*mqc->curctx)->qeval; - } -} - -static void mqc_codelps(opj_mqc_t *mqc) { - mqc->a -= (*mqc->curctx)->qeval; - if (mqc->a < (*mqc->curctx)->qeval) { - mqc->c += (*mqc->curctx)->qeval; - } else { - mqc->a = (*mqc->curctx)->qeval; - } - *mqc->curctx = (*mqc->curctx)->nlps; - mqc_renorme(mqc); -} - -static void mqc_setbits(opj_mqc_t *mqc) { - unsigned int tempc = mqc->c + mqc->a; - mqc->c |= 0xffff; - if (mqc->c >= tempc) { - mqc->c -= 0x8000; - } -} - -static int mqc_mpsexchange(opj_mqc_t *mqc) { - int d; - if (mqc->a < (*mqc->curctx)->qeval) { - d = 1 - (*mqc->curctx)->mps; - *mqc->curctx = (*mqc->curctx)->nlps; - } else { - d = (*mqc->curctx)->mps; - *mqc->curctx = (*mqc->curctx)->nmps; - } - - return d; -} - -static int mqc_lpsexchange(opj_mqc_t *mqc) { - int d; - if (mqc->a < (*mqc->curctx)->qeval) { - mqc->a = (*mqc->curctx)->qeval; - d = (*mqc->curctx)->mps; - *mqc->curctx = (*mqc->curctx)->nmps; - } else { - mqc->a = (*mqc->curctx)->qeval; - d = 1 - (*mqc->curctx)->mps; - *mqc->curctx = (*mqc->curctx)->nlps; - } - - return d; -} - -static void mqc_bytein(opj_mqc_t *mqc) { - if (mqc->bp != mqc->end) { - unsigned int c; - if (mqc->bp + 1 != mqc->end) { - c = *(mqc->bp + 1); - } else { - c = 0xff; - } - if (*mqc->bp == 0xff) { - if (c > 0x8f) { - mqc->c += 0xff00; - mqc->ct = 8; - } else { - mqc->bp++; - mqc->c += c << 9; - mqc->ct = 7; - } - } else { - mqc->bp++; - mqc->c += c << 8; - mqc->ct = 8; - } - } else { - mqc->c += 0xff00; - mqc->ct = 8; - } -} - -static void mqc_renormd(opj_mqc_t *mqc) { - do { - if (mqc->ct == 0) { - mqc_bytein(mqc); - } - mqc->a <<= 1; - mqc->c <<= 1; - mqc->ct--; - } while (mqc->a < 0x8000); -} - -/* -========================================================== - MQ-Coder interface -========================================================== -*/ - -opj_mqc_t* mqc_create() { - opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t)); - return mqc; -} - -void mqc_destroy(opj_mqc_t *mqc) { - if(mqc) { - opj_free(mqc); - } -} - -int mqc_numbytes(opj_mqc_t *mqc) { - return mqc->bp - mqc->start; -} - -void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp) { - mqc_setcurctx(mqc, 0); - mqc->a = 0x8000; - mqc->c = 0; - mqc->bp = bp - 1; - mqc->ct = 12; - if (*mqc->bp == 0xff) { - mqc->ct = 13; - } - mqc->start = bp; -} - -void mqc_setcurctx(opj_mqc_t *mqc, int ctxno) { - mqc->curctx = &mqc->ctxs[ctxno]; -} - -void mqc_encode(opj_mqc_t *mqc, int d) { - if ((*mqc->curctx)->mps == d) { - mqc_codemps(mqc); - } else { - mqc_codelps(mqc); - } -} - -void mqc_flush(opj_mqc_t *mqc) { - mqc_setbits(mqc); - mqc->c <<= mqc->ct; - mqc_byteout(mqc); - mqc->c <<= mqc->ct; - mqc_byteout(mqc); - - if (*mqc->bp != 0xff) { - mqc->bp++; - } -} - -void mqc_bypass_init_enc(opj_mqc_t *mqc) { - mqc->c = 0; - mqc->ct = 8; - /*if (*mqc->bp == 0xff) { - mqc->ct = 7; - } */ -} - -void mqc_bypass_enc(opj_mqc_t *mqc, int d) { - mqc->ct--; - mqc->c = mqc->c + (d << mqc->ct); - if (mqc->ct == 0) { - mqc->bp++; - *mqc->bp = mqc->c; - mqc->ct = 8; - if (*mqc->bp == 0xff) { - mqc->ct = 7; - } - mqc->c = 0; - } -} - -int mqc_bypass_flush_enc(opj_mqc_t *mqc) { - unsigned char bit_padding; - - bit_padding = 0; - - if (mqc->ct != 0) { - while (mqc->ct > 0) { - mqc->ct--; - mqc->c += bit_padding << mqc->ct; - bit_padding = (bit_padding + 1) & 0x01; - } - mqc->bp++; - *mqc->bp = mqc->c; - mqc->ct = 8; - mqc->c = 0; - } - - return 1; -} - -void mqc_reset_enc(opj_mqc_t *mqc) { - mqc_resetstates(mqc); - mqc_setstate(mqc, 18, 0, 46); - mqc_setstate(mqc, 0, 0, 3); - mqc_setstate(mqc, 1, 0, 4); -} - -void mqc_reset_enc_3(opj_mqc_t *mqc) { - mqc_resetstates(mqc); - mqc_setstate(mqc, T1_3D_CTXNO_UNI, 0, 46); - mqc_setstate(mqc, T1_3D_CTXNO_AGG, 0, 3); - mqc_setstate(mqc, T1_3D_CTXNO_ZC, 0, 4); -} - -int mqc_restart_enc(opj_mqc_t *mqc) { - int correction = 1; - - /* */ - int n = 27 - 15 - mqc->ct; - mqc->c <<= mqc->ct; - while (n > 0) { - mqc_byteout(mqc); - n -= mqc->ct; - mqc->c <<= mqc->ct; - } - mqc_byteout(mqc); - - return correction; -} - -void mqc_restart_init_enc(opj_mqc_t *mqc) { - /* */ - mqc_setcurctx(mqc, 0); - mqc->a = 0x8000; - mqc->c = 0; - mqc->ct = 12; - mqc->bp--; - if (*mqc->bp == 0xff) { - mqc->ct = 13; - } -} - -void mqc_erterm_enc(opj_mqc_t *mqc) { - int k = 11 - mqc->ct + 1; - - while (k > 0) { - mqc->c <<= mqc->ct; - mqc->ct = 0; - mqc_byteout(mqc); - k -= mqc->ct; - } - - if (*mqc->bp != 0xff) { - mqc_byteout(mqc); - } -} - -void mqc_segmark_enc(opj_mqc_t *mqc) { - int i; - mqc_setcurctx(mqc, 18); - - for (i = 1; i < 5; i++) { - mqc_encode(mqc, i % 2); - } -} - -void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) { - mqc_setcurctx(mqc, 0); - mqc->start = bp; - mqc->end = bp + len; - mqc->bp = bp; - if (len==0) mqc->c = 0xff << 16; - else mqc->c = *mqc->bp << 16; - mqc_bytein(mqc); - mqc->c <<= 7; - mqc->ct -= 7; - mqc->a = 0x8000; -} - -int mqc_decode(opj_mqc_t *mqc) { - int d; - mqc->a -= (*mqc->curctx)->qeval; - if ((mqc->c >> 16) < (*mqc->curctx)->qeval) { - d = mqc_lpsexchange(mqc); - mqc_renormd(mqc); - } else { - mqc->c -= (*mqc->curctx)->qeval << 16; - if ((mqc->a & 0x8000) == 0) { - d = mqc_mpsexchange(mqc); - mqc_renormd(mqc); - } else { - d = (*mqc->curctx)->mps; - } - } - - return d; -} - -void mqc_resetstates(opj_mqc_t *mqc) { - int i; - for (i = 0; i < MQC_NUMCTXS; i++) { - mqc->ctxs[i] = mqc_states; - } -} - -void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob) { - mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)]; -} - - +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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 "opj_includes.h" + +/** @defgroup MQC MQC - Implementation of an MQ-Coder */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +/** +Output a byte, doing bit-stuffing if necessary. +After a 0xff byte, the next byte must be smaller than 0x90. +@param mqc MQC handle +*/ +static void mqc_byteout(opj_mqc_t *mqc); +/** +Renormalize mqc->a and mqc->c while encoding, so that mqc->a stays between 0x8000 and 0x10000 +@param mqc MQC handle +*/ +static void mqc_renorme(opj_mqc_t *mqc); +/** +Encode the most probable symbol +@param mqc MQC handle +*/ +static void mqc_codemps(opj_mqc_t *mqc); +/** +Encode the most least symbol +@param mqc MQC handle +*/ +static void mqc_codelps(opj_mqc_t *mqc); +/** +Fill mqc->c with 1's for flushing +@param mqc MQC handle +*/ +static void mqc_setbits(opj_mqc_t *mqc); +/** +Exchange MPS with LPS +@param mqc MQC handle +@return +*/ +static int mqc_mpsexchange(opj_mqc_t *mqc); +/** +Exchange LPS with MPS +@param mqc MQC handle +@return +*/ +static int mqc_lpsexchange(opj_mqc_t *mqc); +/** +Input a byte +@param mqc MQC handle +*/ +static void mqc_bytein(opj_mqc_t *mqc); +/** +Renormalize mqc->a and mqc->c while decoding +@param mqc MQC handle +*/ +static void mqc_renormd(opj_mqc_t *mqc); + +/*@}*/ + +/*@}*/ + +/* */ +/* This array defines all the possible states for a context. */ +/* */ +static opj_mqc_state_t mqc_states[47 * 2] = { + {0x5601, 0, &mqc_states[2], &mqc_states[3]}, + {0x5601, 1, &mqc_states[3], &mqc_states[2]}, + {0x3401, 0, &mqc_states[4], &mqc_states[12]}, + {0x3401, 1, &mqc_states[5], &mqc_states[13]}, + {0x1801, 0, &mqc_states[6], &mqc_states[18]}, + {0x1801, 1, &mqc_states[7], &mqc_states[19]}, + {0x0ac1, 0, &mqc_states[8], &mqc_states[24]}, + {0x0ac1, 1, &mqc_states[9], &mqc_states[25]}, + {0x0521, 0, &mqc_states[10], &mqc_states[58]}, + {0x0521, 1, &mqc_states[11], &mqc_states[59]}, + {0x0221, 0, &mqc_states[76], &mqc_states[66]}, + {0x0221, 1, &mqc_states[77], &mqc_states[67]}, + {0x5601, 0, &mqc_states[14], &mqc_states[13]}, + {0x5601, 1, &mqc_states[15], &mqc_states[12]}, + {0x5401, 0, &mqc_states[16], &mqc_states[28]}, + {0x5401, 1, &mqc_states[17], &mqc_states[29]}, + {0x4801, 0, &mqc_states[18], &mqc_states[28]}, + {0x4801, 1, &mqc_states[19], &mqc_states[29]}, + {0x3801, 0, &mqc_states[20], &mqc_states[28]}, + {0x3801, 1, &mqc_states[21], &mqc_states[29]}, + {0x3001, 0, &mqc_states[22], &mqc_states[34]}, + {0x3001, 1, &mqc_states[23], &mqc_states[35]}, + {0x2401, 0, &mqc_states[24], &mqc_states[36]}, + {0x2401, 1, &mqc_states[25], &mqc_states[37]}, + {0x1c01, 0, &mqc_states[26], &mqc_states[40]}, + {0x1c01, 1, &mqc_states[27], &mqc_states[41]}, + {0x1601, 0, &mqc_states[58], &mqc_states[42]}, + {0x1601, 1, &mqc_states[59], &mqc_states[43]}, + {0x5601, 0, &mqc_states[30], &mqc_states[29]}, + {0x5601, 1, &mqc_states[31], &mqc_states[28]}, + {0x5401, 0, &mqc_states[32], &mqc_states[28]}, + {0x5401, 1, &mqc_states[33], &mqc_states[29]}, + {0x5101, 0, &mqc_states[34], &mqc_states[30]}, + {0x5101, 1, &mqc_states[35], &mqc_states[31]}, + {0x4801, 0, &mqc_states[36], &mqc_states[32]}, + {0x4801, 1, &mqc_states[37], &mqc_states[33]}, + {0x3801, 0, &mqc_states[38], &mqc_states[34]}, + {0x3801, 1, &mqc_states[39], &mqc_states[35]}, + {0x3401, 0, &mqc_states[40], &mqc_states[36]}, + {0x3401, 1, &mqc_states[41], &mqc_states[37]}, + {0x3001, 0, &mqc_states[42], &mqc_states[38]}, + {0x3001, 1, &mqc_states[43], &mqc_states[39]}, + {0x2801, 0, &mqc_states[44], &mqc_states[38]}, + {0x2801, 1, &mqc_states[45], &mqc_states[39]}, + {0x2401, 0, &mqc_states[46], &mqc_states[40]}, + {0x2401, 1, &mqc_states[47], &mqc_states[41]}, + {0x2201, 0, &mqc_states[48], &mqc_states[42]}, + {0x2201, 1, &mqc_states[49], &mqc_states[43]}, + {0x1c01, 0, &mqc_states[50], &mqc_states[44]}, + {0x1c01, 1, &mqc_states[51], &mqc_states[45]}, + {0x1801, 0, &mqc_states[52], &mqc_states[46]}, + {0x1801, 1, &mqc_states[53], &mqc_states[47]}, + {0x1601, 0, &mqc_states[54], &mqc_states[48]}, + {0x1601, 1, &mqc_states[55], &mqc_states[49]}, + {0x1401, 0, &mqc_states[56], &mqc_states[50]}, + {0x1401, 1, &mqc_states[57], &mqc_states[51]}, + {0x1201, 0, &mqc_states[58], &mqc_states[52]}, + {0x1201, 1, &mqc_states[59], &mqc_states[53]}, + {0x1101, 0, &mqc_states[60], &mqc_states[54]}, + {0x1101, 1, &mqc_states[61], &mqc_states[55]}, + {0x0ac1, 0, &mqc_states[62], &mqc_states[56]}, + {0x0ac1, 1, &mqc_states[63], &mqc_states[57]}, + {0x09c1, 0, &mqc_states[64], &mqc_states[58]}, + {0x09c1, 1, &mqc_states[65], &mqc_states[59]}, + {0x08a1, 0, &mqc_states[66], &mqc_states[60]}, + {0x08a1, 1, &mqc_states[67], &mqc_states[61]}, + {0x0521, 0, &mqc_states[68], &mqc_states[62]}, + {0x0521, 1, &mqc_states[69], &mqc_states[63]}, + {0x0441, 0, &mqc_states[70], &mqc_states[64]}, + {0x0441, 1, &mqc_states[71], &mqc_states[65]}, + {0x02a1, 0, &mqc_states[72], &mqc_states[66]}, + {0x02a1, 1, &mqc_states[73], &mqc_states[67]}, + {0x0221, 0, &mqc_states[74], &mqc_states[68]}, + {0x0221, 1, &mqc_states[75], &mqc_states[69]}, + {0x0141, 0, &mqc_states[76], &mqc_states[70]}, + {0x0141, 1, &mqc_states[77], &mqc_states[71]}, + {0x0111, 0, &mqc_states[78], &mqc_states[72]}, + {0x0111, 1, &mqc_states[79], &mqc_states[73]}, + {0x0085, 0, &mqc_states[80], &mqc_states[74]}, + {0x0085, 1, &mqc_states[81], &mqc_states[75]}, + {0x0049, 0, &mqc_states[82], &mqc_states[76]}, + {0x0049, 1, &mqc_states[83], &mqc_states[77]}, + {0x0025, 0, &mqc_states[84], &mqc_states[78]}, + {0x0025, 1, &mqc_states[85], &mqc_states[79]}, + {0x0015, 0, &mqc_states[86], &mqc_states[80]}, + {0x0015, 1, &mqc_states[87], &mqc_states[81]}, + {0x0009, 0, &mqc_states[88], &mqc_states[82]}, + {0x0009, 1, &mqc_states[89], &mqc_states[83]}, + {0x0005, 0, &mqc_states[90], &mqc_states[84]}, + {0x0005, 1, &mqc_states[91], &mqc_states[85]}, + {0x0001, 0, &mqc_states[90], &mqc_states[86]}, + {0x0001, 1, &mqc_states[91], &mqc_states[87]}, + {0x5601, 0, &mqc_states[92], &mqc_states[92]}, + {0x5601, 1, &mqc_states[93], &mqc_states[93]}, +}; + +/* +========================================================== + local functions +========================================================== +*/ + +static void mqc_byteout(opj_mqc_t *mqc) { + if (*mqc->bp == 0xff) { + mqc->bp++; + *mqc->bp = mqc->c >> 20; + mqc->c &= 0xfffff; + mqc->ct = 7; + } else { + if ((mqc->c & 0x8000000) == 0) { /* ((mqc->c&0x8000000)==0) CHANGE */ + mqc->bp++; + *mqc->bp = mqc->c >> 19; + mqc->c &= 0x7ffff; + mqc->ct = 8; + } else { + (*mqc->bp)++; + if (*mqc->bp == 0xff) { + mqc->c &= 0x7ffffff; + mqc->bp++; + *mqc->bp = mqc->c >> 20; + mqc->c &= 0xfffff; + mqc->ct = 7; + } else { + mqc->bp++; + *mqc->bp = mqc->c >> 19; + mqc->c &= 0x7ffff; + mqc->ct = 8; + } + } + } +} + +static void mqc_renorme(opj_mqc_t *mqc) { + do { + mqc->a <<= 1; + mqc->c <<= 1; + mqc->ct--; + if (mqc->ct == 0) { + mqc_byteout(mqc); + } + } while ((mqc->a & 0x8000) == 0); +} + +static void mqc_codemps(opj_mqc_t *mqc) { + mqc->a -= (*mqc->curctx)->qeval; + if ((mqc->a & 0x8000) == 0) { + if (mqc->a < (*mqc->curctx)->qeval) { + mqc->a = (*mqc->curctx)->qeval; + } else { + mqc->c += (*mqc->curctx)->qeval; + } + *mqc->curctx = (*mqc->curctx)->nmps; + mqc_renorme(mqc); + } else { + mqc->c += (*mqc->curctx)->qeval; + } +} + +static void mqc_codelps(opj_mqc_t *mqc) { + mqc->a -= (*mqc->curctx)->qeval; + if (mqc->a < (*mqc->curctx)->qeval) { + mqc->c += (*mqc->curctx)->qeval; + } else { + mqc->a = (*mqc->curctx)->qeval; + } + *mqc->curctx = (*mqc->curctx)->nlps; + mqc_renorme(mqc); +} + +static void mqc_setbits(opj_mqc_t *mqc) { + unsigned int tempc = mqc->c + mqc->a; + mqc->c |= 0xffff; + if (mqc->c >= tempc) { + mqc->c -= 0x8000; + } +} + +static int mqc_mpsexchange(opj_mqc_t *mqc) { + int d; + if (mqc->a < (*mqc->curctx)->qeval) { + d = 1 - (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nlps; + } else { + d = (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nmps; + } + + return d; +} + +static int mqc_lpsexchange(opj_mqc_t *mqc) { + int d; + if (mqc->a < (*mqc->curctx)->qeval) { + mqc->a = (*mqc->curctx)->qeval; + d = (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nmps; + } else { + mqc->a = (*mqc->curctx)->qeval; + d = 1 - (*mqc->curctx)->mps; + *mqc->curctx = (*mqc->curctx)->nlps; + } + + return d; +} + +static void mqc_bytein(opj_mqc_t *mqc) { + if (mqc->bp != mqc->end) { + unsigned int c; + if (mqc->bp + 1 != mqc->end) { + c = *(mqc->bp + 1); + } else { + c = 0xff; + } + if (*mqc->bp == 0xff) { + if (c > 0x8f) { + mqc->c += 0xff00; + mqc->ct = 8; + } else { + mqc->bp++; + mqc->c += c << 9; + mqc->ct = 7; + } + } else { + mqc->bp++; + mqc->c += c << 8; + mqc->ct = 8; + } + } else { + mqc->c += 0xff00; + mqc->ct = 8; + } +} + +static void mqc_renormd(opj_mqc_t *mqc) { + do { + if (mqc->ct == 0) { + mqc_bytein(mqc); + } + mqc->a <<= 1; + mqc->c <<= 1; + mqc->ct--; + } while (mqc->a < 0x8000); +} + +/* +========================================================== + MQ-Coder interface +========================================================== +*/ + +opj_mqc_t* mqc_create() { + opj_mqc_t *mqc = (opj_mqc_t*)opj_malloc(sizeof(opj_mqc_t)); + return mqc; +} + +void mqc_destroy(opj_mqc_t *mqc) { + if(mqc) { + opj_free(mqc); + } +} + +int mqc_numbytes(opj_mqc_t *mqc) { + return mqc->bp - mqc->start; +} + +void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp) { + mqc_setcurctx(mqc, 0); + mqc->a = 0x8000; + mqc->c = 0; + mqc->bp = bp - 1; + mqc->ct = 12; + if (*mqc->bp == 0xff) { + mqc->ct = 13; + } + mqc->start = bp; +} + +void mqc_setcurctx(opj_mqc_t *mqc, int ctxno) { + mqc->curctx = &mqc->ctxs[ctxno]; +} + +void mqc_encode(opj_mqc_t *mqc, int d) { + if ((*mqc->curctx)->mps == d) { + mqc_codemps(mqc); + } else { + mqc_codelps(mqc); + } +} + +void mqc_flush(opj_mqc_t *mqc) { + mqc_setbits(mqc); + mqc->c <<= mqc->ct; + mqc_byteout(mqc); + mqc->c <<= mqc->ct; + mqc_byteout(mqc); + + if (*mqc->bp != 0xff) { + mqc->bp++; + } +} + +void mqc_bypass_init_enc(opj_mqc_t *mqc) { + mqc->c = 0; + mqc->ct = 8; + /*if (*mqc->bp == 0xff) { + mqc->ct = 7; + } */ +} + +void mqc_bypass_enc(opj_mqc_t *mqc, int d) { + mqc->ct--; + mqc->c = mqc->c + (d << mqc->ct); + if (mqc->ct == 0) { + mqc->bp++; + *mqc->bp = mqc->c; + mqc->ct = 8; + if (*mqc->bp == 0xff) { + mqc->ct = 7; + } + mqc->c = 0; + } +} + +int mqc_bypass_flush_enc(opj_mqc_t *mqc) { + unsigned char bit_padding; + + bit_padding = 0; + + if (mqc->ct != 0) { + while (mqc->ct > 0) { + mqc->ct--; + mqc->c += bit_padding << mqc->ct; + bit_padding = (bit_padding + 1) & 0x01; + } + mqc->bp++; + *mqc->bp = mqc->c; + mqc->ct = 8; + mqc->c = 0; + } + + return 1; +} + +void mqc_reset_enc(opj_mqc_t *mqc) { + mqc_resetstates(mqc); + mqc_setstate(mqc, 18, 0, 46); + mqc_setstate(mqc, 0, 0, 3); + mqc_setstate(mqc, 1, 0, 4); +} + +void mqc_reset_enc_3(opj_mqc_t *mqc) { + mqc_resetstates(mqc); + mqc_setstate(mqc, T1_3D_CTXNO_UNI, 0, 46); + mqc_setstate(mqc, T1_3D_CTXNO_AGG, 0, 3); + mqc_setstate(mqc, T1_3D_CTXNO_ZC, 0, 4); +} + +int mqc_restart_enc(opj_mqc_t *mqc) { + int correction = 1; + + /* */ + int n = 27 - 15 - mqc->ct; + mqc->c <<= mqc->ct; + while (n > 0) { + mqc_byteout(mqc); + n -= mqc->ct; + mqc->c <<= mqc->ct; + } + mqc_byteout(mqc); + + return correction; +} + +void mqc_restart_init_enc(opj_mqc_t *mqc) { + /* */ + mqc_setcurctx(mqc, 0); + mqc->a = 0x8000; + mqc->c = 0; + mqc->ct = 12; + mqc->bp--; + if (*mqc->bp == 0xff) { + mqc->ct = 13; + } +} + +void mqc_erterm_enc(opj_mqc_t *mqc) { + int k = 11 - mqc->ct + 1; + + while (k > 0) { + mqc->c <<= mqc->ct; + mqc->ct = 0; + mqc_byteout(mqc); + k -= mqc->ct; + } + + if (*mqc->bp != 0xff) { + mqc_byteout(mqc); + } +} + +void mqc_segmark_enc(opj_mqc_t *mqc) { + int i; + mqc_setcurctx(mqc, 18); + + for (i = 1; i < 5; i++) { + mqc_encode(mqc, i % 2); + } +} + +void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) { + mqc_setcurctx(mqc, 0); + mqc->start = bp; + mqc->end = bp + len; + mqc->bp = bp; + if (len==0) mqc->c = 0xff << 16; + else mqc->c = *mqc->bp << 16; + mqc_bytein(mqc); + mqc->c <<= 7; + mqc->ct -= 7; + mqc->a = 0x8000; +} + +int mqc_decode(opj_mqc_t *mqc) { + int d; + mqc->a -= (*mqc->curctx)->qeval; + if ((mqc->c >> 16) < (*mqc->curctx)->qeval) { + d = mqc_lpsexchange(mqc); + mqc_renormd(mqc); + } else { + mqc->c -= (*mqc->curctx)->qeval << 16; + if ((mqc->a & 0x8000) == 0) { + d = mqc_mpsexchange(mqc); + mqc_renormd(mqc); + } else { + d = (*mqc->curctx)->mps; + } + } + + return d; +} + +void mqc_resetstates(opj_mqc_t *mqc) { + int i; + for (i = 0; i < MQC_NUMCTXS; i++) { + mqc->ctxs[i] = mqc_states; + } +} + +void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob) { + mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)]; +} + + diff --git a/src/lib/openjp3d/mqc.h b/src/lib/openjp3d/mqc.h old mode 100755 new mode 100644 index 023bf415..57bfc9f8 --- a/src/lib/openjp3d/mqc.h +++ b/src/lib/openjp3d/mqc.h @@ -1,201 +1,201 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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. - */ - -#ifndef __MQC_H -#define __MQC_H -/** -@file mqc.h -@brief Implementation of an MQ-Coder (MQC) - -The functions in MQC.C have for goal to realize the MQ-coder operations. The functions -in MQC.C are used by some function in T1.C. -*/ - -/** @defgroup MQC MQC - Implementation of an MQ-Coder */ -/*@{*/ - -/** -This struct defines the state of a context. -*/ -typedef struct opj_mqc_state { - /** the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */ - unsigned int qeval; - /** the Most Probable Symbol (0 or 1) */ - int mps; - /** next state if the next encoded symbol is the MPS */ - struct opj_mqc_state *nmps; - /** next state if the next encoded symbol is the LPS */ - struct opj_mqc_state *nlps; -} opj_mqc_state_t; - -#define MQC_NUMCTXS 32 - -/** -MQ coder -*/ -typedef struct opj_mqc { - unsigned int c; - unsigned int a; - unsigned int ct; - unsigned char *bp; - unsigned char *start; - unsigned char *end; - opj_mqc_state_t *ctxs[MQC_NUMCTXS]; - opj_mqc_state_t **curctx; -} opj_mqc_t; - -/** @name Exported functions */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Create a new MQC handle -@return Returns a new MQC handle if successful, returns NULL otherwise -*/ -opj_mqc_t* mqc_create(void); -/** -Destroy a previously created MQC handle -@param mqc MQC handle to destroy -*/ -void mqc_destroy(opj_mqc_t *mqc); -/** -Return the number of bytes written/read since initialisation -@param mqc MQC handle -@return Returns the number of bytes already encoded -*/ -int mqc_numbytes(opj_mqc_t *mqc); -/** -Reset the states of all the context of the coder/decoder -(each context is set to a state where 0 and 1 are more or less equiprobable) -@param mqc MQC handle -*/ -void mqc_resetstates(opj_mqc_t *mqc); -/** -Set the state of a particular context -@param mqc MQC handle -@param ctxno Number that identifies the context -@param msb The MSB of the new state of the context -@param prob Number that identifies the probability of the symbols for the new state of the context -*/ -void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob); -/** -Initialize the encoder -@param mqc MQC handle -@param bp Pointer to the start of the buffer where the bytes will be written -*/ -void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp); -/** -Set the current context used for coding/decoding -@param mqc MQC handle -@param ctxno Number that identifies the context -*/ -void mqc_setcurctx(opj_mqc_t *mqc, int ctxno); -/** -Encode a symbol using the MQ-coder -@param mqc MQC handle -@param d The symbol to be encoded (0 or 1) -*/ -void mqc_encode(opj_mqc_t *mqc, int d); -/** -Flush the encoder, so that all remaining data is written -@param mqc MQC handle -*/ -void mqc_flush(opj_mqc_t *mqc); -/** -BYPASS mode switch, initialization operation. -JPEG 2000 p 505. -

Not fully implemented and tested !!

-@param mqc MQC handle -*/ -void mqc_bypass_init_enc(opj_mqc_t *mqc); -/** -BYPASS mode switch, coding operation. -JPEG 2000 p 505. -

Not fully implemented and tested !!

-@param mqc MQC handle -@param d The symbol to be encoded (0 or 1) -*/ -void mqc_bypass_enc(opj_mqc_t *mqc, int d); -/** -BYPASS mode switch, flush operation -

Not fully implemented and tested !!

-@param mqc MQC handle -@return Returns 1 (always) -*/ -int mqc_bypass_flush_enc(opj_mqc_t *mqc); -/** -RESET mode switch -@param mqc MQC handle -*/ -void mqc_reset_enc(opj_mqc_t *mqc); -/** -RESET mode switch -@param mqc MQC handle -*/ -void mqc_reset_enc_3(opj_mqc_t *mqc); -/** -RESTART mode switch (TERMALL) -@param mqc MQC handle -@return Returns 1 (always) -*/ -int mqc_restart_enc(opj_mqc_t *mqc); -/** -RESTART mode switch (TERMALL) reinitialisation -@param mqc MQC handle -*/ -void mqc_restart_init_enc(opj_mqc_t *mqc); -/** -ERTERM mode switch (PTERM) -@param mqc MQC handle -*/ -void mqc_erterm_enc(opj_mqc_t *mqc); -/** -SEGMARK mode switch (SEGSYM) -@param mqc MQC handle -*/ -void mqc_segmark_enc(opj_mqc_t *mqc); -/** -Initialize the decoder -@param mqc MQC handle -@param bp Pointer to the start of the buffer from which the bytes will be read -@param len Length of the input buffer -*/ -void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len); -/** -Decode a symbol -@param mqc MQC handle -@return Returns the decoded symbol (0 or 1) -*/ -int mqc_decode(opj_mqc_t *mqc); -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __MQC_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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. + */ + +#ifndef __MQC_H +#define __MQC_H +/** +@file mqc.h +@brief Implementation of an MQ-Coder (MQC) + +The functions in MQC.C have for goal to realize the MQ-coder operations. The functions +in MQC.C are used by some function in T1.C. +*/ + +/** @defgroup MQC MQC - Implementation of an MQ-Coder */ +/*@{*/ + +/** +This struct defines the state of a context. +*/ +typedef struct opj_mqc_state { + /** the probability of the Least Probable Symbol (0.75->0x8000, 1.5->0xffff) */ + unsigned int qeval; + /** the Most Probable Symbol (0 or 1) */ + int mps; + /** next state if the next encoded symbol is the MPS */ + struct opj_mqc_state *nmps; + /** next state if the next encoded symbol is the LPS */ + struct opj_mqc_state *nlps; +} opj_mqc_state_t; + +#define MQC_NUMCTXS 32 + +/** +MQ coder +*/ +typedef struct opj_mqc { + unsigned int c; + unsigned int a; + unsigned int ct; + unsigned char *bp; + unsigned char *start; + unsigned char *end; + opj_mqc_state_t *ctxs[MQC_NUMCTXS]; + opj_mqc_state_t **curctx; +} opj_mqc_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new MQC handle +@return Returns a new MQC handle if successful, returns NULL otherwise +*/ +opj_mqc_t* mqc_create(void); +/** +Destroy a previously created MQC handle +@param mqc MQC handle to destroy +*/ +void mqc_destroy(opj_mqc_t *mqc); +/** +Return the number of bytes written/read since initialisation +@param mqc MQC handle +@return Returns the number of bytes already encoded +*/ +int mqc_numbytes(opj_mqc_t *mqc); +/** +Reset the states of all the context of the coder/decoder +(each context is set to a state where 0 and 1 are more or less equiprobable) +@param mqc MQC handle +*/ +void mqc_resetstates(opj_mqc_t *mqc); +/** +Set the state of a particular context +@param mqc MQC handle +@param ctxno Number that identifies the context +@param msb The MSB of the new state of the context +@param prob Number that identifies the probability of the symbols for the new state of the context +*/ +void mqc_setstate(opj_mqc_t *mqc, int ctxno, int msb, int prob); +/** +Initialize the encoder +@param mqc MQC handle +@param bp Pointer to the start of the buffer where the bytes will be written +*/ +void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp); +/** +Set the current context used for coding/decoding +@param mqc MQC handle +@param ctxno Number that identifies the context +*/ +void mqc_setcurctx(opj_mqc_t *mqc, int ctxno); +/** +Encode a symbol using the MQ-coder +@param mqc MQC handle +@param d The symbol to be encoded (0 or 1) +*/ +void mqc_encode(opj_mqc_t *mqc, int d); +/** +Flush the encoder, so that all remaining data is written +@param mqc MQC handle +*/ +void mqc_flush(opj_mqc_t *mqc); +/** +BYPASS mode switch, initialization operation. +JPEG 2000 p 505. +

Not fully implemented and tested !!

+@param mqc MQC handle +*/ +void mqc_bypass_init_enc(opj_mqc_t *mqc); +/** +BYPASS mode switch, coding operation. +JPEG 2000 p 505. +

Not fully implemented and tested !!

+@param mqc MQC handle +@param d The symbol to be encoded (0 or 1) +*/ +void mqc_bypass_enc(opj_mqc_t *mqc, int d); +/** +BYPASS mode switch, flush operation +

Not fully implemented and tested !!

+@param mqc MQC handle +@return Returns 1 (always) +*/ +int mqc_bypass_flush_enc(opj_mqc_t *mqc); +/** +RESET mode switch +@param mqc MQC handle +*/ +void mqc_reset_enc(opj_mqc_t *mqc); +/** +RESET mode switch +@param mqc MQC handle +*/ +void mqc_reset_enc_3(opj_mqc_t *mqc); +/** +RESTART mode switch (TERMALL) +@param mqc MQC handle +@return Returns 1 (always) +*/ +int mqc_restart_enc(opj_mqc_t *mqc); +/** +RESTART mode switch (TERMALL) reinitialisation +@param mqc MQC handle +*/ +void mqc_restart_init_enc(opj_mqc_t *mqc); +/** +ERTERM mode switch (PTERM) +@param mqc MQC handle +*/ +void mqc_erterm_enc(opj_mqc_t *mqc); +/** +SEGMARK mode switch (SEGSYM) +@param mqc MQC handle +*/ +void mqc_segmark_enc(opj_mqc_t *mqc); +/** +Initialize the decoder +@param mqc MQC handle +@param bp Pointer to the start of the buffer from which the bytes will be read +@param len Length of the input buffer +*/ +void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len); +/** +Decode a symbol +@param mqc MQC handle +@return Returns the decoded symbol (0 or 1) +*/ +int mqc_decode(opj_mqc_t *mqc); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __MQC_H */ diff --git a/src/lib/openjp3d/openjp3d.c b/src/lib/openjp3d/openjp3d.c old mode 100755 new mode 100644 index c1f3c44f..7adfbea0 --- a/src/lib/openjp3d/openjp3d.c +++ b/src/lib/openjp3d/openjp3d.c @@ -1,208 +1,208 @@ -/* - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifdef _WIN32 -#include -#endif /* _WIN32 */ - -#include "opj_includes.h" -#include "openjp3d.h" -#define JP3D_VERSION "1.3.0" -/* ---------------------------------------------------------------------- */ -#ifdef _WIN32 -#ifndef OPJ_STATIC -BOOL APIENTRY -DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - switch (ul_reason_for_call) { - case DLL_PROCESS_ATTACH : - break; - case DLL_PROCESS_DETACH : - break; - case DLL_THREAD_ATTACH : - case DLL_THREAD_DETACH : - break; - } - - return TRUE; -} -#endif /* OPJ_STATIC */ -#endif /* _WIN32 */ - -/* ---------------------------------------------------------------------- */ - -const char* OPJ_CALLCONV opj_version() { - return JP3D_VERSION; -} -opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) { - opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_malloc(sizeof(opj_dinfo_t)); - if(!dinfo) return NULL; - dinfo->is_decompressor = true; - switch(format) { - case CODEC_J3D: - case CODEC_J2K: - /* get a J3D decoder handle */ - dinfo->j3d_handle = (void*)j3d_create_decompress((opj_common_ptr)dinfo); - if(!dinfo->j3d_handle) { - opj_free(dinfo); - return NULL; - } - break; - default: - opj_free(dinfo); - return NULL; - } - - dinfo->codec_format = format; - - return dinfo; -} - -void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo) { - if(dinfo) { - /* destroy the codec */ - if(dinfo->codec_format != CODEC_UNKNOWN) { - j3d_destroy_decompress((opj_j3d_t*)dinfo->j3d_handle); - } - /* destroy the decompressor */ - opj_free(dinfo); - } -} - -void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters) { - if(parameters) { - memset(parameters, 0, sizeof(opj_dparameters_t)); - /* default decoding parameters */ - parameters->cp_layer = 0; - parameters->cp_reduce[0] = 0; - parameters->cp_reduce[1] = 0; - parameters->cp_reduce[2] = 0; - parameters->bigendian = 0; - - parameters->decod_format = -1; - parameters->cod_format = -1; - } -} - -void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters) { - if(dinfo && parameters) { - if (dinfo->codec_format != CODEC_UNKNOWN) { - j3d_setup_decoder((opj_j3d_t*)dinfo->j3d_handle, parameters); - } - } -} - -opj_volume_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) { - if(dinfo && cio) { - if (dinfo->codec_format != CODEC_UNKNOWN) { - return j3d_decode((opj_j3d_t*)dinfo->j3d_handle, cio); - } - } - - return NULL; -} - -opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) { - opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_malloc(sizeof(opj_cinfo_t)); - if(!cinfo) return NULL; - cinfo->is_decompressor = false; - switch(format) { - case CODEC_J3D: - case CODEC_J2K: - /* get a J3D coder handle */ - cinfo->j3d_handle = (void*)j3d_create_compress((opj_common_ptr)cinfo); - if(!cinfo->j3d_handle) { - opj_free(cinfo); - return NULL; - } - break; - default: - opj_free(cinfo); - return NULL; - } - - cinfo->codec_format = format; - - return cinfo; -} - -void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo) { - if(cinfo) { - /* destroy the codec */ - if (cinfo->codec_format != CODEC_UNKNOWN) { - j3d_destroy_compress((opj_j3d_t*)cinfo->j3d_handle); - } - /* destroy the decompressor */ - opj_free(cinfo); - } -} - -void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters) { - if(parameters) { - memset(parameters, 0, sizeof(opj_cparameters_t)); - /* default coding parameters */ - parameters->numresolution[0] = 3; - parameters->numresolution[1] = 3; - parameters->numresolution[2] = 1; - parameters->cblock_init[0] = 64; - parameters->cblock_init[1] = 64; - parameters->cblock_init[2] = 64; - parameters->prog_order = LRCP; - parameters->roi_compno = -1; /* no ROI */ - parameters->atk_wt[0] = 1; /* 5-3 WT */ - parameters->atk_wt[1] = 1; /* 5-3 WT */ - parameters->atk_wt[2] = 1; /* 5-3 WT */ - parameters->irreversible = 0; - parameters->subsampling_dx = 1; - parameters->subsampling_dy = 1; - parameters->subsampling_dz = 1; - - parameters->decod_format = -1; - parameters->cod_format = -1; - parameters->encoding_format = ENCOD_2EB; - parameters->transform_format = TRF_2D_DWT; - } -} - -void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_volume_t *volume) { - if(cinfo && parameters && volume) { - if (cinfo->codec_format != CODEC_UNKNOWN) { - j3d_setup_encoder((opj_j3d_t*)cinfo->j3d_handle, parameters, volume); - } - } -} - -bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_volume_t *volume, char *index) { - if(cinfo && cio && volume) { - if (cinfo->codec_format != CODEC_UNKNOWN) { - return j3d_encode((opj_j3d_t*)cinfo->j3d_handle, cio, volume, index); - } - } - - return false; -} - - +/* + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifdef _WIN32 +#include +#endif /* _WIN32 */ + +#include "opj_includes.h" +#include "openjp3d.h" +#define JP3D_VERSION "1.3.0" +/* ---------------------------------------------------------------------- */ +#ifdef _WIN32 +#ifndef OPJ_STATIC +BOOL APIENTRY +DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { + switch (ul_reason_for_call) { + case DLL_PROCESS_ATTACH : + break; + case DLL_PROCESS_DETACH : + break; + case DLL_THREAD_ATTACH : + case DLL_THREAD_DETACH : + break; + } + + return TRUE; +} +#endif /* OPJ_STATIC */ +#endif /* _WIN32 */ + +/* ---------------------------------------------------------------------- */ + +const char* OPJ_CALLCONV opj_version() { + return JP3D_VERSION; +} +opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) { + opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_malloc(sizeof(opj_dinfo_t)); + if(!dinfo) return NULL; + dinfo->is_decompressor = true; + switch(format) { + case CODEC_J3D: + case CODEC_J2K: + /* get a J3D decoder handle */ + dinfo->j3d_handle = (void*)j3d_create_decompress((opj_common_ptr)dinfo); + if(!dinfo->j3d_handle) { + opj_free(dinfo); + return NULL; + } + break; + default: + opj_free(dinfo); + return NULL; + } + + dinfo->codec_format = format; + + return dinfo; +} + +void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo) { + if(dinfo) { + /* destroy the codec */ + if(dinfo->codec_format != CODEC_UNKNOWN) { + j3d_destroy_decompress((opj_j3d_t*)dinfo->j3d_handle); + } + /* destroy the decompressor */ + opj_free(dinfo); + } +} + +void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters) { + if(parameters) { + memset(parameters, 0, sizeof(opj_dparameters_t)); + /* default decoding parameters */ + parameters->cp_layer = 0; + parameters->cp_reduce[0] = 0; + parameters->cp_reduce[1] = 0; + parameters->cp_reduce[2] = 0; + parameters->bigendian = 0; + + parameters->decod_format = -1; + parameters->cod_format = -1; + } +} + +void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters) { + if(dinfo && parameters) { + if (dinfo->codec_format != CODEC_UNKNOWN) { + j3d_setup_decoder((opj_j3d_t*)dinfo->j3d_handle, parameters); + } + } +} + +opj_volume_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) { + if(dinfo && cio) { + if (dinfo->codec_format != CODEC_UNKNOWN) { + return j3d_decode((opj_j3d_t*)dinfo->j3d_handle, cio); + } + } + + return NULL; +} + +opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) { + opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_malloc(sizeof(opj_cinfo_t)); + if(!cinfo) return NULL; + cinfo->is_decompressor = false; + switch(format) { + case CODEC_J3D: + case CODEC_J2K: + /* get a J3D coder handle */ + cinfo->j3d_handle = (void*)j3d_create_compress((opj_common_ptr)cinfo); + if(!cinfo->j3d_handle) { + opj_free(cinfo); + return NULL; + } + break; + default: + opj_free(cinfo); + return NULL; + } + + cinfo->codec_format = format; + + return cinfo; +} + +void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo) { + if(cinfo) { + /* destroy the codec */ + if (cinfo->codec_format != CODEC_UNKNOWN) { + j3d_destroy_compress((opj_j3d_t*)cinfo->j3d_handle); + } + /* destroy the decompressor */ + opj_free(cinfo); + } +} + +void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters) { + if(parameters) { + memset(parameters, 0, sizeof(opj_cparameters_t)); + /* default coding parameters */ + parameters->numresolution[0] = 3; + parameters->numresolution[1] = 3; + parameters->numresolution[2] = 1; + parameters->cblock_init[0] = 64; + parameters->cblock_init[1] = 64; + parameters->cblock_init[2] = 64; + parameters->prog_order = LRCP; + parameters->roi_compno = -1; /* no ROI */ + parameters->atk_wt[0] = 1; /* 5-3 WT */ + parameters->atk_wt[1] = 1; /* 5-3 WT */ + parameters->atk_wt[2] = 1; /* 5-3 WT */ + parameters->irreversible = 0; + parameters->subsampling_dx = 1; + parameters->subsampling_dy = 1; + parameters->subsampling_dz = 1; + + parameters->decod_format = -1; + parameters->cod_format = -1; + parameters->encoding_format = ENCOD_2EB; + parameters->transform_format = TRF_2D_DWT; + } +} + +void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_volume_t *volume) { + if(cinfo && parameters && volume) { + if (cinfo->codec_format != CODEC_UNKNOWN) { + j3d_setup_encoder((opj_j3d_t*)cinfo->j3d_handle, parameters, volume); + } + } +} + +bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_volume_t *volume, char *index) { + if(cinfo && cio && volume) { + if (cinfo->codec_format != CODEC_UNKNOWN) { + return j3d_encode((opj_j3d_t*)cinfo->j3d_handle, cio, volume, index); + } + } + + return false; +} + + diff --git a/src/lib/openjp3d/openjp3d.h b/src/lib/openjp3d/openjp3d.h old mode 100755 new mode 100644 index 44fe1f70..3657f92b --- a/src/lib/openjp3d/openjp3d.h +++ b/src/lib/openjp3d/openjp3d.h @@ -1,721 +1,721 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef OPENJPEG_H -#define OPENJPEG_H - -/* -========================================================== - Compiler directives -========================================================== -*/ - -#if defined(OPJ_STATIC) || !defined(_WIN32) -/* http://gcc.gnu.org/wiki/Visibility */ -#if __GNUC__ >= 4 -#define OPJ_API __attribute__ ((visibility ("default"))) -#define OPJ_LOCAL __attribute__ ((visibility ("hidden"))) -#else -#define OPJ_API -#define OPJ_LOCAL -#endif -#define OPJ_CALLCONV -#else -#define OPJ_CALLCONV __stdcall - -/* -The following ifdef block is the standard way of creating macros which make exporting -from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS -symbol defined on the command line. this symbol should not be defined on any project -that uses this DLL. This way any other project whose source files include this file see -OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols -defined with this macro as being exported. -*/ -#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT) -#define OPJ_API __declspec(dllexport) -#else -#define OPJ_API __declspec(dllimport) -#endif /* OPJ_EXPORTS */ -#endif /* !OPJ_STATIC || !WIN32 */ - -#ifndef __cplusplus -#if defined(HAVE_STDBOOL_H) -/* -The C language implementation does correctly provide the standard header -file "stdbool.h". - */ -#include -#else -/* -The C language implementation does not provide the standard header file -"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this -braindamage below. -*/ -#if !defined(bool) -#define bool int -#endif -#if !defined(true) -#define true 1 -#endif -#if !defined(false) -#define false 0 -#endif -#endif -#endif /* __cplusplus */ - -/* -========================================================== - Useful constant definitions -========================================================== -*/ -#ifndef MAX_SLICES -#define MAX_SLICES 300 /**< Maximum allowed size for slices */ -#endif /* MAX_PATH */ - -#ifndef MAX_PATH -#define MAX_PATH 260 /**< Maximum allowed size for filenames */ -#endif /* MAX_PATH */ - -#define J3D_MAXRLVLS 32 /**< Number of maximum resolution level authorized */ -#define J3D_MAXBANDS (7*J3D_MAXRLVLS + 1) /**< Number of maximum sub-band linked to number of resolution level */ - -#define TINY 1.0E-20 -/* -========================================================== - enum definitions -========================================================== -*/ - -#define J2K_CFMT 0 -#define J3D_CFMT 1 -#define LSE_CFMT 2 - -#define BIN_DFMT 0 -#define PGX_DFMT 1 -#define IMG_DFMT 2 -/* ----------------------------------------------------------------------- */ - -/** Progression order */ -typedef enum PROG_ORDER { -/**< place-holder */ - PROG_UNKNOWN = -1, -/**< layer-resolution-component-precinct order */ - LRCP = 0, -/**< resolution-layer-component-precinct order */ - RLCP = 1, -/**< resolution-precinct-component-layer order */ - RPCL = 2, -/**< precinct-component-resolution-layer order */ - PCRL = 3, -/**< component-precinct-resolution-layer order */ - CPRL = 4 -} OPJ_PROG_ORDER; - -/** -Supported volume color spaces -*/ -typedef enum COLOR_SPACE { -/**< place-holder */ - CLRSPC_UNKNOWN = -1, -/**< sRGB */ - CLRSPC_SRGB = 1, -/**< grayscale */ - CLRSPC_GRAY = 2, -/**< YUV */ - CLRSPC_SYCC = 3 -} OPJ_COLOR_SPACE; - -/** -Supported codec -*/ -typedef enum CODEC_FORMAT { - /**< place-holder */ - CODEC_UNKNOWN = -1, -/**< JPEG-2000 codestream : read/write */ - CODEC_J2K = 0, -/**< JPEG-2000 Part 10 file format : read/write */ - CODEC_J3D = 1 -} OPJ_CODEC_FORMAT; - -/** -Supported entropy coding algorithms -*/ -typedef enum ENTROPY_CODING { -/**< place-holder */ - ENCOD_UNKNOWN = -1, -/**< 2D EBCOT encoding */ - ENCOD_2EB = 0, -/**< 3D EBCOT encoding */ - ENCOD_3EB = 1, -/**< Golomb-Rice coding with 2D context */ - ENCOD_2GR = 2, -/**< Golomb-Rice coding with 3D context */ - ENCOD_3GR = 3 -} OPJ_ENTROPY_CODING; - -/** -Supported transforms -*/ -typedef enum TRANSFORM { -/**< place-holder */ - TRF_UNKNOWN = -1, -/**< 2D DWT, no transform in axial dim */ - TRF_2D_DWT = 0, -/**< 3D DWT */ - TRF_3D_DWT = 1, -/**< 3D prediction*/ - TRF_3D_RLS = 2, - TRF_3D_LSE = 3 -} OPJ_TRANSFORM; -/* -========================================================== - event manager typedef definitions -========================================================== -*/ - -/** -Callback function prototype for events -@param msg Event message -@param client_data -*/ -typedef void (*opj_msg_callback) (const char *msg, void *client_data); - -/** -Message handler object -used for -
    -
  • Error messages -
  • Warning messages -
  • Debugging messages -
-*/ -typedef struct opj_event_mgr { - /** Error message callback if available, NULL otherwise */ - opj_msg_callback error_handler; - /** Warning message callback if available, NULL otherwise */ - opj_msg_callback warning_handler; - /** Debug message callback if available, NULL otherwise */ - opj_msg_callback info_handler; -} opj_event_mgr_t; - - -/* -========================================================== - codec typedef definitions -========================================================== -*/ - -/** -Progression order changes -*/ -typedef struct opj_poc { - int resno0, compno0; - int layno1, resno1, compno1; - OPJ_PROG_ORDER prg; - int tile; - char progorder[4]; -} opj_poc_t; - - -/** -Compression parameters -*/ -typedef struct opj_cparameters { -/** size of tile: tile_size_on = false (not in argument) or = true (in argument) */ - bool tile_size_on; -/** XTOsiz */ - int cp_tx0; -/** YTOsiz */ - int cp_ty0; -/** ZTOsiz */ - int cp_tz0; - -/** XTsiz */ - int cp_tdx; -/** YTsiz */ - int cp_tdy; -/** ZTsiz */ - int cp_tdz; - -/** allocation by rate/distortion */ - int cp_disto_alloc; -/** allocation by fixed layer */ - int cp_fixed_alloc; -/** add fixed_quality */ - int cp_fixed_quality; -/** fixed layer */ - int *cp_matrice; -/** number of layers */ - int tcp_numlayers; -/** rates for successive layers */ - float tcp_rates[100]; -/** psnr's for successive layers */ - float tcp_distoratio[100]; -/** comment for coding */ - char *cp_comment; -/** csty : coding style */ - int csty; -/** DC offset (DCO) */ - int dcoffset; -/** progression order (default LRCP) */ - OPJ_PROG_ORDER prog_order; -/** progression order changes */ - opj_poc_t POC[J3D_MAXRLVLS-1]; -/** number of progression order changes (POC), default to 0 */ - int numpocs; - -/** number of resolutions */ - int numresolution[3]; -/** initial code block width, height and depth, default to 64 */ - int cblock_init[3]; -/** mode switch (1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL) 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)) */ - int mode; - -/** 1 : use the irreversible DWT 9-7, 0 : use lossless compression (default) */ - int irreversible; -/** WT from ATK, default to 0 (false), no of atk used */ - int atk_wt[3]; -/** region of interest: affected component in [0..3], -1 means no ROI */ - int roi_compno; -/** region of interest: upshift value */ - int roi_shift; - -/* number of precinct size specifications */ - int res_spec; -/** initial precinct width */ - int prct_init[3][J3D_MAXRLVLS]; - -/** transform format 0: 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */ - OPJ_TRANSFORM transform_format; -/** output file format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI */ - OPJ_ENTROPY_CODING encoding_format; - - /**@name command line encoder parameters (not used inside the library) */ - /*@{*/ - char infile[MAX_PATH]; /** input file name */ - char outfile[MAX_PATH]; /** output file name */ - char imgfile[MAX_PATH]; /** IMG file name for BIN volumes*/ - int index_on; /** creation of an index file, default to 0 (false) */ - char index[MAX_PATH]; /** index file name */ - - int volume_offset_x0; /** subvolume encoding: origin volume offset in x, y and z direction */ - int volume_offset_y0; - int volume_offset_z0; - - int subsampling_dx; /** subsampling value for dx */ - int subsampling_dy; - int subsampling_dz; - - int decod_format; /** input file format 0: BIN, 1: PGX */ - int cod_format; /** output file format 0: JP3D */ - /*@}*/ -} opj_cparameters_t; - -/** -Decompression parameters -*/ -typedef struct opj_dparameters { -/** Set the number of highest resolution levels to be discarded. if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, volume is decoded to the full resolution */ - int cp_reduce[3]; -/** Set the maximum number of quality layers to decode. if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ - int cp_layer; - int bigendian; - - /**@name command line encoder parameters (not used inside the library) */ - /*@{*/ -/** input file name */ - char infile[MAX_PATH]; -/** output file name */ - char outfile[MAX_PATH]; -/** IMG file name for BIN volumes*/ - char imgfile[MAX_PATH]; -/** Original file name for PSNR measures*/ - char original[MAX_PATH]; -/** input file format 0: J2K, 1: JP3D */ - int decod_format; -/** input file format 0: BIN, 1: PGM */ - int cod_format; -/** original file format 0: BIN, 1: PGM */ - int orig_format; - /*@}*/ -} opj_dparameters_t; - -/** Common fields between JPEG-2000 compression and decompression master structs. */ -#define opj_common_fields \ - opj_event_mgr_t *event_mgr; /**< pointer to the event manager */\ - void * client_data; /**< Available for use by application */\ - bool is_decompressor; /**< So common code can tell which is which */\ - OPJ_CODEC_FORMAT codec_format; /**< selected codec */\ - OPJ_ENTROPY_CODING encoding_format; /**< selected entropy coding */\ - OPJ_TRANSFORM transform_format; /**< selected transform */\ - void *j3d_handle /**< pointer to the J3D codec */ - -/* Routines that are to be used by both halves of the library are declared - * to receive a pointer to this structure. There are no actual instances of - * opj_common_struct_t, only of opj_cinfo_t and opj_dinfo_t. - */ -typedef struct opj_common_struct { - opj_common_fields; /* Fields common to both master struct types */ - /* Additional fields follow in an actual opj_cinfo_t or - * opj_dinfo_t. All three structs must agree on these - * initial fields! (This would be a lot cleaner in C++.) - */ -} opj_common_struct_t; - -typedef opj_common_struct_t * opj_common_ptr; - -/** -Compression context info -*/ -typedef struct opj_cinfo { - /** Fields shared with opj_dinfo_t */ - opj_common_fields; - /* other specific fields go here */ -} opj_cinfo_t; - -/** -Decompression context info -*/ -typedef struct opj_dinfo { - /** Fields shared with opj_cinfo_t */ - opj_common_fields; - /* other specific fields go here */ -} opj_dinfo_t; - -/* -========================================================== - I/O stream typedef definitions -========================================================== -*/ - -/* - * Stream open flags. - */ -/** The stream was opened for reading. */ -#define OPJ_STREAM_READ 0x0001 -/** The stream was opened for writing. */ -#define OPJ_STREAM_WRITE 0x0002 - -/** -Byte input-output stream (CIO) -*/ -typedef struct opj_cio { -/** codec context */ - opj_common_ptr cinfo; -/** open mode (read/write) either OPJ_STREAM_READ or OPJ_STREAM_WRITE */ - int openmode; -/** pointer to the start of the buffer */ - unsigned char *buffer; -/** buffer size in bytes */ - int length; -/** pointer to the start of the stream */ - unsigned char *start; -/** pointer to the end of the stream */ - unsigned char *end; -/** pointer to the current position */ - unsigned char *bp; -} opj_cio_t; - -/* -========================================================== - volume typedef definitions -========================================================== -*/ - -/** -Defines a single volume component -*/ -typedef struct opj_volume_comp { -/** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */ - int dx; -/** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */ - int dy; -/** ZRsiz: vertical separation of a sample of ith component with respect to the reference grid */ - int dz; -/** data width */ - int w; - /** data height */ - int h; - /** data length : no of slices */ - int l; - /** x component offset compared to the whole volume */ - int x0; - /** y component offset compared to the whole volume */ - int y0; - /** z component offset compared to the whole volume */ - int z0; - /** precision */ - int prec; - /** volume depth in bits */ - int bpp; - /** DC offset (15444-2) */ - int dcoffset; - /** signed (1) / unsigned (0) */ - int sgnd; - /** BE byte order (1) / LE byte order (0) */ - int bigendian; - /** number of decoded resolution */ - int resno_decoded[3]; - /** number of division by 2 of the out volume compared to the original size of volume */ - int factor[3]; - /** volume component data */ - int *data; -} opj_volume_comp_t; - -/** -Defines volume data and characteristics -*/ -typedef struct opj_volume { -/** XOsiz: horizontal offset from the origin of the reference grid to the left side of the volume area */ - int x0; -/** YOsiz: vertical offset from the origin of the reference grid to the top side of the volume area */ - int y0; -/** ZOsiz: vertical offset from the origin of the reference grid to the top side of the volume area */ - int z0; -/** Xsiz: width of the reference grid */ - int x1; -/** Ysiz: height of the reference grid */ - int y1; -/** Zsiz: length of the reference grid */ - int z1; -/** number of components in the volume */ - int numcomps; -/** number of slices in the volume */ - int numslices; -/** color space: sRGB, Greyscale or YUV */ - OPJ_COLOR_SPACE color_space; -/** volume components */ - opj_volume_comp_t *comps; -} opj_volume_t; - -/** -Component parameters structure used by the opj_volume_create function -*/ -typedef struct opj_volume_comptparm { - /** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */ - int dx; - /** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */ - int dy; - /** ZRsiz: axial separation of a sample of ith component with respect to the reference grid */ - int dz; - /** data width */ - int w; - /** data height */ - int h; - /** data length */ - int l; - /** x component offset compared to the whole volume */ - int x0; - /** y component offset compared to the whole volume */ - int y0; - /** z component offset compared to the whole volume */ - int z0; - /** precision */ - int prec; - /** volume depth in bits */ - int bpp; - /** signed (1) / unsigned (0) */ - int sgnd; - /** DC offset*/ - int dcoffset; - /** BE byte order (1) / LE byte order (0) */ - int bigendian; -} opj_volume_cmptparm_t; - -#ifdef __cplusplus -extern "C" { -#endif - - -/* -========================================================== - openjpeg version -========================================================== -*/ - -OPJ_API const char * OPJ_CALLCONV opj_version(void); - -/* -========================================================== - volume functions definitions -========================================================== -*/ - -/** -Create an volume -@param numcmpts number of components -@param cmptparms components parameters -@param clrspc volume color space -@return returns a new volume structure if successful, returns NULL otherwise -*/ -OPJ_API opj_volume_t* OPJ_CALLCONV opj_volume_create(int numcmpts, opj_volume_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc); - -/** -Deallocate any resources associated with an volume -@param volume volume to be destroyed -*/ -OPJ_API void OPJ_CALLCONV opj_volume_destroy(opj_volume_t *volume); - -/* -========================================================== - stream functions definitions -========================================================== -*/ - -/** -Open and allocate a memory stream for read / write. -On reading, the user must provide a buffer containing encoded data. The buffer will be -wrapped by the returned CIO handle. -On writing, buffer parameters must be set to 0: a buffer will be allocated by the library -to contain encoded data. -@param cinfo Codec context info -@param buffer Reading: buffer address. Writing: NULL -@param length Reading: buffer length. Writing: 0 -@return Returns a CIO handle if successful, returns NULL otherwise -*/ -OPJ_API opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length); - -/** -Close and free a CIO handle -@param cio CIO handle to free -*/ -OPJ_API void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio); - -/** -Get position in byte stream -@param cio CIO handle -@return Returns the position in bytes -*/ -OPJ_API int OPJ_CALLCONV cio_tell(opj_cio_t *cio); -/** -Set position in byte stream -@param cio CIO handle -@param pos Position, in number of bytes, from the beginning of the stream -*/ -OPJ_API void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos); - -/* -========================================================== - event manager functions definitions -========================================================== -*/ - -OPJ_API opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context); - -/* -========================================================== - codec functions definitions -========================================================== -*/ -/** -Creates a J3D decompression structure -@param format Decoder to select -@return Returns a handle to a decompressor if successful, returns NULL otherwise -*/ -OPJ_API opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format); -/** -Destroy a decompressor handle -@param dinfo decompressor handle to destroy -*/ -OPJ_API void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo); -/** -Set decoding parameters to default values -@param parameters Decompression parameters -*/ -OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters); -/** -Setup the decoder decoding parameters using user parameters. -Decoding parameters are returned in j3d->cp. -@param dinfo decompressor handle -@param parameters decompression parameters -*/ -OPJ_API void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters); -/** -Decode an volume from a JPEG-2000 codestream -@param dinfo decompressor handle -@param cio Input buffer stream -@return Returns a decoded volume if successful, returns NULL otherwise -*/ -OPJ_API opj_volume_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio); -/** -Creates a J3D/JP2 compression structure -@param format Coder to select -@return Returns a handle to a compressor if successful, returns NULL otherwise -*/ -OPJ_API opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format); -/** -Destroy a compressor handle -@param cinfo compressor handle to destroy -*/ -OPJ_API void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo); -/** -Set encoding parameters to default values, that means : -
    -
  • Lossless -
  • 1 tile -
  • Size of precinct : 2^15 x 2^15 (means 1 precinct) -
  • Size of code-block : 64 x 64 -
  • Number of resolutions: 6 -
  • No SOP marker in the codestream -
  • No EPH marker in the codestream -
  • No sub-sampling in x or y direction -
  • No mode switch activated -
  • Progression order: LRCP -
  • No index file -
  • No ROI upshifted -
  • No offset of the origin of the volume -
  • No offset of the origin of the tiles -
  • Reversible DWT 5-3 -
-@param parameters Compression parameters -*/ -OPJ_API void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters); -/** -Setup the encoder parameters using the current volume and using user parameters. -@param cinfo compressor handle -@param parameters compression parameters -@param volume input filled volume -*/ -OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_volume_t *volume); -/** -Encode an volume into a JPEG-2000 codestream -@param cinfo compressor handle -@param cio Output buffer stream -@param volume Volume to encode -@param index Name of the index file if required, NULL otherwise -@return Returns true if successful, returns false otherwise -*/ -OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_volume_t *volume, char *index); - -#ifdef __cplusplus -} -#endif - -#endif /* OPENJPEG_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef OPENJPEG_H +#define OPENJPEG_H + +/* +========================================================== + Compiler directives +========================================================== +*/ + +#if defined(OPJ_STATIC) || !defined(_WIN32) +/* http://gcc.gnu.org/wiki/Visibility */ +#if __GNUC__ >= 4 +#define OPJ_API __attribute__ ((visibility ("default"))) +#define OPJ_LOCAL __attribute__ ((visibility ("hidden"))) +#else +#define OPJ_API +#define OPJ_LOCAL +#endif +#define OPJ_CALLCONV +#else +#define OPJ_CALLCONV __stdcall + +/* +The following ifdef block is the standard way of creating macros which make exporting +from a DLL simpler. All files within this DLL are compiled with the OPJ_EXPORTS +symbol defined on the command line. this symbol should not be defined on any project +that uses this DLL. This way any other project whose source files include this file see +OPJ_API functions as being imported from a DLL, wheras this DLL sees symbols +defined with this macro as being exported. +*/ +#if defined(OPJ_EXPORTS) || defined(DLL_EXPORT) +#define OPJ_API __declspec(dllexport) +#else +#define OPJ_API __declspec(dllimport) +#endif /* OPJ_EXPORTS */ +#endif /* !OPJ_STATIC || !WIN32 */ + +#ifndef __cplusplus +#if defined(HAVE_STDBOOL_H) +/* +The C language implementation does correctly provide the standard header +file "stdbool.h". + */ +#include +#else +/* +The C language implementation does not provide the standard header file +"stdbool.h" as required by ISO/IEC 9899:1999. Try to compensate for this +braindamage below. +*/ +#if !defined(bool) +#define bool int +#endif +#if !defined(true) +#define true 1 +#endif +#if !defined(false) +#define false 0 +#endif +#endif +#endif /* __cplusplus */ + +/* +========================================================== + Useful constant definitions +========================================================== +*/ +#ifndef MAX_SLICES +#define MAX_SLICES 300 /**< Maximum allowed size for slices */ +#endif /* MAX_PATH */ + +#ifndef MAX_PATH +#define MAX_PATH 260 /**< Maximum allowed size for filenames */ +#endif /* MAX_PATH */ + +#define J3D_MAXRLVLS 32 /**< Number of maximum resolution level authorized */ +#define J3D_MAXBANDS (7*J3D_MAXRLVLS + 1) /**< Number of maximum sub-band linked to number of resolution level */ + +#define TINY 1.0E-20 +/* +========================================================== + enum definitions +========================================================== +*/ + +#define J2K_CFMT 0 +#define J3D_CFMT 1 +#define LSE_CFMT 2 + +#define BIN_DFMT 0 +#define PGX_DFMT 1 +#define IMG_DFMT 2 +/* ----------------------------------------------------------------------- */ + +/** Progression order */ +typedef enum PROG_ORDER { +/**< place-holder */ + PROG_UNKNOWN = -1, +/**< layer-resolution-component-precinct order */ + LRCP = 0, +/**< resolution-layer-component-precinct order */ + RLCP = 1, +/**< resolution-precinct-component-layer order */ + RPCL = 2, +/**< precinct-component-resolution-layer order */ + PCRL = 3, +/**< component-precinct-resolution-layer order */ + CPRL = 4 +} OPJ_PROG_ORDER; + +/** +Supported volume color spaces +*/ +typedef enum COLOR_SPACE { +/**< place-holder */ + CLRSPC_UNKNOWN = -1, +/**< sRGB */ + CLRSPC_SRGB = 1, +/**< grayscale */ + CLRSPC_GRAY = 2, +/**< YUV */ + CLRSPC_SYCC = 3 +} OPJ_COLOR_SPACE; + +/** +Supported codec +*/ +typedef enum CODEC_FORMAT { + /**< place-holder */ + CODEC_UNKNOWN = -1, +/**< JPEG-2000 codestream : read/write */ + CODEC_J2K = 0, +/**< JPEG-2000 Part 10 file format : read/write */ + CODEC_J3D = 1 +} OPJ_CODEC_FORMAT; + +/** +Supported entropy coding algorithms +*/ +typedef enum ENTROPY_CODING { +/**< place-holder */ + ENCOD_UNKNOWN = -1, +/**< 2D EBCOT encoding */ + ENCOD_2EB = 0, +/**< 3D EBCOT encoding */ + ENCOD_3EB = 1, +/**< Golomb-Rice coding with 2D context */ + ENCOD_2GR = 2, +/**< Golomb-Rice coding with 3D context */ + ENCOD_3GR = 3 +} OPJ_ENTROPY_CODING; + +/** +Supported transforms +*/ +typedef enum TRANSFORM { +/**< place-holder */ + TRF_UNKNOWN = -1, +/**< 2D DWT, no transform in axial dim */ + TRF_2D_DWT = 0, +/**< 3D DWT */ + TRF_3D_DWT = 1, +/**< 3D prediction*/ + TRF_3D_RLS = 2, + TRF_3D_LSE = 3 +} OPJ_TRANSFORM; +/* +========================================================== + event manager typedef definitions +========================================================== +*/ + +/** +Callback function prototype for events +@param msg Event message +@param client_data +*/ +typedef void (*opj_msg_callback) (const char *msg, void *client_data); + +/** +Message handler object +used for +
    +
  • Error messages +
  • Warning messages +
  • Debugging messages +
+*/ +typedef struct opj_event_mgr { + /** Error message callback if available, NULL otherwise */ + opj_msg_callback error_handler; + /** Warning message callback if available, NULL otherwise */ + opj_msg_callback warning_handler; + /** Debug message callback if available, NULL otherwise */ + opj_msg_callback info_handler; +} opj_event_mgr_t; + + +/* +========================================================== + codec typedef definitions +========================================================== +*/ + +/** +Progression order changes +*/ +typedef struct opj_poc { + int resno0, compno0; + int layno1, resno1, compno1; + OPJ_PROG_ORDER prg; + int tile; + char progorder[4]; +} opj_poc_t; + + +/** +Compression parameters +*/ +typedef struct opj_cparameters { +/** size of tile: tile_size_on = false (not in argument) or = true (in argument) */ + bool tile_size_on; +/** XTOsiz */ + int cp_tx0; +/** YTOsiz */ + int cp_ty0; +/** ZTOsiz */ + int cp_tz0; + +/** XTsiz */ + int cp_tdx; +/** YTsiz */ + int cp_tdy; +/** ZTsiz */ + int cp_tdz; + +/** allocation by rate/distortion */ + int cp_disto_alloc; +/** allocation by fixed layer */ + int cp_fixed_alloc; +/** add fixed_quality */ + int cp_fixed_quality; +/** fixed layer */ + int *cp_matrice; +/** number of layers */ + int tcp_numlayers; +/** rates for successive layers */ + float tcp_rates[100]; +/** psnr's for successive layers */ + float tcp_distoratio[100]; +/** comment for coding */ + char *cp_comment; +/** csty : coding style */ + int csty; +/** DC offset (DCO) */ + int dcoffset; +/** progression order (default LRCP) */ + OPJ_PROG_ORDER prog_order; +/** progression order changes */ + opj_poc_t POC[J3D_MAXRLVLS-1]; +/** number of progression order changes (POC), default to 0 */ + int numpocs; + +/** number of resolutions */ + int numresolution[3]; +/** initial code block width, height and depth, default to 64 */ + int cblock_init[3]; +/** mode switch (1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL) 8=VSC 16=ERTERM(SEGTERM) 32=SEGMARK(SEGSYM)) */ + int mode; + +/** 1 : use the irreversible DWT 9-7, 0 : use lossless compression (default) */ + int irreversible; +/** WT from ATK, default to 0 (false), no of atk used */ + int atk_wt[3]; +/** region of interest: affected component in [0..3], -1 means no ROI */ + int roi_compno; +/** region of interest: upshift value */ + int roi_shift; + +/* number of precinct size specifications */ + int res_spec; +/** initial precinct width */ + int prct_init[3][J3D_MAXRLVLS]; + +/** transform format 0: 0: 2DWT, 1: 2D1P, 2: 3DWT, 3: 3RLS */ + OPJ_TRANSFORM transform_format; +/** output file format 0: 2EB, 1: 3EB, 2: 2GR, 3: 3GR, 4: GRI */ + OPJ_ENTROPY_CODING encoding_format; + + /**@name command line encoder parameters (not used inside the library) */ + /*@{*/ + char infile[MAX_PATH]; /** input file name */ + char outfile[MAX_PATH]; /** output file name */ + char imgfile[MAX_PATH]; /** IMG file name for BIN volumes*/ + int index_on; /** creation of an index file, default to 0 (false) */ + char index[MAX_PATH]; /** index file name */ + + int volume_offset_x0; /** subvolume encoding: origin volume offset in x, y and z direction */ + int volume_offset_y0; + int volume_offset_z0; + + int subsampling_dx; /** subsampling value for dx */ + int subsampling_dy; + int subsampling_dz; + + int decod_format; /** input file format 0: BIN, 1: PGX */ + int cod_format; /** output file format 0: JP3D */ + /*@}*/ +} opj_cparameters_t; + +/** +Decompression parameters +*/ +typedef struct opj_dparameters { +/** Set the number of highest resolution levels to be discarded. if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, volume is decoded to the full resolution */ + int cp_reduce[3]; +/** Set the maximum number of quality layers to decode. if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ + int cp_layer; + int bigendian; + + /**@name command line encoder parameters (not used inside the library) */ + /*@{*/ +/** input file name */ + char infile[MAX_PATH]; +/** output file name */ + char outfile[MAX_PATH]; +/** IMG file name for BIN volumes*/ + char imgfile[MAX_PATH]; +/** Original file name for PSNR measures*/ + char original[MAX_PATH]; +/** input file format 0: J2K, 1: JP3D */ + int decod_format; +/** input file format 0: BIN, 1: PGM */ + int cod_format; +/** original file format 0: BIN, 1: PGM */ + int orig_format; + /*@}*/ +} opj_dparameters_t; + +/** Common fields between JPEG-2000 compression and decompression master structs. */ +#define opj_common_fields \ + opj_event_mgr_t *event_mgr; /**< pointer to the event manager */\ + void * client_data; /**< Available for use by application */\ + bool is_decompressor; /**< So common code can tell which is which */\ + OPJ_CODEC_FORMAT codec_format; /**< selected codec */\ + OPJ_ENTROPY_CODING encoding_format; /**< selected entropy coding */\ + OPJ_TRANSFORM transform_format; /**< selected transform */\ + void *j3d_handle /**< pointer to the J3D codec */ + +/* Routines that are to be used by both halves of the library are declared + * to receive a pointer to this structure. There are no actual instances of + * opj_common_struct_t, only of opj_cinfo_t and opj_dinfo_t. + */ +typedef struct opj_common_struct { + opj_common_fields; /* Fields common to both master struct types */ + /* Additional fields follow in an actual opj_cinfo_t or + * opj_dinfo_t. All three structs must agree on these + * initial fields! (This would be a lot cleaner in C++.) + */ +} opj_common_struct_t; + +typedef opj_common_struct_t * opj_common_ptr; + +/** +Compression context info +*/ +typedef struct opj_cinfo { + /** Fields shared with opj_dinfo_t */ + opj_common_fields; + /* other specific fields go here */ +} opj_cinfo_t; + +/** +Decompression context info +*/ +typedef struct opj_dinfo { + /** Fields shared with opj_cinfo_t */ + opj_common_fields; + /* other specific fields go here */ +} opj_dinfo_t; + +/* +========================================================== + I/O stream typedef definitions +========================================================== +*/ + +/* + * Stream open flags. + */ +/** The stream was opened for reading. */ +#define OPJ_STREAM_READ 0x0001 +/** The stream was opened for writing. */ +#define OPJ_STREAM_WRITE 0x0002 + +/** +Byte input-output stream (CIO) +*/ +typedef struct opj_cio { +/** codec context */ + opj_common_ptr cinfo; +/** open mode (read/write) either OPJ_STREAM_READ or OPJ_STREAM_WRITE */ + int openmode; +/** pointer to the start of the buffer */ + unsigned char *buffer; +/** buffer size in bytes */ + int length; +/** pointer to the start of the stream */ + unsigned char *start; +/** pointer to the end of the stream */ + unsigned char *end; +/** pointer to the current position */ + unsigned char *bp; +} opj_cio_t; + +/* +========================================================== + volume typedef definitions +========================================================== +*/ + +/** +Defines a single volume component +*/ +typedef struct opj_volume_comp { +/** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */ + int dx; +/** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */ + int dy; +/** ZRsiz: vertical separation of a sample of ith component with respect to the reference grid */ + int dz; +/** data width */ + int w; + /** data height */ + int h; + /** data length : no of slices */ + int l; + /** x component offset compared to the whole volume */ + int x0; + /** y component offset compared to the whole volume */ + int y0; + /** z component offset compared to the whole volume */ + int z0; + /** precision */ + int prec; + /** volume depth in bits */ + int bpp; + /** DC offset (15444-2) */ + int dcoffset; + /** signed (1) / unsigned (0) */ + int sgnd; + /** BE byte order (1) / LE byte order (0) */ + int bigendian; + /** number of decoded resolution */ + int resno_decoded[3]; + /** number of division by 2 of the out volume compared to the original size of volume */ + int factor[3]; + /** volume component data */ + int *data; +} opj_volume_comp_t; + +/** +Defines volume data and characteristics +*/ +typedef struct opj_volume { +/** XOsiz: horizontal offset from the origin of the reference grid to the left side of the volume area */ + int x0; +/** YOsiz: vertical offset from the origin of the reference grid to the top side of the volume area */ + int y0; +/** ZOsiz: vertical offset from the origin of the reference grid to the top side of the volume area */ + int z0; +/** Xsiz: width of the reference grid */ + int x1; +/** Ysiz: height of the reference grid */ + int y1; +/** Zsiz: length of the reference grid */ + int z1; +/** number of components in the volume */ + int numcomps; +/** number of slices in the volume */ + int numslices; +/** color space: sRGB, Greyscale or YUV */ + OPJ_COLOR_SPACE color_space; +/** volume components */ + opj_volume_comp_t *comps; +} opj_volume_t; + +/** +Component parameters structure used by the opj_volume_create function +*/ +typedef struct opj_volume_comptparm { + /** XRsiz: horizontal separation of a sample of ith component with respect to the reference grid */ + int dx; + /** YRsiz: vertical separation of a sample of ith component with respect to the reference grid */ + int dy; + /** ZRsiz: axial separation of a sample of ith component with respect to the reference grid */ + int dz; + /** data width */ + int w; + /** data height */ + int h; + /** data length */ + int l; + /** x component offset compared to the whole volume */ + int x0; + /** y component offset compared to the whole volume */ + int y0; + /** z component offset compared to the whole volume */ + int z0; + /** precision */ + int prec; + /** volume depth in bits */ + int bpp; + /** signed (1) / unsigned (0) */ + int sgnd; + /** DC offset*/ + int dcoffset; + /** BE byte order (1) / LE byte order (0) */ + int bigendian; +} opj_volume_cmptparm_t; + +#ifdef __cplusplus +extern "C" { +#endif + + +/* +========================================================== + openjpeg version +========================================================== +*/ + +OPJ_API const char * OPJ_CALLCONV opj_version(void); + +/* +========================================================== + volume functions definitions +========================================================== +*/ + +/** +Create an volume +@param numcmpts number of components +@param cmptparms components parameters +@param clrspc volume color space +@return returns a new volume structure if successful, returns NULL otherwise +*/ +OPJ_API opj_volume_t* OPJ_CALLCONV opj_volume_create(int numcmpts, opj_volume_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc); + +/** +Deallocate any resources associated with an volume +@param volume volume to be destroyed +*/ +OPJ_API void OPJ_CALLCONV opj_volume_destroy(opj_volume_t *volume); + +/* +========================================================== + stream functions definitions +========================================================== +*/ + +/** +Open and allocate a memory stream for read / write. +On reading, the user must provide a buffer containing encoded data. The buffer will be +wrapped by the returned CIO handle. +On writing, buffer parameters must be set to 0: a buffer will be allocated by the library +to contain encoded data. +@param cinfo Codec context info +@param buffer Reading: buffer address. Writing: NULL +@param length Reading: buffer length. Writing: 0 +@return Returns a CIO handle if successful, returns NULL otherwise +*/ +OPJ_API opj_cio_t* OPJ_CALLCONV opj_cio_open(opj_common_ptr cinfo, unsigned char *buffer, int length); + +/** +Close and free a CIO handle +@param cio CIO handle to free +*/ +OPJ_API void OPJ_CALLCONV opj_cio_close(opj_cio_t *cio); + +/** +Get position in byte stream +@param cio CIO handle +@return Returns the position in bytes +*/ +OPJ_API int OPJ_CALLCONV cio_tell(opj_cio_t *cio); +/** +Set position in byte stream +@param cio CIO handle +@param pos Position, in number of bytes, from the beginning of the stream +*/ +OPJ_API void OPJ_CALLCONV cio_seek(opj_cio_t *cio, int pos); + +/* +========================================================== + event manager functions definitions +========================================================== +*/ + +OPJ_API opj_event_mgr_t* OPJ_CALLCONV opj_set_event_mgr(opj_common_ptr cinfo, opj_event_mgr_t *event_mgr, void *context); + +/* +========================================================== + codec functions definitions +========================================================== +*/ +/** +Creates a J3D decompression structure +@param format Decoder to select +@return Returns a handle to a decompressor if successful, returns NULL otherwise +*/ +OPJ_API opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format); +/** +Destroy a decompressor handle +@param dinfo decompressor handle to destroy +*/ +OPJ_API void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo); +/** +Set decoding parameters to default values +@param parameters Decompression parameters +*/ +OPJ_API void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *parameters); +/** +Setup the decoder decoding parameters using user parameters. +Decoding parameters are returned in j3d->cp. +@param dinfo decompressor handle +@param parameters decompression parameters +*/ +OPJ_API void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters); +/** +Decode an volume from a JPEG-2000 codestream +@param dinfo decompressor handle +@param cio Input buffer stream +@return Returns a decoded volume if successful, returns NULL otherwise +*/ +OPJ_API opj_volume_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio); +/** +Creates a J3D/JP2 compression structure +@param format Coder to select +@return Returns a handle to a compressor if successful, returns NULL otherwise +*/ +OPJ_API opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format); +/** +Destroy a compressor handle +@param cinfo compressor handle to destroy +*/ +OPJ_API void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo); +/** +Set encoding parameters to default values, that means : +
    +
  • Lossless +
  • 1 tile +
  • Size of precinct : 2^15 x 2^15 (means 1 precinct) +
  • Size of code-block : 64 x 64 +
  • Number of resolutions: 6 +
  • No SOP marker in the codestream +
  • No EPH marker in the codestream +
  • No sub-sampling in x or y direction +
  • No mode switch activated +
  • Progression order: LRCP +
  • No index file +
  • No ROI upshifted +
  • No offset of the origin of the volume +
  • No offset of the origin of the tiles +
  • Reversible DWT 5-3 +
+@param parameters Compression parameters +*/ +OPJ_API void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters); +/** +Setup the encoder parameters using the current volume and using user parameters. +@param cinfo compressor handle +@param parameters compression parameters +@param volume input filled volume +*/ +OPJ_API void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_volume_t *volume); +/** +Encode an volume into a JPEG-2000 codestream +@param cinfo compressor handle +@param cio Output buffer stream +@param volume Volume to encode +@param index Name of the index file if required, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +OPJ_API bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_volume_t *volume, char *index); + +#ifdef __cplusplus +} +#endif + +#endif /* OPENJPEG_H */ diff --git a/src/lib/openjp3d/opj_includes.h b/src/lib/openjp3d/opj_includes.h old mode 100755 new mode 100644 diff --git a/src/lib/openjp3d/pi.c b/src/lib/openjp3d/pi.c old mode 100755 new mode 100644 index 960c1d84..44c7c529 --- a/src/lib/openjp3d/pi.c +++ b/src/lib/openjp3d/pi.c @@ -1,630 +1,633 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyright (c) 2006, Mónica Díez, LPI-UVA, Spain - * 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" - -/** @defgroup PI PI - Implementation of a packet iterator */ -/*@{*/ - -/** @name Funciones locales */ -/*@{*/ - -/** -Get next packet in layer-resolution-component-precinct order. -@param pi packet iterator to modify -@return returns false if pi pointed to the last packet or else returns true -*/ -static bool pi_next_lrcp(opj_pi_iterator_t * pi); -/** -Get next packet in resolution-layer-component-precinct order. -@param pi packet iterator to modify -@return returns false if pi pointed to the last packet or else returns true -*/ -static bool pi_next_rlcp(opj_pi_iterator_t * pi); -/** -Get next packet in resolution-precinct-component-layer order. -@param pi packet iterator to modify -@return returns false if pi pointed to the last packet or else returns true -*/ -static bool pi_next_rpcl(opj_pi_iterator_t * pi); -/** -Get next packet in precinct-component-resolution-layer order. -@param pi packet iterator to modify -@return returns false if pi pointed to the last packet or else returns true -*/ -static bool pi_next_pcrl(opj_pi_iterator_t * pi); -/** -Get next packet in component-precinct-resolution-layer order. -@param pi packet iterator to modify -@return returns false if pi pointed to the last packet or else returns true -*/ -static bool pi_next_cprl(opj_pi_iterator_t * pi); - -/*@}*/ - -/*@}*/ - -/* -========================================================== - local functions -========================================================== -*/ - -static bool pi_next_lrcp(opj_pi_iterator_t * pi) { - opj_pi_comp_t *comp = NULL; - opj_pi_resolution_t *res = NULL; - long index = 0; - - if (!pi->first) { - comp = &pi->comps[pi->compno]; - res = &comp->resolutions[pi->resno]; - goto LABEL_SKIP; - } else { - pi->first = 0; - } - - for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { - for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { - comp = &pi->comps[pi->compno]; - if (pi->resno >= comp->numresolution[0]) { - continue; - } - res = &comp->resolutions[pi->resno]; - /*for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1]); pi->precno++) {*/ - for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); pi->precno++) { - index = pi->layno * pi->step_l - + pi->resno * pi->step_r - + pi->compno * pi->step_c - + pi->precno * pi->step_p; - if (!pi->include[index]) { - pi->include[index] = 1; - return true; - } -LABEL_SKIP:; - - } - } - } - } - - return false; -} - -static bool pi_next_rlcp(opj_pi_iterator_t * pi) { - opj_pi_comp_t *comp = NULL; - opj_pi_resolution_t *res = NULL; - long index = 0; - - if (!pi->first) { - comp = &pi->comps[pi->compno]; - res = &comp->resolutions[pi->resno]; - goto LABEL_SKIP; - } else { - pi->first = 0; - } - - for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { - for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { - comp = &pi->comps[pi->compno]; - if (pi->resno >= comp->numresolution[0]) { - continue; - } - res = &comp->resolutions[pi->resno]; - /*for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1]); pi->precno++) {*/ - for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); pi->precno++) { - index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; - if (!pi->include[index]) { - pi->include[index] = 1; - return true; - } -LABEL_SKIP:; - } - } - } - } - - return false; -} - -static bool pi_next_rpcl(opj_pi_iterator_t * pi) { - opj_pi_comp_t *comp = NULL; - opj_pi_resolution_t *res = NULL; - long index = 0; - - if (!pi->first) { - goto LABEL_SKIP; - } else { - int compno, resno; - pi->first = 0; - pi->dx = 0; - pi->dy = 0; - for (compno = 0; compno < pi->numcomps; compno++) { - comp = &pi->comps[compno]; - for (resno = 0; resno < comp->numresolution[0]; resno++) { - int dx, dy,dz; - res = &comp->resolutions[resno]; - dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno)); - dy = comp->dy * (1 << (res->pdy + comp->numresolution[1] - 1 - resno)); - dz = comp->dz * (1 << (res->pdz + comp->numresolution[2] - 1 - resno)); - pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); - pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); - pi->dz = !pi->dz ? dz : int_min(pi->dz, dz); - } - } - } - - for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { - for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) { - for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { - for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { - int levelnox, levelnoy, levelnoz; - int trx0, try0, trz0; - int trx1, try1, trz1; - int rpx, rpy, rpz; - int prci, prcj, prck; - comp = &pi->comps[pi->compno]; - if (pi->resno >= comp->numresolution[0]) { - continue; - } - res = &comp->resolutions[pi->resno]; - levelnox = comp->numresolution[0] - 1 - pi->resno; - levelnoy = comp->numresolution[1] - 1 - pi->resno; - levelnoz = comp->numresolution[2] - 1 - pi->resno; - trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox); - try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy); - trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz); - trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox); - try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy); - trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz); - rpx = res->pdx + levelnox; - rpy = res->pdy + levelnoy; - rpz = res->pdz + levelnoz; - if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) { - continue; - } - if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) { - continue; - } - if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) { - continue; - } - if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue; - - if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue; - - prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx) - - int_floordivpow2(trx0, res->pdx); - prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy) - - int_floordivpow2(try0, res->pdy); - prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz) - - int_floordivpow2(trz0, res->pdz); - pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1]; - for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; - if (!pi->include[index]) { - pi->include[index] = 1; - return true; - } - LABEL_SKIP:; - } - } - } - } - } - } - - return false; -} - -static bool pi_next_pcrl(opj_pi_iterator_t * pi) { - opj_pi_comp_t *comp = NULL; - opj_pi_resolution_t *res = NULL; - long index = 0; - - if (!pi->first) { - comp = &pi->comps[pi->compno]; - goto LABEL_SKIP; - } else { - int compno, resno; - pi->first = 0; - pi->dx = 0; - pi->dy = 0; - pi->dz = 0; - for (compno = 0; compno < pi->numcomps; compno++) { - comp = &pi->comps[compno]; - for (resno = 0; resno < comp->numresolution[0]; resno++) { - int dx, dy, dz; - res = &comp->resolutions[resno]; - dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno)); - dy = comp->dy * (1 << (res->pdy + comp->numresolution[1] - 1 - resno)); - dz = comp->dz * (1 << (res->pdy + comp->numresolution[2] - 1 - resno)); - pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); - pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); - pi->dz = !pi->dz ? dz : int_min(pi->dz, dz); - } - } - } - -for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) { - for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { - for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { - comp = &pi->comps[pi->compno]; - for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolution[0]); pi->resno++) { - int levelnox, levelnoy, levelnoz; - int trx0, try0, trz0; - int trx1, try1, trz1; - int rpx, rpy, rpz; - int prci, prcj, prck; - comp = &pi->comps[pi->compno]; - if (pi->resno >= comp->numresolution[0]) { - continue; - } - res = &comp->resolutions[pi->resno]; - levelnox = comp->numresolution[0] - 1 - pi->resno; - levelnoy = comp->numresolution[1] - 1 - pi->resno; - levelnoz = comp->numresolution[2] - 1 - pi->resno; - trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox); - try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy); - trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz); - trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox); - try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy); - trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz); - rpx = res->pdx + levelnox; - rpy = res->pdy + levelnoy; - rpz = res->pdz + levelnoz; - if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) { - continue; - } - if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) { - continue; - } - if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) { - continue; - } - if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue; - - if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue; - - prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx) - - int_floordivpow2(trx0, res->pdx); - prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy) - - int_floordivpow2(try0, res->pdy); - prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz) - - int_floordivpow2(trz0, res->pdz); - pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1]; - for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; - if (!pi->include[index]) { - pi->include[index] = 1; - return true; - } -LABEL_SKIP:; - } - } - } - } - } -} - - return false; -} - -static bool pi_next_cprl(opj_pi_iterator_t * pi) { - opj_pi_comp_t *comp = NULL; - opj_pi_resolution_t *res = NULL; - long index = 0; - - if (!pi->first) { - comp = &pi->comps[pi->compno]; - goto LABEL_SKIP; - } else { - pi->first = 0; - } - - for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { - int resno; - comp = &pi->comps[pi->compno]; - pi->dx = 0; - pi->dy = 0; - for (resno = 0; resno < comp->numresolution[0]; resno++) { - int dx, dy; - res = &comp->resolutions[resno]; - dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno)); - dy = comp->dy * (1 << (res->pdy + comp->numresolution[0] - 1 - resno)); - pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); - pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); - } - for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) { - for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { - for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { - for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolution[0]); pi->resno++) { - int levelnox, levelnoy, levelnoz; - int trx0, try0, trz0; - int trx1, try1, trz1; - int rpx, rpy, rpz; - int prci, prcj, prck; - comp = &pi->comps[pi->compno]; - if (pi->resno >= comp->numresolution[0]) { - continue; - } - res = &comp->resolutions[pi->resno]; - levelnox = comp->numresolution[0] - 1 - pi->resno; - levelnoy = comp->numresolution[1] - 1 - pi->resno; - levelnoz = comp->numresolution[2] - 1 - pi->resno; - trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox); - try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy); - trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz); - trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox); - try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy); - trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz); - rpx = res->pdx + levelnox; - rpy = res->pdy + levelnoy; - rpz = res->pdz + levelnoz; - if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) { - continue; - } - if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) { - continue; - } - if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) { - continue; - } - if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue; - - if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue; - - prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx) - - int_floordivpow2(trx0, res->pdx); - prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy) - - int_floordivpow2(try0, res->pdy); - prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz) - - int_floordivpow2(trz0, res->pdz); - pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1]; - for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; - if (!pi->include[index]) { - pi->include[index] = 1; - return true; - } - LABEL_SKIP:; - } - } - } - } - } - } - - return false; -} - -/* -========================================================== - Packet iterator interface -========================================================== -*/ - -opj_pi_iterator_t *pi_create(opj_volume_t *volume, opj_cp_t *cp, int tileno) { - int p, q, r; - int compno, resno, pino; - opj_pi_iterator_t *pi = NULL; - opj_tcp_t *tcp = NULL; - opj_tccp_t *tccp = NULL; - size_t array_size; - - tcp = &cp->tcps[tileno]; - - array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); - pi = (opj_pi_iterator_t *) opj_malloc(array_size); - if(!pi) { - fprintf(stdout,"[ERROR] Malloc of opj_pi_iterator failed \n"); - return NULL; - } - - for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */ - int maxres = 0; - int maxprec = 0; - p = tileno % cp->tw; - q = tileno / cp->tw; - r = tileno / (cp->tw * cp->th); - - pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); - pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); - pi[pino].tz0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); - pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); - pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); - pi[pino].tz1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); - pi[pino].numcomps = volume->numcomps; - - array_size = volume->numcomps * sizeof(opj_pi_comp_t); - pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); - if(!pi[pino].comps) { - fprintf(stdout,"[ERROR] Malloc of opj_pi_comp failed \n"); - pi_destroy(pi, cp, tileno); - return NULL; - } - memset(pi[pino].comps, 0, array_size); - - for (compno = 0; compno < pi->numcomps; compno++) { - int tcx0, tcx1, tcy0, tcy1, tcz0, tcz1; - int i; - opj_pi_comp_t *comp = &pi[pino].comps[compno]; - tccp = &tcp->tccps[compno]; - - comp->dx = volume->comps[compno].dx; - comp->dy = volume->comps[compno].dy; - comp->dz = volume->comps[compno].dz; - for (i = 0; i < 3; i++) { - comp->numresolution[i] = tccp->numresolution[i]; - if (comp->numresolution[i] > maxres) { - maxres = comp->numresolution[i]; - } - } - array_size = comp->numresolution[0] * sizeof(opj_pi_resolution_t); - comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); - if(!comp->resolutions) { - fprintf(stdout,"[ERROR] Malloc of opj_pi_resolution failed \n"); - pi_destroy(pi, cp, tileno); - return NULL; - } - - tcx0 = int_ceildiv(pi->tx0, comp->dx); - tcy0 = int_ceildiv(pi->ty0, comp->dy); - tcz0 = int_ceildiv(pi->tz0, comp->dz); - tcx1 = int_ceildiv(pi->tx1, comp->dx); - tcy1 = int_ceildiv(pi->ty1, comp->dy); - tcz1 = int_ceildiv(pi->tz1, comp->dz); - - for (resno = 0; resno < comp->numresolution[0]; resno++) { - int levelnox, levelnoy, levelnoz, diff; - int rx0, ry0, rz0, rx1, ry1, rz1; - int px0, py0, pz0, px1, py1, pz1; - opj_pi_resolution_t *res = &comp->resolutions[resno]; - if (tccp->csty & J3D_CCP_CSTY_PRT) { - res->pdx = tccp->prctsiz[0][resno]; - res->pdy = tccp->prctsiz[1][resno]; - res->pdz = tccp->prctsiz[2][resno]; - } else { - res->pdx = 15; - res->pdy = 15; - res->pdz = 15; - } - levelnox = comp->numresolution[0] - 1 - resno; - levelnoy = comp->numresolution[1] - 1 - resno; - levelnoz = comp->numresolution[2] - 1 - resno; - if (levelnoz < 0) levelnoz = 0; - diff = comp->numresolution[0] - comp->numresolution[2]; - - rx0 = int_ceildivpow2(tcx0, levelnox); - ry0 = int_ceildivpow2(tcy0, levelnoy); - rz0 = int_ceildivpow2(tcz0, levelnoz); - rx1 = int_ceildivpow2(tcx1, levelnox); - ry1 = int_ceildivpow2(tcy1, levelnoy); - rz1 = int_ceildivpow2(tcz1, levelnoz); - px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; - py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; - pz0 = int_floordivpow2(rz0, res->pdz) << res->pdz; - px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; - py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; - pz1 = int_ceildivpow2(rz1, res->pdz) << res->pdz; - res->prctno[0] = (rx0==rx1)? 0 : ((px1 - px0) >> res->pdx); - res->prctno[1] = (ry0==ry1)? 0 : ((py1 - py0) >> res->pdy); - res->prctno[2] = (rz0==rz1)? 0 : ((pz1 - pz0) >> res->pdz); - - if (res->prctno[0]*res->prctno[1]*res->prctno[2] > maxprec) { - maxprec = res->prctno[0]*res->prctno[1]*res->prctno[2]; - } - } - } - - tccp = &tcp->tccps[0]; - pi[pino].step_p = 1; - pi[pino].step_c = maxprec * pi[pino].step_p; - pi[pino].step_r = volume->numcomps * pi[pino].step_c; - pi[pino].step_l = maxres * pi[pino].step_r; - - if (pino == 0) { - array_size = volume->numcomps * maxres * tcp->numlayers * maxprec * sizeof(short int); - pi[pino].include = (short int *) opj_malloc(array_size); - if(!pi[pino].include) { - fprintf(stdout,"[ERROR] Malloc of pi[pino].include failed \n"); - pi_destroy(pi, cp, tileno); - return NULL; - } - } - else { - pi[pino].include = pi[pino - 1].include; - } - - if (tcp->POC == 0) { - pi[pino].first = 1; - pi[pino].poc.resno0 = 0; - pi[pino].poc.compno0 = 0; - pi[pino].poc.layno1 = tcp->numlayers; - pi[pino].poc.resno1 = maxres; - pi[pino].poc.compno1 = volume->numcomps; - pi[pino].poc.prg = tcp->prg; - } else { - pi[pino].first = 1; - pi[pino].poc.resno0 = tcp->pocs[pino].resno0; - pi[pino].poc.compno0 = tcp->pocs[pino].compno0; - pi[pino].poc.layno1 = tcp->pocs[pino].layno1; - pi[pino].poc.resno1 = tcp->pocs[pino].resno1; - pi[pino].poc.compno1 = tcp->pocs[pino].compno1; - pi[pino].poc.prg = tcp->pocs[pino].prg; - } - } - - return pi; -} - -void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) { - int compno, pino; - opj_tcp_t *tcp = &cp->tcps[tileno]; - if(pi) { - for (pino = 0; pino < tcp->numpocs + 1; pino++) { - if(pi[pino].comps) { - for (compno = 0; compno < pi->numcomps; compno++) { - opj_pi_comp_t *comp = &pi[pino].comps[compno]; - if(comp->resolutions) { - opj_free(comp->resolutions); - } - } - opj_free(pi[pino].comps); - } - } - if(pi->include) { - opj_free(pi->include); - } - opj_free(pi); - } -} - -bool pi_next(opj_pi_iterator_t * pi) { - switch (pi->poc.prg) { - case LRCP: - return pi_next_lrcp(pi); - case RLCP: - return pi_next_rlcp(pi); - case RPCL: - return pi_next_rpcl(pi); - case PCRL: - return pi_next_pcrl(pi); - case CPRL: - return pi_next_cprl(pi); - } - - return false; -} - +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2006, Mónica Díez, LPI-UVA, Spain + * 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" + +/** @defgroup PI PI - Implementation of a packet iterator */ +/*@{*/ + +/** @name Funciones locales */ +/*@{*/ + +/** +Get next packet in layer-resolution-component-precinct order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_lrcp(opj_pi_iterator_t * pi); +/** +Get next packet in resolution-layer-component-precinct order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_rlcp(opj_pi_iterator_t * pi); +/** +Get next packet in resolution-precinct-component-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_rpcl(opj_pi_iterator_t * pi); +/** +Get next packet in precinct-component-resolution-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_pcrl(opj_pi_iterator_t * pi); +/** +Get next packet in component-precinct-resolution-layer order. +@param pi packet iterator to modify +@return returns false if pi pointed to the last packet or else returns true +*/ +static bool pi_next_cprl(opj_pi_iterator_t * pi); + +/*@}*/ + +/*@}*/ + +/* +========================================================== + local functions +========================================================== +*/ + +static bool pi_next_lrcp(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + comp = &pi->comps[pi->compno]; + res = &comp->resolutions[pi->resno]; + goto LABEL_SKIP; + } else { + pi->first = 0; + } + + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { + for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + comp = &pi->comps[pi->compno]; + if (pi->resno >= comp->numresolution[0]) { + continue; + } + res = &comp->resolutions[pi->resno]; + /*for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1]); pi->precno++) {*/ + for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); pi->precno++) { + index = pi->layno * pi->step_l + + pi->resno * pi->step_r + + pi->compno * pi->step_c + + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + + } + } + } + } + + return false; +} + +static bool pi_next_rlcp(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + comp = &pi->comps[pi->compno]; + res = &comp->resolutions[pi->resno]; + goto LABEL_SKIP; + } else { + pi->first = 0; + } + + for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + comp = &pi->comps[pi->compno]; + if (pi->resno >= comp->numresolution[0]) { + continue; + } + res = &comp->resolutions[pi->resno]; + /*for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1]); pi->precno++) {*/ + for (pi->precno = 0; pi->precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); pi->precno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } + } + } + + return false; +} + +static bool pi_next_rpcl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + goto LABEL_SKIP; + } else { + int compno, resno; + pi->first = 0; + pi->dx = 0; + pi->dy = 0; + for (compno = 0; compno < pi->numcomps; compno++) { + comp = &pi->comps[compno]; + for (resno = 0; resno < comp->numresolution[0]; resno++) { + int dx, dy,dz; + res = &comp->resolutions[resno]; + dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno)); + dy = comp->dy * (1 << (res->pdy + comp->numresolution[1] - 1 - resno)); + dz = comp->dz * (1 << (res->pdz + comp->numresolution[2] - 1 - resno)); + pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); + pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); + pi->dz = !pi->dz ? dz : int_min(pi->dz, dz); + } + } + } + + for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { + for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) { + for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + int levelnox, levelnoy, levelnoz; + int trx0, try0, trz0; + int trx1, try1, trz1; + int rpx, rpy, rpz; + int prci, prcj, prck; + comp = &pi->comps[pi->compno]; + if (pi->resno >= comp->numresolution[0]) { + continue; + } + res = &comp->resolutions[pi->resno]; + levelnox = comp->numresolution[0] - 1 - pi->resno; + levelnoy = comp->numresolution[1] - 1 - pi->resno; + levelnoz = comp->numresolution[2] - 1 - pi->resno; + trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox); + try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy); + trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox); + try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy); + trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz); + rpx = res->pdx + levelnox; + rpy = res->pdy + levelnoy; + rpz = res->pdz + levelnoz; + if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) { + continue; + } + if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) { + continue; + } + if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) { + continue; + } + if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue; + + if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy) + - int_floordivpow2(try0, res->pdy); + prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz) + - int_floordivpow2(trz0, res->pdz); + pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1]; + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } + LABEL_SKIP:; + } + } + } + } + } + } + + return false; +} + +static bool pi_next_pcrl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + comp = &pi->comps[pi->compno]; + goto LABEL_SKIP; + } else { + int compno, resno; + pi->first = 0; + pi->dx = 0; + pi->dy = 0; + pi->dz = 0; + for (compno = 0; compno < pi->numcomps; compno++) { + comp = &pi->comps[compno]; + for (resno = 0; resno < comp->numresolution[0]; resno++) { + int dx, dy, dz; + res = &comp->resolutions[resno]; + dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno)); + dy = comp->dy * (1 << (res->pdy + comp->numresolution[1] - 1 - resno)); + dz = comp->dz * (1 << (res->pdy + comp->numresolution[2] - 1 - resno)); + pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); + pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); + pi->dz = !pi->dz ? dz : int_min(pi->dz, dz); + } + } + } + +for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) { + for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + comp = &pi->comps[pi->compno]; + for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolution[0]); pi->resno++) { + int levelnox, levelnoy, levelnoz; + int trx0, try0, trz0; + int trx1, try1, trz1; + int rpx, rpy, rpz; + int prci, prcj, prck; + comp = &pi->comps[pi->compno]; + if (pi->resno >= comp->numresolution[0]) { + continue; + } + res = &comp->resolutions[pi->resno]; + levelnox = comp->numresolution[0] - 1 - pi->resno; + levelnoy = comp->numresolution[1] - 1 - pi->resno; + levelnoz = comp->numresolution[2] - 1 - pi->resno; + trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox); + try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy); + trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox); + try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy); + trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz); + rpx = res->pdx + levelnox; + rpy = res->pdy + levelnoy; + rpz = res->pdz + levelnoz; + if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) { + continue; + } + if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) { + continue; + } + if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) { + continue; + } + if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue; + + if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy) + - int_floordivpow2(try0, res->pdy); + prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz) + - int_floordivpow2(trz0, res->pdz); + pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1]; + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } +LABEL_SKIP:; + } + } + } + } + } +} + + return false; +} + +static bool pi_next_cprl(opj_pi_iterator_t * pi) { + opj_pi_comp_t *comp = NULL; + opj_pi_resolution_t *res = NULL; + long index = 0; + + if (!pi->first) { + comp = &pi->comps[pi->compno]; + goto LABEL_SKIP; + } else { + pi->first = 0; + } + + for (pi->compno = pi->poc.compno0; pi->compno < pi->poc.compno1; pi->compno++) { + int resno; + comp = &pi->comps[pi->compno]; + pi->dx = 0; + pi->dy = 0; + pi->dz = 0; + for (resno = 0; resno < comp->numresolution[0]; resno++) { + int dx, dy, dz; + res = &comp->resolutions[resno]; + dx = comp->dx * (1 << (res->pdx + comp->numresolution[0] - 1 - resno)); + dy = comp->dy * (1 << (res->pdy + comp->numresolution[1] - 1 - resno)); + dz = comp->dz * (1 << (res->pdz + comp->numresolution[2] - 1 - resno)); + pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); + pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); + pi->dz = !pi->dz ? dz : int_min(pi->dz, dz); + } + for (pi->z = pi->tz0; pi->z < pi->tz1; pi->z += pi->dz - (pi->z % pi->dz)) { + for (pi->y = pi->ty0; pi->y < pi->ty1; pi->y += pi->dy - (pi->y % pi->dy)) { + for (pi->x = pi->tx0; pi->x < pi->tx1; pi->x += pi->dx - (pi->x % pi->dx)) { + for (pi->resno = pi->poc.resno0; pi->resno < int_min(pi->poc.resno1, comp->numresolution[0]); pi->resno++) { + int levelnox, levelnoy, levelnoz; + int trx0, try0, trz0; + int trx1, try1, trz1; + int rpx, rpy, rpz; + int prci, prcj, prck; + comp = &pi->comps[pi->compno]; + if (pi->resno >= comp->numresolution[0]) { + continue; + } + res = &comp->resolutions[pi->resno]; + levelnox = comp->numresolution[0] - 1 - pi->resno; + levelnoy = comp->numresolution[1] - 1 - pi->resno; + levelnoz = comp->numresolution[2] - 1 - pi->resno; + trx0 = int_ceildiv(pi->tx0, comp->dx << levelnox); + try0 = int_ceildiv(pi->ty0, comp->dy << levelnoy); + trz0 = int_ceildiv(pi->tz0, comp->dz << levelnoz); + trx1 = int_ceildiv(pi->tx1, comp->dx << levelnox); + try1 = int_ceildiv(pi->ty1, comp->dy << levelnoy); + trz1 = int_ceildiv(pi->tz1, comp->dz << levelnoz); + rpx = res->pdx + levelnox; + rpy = res->pdy + levelnoy; + rpz = res->pdz + levelnoz; + if ((!(pi->x % (comp->dx << rpx) == 0) || (pi->x == pi->tx0 && (trx0 << levelnox) % (1 << rpx)))) { + continue; + } + if ((!(pi->y % (comp->dy << rpy) == 0) || (pi->y == pi->ty0 && (try0 << levelnoy) % (1 << rpx)))) { + continue; + } + if ((!(pi->z % (comp->dz << rpz) == 0) || (pi->z == pi->tz0 && (trz0 << levelnoz) % (1 << rpx)))) { + continue; + } + if ((res->prctno[0]==0)||(res->prctno[1]==0)||(res->prctno[2]==0)) continue; + + if ((trx0==trx1)||(try0==try1)||(trz0==trz1)) continue; + + prci = int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelnox), res->pdx) + - int_floordivpow2(trx0, res->pdx); + prcj = int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelnoy), res->pdy) + - int_floordivpow2(try0, res->pdy); + prck = int_floordivpow2(int_ceildiv(pi->z, comp->dz << levelnoz), res->pdz) + - int_floordivpow2(trz0, res->pdz); + pi->precno = prci + prcj * res->prctno[0] + prck * res->prctno[0] * res->prctno[1]; + for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { + index = pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p; + if (!pi->include[index]) { + pi->include[index] = 1; + return true; + } + LABEL_SKIP:; + } + } + } + } + } + } + + return false; +} + +/* +========================================================== + Packet iterator interface +========================================================== +*/ + +opj_pi_iterator_t *pi_create(opj_volume_t *volume, opj_cp_t *cp, int tileno) { + int p, q, r; + int compno, resno, pino; + opj_pi_iterator_t *pi = NULL; + opj_tcp_t *tcp = NULL; + opj_tccp_t *tccp = NULL; + size_t array_size; + + tcp = &cp->tcps[tileno]; + + array_size = (tcp->numpocs + 1) * sizeof(opj_pi_iterator_t); + pi = (opj_pi_iterator_t *) opj_malloc(array_size); + if(!pi) { + fprintf(stdout,"[ERROR] Malloc of opj_pi_iterator failed \n"); + return NULL; + } + + for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */ + int maxres = 0; + int maxprec = 0; + p = tileno % cp->tw; + q = tileno / cp->tw; + r = tileno / (cp->tw * cp->th); + + pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); + pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); + pi[pino].tz0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); + pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); + pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); + pi[pino].tz1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); + pi[pino].numcomps = volume->numcomps; + + array_size = volume->numcomps * sizeof(opj_pi_comp_t); + pi[pino].comps = (opj_pi_comp_t *) opj_malloc(array_size); + if(!pi[pino].comps) { + fprintf(stdout,"[ERROR] Malloc of opj_pi_comp failed \n"); + pi_destroy(pi, cp, tileno); + return NULL; + } + memset(pi[pino].comps, 0, array_size); + + for (compno = 0; compno < pi->numcomps; compno++) { + int tcx0, tcx1, tcy0, tcy1, tcz0, tcz1; + int i; + opj_pi_comp_t *comp = &pi[pino].comps[compno]; + tccp = &tcp->tccps[compno]; + + comp->dx = volume->comps[compno].dx; + comp->dy = volume->comps[compno].dy; + comp->dz = volume->comps[compno].dz; + for (i = 0; i < 3; i++) { + comp->numresolution[i] = tccp->numresolution[i]; + if (comp->numresolution[i] > maxres) { + maxres = comp->numresolution[i]; + } + } + array_size = comp->numresolution[0] * sizeof(opj_pi_resolution_t); + comp->resolutions = (opj_pi_resolution_t *) opj_malloc(array_size); + if(!comp->resolutions) { + fprintf(stdout,"[ERROR] Malloc of opj_pi_resolution failed \n"); + pi_destroy(pi, cp, tileno); + return NULL; + } + + tcx0 = int_ceildiv(pi->tx0, comp->dx); + tcy0 = int_ceildiv(pi->ty0, comp->dy); + tcz0 = int_ceildiv(pi->tz0, comp->dz); + tcx1 = int_ceildiv(pi->tx1, comp->dx); + tcy1 = int_ceildiv(pi->ty1, comp->dy); + tcz1 = int_ceildiv(pi->tz1, comp->dz); + + for (resno = 0; resno < comp->numresolution[0]; resno++) { + int levelnox, levelnoy, levelnoz, diff; + int rx0, ry0, rz0, rx1, ry1, rz1; + int px0, py0, pz0, px1, py1, pz1; + opj_pi_resolution_t *res = &comp->resolutions[resno]; + if (tccp->csty & J3D_CCP_CSTY_PRT) { + res->pdx = tccp->prctsiz[0][resno]; + res->pdy = tccp->prctsiz[1][resno]; + res->pdz = tccp->prctsiz[2][resno]; + } else { + res->pdx = 15; + res->pdy = 15; + res->pdz = 15; + } + levelnox = comp->numresolution[0] - 1 - resno; + levelnoy = comp->numresolution[1] - 1 - resno; + levelnoz = comp->numresolution[2] - 1 - resno; + if (levelnoz < 0) levelnoz = 0; + diff = comp->numresolution[0] - comp->numresolution[2]; + + rx0 = int_ceildivpow2(tcx0, levelnox); + ry0 = int_ceildivpow2(tcy0, levelnoy); + rz0 = int_ceildivpow2(tcz0, levelnoz); + rx1 = int_ceildivpow2(tcx1, levelnox); + ry1 = int_ceildivpow2(tcy1, levelnoy); + rz1 = int_ceildivpow2(tcz1, levelnoz); + px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; + py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; + pz0 = int_floordivpow2(rz0, res->pdz) << res->pdz; + px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; + py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; + pz1 = int_ceildivpow2(rz1, res->pdz) << res->pdz; + res->prctno[0] = (rx0==rx1)? 0 : ((px1 - px0) >> res->pdx); + res->prctno[1] = (ry0==ry1)? 0 : ((py1 - py0) >> res->pdy); + res->prctno[2] = (rz0==rz1)? 0 : ((pz1 - pz0) >> res->pdz); + + if (res->prctno[0]*res->prctno[1]*res->prctno[2] > maxprec) { + maxprec = res->prctno[0]*res->prctno[1]*res->prctno[2]; + } + } + } + + tccp = &tcp->tccps[0]; + pi[pino].step_p = 1; + pi[pino].step_c = maxprec * pi[pino].step_p; + pi[pino].step_r = volume->numcomps * pi[pino].step_c; + pi[pino].step_l = maxres * pi[pino].step_r; + + if (pino == 0) { + array_size = volume->numcomps * maxres * tcp->numlayers * maxprec * sizeof(short int); + pi[pino].include = (short int *) opj_malloc(array_size); + if(!pi[pino].include) { + fprintf(stdout,"[ERROR] Malloc of pi[pino].include failed \n"); + pi_destroy(pi, cp, tileno); + return NULL; + } + } + else { + pi[pino].include = pi[pino - 1].include; + } + + if (tcp->POC == 0) { + pi[pino].first = 1; + pi[pino].poc.resno0 = 0; + pi[pino].poc.compno0 = 0; + pi[pino].poc.layno1 = tcp->numlayers; + pi[pino].poc.resno1 = maxres; + pi[pino].poc.compno1 = volume->numcomps; + pi[pino].poc.prg = tcp->prg; + } else { + pi[pino].first = 1; + pi[pino].poc.resno0 = tcp->pocs[pino].resno0; + pi[pino].poc.compno0 = tcp->pocs[pino].compno0; + pi[pino].poc.layno1 = tcp->pocs[pino].layno1; + pi[pino].poc.resno1 = tcp->pocs[pino].resno1; + pi[pino].poc.compno1 = tcp->pocs[pino].compno1; + pi[pino].poc.prg = tcp->pocs[pino].prg; + } + } + + return pi; +} + +void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno) { + int compno, pino; + opj_tcp_t *tcp = &cp->tcps[tileno]; + if(pi) { + for (pino = 0; pino < tcp->numpocs + 1; pino++) { + if(pi[pino].comps) { + for (compno = 0; compno < pi->numcomps; compno++) { + opj_pi_comp_t *comp = &pi[pino].comps[compno]; + if(comp->resolutions) { + opj_free(comp->resolutions); + } + } + opj_free(pi[pino].comps); + } + } + if(pi->include) { + opj_free(pi->include); + } + opj_free(pi); + } +} + +bool pi_next(opj_pi_iterator_t * pi) { + switch (pi->poc.prg) { + case LRCP: + return pi_next_lrcp(pi); + case RLCP: + return pi_next_rlcp(pi); + case RPCL: + return pi_next_rpcl(pi); + case PCRL: + return pi_next_pcrl(pi); + case CPRL: + return pi_next_cprl(pi); + } + + return false; +} + diff --git a/src/lib/openjp3d/pi.h b/src/lib/openjp3d/pi.h old mode 100755 new mode 100644 index 1edcc5fc..4274f4e6 --- a/src/lib/openjp3d/pi.h +++ b/src/lib/openjp3d/pi.h @@ -1,145 +1,145 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __PI_H -#define __PI_H -/** -@file pi.h -@brief Implementation of a packet iterator (PI) - -The functions in PI.C have for goal to realize a packet iterator that permits to get the next -packet following the progression order and change of it. The functions in PI.C are used -by some function in T2.C. -*/ - -/** @defgroup PI PI - Implementation of a packet iterator */ -/*@{*/ - -/** -Packet iterator : resolution level information -*/ -typedef struct opj_pi_resolution { -/** Size of precints in horizontal axis */ - int pdx; -/** Size of precints in vertical axis */ - int pdy; -/** Size of precints in axial axis */ - int pdz; -/** Number of precints in each axis */ - int prctno[3]; -} opj_pi_resolution_t; - -/** -Packet iterator : component information -*/ -typedef struct opj_pi_comp { -/** Size in horizontal axis */ - int dx; -/** Size in vertical axis */ - int dy; -/** Size in axial axis */ - int dz; -/** Number of resolution levels */ - int numresolution[3]; -/** Packet iterator : resolution level information */ - opj_pi_resolution_t *resolutions; -} opj_pi_comp_t; - -/** -Packet iterator -*/ -typedef struct opj_pi_iterator { -/** precise if the packet has been already used (usefull for progression order change) */ - short int *include; -/** layer step used to localize the packet in the include vector */ - int step_l; -/** resolution step used to localize the packet in the include vector */ - int step_r; -/** component step used to localize the packet in the include vector */ - int step_c; -/** precinct step used to localize the packet in the include vector */ - int step_p; -/** component that identify the packet */ - int compno; -/** resolution that identify the packet */ - int resno; -/** precinct that identify the packet */ - int precno; -/** layer that identify the packet */ - int layno; -/** 0 if the first packet */ - int first; -/** progression order change information */ - opj_poc_t poc; -/** Packet iterator : component information */ -opj_pi_comp_t *comps; - - int numcomps; - int tx0, ty0, tz0; - int tx1, ty1, tz1; - int x, y, z; - int dx, dy, dz; -} opj_pi_iterator_t; - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Create a packet iterator -@param volume Raw volume for which the packets will be listed -@param cp Coding parameters -@param tileno Number that identifies the tile for which to list the packets -@return Returns a packet iterator that points to the first packet of the tile -@see pi_destroy -*/ -opj_pi_iterator_t *pi_create(opj_volume_t * volume, opj_cp_t * cp, int tileno); - -/** -Destroy a packet iterator -@param pi Previously created packet iterator -@param cp Coding parameters -@param tileno Number that identifies the tile for which the packets were listed -@see pi_create -*/ -void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno); - -/** -Modify the packet iterator to point to the next packet -@param pi Packet iterator to modify -@return Returns false if pi pointed to the last packet or else returns true -*/ -bool pi_next(opj_pi_iterator_t * pi); -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __PI_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __PI_H +#define __PI_H +/** +@file pi.h +@brief Implementation of a packet iterator (PI) + +The functions in PI.C have for goal to realize a packet iterator that permits to get the next +packet following the progression order and change of it. The functions in PI.C are used +by some function in T2.C. +*/ + +/** @defgroup PI PI - Implementation of a packet iterator */ +/*@{*/ + +/** +Packet iterator : resolution level information +*/ +typedef struct opj_pi_resolution { +/** Size of precints in horizontal axis */ + int pdx; +/** Size of precints in vertical axis */ + int pdy; +/** Size of precints in axial axis */ + int pdz; +/** Number of precints in each axis */ + int prctno[3]; +} opj_pi_resolution_t; + +/** +Packet iterator : component information +*/ +typedef struct opj_pi_comp { +/** Size in horizontal axis */ + int dx; +/** Size in vertical axis */ + int dy; +/** Size in axial axis */ + int dz; +/** Number of resolution levels */ + int numresolution[3]; +/** Packet iterator : resolution level information */ + opj_pi_resolution_t *resolutions; +} opj_pi_comp_t; + +/** +Packet iterator +*/ +typedef struct opj_pi_iterator { +/** precise if the packet has been already used (usefull for progression order change) */ + short int *include; +/** layer step used to localize the packet in the include vector */ + int step_l; +/** resolution step used to localize the packet in the include vector */ + int step_r; +/** component step used to localize the packet in the include vector */ + int step_c; +/** precinct step used to localize the packet in the include vector */ + int step_p; +/** component that identify the packet */ + int compno; +/** resolution that identify the packet */ + int resno; +/** precinct that identify the packet */ + int precno; +/** layer that identify the packet */ + int layno; +/** 0 if the first packet */ + int first; +/** progression order change information */ + opj_poc_t poc; +/** Packet iterator : component information */ +opj_pi_comp_t *comps; + + int numcomps; + int tx0, ty0, tz0; + int tx1, ty1, tz1; + int x, y, z; + int dx, dy, dz; +} opj_pi_iterator_t; + +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a packet iterator +@param volume Raw volume for which the packets will be listed +@param cp Coding parameters +@param tileno Number that identifies the tile for which to list the packets +@return Returns a packet iterator that points to the first packet of the tile +@see pi_destroy +*/ +opj_pi_iterator_t *pi_create(opj_volume_t * volume, opj_cp_t * cp, int tileno); + +/** +Destroy a packet iterator +@param pi Previously created packet iterator +@param cp Coding parameters +@param tileno Number that identifies the tile for which the packets were listed +@see pi_create +*/ +void pi_destroy(opj_pi_iterator_t *pi, opj_cp_t *cp, int tileno); + +/** +Modify the packet iterator to point to the next packet +@param pi Packet iterator to modify +@return Returns false if pi pointed to the last packet or else returns true +*/ +bool pi_next(opj_pi_iterator_t * pi); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __PI_H */ diff --git a/src/lib/openjp3d/raw.c b/src/lib/openjp3d/raw.c old mode 100755 new mode 100644 index b6a58106..1457a66b --- a/src/lib/openjp3d/raw.c +++ b/src/lib/openjp3d/raw.c @@ -1,86 +1,86 @@ -/* - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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 "opj_includes.h" - -/* -========================================================== - local functions -========================================================== -*/ - - -/* -========================================================== - RAW encoding interface -========================================================== -*/ - -opj_raw_t* raw_create() { - opj_raw_t *raw = (opj_raw_t*)opj_malloc(sizeof(opj_raw_t)); - return raw; -} - -void raw_destroy(opj_raw_t *raw) { - if(raw) { - opj_free(raw); - } -} - -int raw_numbytes(opj_raw_t *raw) { - return raw->bp - raw->start; -} - -void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len) { - raw->start = bp; - raw->lenmax = len; - raw->len = 0; - raw->c = 0; - raw->ct = 0; -} - -int raw_decode(opj_raw_t *raw) { - int d; - if (raw->ct == 0) { - raw->ct = 8; - if (raw->len == raw->lenmax) { - raw->c = 0xff; - } else { - if (raw->c == 0xff) { - raw->ct = 7; - } - raw->c = *(raw->start + raw->len); - raw->len++; - } - } - raw->ct--; - d = (raw->c >> raw->ct) & 0x01; - - return d; -} - +/* + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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 "opj_includes.h" + +/* +========================================================== + local functions +========================================================== +*/ + + +/* +========================================================== + RAW encoding interface +========================================================== +*/ + +opj_raw_t* raw_create() { + opj_raw_t *raw = (opj_raw_t*)opj_malloc(sizeof(opj_raw_t)); + return raw; +} + +void raw_destroy(opj_raw_t *raw) { + if(raw) { + opj_free(raw); + } +} + +int raw_numbytes(opj_raw_t *raw) { + return raw->bp - raw->start; +} + +void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len) { + raw->start = bp; + raw->lenmax = len; + raw->len = 0; + raw->c = 0; + raw->ct = 0; +} + +int raw_decode(opj_raw_t *raw) { + int d; + if (raw->ct == 0) { + raw->ct = 8; + if (raw->len == raw->lenmax) { + raw->c = 0xff; + } else { + if (raw->c == 0xff) { + raw->ct = 7; + } + raw->c = *(raw->start + raw->len); + raw->len++; + } + } + raw->ct--; + d = (raw->c >> raw->ct) & 0x01; + + return d; +} + diff --git a/src/lib/openjp3d/raw.h b/src/lib/openjp3d/raw.h old mode 100755 new mode 100644 index 55e889da..c452804d --- a/src/lib/openjp3d/raw.h +++ b/src/lib/openjp3d/raw.h @@ -1,99 +1,99 @@ -/* - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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. - */ - -#ifndef __RAW_H -#define __RAW_H -/** -@file raw.h -@brief Implementation of operations for raw encoding (RAW) - -The functions in RAW.C have for goal to realize the operation of raw encoding linked -with the corresponding mode switch. -*/ - -/** @defgroup RAW RAW - Implementation of operations for raw encoding */ -/*@{*/ - -/** -RAW encoding operations -*/ -typedef struct opj_raw { -/** Temporary buffer where bits are coded or decoded */ - unsigned char c; -/** Number of bits already read or free to write */ - unsigned int ct; -/** Maximum length to decode */ - unsigned int lenmax; -/** Length decoded */ - unsigned int len; -/** Pointer to the current position in the buffer */ - unsigned char *bp; -/** Pointer to the start of the buffer */ - unsigned char *start; -/** Pointer to the end of the buffer */ - unsigned char *end; -} opj_raw_t; - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Create a new RAW handle -@return Returns a new RAW handle if successful, returns NULL otherwise -*/ -opj_raw_t* raw_create(void); -/** -Destroy a previously created RAW handle -@param raw RAW handle to destroy -*/ -void raw_destroy(opj_raw_t *raw); -/** -Return the number of bytes written/read since initialisation -@param raw RAW handle to destroy -@return Returns the number of bytes already encoded -*/ -int raw_numbytes(opj_raw_t *raw); -/** -Initialize the decoder -@param raw RAW handle -@param bp Pointer to the start of the buffer from which the bytes will be read -@param len Length of the input buffer -*/ -void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len); -/** -Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN -@param raw RAW handle -@return Returns the decoded symbol (0 or 1) -*/ -int raw_decode(opj_raw_t *raw); -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __RAW_H */ +/* + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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. + */ + +#ifndef __RAW_H +#define __RAW_H +/** +@file raw.h +@brief Implementation of operations for raw encoding (RAW) + +The functions in RAW.C have for goal to realize the operation of raw encoding linked +with the corresponding mode switch. +*/ + +/** @defgroup RAW RAW - Implementation of operations for raw encoding */ +/*@{*/ + +/** +RAW encoding operations +*/ +typedef struct opj_raw { +/** Temporary buffer where bits are coded or decoded */ + unsigned char c; +/** Number of bits already read or free to write */ + unsigned int ct; +/** Maximum length to decode */ + unsigned int lenmax; +/** Length decoded */ + unsigned int len; +/** Pointer to the current position in the buffer */ + unsigned char *bp; +/** Pointer to the start of the buffer */ + unsigned char *start; +/** Pointer to the end of the buffer */ + unsigned char *end; +} opj_raw_t; + +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new RAW handle +@return Returns a new RAW handle if successful, returns NULL otherwise +*/ +opj_raw_t* raw_create(void); +/** +Destroy a previously created RAW handle +@param raw RAW handle to destroy +*/ +void raw_destroy(opj_raw_t *raw); +/** +Return the number of bytes written/read since initialisation +@param raw RAW handle to destroy +@return Returns the number of bytes already encoded +*/ +int raw_numbytes(opj_raw_t *raw); +/** +Initialize the decoder +@param raw RAW handle +@param bp Pointer to the start of the buffer from which the bytes will be read +@param len Length of the input buffer +*/ +void raw_init_dec(opj_raw_t *raw, unsigned char *bp, int len); +/** +Decode a symbol using raw-decoder. Cfr p.506 TAUBMAN +@param raw RAW handle +@return Returns the decoded symbol (0 or 1) +*/ +int raw_decode(opj_raw_t *raw); +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __RAW_H */ diff --git a/src/lib/openjp3d/t1.c b/src/lib/openjp3d/t1.c old mode 100755 new mode 100644 index 6a389864..8ba8ee5e --- a/src/lib/openjp3d/t1.c +++ b/src/lib/openjp3d/t1.c @@ -1,1181 +1,1181 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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 "opj_includes.h" - -/** @defgroup T1 T1 - Implementation of the tier-1 coding */ -/*@{*/ - -/** @name Local static functions */ -/*@{*/ - -static int t1_getctxno_zc(opj_t1_t *t1, int f, int orient); -static int t1_getctxno_sc(opj_t1_t *t1, int f); -static int t1_getctxno_mag(opj_t1_t *t1, int f); -static int t1_getspb(opj_t1_t *t1, int f); -static int t1_getnmsedec_sig(opj_t1_t *t1, int x, int bitpos); -static int t1_getnmsedec_ref(opj_t1_t *t1, int x, int bitpos); -static void t1_updateflags(int *fp, int s); -/** -Encode significant pass -*/ -static void t1_enc_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc); -/** -Decode significant pass -*/ -static void t1_dec_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, char type, int vsc); -/** -Encode significant pass -*/ -static void t1_enc_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty); -/** -Decode significant pass -*/ -static void t1_dec_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty); -/** -Encode refinement pass -*/ -static void t1_enc_refpass_step(opj_t1_t *t1, int *fp, int *dp, int bpno, int one, int *nmsedec, char type, int vsc); -/** -Decode refinement pass -*/ -static void t1_dec_refpass_step(opj_t1_t *t1, int *fp, int *dp, int poshalf, int neghalf, char type, int vsc); -/** -Encode refinement pass -*/ -static void t1_enc_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty); -/** -Decode refinement pass -*/ -static void t1_dec_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, char type, int cblksty); -/** -Encode clean-up pass -*/ -static void t1_enc_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc); -/** -Decode clean-up pass -*/ -static void t1_dec_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, int partial, int vsc); -/** -Encode clean-up pass -*/ -static void t1_enc_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty); -/** -Decode clean-up pass -*/ -static void t1_dec_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int cblksty); -/** -Encode 1 code-block -@param t1 T1 handle -@param cblk Code-block coding parameters -@param orient -@param compno Component number -@param level -@param dwtid -@param stepsize -@param cblksty Code-block style -@param numcomps -@param tile -*/ -static void t1_encode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile); -/** -Decode 1 code-block -@param t1 T1 handle -@param cblk Code-block coding parameters -@param orient -@param roishift Region of interest shifting value -@param cblksty Code-block style -*/ -static void t1_decode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty); - -static int t1_init_ctxno_zc(int f, int orient); -static int t1_init_ctxno_sc(int f); -static int t1_init_ctxno_mag(int f); -static int t1_init_spb(int f); -/** -Initialize the look-up tables of the Tier-1 coder/decoder -@param t1 T1 handle -*/ -static void t1_init_luts(opj_t1_t *t1); - -/*@}*/ - -/*@}*/ - -/* ----------------------------------------------------------------------- */ - -static int t1_getctxno_zc(opj_t1_t *t1, int f, int orient) { - return t1->lut_ctxno_zc[(orient << 8) | (f & T1_SIG_OTH)]; -} - -static int t1_getctxno_sc(opj_t1_t *t1, int f) { - return t1->lut_ctxno_sc[(f & (T1_SIG_PRIM | T1_SGN)) >> 4]; -} - -static int t1_getctxno_mag(opj_t1_t *t1, int f) { - return t1->lut_ctxno_mag[(f & T1_SIG_OTH) | (((f & T1_REFINE) != 0) << 11)]; -} - -static int t1_getspb(opj_t1_t *t1, int f) { - return t1->lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4]; -} - -static int t1_getnmsedec_sig(opj_t1_t *t1, int x, int bitpos) { - if (bitpos > T1_NMSEDEC_FRACBITS) { - return t1->lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; - } - - return t1->lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; -} - -static int t1_getnmsedec_ref(opj_t1_t *t1, int x, int bitpos) { - if (bitpos > T1_NMSEDEC_FRACBITS) { - return t1->lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; - } - - return t1->lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; -} - -static void t1_updateflags(int *fp, int s) { - int *np = fp - (T1_MAXCBLKW + 2); - int *sp = fp + (T1_MAXCBLKW + 2); - np[-1] |= T1_SIG_SE; - np[1] |= T1_SIG_SW; - sp[-1] |= T1_SIG_NE; - sp[1] |= T1_SIG_NW; - *np |= T1_SIG_S; - *sp |= T1_SIG_N; - fp[-1] |= T1_SIG_E; - fp[1] |= T1_SIG_W; - if (s) { - *np |= T1_SGN_S; - *sp |= T1_SGN_N; - fp[-1] |= T1_SGN_E; - fp[1] |= T1_SGN_W; - } -} - -static void t1_enc_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc) { - int v, flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); - if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { - v = int_abs(*dp) & one ? 1 : 0; - if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); /* ESSAI */ - mqc_bypass_enc(mqc, v); - } else { - mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); - mqc_encode(mqc, v); - } - if (v) { - v = *dp < 0 ? 1 : 0; - *nmsedec += t1_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); - if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); /* ESSAI */ - mqc_bypass_enc(mqc, v); - } else { - mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); - mqc_encode(mqc, v ^ t1_getspb(t1, flag)); - } - t1_updateflags(fp, v); - *fp |= T1_SIG; - } - *fp |= T1_VISIT; - } -} - -static void t1_dec_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, char type, int vsc) { - int v, flag; - - opj_raw_t *raw = t1->raw; /* RAW component */ - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); - if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { - if (type == T1_TYPE_RAW) { - if (raw_decode(raw)) { - v = raw_decode(raw); /* ESSAI */ - *dp = v ? -oneplushalf : oneplushalf; - t1_updateflags(fp, v); - *fp |= T1_SIG; - } - } else { - mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); - if (mqc_decode(mqc)) { - mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); - v = mqc_decode(mqc) ^ t1_getspb(t1, flag); - *dp = v ? -oneplushalf : oneplushalf; - t1_updateflags(fp, v); - *fp |= T1_SIG; - } - } - *fp |= T1_VISIT; - } -} /* VSC and BYPASS by Antonin */ - -static void t1_enc_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty) { - int i, j, k, m, one, vsc; - *nmsedec = 0; - one = 1 << (bpno + T1_NMSEDEC_FRACBITS); - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - for (j = k; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_enc_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, type, vsc); - } - } - } - } -} - -static void t1_dec_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty) { - int i, j, k, m, one, half, oneplushalf, vsc; - one = 1 << bpno; - half = one >> 1; - oneplushalf = one | half; - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - for (j = k; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_dec_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, type, vsc); - } - } - } - } -} /* VSC and BYPASS by Antonin */ - -static void t1_enc_refpass_step(opj_t1_t *t1, int *fp, int *dp, int bpno, int one, int *nmsedec, char type, int vsc) { - int v, flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); - if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { - *nmsedec += t1_getnmsedec_ref(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); - v = int_abs(*dp) & one ? 1 : 0; - if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); /* ESSAI */ - mqc_bypass_enc(mqc, v); - } else { - mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); - mqc_encode(mqc, v); - } - *fp |= T1_REFINE; - } -} - -static void t1_dec_refpass_step(opj_t1_t *t1, int *fp, int *dp, int poshalf, int neghalf, char type, int vsc) { - int v, t, flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - opj_raw_t *raw = t1->raw; /* RAW component */ - - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); - if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { - if (type == T1_TYPE_RAW) { - mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); /* ESSAI */ - v = raw_decode(raw); - } else { - mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); - v = mqc_decode(mqc); - } - t = v ? poshalf : neghalf; - *dp += *dp < 0 ? -t : t; - *fp |= T1_REFINE; - } -} /* VSC and BYPASS by Antonin */ - -static void t1_enc_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty) { - int i, j, k, m, one, vsc; - *nmsedec = 0; - one = 1 << (bpno + T1_NMSEDEC_FRACBITS); - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - for (j = k; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_enc_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], bpno, one, nmsedec, type, vsc); - } - } - } - } -} - -static void t1_dec_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, char type, int cblksty) { - int i, j, k, m, one, poshalf, neghalf; - int vsc; - one = 1 << bpno; - poshalf = one >> 1; - neghalf = bpno > 0 ? -poshalf : -1; - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - for (j = k; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_dec_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], poshalf, neghalf, type, vsc); - } - } - } - } -} /* VSC and BYPASS by Antonin */ - -static void t1_enc_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc) { - int v, flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); - if (partial) { - goto LABEL_PARTIAL; - } - if (!(*fp & (T1_SIG | T1_VISIT))) { - mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); - v = int_abs(*dp) & one ? 1 : 0; - mqc_encode(mqc, v); - if (v) { -LABEL_PARTIAL: - *nmsedec += t1_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); - mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); - v = *dp < 0 ? 1 : 0; - mqc_encode(mqc, v ^ t1_getspb(t1, flag)); - t1_updateflags(fp, v); - *fp |= T1_SIG; - } - } - *fp &= ~T1_VISIT; -} - -static void t1_dec_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, int partial, int vsc) { - int v, flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); - if (partial) { - goto LABEL_PARTIAL; - } - if (!(flag & (T1_SIG | T1_VISIT))) { - mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); - if (mqc_decode(mqc)) { -LABEL_PARTIAL: - mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); - v = mqc_decode(mqc) ^ t1_getspb(t1, flag); - *dp = v ? -oneplushalf : oneplushalf; - t1_updateflags(fp, v); - *fp |= T1_SIG; - } - } - *fp &= ~T1_VISIT; -} /* VSC and BYPASS by Antonin */ - -static void t1_enc_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty) { - int i, j, k, m, one, agg, runlen, vsc; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - *nmsedec = 0; - one = 1 << (bpno + T1_NMSEDEC_FRACBITS); - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - if (k + 3 < h) { - if (cblksty & J3D_CCP_CBLKSTY_VSC) { - agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || (t1->flags[1 + m][1 + k + 3][1 + i] - & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH)); - } else { - agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 3][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)); - } - } else { - agg = 0; - } - if (agg) { - for (runlen = 0; runlen < 4; runlen++) { - if (int_abs(t1->data[m][k + runlen][i]) & one) - break; - } - mqc_setcurctx(mqc, T1_CTXNO_AGG); - mqc_encode(mqc, runlen != 4); - if (runlen == 4) { - continue; - } - mqc_setcurctx(mqc, T1_CTXNO_UNI); - mqc_encode(mqc, runlen >> 1); - mqc_encode(mqc, runlen & 1); - } else { - runlen = 0; - } - for (j = k + runlen; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_enc_clnpass_step(t1, &(t1->flags[1 + m][1 + j][1 + i]), &(t1->data[m][j][i]), orient, bpno, one, nmsedec, agg && (j == k + runlen), vsc); - } - } - } - } -} - -static void t1_dec_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int cblksty) { - int i, j, k, m, one, half, oneplushalf, agg, runlen, vsc; - int segsym = cblksty & J3D_CCP_CBLKSTY_SEGSYM; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - one = 1 << bpno; - half = one >> 1; - oneplushalf = one | half; - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - if (k + 3 < h) { - if (cblksty & J3D_CCP_CBLKSTY_VSC) { - agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || (t1->flags[1 + m][1 + k + 3][1 + i] - & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH)); - } else { - agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) - || t1->flags[1 + m][1 + k + 3][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)); - } - } else { - agg = 0; - } - if (agg) { - mqc_setcurctx(mqc, T1_CTXNO_AGG); - if (!mqc_decode(mqc)) { - continue; - } - mqc_setcurctx(mqc, T1_CTXNO_UNI); - runlen = mqc_decode(mqc); - runlen = (runlen << 1) | mqc_decode(mqc); - } else { - runlen = 0; - } - for (j = k + runlen; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_dec_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, agg && (j == k + runlen), vsc); - } - } - } - } - if (segsym) { - int v = 0; - mqc_setcurctx(mqc, T1_CTXNO_UNI); - v = mqc_decode(mqc); - v = (v << 1) | mqc_decode(mqc); - v = (v << 1) | mqc_decode(mqc); - v = (v << 1) | mqc_decode(mqc); - /* - if (v!=0xa) { - opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v); - } - */ - } -} /* VSC and BYPASS by Antonin */ - - -static void t1_encode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile) { - int i, j, k; - int w, h, l; - int passno; - int bpno, passtype; - int max; - int nmsedec = 0; - double cumwmsedec = 0; - char type = T1_TYPE_MQ; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - w = cblk->x1 - cblk->x0; - h = cblk->y1 - cblk->y0; - l = cblk->z1 - cblk->z0; - - max = 0; - for (k = 0; k < l; k++) { - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - max = int_max(max, int_abs(t1->data[k][j][i])); - } - } - } - for (k = 0; k <= l; k++) { - for (j = 0; j <= h; j++) { - for (i = 0; i <= w; i++) { - t1->flags[k][j][i] = 0; - } - } - } - - cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0; - - bpno = cblk->numbps - 1; - passtype = 2; - - mqc_reset_enc(mqc); - mqc_init_enc(mqc, cblk->data); - - for (passno = 0; bpno >= 0; passno++) { - opj_tcd_pass_t *pass = &cblk->passes[passno]; - int correction = 3; - double tmpwmsedec; - type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; - /*fprintf(stdout,"passno %d passtype %d w %d h %d l %d bpno %d orient %d type %d cblksty %d\n",passno,passtype,w,h,l,bpno,orient,type,cblksty);*/ - - switch (passtype) { - case 0: - t1_enc_sigpass(t1, w, h, l, bpno, orient, &nmsedec, type, cblksty); - break; - case 1: - t1_enc_refpass(t1, w, h, l, bpno, &nmsedec, type, cblksty); - break; - case 2: - /*fprintf(stdout,"w %d h %d l %d bpno %d orient %d \n",w,h,l,bpno,orient);*/ - t1_enc_clnpass(t1, w, h, l, bpno, orient, &nmsedec, cblksty); - /* code switch SEGMARK (i.e. SEGSYM) */ - if (cblksty & J3D_CCP_CBLKSTY_SEGSYM) - mqc_segmark_enc(mqc); - break; - } - - /* fixed_quality */ - tmpwmsedec = t1_getwmsedec(nmsedec, compno, level, orient, bpno, stepsize, numcomps, dwtid); - cumwmsedec += tmpwmsedec; - tile->distotile += tmpwmsedec; - - /* Code switch "RESTART" (i.e. TERMALL) */ - if ((cblksty & J3D_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) { - if (type == T1_TYPE_RAW) { - mqc_flush(mqc); - correction = 1; - /* correction = mqc_bypass_flush_enc(); */ - } else { /* correction = mqc_restart_enc(); */ - mqc_flush(mqc); - correction = 1; - } - pass->term = 1; - } else { - if (((bpno < (cblk->numbps - 4) && (passtype > 0)) - || ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) { - if (type == T1_TYPE_RAW) { - mqc_flush(mqc); - correction = 1; - /* correction = mqc_bypass_flush_enc(); */ - } else { /* correction = mqc_restart_enc(); */ - mqc_flush(mqc); - correction = 1; - } - pass->term = 1; - } else { - pass->term = 0; - } - } - - if (++passtype == 3) { - passtype = 0; - bpno--; - } - - if (pass->term && bpno > 0) { - type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; - if (type == T1_TYPE_RAW) - mqc_bypass_init_enc(mqc); - else - mqc_restart_init_enc(mqc); - } - - pass->distortiondec = cumwmsedec; - pass->rate = mqc_numbytes(mqc) + correction; /* FIXME */ - pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate); - - /* Code-switch "RESET" */ - if (cblksty & J3D_CCP_CBLKSTY_RESET) - mqc_reset_enc(mqc); - } - - /* Code switch "ERTERM" (i.e. PTERM) */ - if (cblksty & J3D_CCP_CBLKSTY_PTERM) - mqc_erterm_enc(mqc); - else /* Default coding */ if (!(cblksty & J3D_CCP_CBLKSTY_LAZY)) - mqc_flush(mqc); - - cblk->totalpasses = passno; -} - -static void t1_decode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty) { - int i, j, k, w, h, l; - int bpno, passtype; - int segno, passno; - char type = T1_TYPE_MQ; /* BYPASS mode */ - - opj_raw_t *raw = t1->raw; /* RAW component */ - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - w = cblk->x1 - cblk->x0; - h = cblk->y1 - cblk->y0; - l = cblk->z1 - cblk->z0; - - for (k = 0; k < l; k++) { - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - t1->data[k][j][i] = 0; - } - } - } - - for (k = 0; k <= l; k++) { - for (j = 0; j <= h; j++) { - for (i = 0; i <= w; i++) { - t1->flags[k][j][i] = 0; - } - } - } - - bpno = roishift + cblk->numbps - 1; - passtype = 2; - - mqc_reset_enc(mqc); - - for (segno = 0; segno < cblk->numsegs; segno++) { - opj_tcd_seg_t *seg = &cblk->segs[segno]; - - /* BYPASS mode */ - type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; - if (type == T1_TYPE_RAW) { - raw_init_dec(raw, seg->data, seg->len); - } else { - mqc_init_dec(mqc, seg->data, seg->len); - } - - for (passno = 0; passno < seg->numpasses; passno++) { - switch (passtype) { - case 0: - t1_dec_sigpass(t1, w, h, l, bpno+1, orient, type, cblksty); - break; - case 1: - t1_dec_refpass(t1, w, h, l, bpno+1, type, cblksty); - break; - case 2: - t1_dec_clnpass(t1, w, h, l, bpno+1, orient, cblksty); - break; - } - - if ((cblksty & J3D_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) { - mqc_reset_enc(mqc); - } - if (++passtype == 3) { - passtype = 0; - bpno--; - } - } - } -} - -static int t1_init_ctxno_zc(int f, int orient) { - int h, v, d, n, t, hv; - n = 0; - h = ((f & T1_SIG_W) != 0) + ((f & T1_SIG_E) != 0); - v = ((f & T1_SIG_N) != 0) + ((f & T1_SIG_S) != 0); - d = ((f & T1_SIG_NW) != 0) + ((f & T1_SIG_NE) != 0) + ((f & T1_SIG_SE) != 0) + ((f & T1_SIG_SW) != 0); - - switch (orient) { - case 2: - t = h; - h = v; - v = t; - case 0: - case 1: - if (!h) { - if (!v) { - if (!d) - n = 0; - else if (d == 1) - n = 1; - else - n = 2; - } else if (v == 1) { - n = 3; - } else { - n = 4; - } - } else if (h == 1) { - if (!v) { - if (!d) - n = 5; - else - n = 6; - } else { - n = 7; - } - } else - n = 8; - break; - case 3: - hv = h + v; - if (!d) { - if (!hv) { - n = 0; - } else if (hv == 1) { - n = 1; - } else { - n = 2; - } - } else if (d == 1) { - if (!hv) { - n = 3; - } else if (hv == 1) { - n = 4; - } else { - n = 5; - } - } else if (d == 2) { - if (!hv) { - n = 6; - } else { - n = 7; - } - } else { - n = 8; - } - break; - } - - return (T1_CTXNO_ZC + n); -} - -static int t1_init_ctxno_sc(int f) { - int hc, vc, n; - n = 0; - - hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) == - T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W), - 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) == - (T1_SIG_E | T1_SGN_E)) + - ((f & (T1_SIG_W | T1_SGN_W)) == - (T1_SIG_W | T1_SGN_W)), 1); - - vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) == - T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S), - 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) == - (T1_SIG_N | T1_SGN_N)) + - ((f & (T1_SIG_S | T1_SGN_S)) == - (T1_SIG_S | T1_SGN_S)), 1); - - if (hc < 0) { - hc = -hc; - vc = -vc; - } - if (!hc) { - if (vc == -1) - n = 1; - else if (!vc) - n = 0; - else - n = 1; - } else if (hc == 1) { - if (vc == -1) - n = 2; - else if (!vc) - n = 3; - else - n = 4; - } - - return (T1_CTXNO_SC + n); -} - -static int t1_init_ctxno_mag(int f) { - int n; - if (!(f & T1_REFINE)) - n = (f & (T1_SIG_OTH)) ? 1 : 0; - else - n = 2; - - return (T1_CTXNO_MAG + n); -} - -static int t1_init_spb(int f) { - int hc, vc, n; - - hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) == - T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W), - 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) == - (T1_SIG_E | T1_SGN_E)) + - ((f & (T1_SIG_W | T1_SGN_W)) == - (T1_SIG_W | T1_SGN_W)), 1); - - vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) == - T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S), - 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) == - (T1_SIG_N | T1_SGN_N)) + - ((f & (T1_SIG_S | T1_SGN_S)) == - (T1_SIG_S | T1_SGN_S)), 1); - - if (!hc && !vc) - n = 0; - else - n = (!(hc > 0 || (!hc && vc > 0))); - - return n; -} - -static void t1_init_luts(opj_t1_t *t1) { - int i, j; - double u, v, t; - for (j = 0; j < 4; j++) { - for (i = 0; i < 256; ++i) { - t1->lut_ctxno_zc[(j << 8) | i] = t1_init_ctxno_zc(i, j); - } - } - for (i = 0; i < 256; i++) { - t1->lut_ctxno_sc[i] = t1_init_ctxno_sc(i << 4); - } - for (j = 0; j < 2; j++) { - for (i = 0; i < 2048; ++i) { - t1->lut_ctxno_mag[(j << 11) + i] = t1_init_ctxno_mag((j ? T1_REFINE : 0) | i); - } - } - for (i = 0; i < 256; ++i) { - t1->lut_spb[i] = t1_init_spb(i << 4); - } - /* FIXME FIXME FIXME */ - /* fprintf(stdout,"nmsedec luts:\n"); */ - for (i = 0; i < (1 << T1_NMSEDEC_BITS); i++) { - t = i / pow(2, T1_NMSEDEC_FRACBITS); - u = t; - v = t - 1.5; - t1->lut_nmsedec_sig[i] = - int_max(0, - (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); - t1->lut_nmsedec_sig0[i] = - int_max(0, - (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); - u = t - 1.0; - if (i & (1 << (T1_NMSEDEC_BITS - 1))) { - v = t - 1.5; - } else { - v = t - 0.5; - } - t1->lut_nmsedec_ref[i] = - int_max(0, - (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); - t1->lut_nmsedec_ref0[i] = - int_max(0, - (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); - } -} - -/* ----------------------------------------------------------------------- */ - -opj_t1_t* t1_create(opj_common_ptr cinfo) { - opj_t1_t *t1 = (opj_t1_t*)opj_malloc(sizeof(opj_t1_t)); - if(t1) { - t1->cinfo = cinfo; - /* create MQC and RAW handles */ - t1->mqc = mqc_create(); - t1->raw = raw_create(); - /* initialize the look-up tables of the Tier-1 coder/decoder */ - t1_init_luts(t1); - } - return t1; -} - -void t1_destroy(opj_t1_t *t1) { - if(t1) { - /* destroy MQC and RAW handles */ - mqc_destroy(t1->mqc); - raw_destroy(t1->raw); - /*opj_free(t1->data);*/ - /*opj_free(t1->flags);*/ - opj_free(t1); - } -} - -void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { - int compno, resno, bandno, precno, cblkno; - int x, y, z, i, j, k, orient; - int n=0; - int level[3]; - FILE *fid = NULL; -/* char filename[10];*/ - tile->distotile = 0; /* fixed_quality */ - - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - - /* Weighted first order entropy - sprintf(filename,"res%d.txt",resno); - if ((fid = fopen(filename,"w")) == 0){ - fprintf(stdout,"Error while opening %s\n", filename); - exit(1); - } - */ - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - opj_tcd_precinct_t *prc = &band->precincts[precno]; - - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - - /*fprintf(stdout,"Precno %d Cblkno %d \n",precno,cblkno);*/ - if (band->bandno == 0) { - x = cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 1) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 2) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 3) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 4) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 5) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 6) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 7) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } - - if (tcp->tccps[compno].reversible == 1) { - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - t1->data[k][j][i] = - tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] << T1_NMSEDEC_FRACBITS; -/*fprintf(fid," %d",t1->data[k][j][i]);*/ - } - } - } - } else if (tcp->tccps[compno].reversible == 0) { - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - t1->data[k][j][i] = fix_mul( - tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)], - 8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (13 - T1_NMSEDEC_FRACBITS); - } - } - } - } - - orient = band->bandno; /* FIXME */ - if (orient == 2) { - orient = 1; - } else if (orient == 1) { - orient = 2; - } - for (i = 0; i < 3; i++) - level[i] = tilec->numresolution[i] - 1 - resno; - /*fprintf(stdout,"t1_encode_cblk(t1, cblk, %d, %d, %d %d %d, %d, %f, %d, %d, tile);\n", orient, compno, level[0], level[1], level[2], tcp->tccps[compno].reversible, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps);*/ - t1_encode_cblk(t1, cblk, orient, compno, level, tcp->tccps[compno].dwtid, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps, tile); - - } /* cblkno */ - } /* precno */ -/*fprintf(fid,"\n");*/ - } /* bandno */ -/*fclose(fid);*/ - } /* resno */ - } /* compno */ -} - -void t1_decode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { - int compno, resno, bandno, precno, cblkno; - - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - opj_tcd_precinct_t *prc = &band->precincts[precno]; - - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - int x, y, k, i, j, z, orient; - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - - orient = band->bandno; /* FIXME */ - if (orient == 2) { - orient = 1; - } else if (orient == 1) { - orient = 2; - } - - t1_decode_cblk(t1, cblk, orient, tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty); - - if (band->bandno == 0) { - x = cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 1) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 2) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 3) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 4) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 5) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 6) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 7) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } - - if (tcp->tccps[compno].roishift) { - int thresh, val, mag; - thresh = 1 << tcp->tccps[compno].roishift; - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - val = t1->data[k][j][i]; - mag = int_abs(val); - if (mag >= thresh) { - mag >>= tcp->tccps[compno].roishift; - t1->data[k][j][i] = val < 0 ? -mag : mag; - } - } - } - } - } - - if (tcp->tccps[compno].reversible == 1) { - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - int tmp = t1->data[k][j][i]; - tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = tmp/2; - } - } - } - } else { /* if (tcp->tccps[compno].reversible == 0) */ - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - double tmp = (double)(t1->data[k][j][i] * band->stepsize * 4096.0); - if (t1->data[k][j][i] >> 1 == 0) { - tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = 0; - } else { - int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); - tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = ((tmp<0)?-tmp2:tmp2); - } - } - } - } - } - } /* cblkno */ - } /* precno */ - } /* bandno */ - } /* resno */ - } /* compno */ -} - - -/** mod fixed_quality */ -double t1_getwmsedec(int nmsedec, int compno, int level[3], int orient, int bpno, double stepsize, int numcomps, int dwtid[3]) { - double w1, w2, wmsedec; - - if (dwtid[0] == 1 || dwtid[1] == 1 || dwtid[2] == 1) { - w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1; - } else { - w1 = (numcomps > 1) ? mct_getnorm(compno) : 1; - } - w2 = dwt_getnorm(orient, level, dwtid); - - /*fprintf(stdout,"nmsedec %d level %d %d %d orient %d bpno %d stepsize %f \n",nmsedec ,level[0],level[1],level[2],orient,bpno,stepsize);*/ - wmsedec = w1 * w2 * stepsize * (1 << bpno); - wmsedec *= wmsedec * nmsedec / 8192.0; - - return wmsedec; -} -/** mod fixed_quality */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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 "opj_includes.h" + +/** @defgroup T1 T1 - Implementation of the tier-1 coding */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +static int t1_getctxno_zc(opj_t1_t *t1, int f, int orient); +static int t1_getctxno_sc(opj_t1_t *t1, int f); +static int t1_getctxno_mag(opj_t1_t *t1, int f); +static int t1_getspb(opj_t1_t *t1, int f); +static int t1_getnmsedec_sig(opj_t1_t *t1, int x, int bitpos); +static int t1_getnmsedec_ref(opj_t1_t *t1, int x, int bitpos); +static void t1_updateflags(int *fp, int s); +/** +Encode significant pass +*/ +static void t1_enc_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc); +/** +Decode significant pass +*/ +static void t1_dec_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, char type, int vsc); +/** +Encode significant pass +*/ +static void t1_enc_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty); +/** +Decode significant pass +*/ +static void t1_dec_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty); +/** +Encode refinement pass +*/ +static void t1_enc_refpass_step(opj_t1_t *t1, int *fp, int *dp, int bpno, int one, int *nmsedec, char type, int vsc); +/** +Decode refinement pass +*/ +static void t1_dec_refpass_step(opj_t1_t *t1, int *fp, int *dp, int poshalf, int neghalf, char type, int vsc); +/** +Encode refinement pass +*/ +static void t1_enc_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty); +/** +Decode refinement pass +*/ +static void t1_dec_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, char type, int cblksty); +/** +Encode clean-up pass +*/ +static void t1_enc_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc); +/** +Decode clean-up pass +*/ +static void t1_dec_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, int partial, int vsc); +/** +Encode clean-up pass +*/ +static void t1_enc_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty); +/** +Decode clean-up pass +*/ +static void t1_dec_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int cblksty); +/** +Encode 1 code-block +@param t1 T1 handle +@param cblk Code-block coding parameters +@param orient +@param compno Component number +@param level +@param dwtid +@param stepsize +@param cblksty Code-block style +@param numcomps +@param tile +*/ +static void t1_encode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile); +/** +Decode 1 code-block +@param t1 T1 handle +@param cblk Code-block coding parameters +@param orient +@param roishift Region of interest shifting value +@param cblksty Code-block style +*/ +static void t1_decode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty); + +static int t1_init_ctxno_zc(int f, int orient); +static int t1_init_ctxno_sc(int f); +static int t1_init_ctxno_mag(int f); +static int t1_init_spb(int f); +/** +Initialize the look-up tables of the Tier-1 coder/decoder +@param t1 T1 handle +*/ +static void t1_init_luts(opj_t1_t *t1); + +/*@}*/ + +/*@}*/ + +/* ----------------------------------------------------------------------- */ + +static int t1_getctxno_zc(opj_t1_t *t1, int f, int orient) { + return t1->lut_ctxno_zc[(orient << 8) | (f & T1_SIG_OTH)]; +} + +static int t1_getctxno_sc(opj_t1_t *t1, int f) { + return t1->lut_ctxno_sc[(f & (T1_SIG_PRIM | T1_SGN)) >> 4]; +} + +static int t1_getctxno_mag(opj_t1_t *t1, int f) { + return t1->lut_ctxno_mag[(f & T1_SIG_OTH) | (((f & T1_REFINE) != 0) << 11)]; +} + +static int t1_getspb(opj_t1_t *t1, int f) { + return t1->lut_spb[(f & (T1_SIG_PRIM | T1_SGN)) >> 4]; +} + +static int t1_getnmsedec_sig(opj_t1_t *t1, int x, int bitpos) { + if (bitpos > T1_NMSEDEC_FRACBITS) { + return t1->lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; + } + + return t1->lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; +} + +static int t1_getnmsedec_ref(opj_t1_t *t1, int x, int bitpos) { + if (bitpos > T1_NMSEDEC_FRACBITS) { + return t1->lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; + } + + return t1->lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; +} + +static void t1_updateflags(int *fp, int s) { + int *np = fp - (T1_MAXCBLKW + 2); + int *sp = fp + (T1_MAXCBLKW + 2); + np[-1] |= T1_SIG_SE; + np[1] |= T1_SIG_SW; + sp[-1] |= T1_SIG_NE; + sp[1] |= T1_SIG_NW; + *np |= T1_SIG_S; + *sp |= T1_SIG_N; + fp[-1] |= T1_SIG_E; + fp[1] |= T1_SIG_W; + if (s) { + *np |= T1_SGN_S; + *sp |= T1_SGN_N; + fp[-1] |= T1_SGN_E; + fp[1] |= T1_SGN_W; + } +} + +static void t1_enc_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc) { + int v, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); + if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { + v = int_abs(*dp) & one ? 1 : 0; + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); /* ESSAI */ + mqc_bypass_enc(mqc, v); + } else { + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); + mqc_encode(mqc, v); + } + if (v) { + v = *dp < 0 ? 1 : 0; + *nmsedec += t1_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); /* ESSAI */ + mqc_bypass_enc(mqc, v); + } else { + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); + mqc_encode(mqc, v ^ t1_getspb(t1, flag)); + } + t1_updateflags(fp, v); + *fp |= T1_SIG; + } + *fp |= T1_VISIT; + } +} + +static void t1_dec_sigpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, char type, int vsc) { + int v, flag; + + opj_raw_t *raw = t1->raw; /* RAW component */ + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); + if ((flag & T1_SIG_OTH) && !(flag & (T1_SIG | T1_VISIT))) { + if (type == T1_TYPE_RAW) { + if (raw_decode(raw)) { + v = raw_decode(raw); /* ESSAI */ + *dp = v ? -oneplushalf : oneplushalf; + t1_updateflags(fp, v); + *fp |= T1_SIG; + } + } else { + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); + if (mqc_decode(mqc)) { + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); + v = mqc_decode(mqc) ^ t1_getspb(t1, flag); + *dp = v ? -oneplushalf : oneplushalf; + t1_updateflags(fp, v); + *fp |= T1_SIG; + } + } + *fp |= T1_VISIT; + } +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty) { + int i, j, k, m, one, vsc; + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + for (j = k; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_enc_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, type, vsc); + } + } + } + } +} + +static void t1_dec_sigpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty) { + int i, j, k, m, one, half, oneplushalf, vsc; + one = 1 << bpno; + half = one >> 1; + oneplushalf = one | half; + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + for (j = k; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_dec_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, type, vsc); + } + } + } + } +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_refpass_step(opj_t1_t *t1, int *fp, int *dp, int bpno, int one, int *nmsedec, char type, int vsc) { + int v, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); + if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { + *nmsedec += t1_getnmsedec_ref(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + v = int_abs(*dp) & one ? 1 : 0; + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); /* ESSAI */ + mqc_bypass_enc(mqc, v); + } else { + mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); + mqc_encode(mqc, v); + } + *fp |= T1_REFINE; + } +} + +static void t1_dec_refpass_step(opj_t1_t *t1, int *fp, int *dp, int poshalf, int neghalf, char type, int vsc) { + int v, t, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + opj_raw_t *raw = t1->raw; /* RAW component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); + if ((flag & (T1_SIG | T1_VISIT)) == T1_SIG) { + if (type == T1_TYPE_RAW) { + mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); /* ESSAI */ + v = raw_decode(raw); + } else { + mqc_setcurctx(mqc, t1_getctxno_mag(t1, flag)); + v = mqc_decode(mqc); + } + t = v ? poshalf : neghalf; + *dp += *dp < 0 ? -t : t; + *fp |= T1_REFINE; + } +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty) { + int i, j, k, m, one, vsc; + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + for (j = k; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_enc_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], bpno, one, nmsedec, type, vsc); + } + } + } + } +} + +static void t1_dec_refpass(opj_t1_t *t1, int w, int h, int l, int bpno, char type, int cblksty) { + int i, j, k, m, one, poshalf, neghalf; + int vsc; + one = 1 << bpno; + poshalf = one >> 1; + neghalf = bpno > 0 ? -poshalf : -1; + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + for (j = k; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_dec_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], poshalf, neghalf, type, vsc); + } + } + } + } +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc) { + int v, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); + if (partial) { + goto LABEL_PARTIAL; + } + if (!(*fp & (T1_SIG | T1_VISIT))) { + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); + v = int_abs(*dp) & one ? 1 : 0; + mqc_encode(mqc, v); + if (v) { +LABEL_PARTIAL: + *nmsedec += t1_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); + v = *dp < 0 ? 1 : 0; + mqc_encode(mqc, v ^ t1_getspb(t1, flag)); + t1_updateflags(fp, v); + *fp |= T1_SIG; + } + } + *fp &= ~T1_VISIT; +} + +static void t1_dec_clnpass_step(opj_t1_t *t1, int *fp, int *dp, int orient, int oneplushalf, int partial, int vsc) { + int v, flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) : (*fp); + if (partial) { + goto LABEL_PARTIAL; + } + if (!(flag & (T1_SIG | T1_VISIT))) { + mqc_setcurctx(mqc, t1_getctxno_zc(t1, flag, orient)); + if (mqc_decode(mqc)) { +LABEL_PARTIAL: + mqc_setcurctx(mqc, t1_getctxno_sc(t1, flag)); + v = mqc_decode(mqc) ^ t1_getspb(t1, flag); + *dp = v ? -oneplushalf : oneplushalf; + t1_updateflags(fp, v); + *fp |= T1_SIG; + } + } + *fp &= ~T1_VISIT; +} /* VSC and BYPASS by Antonin */ + +static void t1_enc_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty) { + int i, j, k, m, one, agg, runlen, vsc; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + if (k + 3 < h) { + if (cblksty & J3D_CCP_CBLKSTY_VSC) { + agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || (t1->flags[1 + m][1 + k + 3][1 + i] + & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH)); + } else { + agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 3][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)); + } + } else { + agg = 0; + } + if (agg) { + for (runlen = 0; runlen < 4; runlen++) { + if (int_abs(t1->data[m][k + runlen][i]) & one) + break; + } + mqc_setcurctx(mqc, T1_CTXNO_AGG); + mqc_encode(mqc, runlen != 4); + if (runlen == 4) { + continue; + } + mqc_setcurctx(mqc, T1_CTXNO_UNI); + mqc_encode(mqc, runlen >> 1); + mqc_encode(mqc, runlen & 1); + } else { + runlen = 0; + } + for (j = k + runlen; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_enc_clnpass_step(t1, &(t1->flags[1 + m][1 + j][1 + i]), &(t1->data[m][j][i]), orient, bpno, one, nmsedec, agg && (j == k + runlen), vsc); + } + } + } + } +} + +static void t1_dec_clnpass(opj_t1_t *t1, int w, int h, int l, int bpno, int orient, int cblksty) { + int i, j, k, m, one, half, oneplushalf, agg, runlen, vsc; + int segsym = cblksty & J3D_CCP_CBLKSTY_SEGSYM; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + one = 1 << bpno; + half = one >> 1; + oneplushalf = one | half; + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + if (k + 3 < h) { + if (cblksty & J3D_CCP_CBLKSTY_VSC) { + agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || (t1->flags[1 + m][1 + k + 3][1 + i] + & (~(T1_SIG_S | T1_SIG_SE | T1_SIG_SW | T1_SGN_S))) & (T1_SIG | T1_VISIT | T1_SIG_OTH)); + } else { + agg = !(t1->flags[1 + m][1 + k][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 1][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 2][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH) + || t1->flags[1 + m][1 + k + 3][1 + i] & (T1_SIG | T1_VISIT | T1_SIG_OTH)); + } + } else { + agg = 0; + } + if (agg) { + mqc_setcurctx(mqc, T1_CTXNO_AGG); + if (!mqc_decode(mqc)) { + continue; + } + mqc_setcurctx(mqc, T1_CTXNO_UNI); + runlen = mqc_decode(mqc); + runlen = (runlen << 1) | mqc_decode(mqc); + } else { + runlen = 0; + } + for (j = k + runlen; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_dec_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, agg && (j == k + runlen), vsc); + } + } + } + } + if (segsym) { + int v = 0; + mqc_setcurctx(mqc, T1_CTXNO_UNI); + v = mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + /* + if (v!=0xa) { + opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v); + } + */ + } +} /* VSC and BYPASS by Antonin */ + + +static void t1_encode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile) { + int i, j, k; + int w, h, l; + int passno; + int bpno, passtype; + int max; + int nmsedec = 0; + double cumwmsedec = 0; + char type = T1_TYPE_MQ; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + w = cblk->x1 - cblk->x0; + h = cblk->y1 - cblk->y0; + l = cblk->z1 - cblk->z0; + + max = 0; + for (k = 0; k < l; k++) { + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + max = int_max(max, int_abs(t1->data[k][j][i])); + } + } + } + for (k = 0; k <= l; k++) { + for (j = 0; j <= h; j++) { + for (i = 0; i <= w; i++) { + t1->flags[k][j][i] = 0; + } + } + } + + cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0; + + bpno = cblk->numbps - 1; + passtype = 2; + + mqc_reset_enc(mqc); + mqc_init_enc(mqc, cblk->data); + + for (passno = 0; bpno >= 0; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + int correction = 3; + double tmpwmsedec; + type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + /*fprintf(stdout,"passno %d passtype %d w %d h %d l %d bpno %d orient %d type %d cblksty %d\n",passno,passtype,w,h,l,bpno,orient,type,cblksty);*/ + + switch (passtype) { + case 0: + t1_enc_sigpass(t1, w, h, l, bpno, orient, &nmsedec, type, cblksty); + break; + case 1: + t1_enc_refpass(t1, w, h, l, bpno, &nmsedec, type, cblksty); + break; + case 2: + /*fprintf(stdout,"w %d h %d l %d bpno %d orient %d \n",w,h,l,bpno,orient);*/ + t1_enc_clnpass(t1, w, h, l, bpno, orient, &nmsedec, cblksty); + /* code switch SEGMARK (i.e. SEGSYM) */ + if (cblksty & J3D_CCP_CBLKSTY_SEGSYM) + mqc_segmark_enc(mqc); + break; + } + + /* fixed_quality */ + tmpwmsedec = t1_getwmsedec(nmsedec, compno, level, orient, bpno, stepsize, numcomps, dwtid); + cumwmsedec += tmpwmsedec; + tile->distotile += tmpwmsedec; + + /* Code switch "RESTART" (i.e. TERMALL) */ + if ((cblksty & J3D_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) { + if (type == T1_TYPE_RAW) { + mqc_flush(mqc); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(mqc); + correction = 1; + } + pass->term = 1; + } else { + if (((bpno < (cblk->numbps - 4) && (passtype > 0)) + || ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) { + if (type == T1_TYPE_RAW) { + mqc_flush(mqc); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(mqc); + correction = 1; + } + pass->term = 1; + } else { + pass->term = 0; + } + } + + if (++passtype == 3) { + passtype = 0; + bpno--; + } + + if (pass->term && bpno > 0) { + type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + if (type == T1_TYPE_RAW) + mqc_bypass_init_enc(mqc); + else + mqc_restart_init_enc(mqc); + } + + pass->distortiondec = cumwmsedec; + pass->rate = mqc_numbytes(mqc) + correction; /* FIXME */ + pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate); + + /* Code-switch "RESET" */ + if (cblksty & J3D_CCP_CBLKSTY_RESET) + mqc_reset_enc(mqc); + } + + /* Code switch "ERTERM" (i.e. PTERM) */ + if (cblksty & J3D_CCP_CBLKSTY_PTERM) + mqc_erterm_enc(mqc); + else /* Default coding */ if (!(cblksty & J3D_CCP_CBLKSTY_LAZY)) + mqc_flush(mqc); + + cblk->totalpasses = passno; +} + +static void t1_decode_cblk(opj_t1_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty) { + int i, j, k, w, h, l; + int bpno, passtype; + int segno, passno; + char type = T1_TYPE_MQ; /* BYPASS mode */ + + opj_raw_t *raw = t1->raw; /* RAW component */ + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + w = cblk->x1 - cblk->x0; + h = cblk->y1 - cblk->y0; + l = cblk->z1 - cblk->z0; + + for (k = 0; k < l; k++) { + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + t1->data[k][j][i] = 0; + } + } + } + + for (k = 0; k <= l; k++) { + for (j = 0; j <= h; j++) { + for (i = 0; i <= w; i++) { + t1->flags[k][j][i] = 0; + } + } + } + + bpno = roishift + cblk->numbps - 1; + passtype = 2; + + mqc_reset_enc(mqc); + + for (segno = 0; segno < cblk->numsegs; segno++) { + opj_tcd_seg_t *seg = &cblk->segs[segno]; + + /* BYPASS mode */ + type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + if (type == T1_TYPE_RAW) { + raw_init_dec(raw, seg->data, seg->len); + } else { + mqc_init_dec(mqc, seg->data, seg->len); + } + + for (passno = 0; passno < seg->numpasses; passno++) { + switch (passtype) { + case 0: + t1_dec_sigpass(t1, w, h, l, bpno+1, orient, type, cblksty); + break; + case 1: + t1_dec_refpass(t1, w, h, l, bpno+1, type, cblksty); + break; + case 2: + t1_dec_clnpass(t1, w, h, l, bpno+1, orient, cblksty); + break; + } + + if ((cblksty & J3D_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) { + mqc_reset_enc(mqc); + } + if (++passtype == 3) { + passtype = 0; + bpno--; + } + } + } +} + +static int t1_init_ctxno_zc(int f, int orient) { + int h, v, d, n, t, hv; + n = 0; + h = ((f & T1_SIG_W) != 0) + ((f & T1_SIG_E) != 0); + v = ((f & T1_SIG_N) != 0) + ((f & T1_SIG_S) != 0); + d = ((f & T1_SIG_NW) != 0) + ((f & T1_SIG_NE) != 0) + ((f & T1_SIG_SE) != 0) + ((f & T1_SIG_SW) != 0); + + switch (orient) { + case 2: + t = h; + h = v; + v = t; + case 0: + case 1: + if (!h) { + if (!v) { + if (!d) + n = 0; + else if (d == 1) + n = 1; + else + n = 2; + } else if (v == 1) { + n = 3; + } else { + n = 4; + } + } else if (h == 1) { + if (!v) { + if (!d) + n = 5; + else + n = 6; + } else { + n = 7; + } + } else + n = 8; + break; + case 3: + hv = h + v; + if (!d) { + if (!hv) { + n = 0; + } else if (hv == 1) { + n = 1; + } else { + n = 2; + } + } else if (d == 1) { + if (!hv) { + n = 3; + } else if (hv == 1) { + n = 4; + } else { + n = 5; + } + } else if (d == 2) { + if (!hv) { + n = 6; + } else { + n = 7; + } + } else { + n = 8; + } + break; + } + + return (T1_CTXNO_ZC + n); +} + +static int t1_init_ctxno_sc(int f) { + int hc, vc, n; + n = 0; + + hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) == + T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W), + 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) == + (T1_SIG_E | T1_SGN_E)) + + ((f & (T1_SIG_W | T1_SGN_W)) == + (T1_SIG_W | T1_SGN_W)), 1); + + vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) == + T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S), + 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) == + (T1_SIG_N | T1_SGN_N)) + + ((f & (T1_SIG_S | T1_SGN_S)) == + (T1_SIG_S | T1_SGN_S)), 1); + + if (hc < 0) { + hc = -hc; + vc = -vc; + } + if (!hc) { + if (vc == -1) + n = 1; + else if (!vc) + n = 0; + else + n = 1; + } else if (hc == 1) { + if (vc == -1) + n = 2; + else if (!vc) + n = 3; + else + n = 4; + } + + return (T1_CTXNO_SC + n); +} + +static int t1_init_ctxno_mag(int f) { + int n; + if (!(f & T1_REFINE)) + n = (f & (T1_SIG_OTH)) ? 1 : 0; + else + n = 2; + + return (T1_CTXNO_MAG + n); +} + +static int t1_init_spb(int f) { + int hc, vc, n; + + hc = int_min(((f & (T1_SIG_E | T1_SGN_E)) == + T1_SIG_E) + ((f & (T1_SIG_W | T1_SGN_W)) == T1_SIG_W), + 1) - int_min(((f & (T1_SIG_E | T1_SGN_E)) == + (T1_SIG_E | T1_SGN_E)) + + ((f & (T1_SIG_W | T1_SGN_W)) == + (T1_SIG_W | T1_SGN_W)), 1); + + vc = int_min(((f & (T1_SIG_N | T1_SGN_N)) == + T1_SIG_N) + ((f & (T1_SIG_S | T1_SGN_S)) == T1_SIG_S), + 1) - int_min(((f & (T1_SIG_N | T1_SGN_N)) == + (T1_SIG_N | T1_SGN_N)) + + ((f & (T1_SIG_S | T1_SGN_S)) == + (T1_SIG_S | T1_SGN_S)), 1); + + if (!hc && !vc) + n = 0; + else + n = (!(hc > 0 || (!hc && vc > 0))); + + return n; +} + +static void t1_init_luts(opj_t1_t *t1) { + int i, j; + double u, v, t; + for (j = 0; j < 4; j++) { + for (i = 0; i < 256; ++i) { + t1->lut_ctxno_zc[(j << 8) | i] = t1_init_ctxno_zc(i, j); + } + } + for (i = 0; i < 256; i++) { + t1->lut_ctxno_sc[i] = t1_init_ctxno_sc(i << 4); + } + for (j = 0; j < 2; j++) { + for (i = 0; i < 2048; ++i) { + t1->lut_ctxno_mag[(j << 11) + i] = t1_init_ctxno_mag((j ? T1_REFINE : 0) | i); + } + } + for (i = 0; i < 256; ++i) { + t1->lut_spb[i] = t1_init_spb(i << 4); + } + /* FIXME FIXME FIXME */ + /* fprintf(stdout,"nmsedec luts:\n"); */ + for (i = 0; i < (1 << T1_NMSEDEC_BITS); i++) { + t = i / pow(2, T1_NMSEDEC_FRACBITS); + u = t; + v = t - 1.5; + t1->lut_nmsedec_sig[i] = + int_max(0, + (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + t1->lut_nmsedec_sig0[i] = + int_max(0, + (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + u = t - 1.0; + if (i & (1 << (T1_NMSEDEC_BITS - 1))) { + v = t - 1.5; + } else { + v = t - 0.5; + } + t1->lut_nmsedec_ref[i] = + int_max(0, + (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + t1->lut_nmsedec_ref0[i] = + int_max(0, + (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + } +} + +/* ----------------------------------------------------------------------- */ + +opj_t1_t* t1_create(opj_common_ptr cinfo) { + opj_t1_t *t1 = (opj_t1_t*)opj_malloc(sizeof(opj_t1_t)); + if(t1) { + t1->cinfo = cinfo; + /* create MQC and RAW handles */ + t1->mqc = mqc_create(); + t1->raw = raw_create(); + /* initialize the look-up tables of the Tier-1 coder/decoder */ + t1_init_luts(t1); + } + return t1; +} + +void t1_destroy(opj_t1_t *t1) { + if(t1) { + /* destroy MQC and RAW handles */ + mqc_destroy(t1->mqc); + raw_destroy(t1->raw); + /*opj_free(t1->data);*/ + /*opj_free(t1->flags);*/ + opj_free(t1); + } +} + +void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { + int compno, resno, bandno, precno, cblkno; + int x, y, z, i, j, k, orient; + int n=0; + int level[3]; + FILE *fid = NULL; +/* char filename[10];*/ + tile->distotile = 0; /* fixed_quality */ + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + /* Weighted first order entropy + sprintf(filename,"res%d.txt",resno); + if ((fid = fopen(filename,"w")) == 0){ + fprintf(stdout,"Error while opening %s\n", filename); + exit(1); + } + */ + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + + /*fprintf(stdout,"Precno %d Cblkno %d \n",precno,cblkno);*/ + if (band->bandno == 0) { + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 1) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 2) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 3) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 4) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 5) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 6) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 7) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } + + if (tcp->tccps[compno].reversible == 1) { + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + t1->data[k][j][i] = + tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] << T1_NMSEDEC_FRACBITS; +/*fprintf(fid," %d",t1->data[k][j][i]);*/ + } + } + } + } else if (tcp->tccps[compno].reversible == 0) { + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + t1->data[k][j][i] = fix_mul( + tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)], + 8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (13 - T1_NMSEDEC_FRACBITS); + } + } + } + } + + orient = band->bandno; /* FIXME */ + if (orient == 2) { + orient = 1; + } else if (orient == 1) { + orient = 2; + } + for (i = 0; i < 3; i++) + level[i] = tilec->numresolution[i] - 1 - resno; + /*fprintf(stdout,"t1_encode_cblk(t1, cblk, %d, %d, %d %d %d, %d, %f, %d, %d, tile);\n", orient, compno, level[0], level[1], level[2], tcp->tccps[compno].reversible, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps);*/ + t1_encode_cblk(t1, cblk, orient, compno, level, tcp->tccps[compno].dwtid, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps, tile); + + } /* cblkno */ + } /* precno */ +/*fprintf(fid,"\n");*/ + } /* bandno */ +/*fclose(fid);*/ + } /* resno */ + } /* compno */ +} + +void t1_decode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { + int compno, resno, bandno, precno, cblkno; + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + int x, y, k, i, j, z, orient; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + + orient = band->bandno; /* FIXME */ + if (orient == 2) { + orient = 1; + } else if (orient == 1) { + orient = 2; + } + + t1_decode_cblk(t1, cblk, orient, tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty); + + if (band->bandno == 0) { + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 1) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 2) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 3) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 4) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 5) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 6) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 7) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } + + if (tcp->tccps[compno].roishift) { + int thresh, val, mag; + thresh = 1 << tcp->tccps[compno].roishift; + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + val = t1->data[k][j][i]; + mag = int_abs(val); + if (mag >= thresh) { + mag >>= tcp->tccps[compno].roishift; + t1->data[k][j][i] = val < 0 ? -mag : mag; + } + } + } + } + } + + if (tcp->tccps[compno].reversible == 1) { + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + int tmp = t1->data[k][j][i]; + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = tmp/2; + } + } + } + } else { /* if (tcp->tccps[compno].reversible == 0) */ + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + double tmp = (double)(t1->data[k][j][i] * band->stepsize * 4096.0); + if (t1->data[k][j][i] >> 1 == 0) { + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = 0; + } else { + int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = ((tmp<0)?-tmp2:tmp2); + } + } + } + } + } + } /* cblkno */ + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ +} + + +/** mod fixed_quality */ +double t1_getwmsedec(int nmsedec, int compno, int level[3], int orient, int bpno, double stepsize, int numcomps, int dwtid[3]) { + double w1, w2, wmsedec; + + if (dwtid[0] == 1 || dwtid[1] == 1 || dwtid[2] == 1) { + w1 = (numcomps > 1) ? mct_getnorm_real(compno) : 1; + } else { + w1 = (numcomps > 1) ? mct_getnorm(compno) : 1; + } + w2 = dwt_getnorm(orient, level, dwtid); + + /*fprintf(stdout,"nmsedec %d level %d %d %d orient %d bpno %d stepsize %f \n",nmsedec ,level[0],level[1],level[2],orient,bpno,stepsize);*/ + wmsedec = w1 * w2 * stepsize * (1 << bpno); + wmsedec *= wmsedec * nmsedec / 8192.0; + + return wmsedec; +} +/** mod fixed_quality */ diff --git a/src/lib/openjp3d/t1.h b/src/lib/openjp3d/t1.h old mode 100755 new mode 100644 index 1863484c..138f04c7 --- a/src/lib/openjp3d/t1.h +++ b/src/lib/openjp3d/t1.h @@ -1,173 +1,173 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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. - */ -#ifndef __T1_H -#define __T1_H -/** -@file t1.h -@brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1) - -The functions in T1.C have for goal to realize the tier-1 coding operation. The functions -in T1.C are used by some function in TCD.C. -*/ - -/** @defgroup T1 T1 - Implementation of the tier-1 coding */ -/*@{*/ - -/* ----------------------------------------------------------------------- */ -#define T1_NMSEDEC_BITS 7 - -#define T1_MAXCBLKW 256 /*< Maximum size of code-block (width) */ -#define T1_MAXCBLKH 256 /*< Maximum size of code-block (heigth) */ -#define T1_MAXCBLKD 256 /*< Maximum size of code-block (depth) */ -#define T1_MINCBLKW 4 /*< Minimum size of code-block (width) */ -#define T1_MINCBLKH 4 /*< Minimum size of code-block (heigth) */ -#define T1_MINCBLKD 4 /*< Minimum size of code-block (depth) */ -#define T1_MAXWHD 18 -#define T1_CBLKW 256 -#define T1_CBLKH 256 -#define T1_CBLKD 256 - -#define T1_SIG_NE 0x0001 /*< Context orientation : North-East direction */ -#define T1_SIG_SE 0x0002 /*< Context orientation : South-East direction */ -#define T1_SIG_SW 0x0004 /*< Context orientation : South-West direction */ -#define T1_SIG_NW 0x0008 /*< Context orientation : North-West direction */ -#define T1_SIG_N 0x0010 /*< Context orientation : North direction */ -#define T1_SIG_E 0x0020 /*< Context orientation : East direction */ -#define T1_SIG_S 0x0040 /*< Context orientation : South direction */ -#define T1_SIG_W 0x0080 /*< Context orientation : West direction */ -#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW) -#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W) - -#define T1_SGN_N 0x0100 -#define T1_SGN_E 0x0200 -#define T1_SGN_S 0x0400 -#define T1_SGN_W 0x0800 -#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W) - -#define T1_SIG 0x1000 -#define T1_REFINE 0x2000 -#define T1_VISIT 0x4000 - -#define T1_NUMCTXS_AGG 1 -#define T1_NUMCTXS_ZC 9 -#define T1_NUMCTXS_MAG 3 -#define T1_NUMCTXS_SC 5 -#define T1_NUMCTXS_UNI 1 - -#define T1_CTXNO_AGG 0 -#define T1_CTXNO_ZC (T1_CTXNO_AGG+T1_NUMCTXS_AGG) -#define T1_CTXNO_MAG (T1_CTXNO_ZC+T1_NUMCTXS_ZC) -#define T1_CTXNO_SC (T1_CTXNO_MAG+T1_NUMCTXS_MAG) -#define T1_CTXNO_UNI (T1_CTXNO_SC+T1_NUMCTXS_SC) -#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI) - -#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1) - -#define T1_TYPE_MQ 0 /*< Normal coding using entropy coder */ -#define T1_TYPE_RAW 1 /*< No encoding the information is store under raw format in codestream (mode switch RAW)*/ - -/* ----------------------------------------------------------------------- */ - -/** -Tier-1 coding (coding of code-block coefficients) -*/ -typedef struct opj_t1 { - /** codec context */ - opj_common_ptr cinfo; - - /** MQC component */ - opj_mqc_t *mqc; - /** RAW component */ - opj_raw_t *raw; - /** LUTs for context-based coding */ - int lut_ctxno_zc[1024]; - int lut_ctxno_sc[256]; - int lut_ctxno_mag[4096]; - int lut_spb[256]; - /** LUTs for decoding normalised MSE */ - int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS]; - int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS]; - int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS]; - int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS]; - /** Codeblock data */ - int data[T1_CBLKD][T1_CBLKH][T1_CBLKW];/*int ***data;*/ - /** Context information for each voxel in codeblock */ - int flags[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2];/*int ***flags;*/ -} opj_t1_t; - -/** @name Exported functions */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Create a new T1 handle -and initialize the look-up tables of the Tier-1 coder/decoder -@return Returns a new T1 handle if successful, returns NULL otherwise -@see t1_init_luts -*/ -opj_t1_t* t1_create(opj_common_ptr cinfo); -/** -Destroy a previously created T1 handle -@param t1 T1 handle to destroy -*/ -void t1_destroy(opj_t1_t *t1); -/** -Encode the code-blocks of a tile -@param t1 T1 handle -@param tile The tile to encode -@param tcp Tile coding parameters -*/ -void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); -/** -Decode the code-blocks of a tile -@param t1 T1 handle -@param tile The tile to decode -@param tcp Tile coding parameters -*/ -void t1_decode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); -/** -Get weigths of MSE decoding -@param nmsedec The normalized MSE reduction -@param compno -@param level -@param orient -@param bpno -@param stepsize -@param numcomps -@param dwtid -returns MSE associated to decoding pass -*/ -double t1_getwmsedec(int nmsedec, int compno, int level[3], int orient, int bpno, double stepsize, int numcomps, int dwtid[3]); - -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __T1_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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. + */ +#ifndef __T1_H +#define __T1_H +/** +@file t1.h +@brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1) + +The functions in T1.C have for goal to realize the tier-1 coding operation. The functions +in T1.C are used by some function in TCD.C. +*/ + +/** @defgroup T1 T1 - Implementation of the tier-1 coding */ +/*@{*/ + +/* ----------------------------------------------------------------------- */ +#define T1_NMSEDEC_BITS 7 + +#define T1_MAXCBLKW 256 /*< Maximum size of code-block (width) */ +#define T1_MAXCBLKH 256 /*< Maximum size of code-block (heigth) */ +#define T1_MAXCBLKD 256 /*< Maximum size of code-block (depth) */ +#define T1_MINCBLKW 4 /*< Minimum size of code-block (width) */ +#define T1_MINCBLKH 4 /*< Minimum size of code-block (heigth) */ +#define T1_MINCBLKD 4 /*< Minimum size of code-block (depth) */ +#define T1_MAXWHD 18 +#define T1_CBLKW 256 +#define T1_CBLKH 256 +#define T1_CBLKD 256 + +#define T1_SIG_NE 0x0001 /*< Context orientation : North-East direction */ +#define T1_SIG_SE 0x0002 /*< Context orientation : South-East direction */ +#define T1_SIG_SW 0x0004 /*< Context orientation : South-West direction */ +#define T1_SIG_NW 0x0008 /*< Context orientation : North-West direction */ +#define T1_SIG_N 0x0010 /*< Context orientation : North direction */ +#define T1_SIG_E 0x0020 /*< Context orientation : East direction */ +#define T1_SIG_S 0x0040 /*< Context orientation : South direction */ +#define T1_SIG_W 0x0080 /*< Context orientation : West direction */ +#define T1_SIG_OTH (T1_SIG_N|T1_SIG_NE|T1_SIG_E|T1_SIG_SE|T1_SIG_S|T1_SIG_SW|T1_SIG_W|T1_SIG_NW) +#define T1_SIG_PRIM (T1_SIG_N|T1_SIG_E|T1_SIG_S|T1_SIG_W) + +#define T1_SGN_N 0x0100 +#define T1_SGN_E 0x0200 +#define T1_SGN_S 0x0400 +#define T1_SGN_W 0x0800 +#define T1_SGN (T1_SGN_N|T1_SGN_E|T1_SGN_S|T1_SGN_W) + +#define T1_SIG 0x1000 +#define T1_REFINE 0x2000 +#define T1_VISIT 0x4000 + +#define T1_NUMCTXS_AGG 1 +#define T1_NUMCTXS_ZC 9 +#define T1_NUMCTXS_MAG 3 +#define T1_NUMCTXS_SC 5 +#define T1_NUMCTXS_UNI 1 + +#define T1_CTXNO_AGG 0 +#define T1_CTXNO_ZC (T1_CTXNO_AGG+T1_NUMCTXS_AGG) +#define T1_CTXNO_MAG (T1_CTXNO_ZC+T1_NUMCTXS_ZC) +#define T1_CTXNO_SC (T1_CTXNO_MAG+T1_NUMCTXS_MAG) +#define T1_CTXNO_UNI (T1_CTXNO_SC+T1_NUMCTXS_SC) +#define T1_NUMCTXS (T1_CTXNO_UNI+T1_NUMCTXS_UNI) + +#define T1_NMSEDEC_FRACBITS (T1_NMSEDEC_BITS-1) + +#define T1_TYPE_MQ 0 /*< Normal coding using entropy coder */ +#define T1_TYPE_RAW 1 /*< No encoding the information is store under raw format in codestream (mode switch RAW)*/ + +/* ----------------------------------------------------------------------- */ + +/** +Tier-1 coding (coding of code-block coefficients) +*/ +typedef struct opj_t1 { + /** codec context */ + opj_common_ptr cinfo; + + /** MQC component */ + opj_mqc_t *mqc; + /** RAW component */ + opj_raw_t *raw; + /** LUTs for context-based coding */ + int lut_ctxno_zc[1024]; + int lut_ctxno_sc[256]; + int lut_ctxno_mag[4096]; + int lut_spb[256]; + /** LUTs for decoding normalised MSE */ + int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS]; + /** Codeblock data */ + int data[T1_CBLKD][T1_CBLKH][T1_CBLKW];/*int ***data;*/ + /** Context information for each voxel in codeblock */ + int flags[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2];/*int ***flags;*/ +} opj_t1_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new T1 handle +and initialize the look-up tables of the Tier-1 coder/decoder +@return Returns a new T1 handle if successful, returns NULL otherwise +@see t1_init_luts +*/ +opj_t1_t* t1_create(opj_common_ptr cinfo); +/** +Destroy a previously created T1 handle +@param t1 T1 handle to destroy +*/ +void t1_destroy(opj_t1_t *t1); +/** +Encode the code-blocks of a tile +@param t1 T1 handle +@param tile The tile to encode +@param tcp Tile coding parameters +*/ +void t1_encode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); +/** +Decode the code-blocks of a tile +@param t1 T1 handle +@param tile The tile to decode +@param tcp Tile coding parameters +*/ +void t1_decode_cblks(opj_t1_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); +/** +Get weigths of MSE decoding +@param nmsedec The normalized MSE reduction +@param compno +@param level +@param orient +@param bpno +@param stepsize +@param numcomps +@param dwtid +returns MSE associated to decoding pass +*/ +double t1_getwmsedec(int nmsedec, int compno, int level[3], int orient, int bpno, double stepsize, int numcomps, int dwtid[3]); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __T1_H */ diff --git a/src/lib/openjp3d/t1_3d.c b/src/lib/openjp3d/t1_3d.c old mode 100755 new mode 100644 index 24038242..63332d21 --- a/src/lib/openjp3d/t1_3d.c +++ b/src/lib/openjp3d/t1_3d.c @@ -1,1230 +1,1230 @@ -/* - * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain - * 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" - -/** @defgroup T1_3D T1_3D - Implementation of the tier-1 coding */ -/*@{*/ - -/** @name Local static functions */ -/*@{*/ - -static int t1_3d_getctxno_zc(unsigned int f, int orient); -static int t1_3d_getctxno_sc(unsigned int f); -static int t1_3d_getctxno_mag(unsigned int f, int fsvr); -static int t1_3d_getspb(unsigned int f); -static int t1_3d_getnmsedec_sig(opj_t1_3d_t *t1, int x, int bitpos); -static int t1_3d_getnmsedec_ref(opj_t1_3d_t *t1, int x, int bitpos); -static void t1_3d_updateflags(unsigned int *fp, int s); -/** -Encode significant pass -*/ -static void t1_3d_enc_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc); -/** -Decode significant pass -*/ -static void t1_3d_dec_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, char type, int vsc); -/** -Encode significant pass -*/ -static void t1_3d_enc_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty); -/** -Decode significant pass -*/ -static void t1_3d_dec_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty); -/** -Encode refinement pass -*/ -static void t1_3d_enc_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int bpno, int one, int *nmsedec, char type, int vsc); -/** -Decode refinement pass -*/ -static void t1_3d_dec_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int poshalf, int neghalf, char type, int vsc); -/** -Encode refinement pass -*/ -static void t1_3d_enc_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty); -/** -Decode refinement pass -*/ -static void t1_3d_dec_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, char type, int cblksty); -/** -Encode clean-up pass -*/ -static void t1_3d_enc_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc); -/** -Decode clean-up pass -*/ -static void t1_3d_dec_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, int partial, int vsc); -/** -Encode clean-up pass -*/ -static void t1_3d_enc_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty); -/** -Decode clean-up pass -*/ -static void t1_3d_dec_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int cblksty); -/** -Encode 1 code-block -@param t1 T1 handle -@param cblk Code-block coding parameters -@param orient -@param compno Component number -@param level[3] -@param dwtid[3] -@param stepsize -@param cblksty Code-block style -@param numcomps -@param tile -*/ -static void t1_3d_encode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile); -/** -Decode 1 code-block -@param t1 T1 handle -@param cblk Code-block coding parameters -@param orient -@param roishift Region of interest shifting value -@param cblksty Code-block style -*/ -static void t1_3d_decode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty); -static int t1_3d_init_ctxno_zc(unsigned int f, int orient); -static int t1_3d_init_ctxno_sc(unsigned int f); -static int t1_3d_init_ctxno_mag(unsigned int f, int f2); -static int t1_3d_init_spb(unsigned int f); -/** -Initialize the look-up tables of the Tier-1 coder/decoder -@param t1 T1 handle -*/ -static void t1_3d_init_luts(opj_t1_3d_t *t1); - -/*@}*/ - -/*@}*/ - -/* ----------------------------------------------------------------------- */ - -static int t1_3d_getctxno_zc(unsigned int f, int orient) { - return t1_3d_init_ctxno_zc((f & T1_3D_SIG_OTH), orient); -} - -static int t1_3d_getctxno_sc(unsigned int f) { - return t1_3d_init_ctxno_sc((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)); - /*return t1->lut_ctxno_sc[((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)) >> 4];*/ -} - -static int t1_3d_getctxno_mag(unsigned int f, int fsvr) { - return t1_3d_init_ctxno_mag((f & T1_3D_SIG_OTH), fsvr); -} - -static int t1_3d_getspb(unsigned int f) { - return t1_3d_init_spb((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)); - /*return t1->lut_spb[((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)) >> 4];*/ -} - -static int t1_3d_getnmsedec_sig(opj_t1_3d_t *t1, int x, int bitpos) { - if (bitpos > T1_NMSEDEC_FRACBITS) { - return t1->lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; - } - - return t1->lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; -} - -static int t1_3d_getnmsedec_ref(opj_t1_3d_t *t1, int x, int bitpos) { - if (bitpos > T1_NMSEDEC_FRACBITS) { - return t1->lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; - } - - return t1->lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; -} - -static void t1_3d_updateflags(unsigned int *fp, int s) { - unsigned int *np = fp - (T1_MAXCBLKW + 2); - unsigned int *sp = fp + (T1_MAXCBLKW + 2); - - unsigned int *bwp = fp + ((T1_MAXCBLKW + 2)*(T1_MAXCBLKH +2)); - unsigned int *bnp = bwp - (T1_MAXCBLKW + 2); - unsigned int *bsp = bwp + (T1_MAXCBLKW + 2); - - unsigned int *fwp = fp - ((T1_MAXCBLKW + 2)*(T1_MAXCBLKH +2)); - unsigned int *fnp = fwp - (T1_MAXCBLKW + 2); - unsigned int *fsp = fwp + (T1_MAXCBLKW + 2); - - np[-1] |= T1_3D_SIG_SE; - np[1] |= T1_3D_SIG_SW; - sp[-1] |= T1_3D_SIG_NE; - sp[1] |= T1_3D_SIG_NW; - *np |= T1_3D_SIG_S; - *sp |= T1_3D_SIG_N; - fp[-1] |= T1_3D_SIG_E; - fp[1] |= T1_3D_SIG_W; - - *fwp |= T1_3D_SIG_FC; - *bwp |= T1_3D_SIG_BC; - - fnp[-1] |= T1_3D_SIG_FSE; - fnp[1] |= T1_3D_SIG_FSW; - fsp[-1] |= T1_3D_SIG_FNE; - fsp[1] |= T1_3D_SIG_FNW; - *fnp |= T1_3D_SIG_FS; - *fsp |= T1_3D_SIG_FN; - fwp[-1] |= T1_3D_SIG_FE; - fwp[1] |= T1_3D_SIG_FW; - - bnp[-1] |= T1_3D_SIG_BSE; - bnp[1] |= T1_3D_SIG_BSW; - bsp[-1] |= T1_3D_SIG_BNE; - bsp[1] |= T1_3D_SIG_BNW; - *bnp |= T1_3D_SIG_BS; - *bsp |= T1_3D_SIG_BN; - bwp[-1] |= T1_3D_SIG_BE; - bwp[1] |= T1_3D_SIG_BW; - - if (s) { - *np |= (T1_3D_SGN_S << 16); - *sp |= (T1_3D_SGN_N << 16); - fp[-1] |= (T1_3D_SGN_E << 16); - fp[1] |= (T1_3D_SGN_W << 16); - *fwp |= (T1_3D_SGN_F << 16); - *bwp |= (T1_3D_SGN_B << 16); - } -} - -static void t1_3d_enc_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc) { - int v, flagsvr; - unsigned int flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); - flagsvr = (*fsvr); - if ((flag & T1_3D_SIG_OTH) && !(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) { - v = int_abs(*dp) & one ? 1 : 0; - if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); /* ESSAI */ - mqc_bypass_enc(mqc, v); - } else { - mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); - mqc_encode(mqc, v); - } - if (v) { - v = *dp < 0 ? 1 : 0; - *nmsedec += t1_3d_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); - if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); /* ESSAI */ - mqc_bypass_enc(mqc, v); - } else { - mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); - mqc_encode(mqc, v ^ t1_3d_getspb(flag)); - } - t1_3d_updateflags(fp, v); - *fsvr |= T1_3D_SIG; - } - *fsvr |= T1_3D_VISIT; - } -} - -static void t1_3d_dec_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, char type, int vsc) { - int v, flagsvr; - unsigned int flag; - - opj_raw_t *raw = t1->raw; /* RAW component */ - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); - flagsvr = (*fsvr); - if ((flag & T1_3D_SIG_OTH) && !(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) { - if (type == T1_TYPE_RAW) { - if (raw_decode(raw)) { - v = raw_decode(raw); /* ESSAI */ - *dp = v ? -oneplushalf : oneplushalf; - t1_3d_updateflags(fp, v); - *fsvr |= T1_3D_SIG; - } - } else { - mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); - if (mqc_decode(mqc)) { - mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); - v = mqc_decode(mqc) ^ t1_3d_getspb(flag); - *dp = v ? -oneplushalf : oneplushalf; - t1_3d_updateflags(fp, v); - *fsvr |= T1_3D_SIG; - } - } - *fsvr |= T1_3D_VISIT; - } -} /* VSC and BYPASS by Antonin */ - -static void t1_3d_enc_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty) { - int i, j, k, m, one, vsc; - *nmsedec = 0; - one = 1 << (bpno + T1_NMSEDEC_FRACBITS); - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - for (j = k; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_3d_enc_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, type, vsc); - } - } - } - } -} - -static void t1_3d_dec_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty) { - int i, j, k, m, one, half, oneplushalf, vsc; - one = 1 << bpno; - half = one >> 1; - oneplushalf = one | half; - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - for (j = k; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_3d_dec_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, type, vsc); - } - } - } - } -} /* VSC and BYPASS by Antonin */ - -static void t1_3d_enc_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int bpno, int one, int *nmsedec, char type, int vsc) { - int v, flagsvr; - unsigned int flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); - flagsvr = (*fsvr); - if ((flagsvr & (T1_3D_SIG | T1_3D_VISIT)) == T1_3D_SIG) { - *nmsedec += t1_3d_getnmsedec_ref(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); - v = int_abs(*dp) & one ? 1 : 0; - if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ - mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); /* ESSAI */ - mqc_bypass_enc(mqc, v); - } else { - mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); - mqc_encode(mqc, v); - } - *fsvr |= T1_3D_REFINE; - } -} - -static void t1_3d_dec_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int poshalf, int neghalf, char type, int vsc) { - int v, t, flagsvr; - unsigned int flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - opj_raw_t *raw = t1->raw; /* RAW component */ - - flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); - flagsvr = (*fsvr); - if ((flagsvr & (T1_3D_SIG | T1_3D_VISIT)) == T1_3D_SIG) { - if (type == T1_TYPE_RAW) { - mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); /* ESSAI */ - v = raw_decode(raw); - } else { - mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); - v = mqc_decode(mqc); - } - t = v ? poshalf : neghalf; - *dp += *dp < 0 ? -t : t; - *fsvr |= T1_3D_REFINE; - } -} /* VSC and BYPASS by Antonin */ - -static void t1_3d_enc_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty) { - int i, j, k, m, one, vsc; - *nmsedec = 0; - one = 1 << (bpno + T1_NMSEDEC_FRACBITS); - for (m = 0; m < l; m++){ - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - for (j = k; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_3d_enc_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], bpno, one, nmsedec, type, vsc); - } - } - } - } -} - -static void t1_3d_dec_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, char type, int cblksty) { - int i, j, k, m, one, poshalf, neghalf; - int vsc; - one = 1 << bpno; - poshalf = one >> 1; - neghalf = bpno > 0 ? -poshalf : -1; - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - for (j = k; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_3d_dec_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], poshalf, neghalf, type, vsc); - } - } - } - } -} /* VSC and BYPASS by Antonin */ - -static void t1_3d_enc_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc) { - int v, flagsvr; - unsigned int flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); - flagsvr = (*fsvr); - if (partial) { - goto LABEL_PARTIAL; - } - if (!(*fsvr & (T1_3D_SIG | T1_3D_VISIT))) { - mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); - v = int_abs(*dp) & one ? 1 : 0; - mqc_encode(mqc, v); - if (v) { -LABEL_PARTIAL: - *nmsedec += t1_3d_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); - mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); - v = *dp < 0 ? 1 : 0; - mqc_encode(mqc, v ^ t1_3d_getspb(flag)); - t1_3d_updateflags(fp, v); - *fsvr |= T1_3D_SIG; - } - } - *fsvr &= ~T1_3D_VISIT; -} - -static void t1_3d_dec_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, int partial, int vsc) { - int v, flagsvr; - unsigned int flag; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); - flagsvr = (*fsvr); - if (partial) { - goto LABEL_PARTIAL; - } - if (!(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) { - mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); - if (mqc_decode(mqc)) { -LABEL_PARTIAL: - mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); - v = mqc_decode(mqc) ^ t1_3d_getspb(flag); - *dp = v ? -oneplushalf : oneplushalf; - t1_3d_updateflags(fp, v); - *fsvr |= T1_3D_SIG; - } - } - *fsvr &= ~T1_3D_VISIT; -} /* VSC and BYPASS by Antonin */ - -static void t1_3d_enc_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty) { - int i, j, k, m, one, agg, runlen, vsc; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - *nmsedec = 0; - one = 1 << (bpno + T1_NMSEDEC_FRACBITS); - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - if (k + 3 < h) { - if (cblksty & J3D_CCP_CBLKSTY_VSC) { - agg = !( ((t1->flagSVR[1 + m][1 + k][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & ((t1->flags[1 + m][1 + k + 3][1 + i] & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) & (T1_3D_SIG_OTH))) - ); - } else { - agg = !( - ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 3][1 + i] & T1_3D_SIG_OTH)) - ); - } - } else { - agg = 0; - } - if (agg) { - for (runlen = 0; runlen < 4; runlen++) { - if (int_abs(t1->data[m][k + runlen][i]) & one) - break; - } - mqc_setcurctx(mqc, T1_CTXNO_AGG); - mqc_encode(mqc, runlen != 4); - if (runlen == 4) { - continue; - } - mqc_setcurctx(mqc, T1_CTXNO_UNI); - mqc_encode(mqc, runlen >> 1); - mqc_encode(mqc, runlen & 1); - } else { - runlen = 0; - } - for (j = k + runlen; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_3d_enc_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, agg && (j == k + runlen), vsc); - } - } - } - } -} - -static void t1_3d_dec_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int cblksty) { - int i, j, k, m, one, half, oneplushalf, agg, runlen, vsc; - int segsym = cblksty & J3D_CCP_CBLKSTY_SEGSYM; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - one = 1 << bpno; - half = one >> 1; - oneplushalf = one | half; - for (m = 0; m < l; m++) { - for (k = 0; k < h; k += 4) { - for (i = 0; i < w; i++) { - if (k + 3 < h) { - if (cblksty & J3D_CCP_CBLKSTY_VSC) { - agg = !( - ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | ((t1->flags[1 + m][1 + k + 3][1 + i] & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) & (T1_3D_SIG_OTH))) - ); - } else { - agg = !( - ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH)) - || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 3][1 + i] & T1_3D_SIG_OTH)) - ); - } - } else { - agg = 0; - } - if (agg) { - mqc_setcurctx(mqc, T1_CTXNO_AGG); - if (!mqc_decode(mqc)) { - continue; - } - mqc_setcurctx(mqc, T1_CTXNO_UNI); - runlen = mqc_decode(mqc); - runlen = (runlen << 1) | mqc_decode(mqc); - } else { - runlen = 0; - } - for (j = k + runlen; j < k + 4 && j < h; j++) { - vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; - t1_3d_dec_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, agg && (j == k + runlen), vsc); - } - } - } - } - if (segsym) { - int v = 0; - mqc_setcurctx(mqc, T1_CTXNO_UNI); - v = mqc_decode(mqc); - v = (v << 1) | mqc_decode(mqc); - v = (v << 1) | mqc_decode(mqc); - v = (v << 1) | mqc_decode(mqc); - /* - if (v!=0xa) { - opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v); - } - */ - } -} /* VSC and BYPASS by Antonin */ - - -static void t1_3d_encode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile) { - int i, j, k; - int w, h, l; - int passno; - int bpno, passtype; - int max; - int nmsedec = 0; - double cumwmsedec = 0; - char type = T1_TYPE_MQ; - - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - w = cblk->x1 - cblk->x0; - h = cblk->y1 - cblk->y0; - l = cblk->z1 - cblk->z0; - - max = 0; - for (k = 0; k < l; k++) { - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - max = int_max(max, int_abs(t1->data[k][j][i])); - } - } - } - for (k = 0; k <= l; k++) { - for (j = 0; j <= h; j++) { - for (i = 0; i <= w; i++) { - t1->flags[k][j][i] = 0; - t1->flagSVR[k][j][i] = 0; - } - } - } - - cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0; - - bpno = cblk->numbps - 1; - passtype = 2; - - mqc_reset_enc(mqc); - mqc_init_enc(mqc, cblk->data); - - for (passno = 0; bpno >= 0; passno++) { - opj_tcd_pass_t *pass = &cblk->passes[passno]; - int correction = 3; - double tmpwmsedec; - type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; - - switch (passtype) { - case 0: - t1_3d_enc_sigpass(t1, w, h, l, bpno, orient, &nmsedec, type, cblksty); - break; - case 1: - t1_3d_enc_refpass(t1, w, h, l, bpno, &nmsedec, type, cblksty); - break; - case 2: - t1_3d_enc_clnpass(t1, w, h, l, bpno, orient, &nmsedec, cblksty); - /* code switch SEGMARK (i.e. SEGSYM) */ - if (cblksty & J3D_CCP_CBLKSTY_SEGSYM) - mqc_segmark_enc(mqc); - break; - } - - /* fixed_quality */ - tmpwmsedec = t1_getwmsedec(nmsedec, compno, level, orient, bpno, stepsize, numcomps, dwtid); - cumwmsedec += tmpwmsedec; - tile->distotile += tmpwmsedec; - - /* Code switch "RESTART" (i.e. TERMALL) */ - if ((cblksty & J3D_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) { - if (type == T1_TYPE_RAW) { - mqc_flush(mqc); - correction = 1; - /* correction = mqc_bypass_flush_enc(); */ - } else { /* correction = mqc_restart_enc(); */ - mqc_flush(mqc); - correction = 1; - } - pass->term = 1; - } else { - if (((bpno < (cblk->numbps - 4) && (passtype > 0)) - || ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) { - if (type == T1_TYPE_RAW) { - mqc_flush(mqc); - correction = 1; - } else { - mqc_flush(mqc); - correction = 1; - } - pass->term = 1; - } else { - pass->term = 0; - } - } - - if (++passtype == 3) { - passtype = 0; - bpno--; - } - - if (pass->term && bpno > 0) { - type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; - if (type == T1_TYPE_RAW) - mqc_bypass_init_enc(mqc); - else - mqc_restart_init_enc(mqc); - } - - pass->distortiondec = cumwmsedec; - pass->rate = mqc_numbytes(mqc) + correction; /* FIXME */ - pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate); - - /* Code-switch "RESET" */ - if (cblksty & J3D_CCP_CBLKSTY_RESET) - mqc_reset_enc(mqc); - } - - /* Code switch "ERTERM" (i.e. PTERM) */ - if (cblksty & J3D_CCP_CBLKSTY_PTERM) - mqc_erterm_enc(mqc); - else /* Default coding */ if (!(cblksty & J3D_CCP_CBLKSTY_LAZY)) - mqc_flush(mqc); - - cblk->totalpasses = passno; -} - -static void t1_3d_decode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty) { - int i, j, k; - int w, h, l; - int bpno, passtype; - int segno, passno; - char type = T1_TYPE_MQ; /* BYPASS mode */ - opj_raw_t *raw = t1->raw; /* RAW component */ - opj_mqc_t *mqc = t1->mqc; /* MQC component */ - - w = cblk->x1 - cblk->x0; - h = cblk->y1 - cblk->y0; - l = cblk->z1 - cblk->z0; - - for (k = 0; k < l; k++) { - for (j = 0; j < h; j++) { - for (i = 0; i < w; i++) { - t1->data[k][j][i] = 0; - } - } - } - - for (k = 0; k <= l; k++) { - for (j = 0; j <= h; j++) { - for (i = 0; i <= w; i++) { - t1->flags[k][j][i] = 0; - t1->flagSVR[k][j][i] = 0; - } - } - } - - - bpno = roishift + cblk->numbps - 1; - passtype = 2; - - mqc_reset_enc(mqc); - - for (segno = 0; segno < cblk->numsegs; segno++) { - opj_tcd_seg_t *seg = &cblk->segs[segno]; - - /* BYPASS mode */ - type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; - if (type == T1_TYPE_RAW) { - raw_init_dec(raw, seg->data, seg->len); - } else { - mqc_init_dec(mqc, seg->data, seg->len); - } - - for (passno = 0; passno < seg->numpasses; passno++) { - switch (passtype) { - case 0: - t1_3d_dec_sigpass(t1, w, h, l, bpno+1, orient, type, cblksty); - break; - case 1: - t1_3d_dec_refpass(t1, w, h, l, bpno+1, type, cblksty); - break; - case 2: - t1_3d_dec_clnpass(t1, w, h, l, bpno+1, orient, cblksty); - break; - } - - if ((cblksty & J3D_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) { - mqc_reset_enc(mqc); - } - if (++passtype == 3) { - passtype = 0; - bpno--; - } - - } - } -} - -static int t1_3d_init_ctxno_zc(unsigned int f, int orient) { - unsigned int h, v, c; - unsigned int d2xy, d2xz, d2yz, d3; - int n; - unsigned int hvc, hc, d2, d2xy2yz, d2xy2xz; - n = 0; - h = ((f & T1_3D_SIG_W) != 0) + ((f & T1_3D_SIG_E) != 0); - v = ((f & T1_3D_SIG_N) != 0) + ((f & T1_3D_SIG_S) != 0); - c = ((f & T1_3D_SIG_FC) != 0) + ((f & T1_3D_SIG_BC) != 0); - d2xy = ((f & T1_3D_SIG_NW) != 0) + ((f & T1_3D_SIG_NE) != 0) + ((f & T1_3D_SIG_SE) != 0) + ((f & T1_3D_SIG_SW) != 0); - d2xz = ((f & T1_3D_SIG_FW) != 0) + ((f & T1_3D_SIG_BW) != 0) + ((f & T1_3D_SIG_FE) != 0) + ((f & T1_3D_SIG_BE) != 0); - d2yz = ((f & T1_3D_SIG_FN) != 0) + ((f & T1_3D_SIG_FS) != 0) + ((f & T1_3D_SIG_BN) != 0) + ((f & T1_3D_SIG_BS) != 0); - d3 = ((f & T1_3D_SIG_FNW) != 0) + ((f & T1_3D_SIG_FNE) != 0) + ((f & T1_3D_SIG_FSE) != 0) + ((f & T1_3D_SIG_FSW) != 0) - + ((f & T1_3D_SIG_BNW) != 0) + ((f & T1_3D_SIG_BNE) != 0) + ((f & T1_3D_SIG_BSE) != 0) + ((f & T1_3D_SIG_BSW) != 0); - - switch (orient) { - case 0: /*LLL*/ - case 7: /*HHH*/ - hvc = h + v + c; - d2 = d2xy + d2xz + d2yz; - if (!hvc) { - if (!d2) { - n = (!d3) ? 0 : 1; - } else if (d2 == 1) { - n = (!d3) ? 2 : 3; - } else { - n = (!d3) ? 4 : 5; - } - } else if (hvc == 1) { - if (!d2) { - n = (!d3) ? 6 : 7; - } else if (d2 == 1) { - n = (!d3) ? 8 : 9; - } else { - n = 10; - } - } else if (hvc == 2) { - if (!d2) { - n = (!d3) ? 11 : 12; - } else { - n = 13; - } - } else if (hvc == 3) { - n = 14; - } else { - n = 15; - } - break; - /*LHL, HLL, LLH*/ - case 1: - case 2: - case 4: - hc = h + c; - d2xy2yz = d2xy + d2yz; - if (!hc) { - if (!v) { - if (!d2xy) { - n = (!d2xy2yz) ? ((!d3) ? 0 : 1) : ((!d3) ? 2 : 3); - } else if (d2xy == 1) { - n = (!d2xy2yz) ? ((!d3) ? 4 : 5) : 6; - } else { /*>=2*/ - n = 7; - } - } else { - n = (v == 1) ? 8 : 9; /* =1 or =2*/ - } - } else if (hc == 1) { - n = (!v) ? ( (!d2xy) ? ( (!d2xy2yz) ? ( (!d3) ? 10 : 11) : (12) ) : (13) ) : (14); - } else { /*if (hc >= 2)*/ - n = 15; - } - break; - /*HLH, HHL, LHH*/ - case 3: - case 5: - case 6: - hc = h + c; - d2xy2xz = d2xy + d2xz; - if (!v) { - if (!d2xz) { - if (!hc && !d2xy2xz) { - n = (!d3) ? 0 : 1; - } else if (hc == 1) { - n = (!d2xy2xz) ? 2 : 3; - } else { /*if >= 2*/ - n = 4; - } - } else if ( d2xz>=1 && !hc ) { - n = 5; - } else if ( hc>=1 ) { - n = (d2xz==1) ? 6 : 7; - } - } else if (v == 1) { - if (!d2xz) { - n = (!hc) ? 8 : 9; - } else if (d2xz == 1) { - n = (!hc) ? 10 : 11; - } else if (d2xz == 2) { - n = (!hc) ? 12 : 13; - } else { /* if (d2xz >= 3) {*/ - n = 14; - } - } else if (v == 2) { - n = 15; - } - break; - } - - return (T1_3D_CTXNO_ZC + n); -} - -static int t1_3d_init_ctxno_sc(unsigned int f) { - int hc, vc, cc; - int n = 0; - - hc = int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == T1_3D_SIG_E ) - + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W)) == T1_3D_SIG_W ) , 1) - - int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == (T1_3D_SIG_E | T1_3D_SGN_E) ) - + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W) ) == (T1_3D_SIG_W | T1_3D_SGN_W)), 1); - - vc = int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == T1_3D_SIG_N) - + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == T1_3D_SIG_S), 1) - - int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == (T1_3D_SIG_N | T1_3D_SGN_N)) - + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == (T1_3D_SIG_S | T1_3D_SGN_S)), 1); - - cc = int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == T1_3D_SIG_FC) - + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == T1_3D_SIG_BC), 1) - - int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == (T1_3D_SIG_FC | T1_3D_SGN_F)) - + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == (T1_3D_SIG_BC | T1_3D_SGN_B)), 1); - if (hc < 0) { - hc = -hc; - vc = -vc; - cc = -cc; - } - - if (!hc) { - if (!vc) - n = (!cc) ? 0 : 1; - else if (vc == -1) - n = (!cc) ? 1 : ( (cc>0) ? 2 : 4); - else if (vc == 1) - n = (!cc) ? 1 : ( (cc<0) ? 2 : 4); - } else if (hc == 1) { - if (!vc) - n = (!cc) ? 1 : ( (cc<0) ? 2 : 4); - else if (vc == 1) - n = (!cc) ? 4 : ( (cc>0) ? 5 : 3); - else if (vc == -1) - n = (!cc) ? 2 : 3; - } else if (hc == -1) { - if (!vc) - n = (!cc) ? 1 : ( (cc>0) ? 2 : 4); - else if (vc == 1) - n = (!cc) ? 2 : 3; - else if (vc == -1) - n = (!cc) ? 4 : ( (cc<0) ? 5 : 3); - } - - return (T1_3D_CTXNO_SC + n); -} - -static int t1_3d_init_ctxno_mag(unsigned int f, int f2) { - int n; - if (!(f2 & T1_3D_REFINE)) /*First refinement for this coefficient (no previous refinement)*/ - n = (f & (T1_3D_SIG_PRIM)) ? 1 : 0; - else - n = 2; - - return (T1_3D_CTXNO_MAG + n); -} - -static int t1_3d_init_spb(unsigned int f) { - int hc, vc, cc; - int n = 0; - - hc = int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == T1_3D_SIG_E ) - + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W)) == T1_3D_SIG_W ) , 1) - - int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == (T1_3D_SIG_E | T1_3D_SGN_E) ) - + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W) ) == (T1_3D_SIG_W | T1_3D_SGN_W)), 1); - - vc = int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == T1_3D_SIG_N) - + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == T1_3D_SIG_S), 1) - - int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == (T1_3D_SIG_N | T1_3D_SGN_N)) - + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == (T1_3D_SIG_S | T1_3D_SGN_S)), 1); - - cc = int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == T1_3D_SIG_FC) - + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == T1_3D_SIG_BC), 1) - - int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == (T1_3D_SIG_FC | T1_3D_SGN_F)) - + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == (T1_3D_SIG_BC | T1_3D_SGN_B)), 1); - - n = ((hc + vc + cc) < 0); - - return n; -} - -static void t1_3d_init_luts(opj_t1_3d_t *t1) { - int i; - double u, v, t; - /*for (j = 0; j < 4; j++) { - for (i = 0; i < 256; ++i) { - t1->lut_ctxno_zc[(j << 8) | i] = t1_3d_init_ctxno_zc(i, j); - } - } - for (i = 0; i < 4096; i++) { - t1->lut_ctxno_sc[i] = t1_3d_init_ctxno_sc(i << 4); - } - for (j = 0; j < 2; j++) { - for (i = 0; i < 2048; ++i) { - t1->lut_ctxno_mag[(j << 11) + i] = t1_3d_init_ctxno_mag((j ? T1_3D_REFINE : 0) | i); - } - } - for (i = 0; i < 4096; ++i) { - t1->lut_spb[i] = t1_3d_init_spb(i << 4); - }*/ - /* FIXME FIXME FIXME */ - for (i = 0; i < (1 << T1_NMSEDEC_BITS); i++) { - t = i / pow(2, T1_NMSEDEC_FRACBITS); - u = t; - v = t - 1.5; - t1->lut_nmsedec_sig[i] = - int_max(0, - (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); - t1->lut_nmsedec_sig0[i] = - int_max(0, - (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); - u = t - 1.0; - if (i & (1 << (T1_NMSEDEC_BITS - 1))) { - v = t - 1.5; - } else { - v = t - 0.5; - } - t1->lut_nmsedec_ref[i] = - int_max(0, - (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); - t1->lut_nmsedec_ref0[i] = - int_max(0, - (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); - } -} - -/* ----------------------------------------------------------------------- */ - -opj_t1_3d_t* t1_3d_create(opj_common_ptr cinfo) { - opj_t1_3d_t *t1 = (opj_t1_3d_t*)opj_malloc(sizeof(opj_t1_3d_t)); - if(t1) { - t1->cinfo = cinfo; - /* create MQC and RAW handles */ - t1->mqc = mqc_create(); - t1->raw = raw_create(); - /* initialize the look-up tables of the Tier-1 coder/decoder */ - t1_3d_init_luts(t1); - } - return t1; -} - -void t1_3d_destroy(opj_t1_3d_t *t1) { - if(t1) { - /* destroy MQC and RAW handles */ - mqc_destroy(t1->mqc); - raw_destroy(t1->raw); - opj_free(t1); - } -} - -void t1_3d_encode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { - int compno, resno, bandno, precno, cblkno; - int x, y, z, i, j, k, orient; - int level[3]; - tile->distotile = 0; /* fixed_quality */ - - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - opj_tcd_precinct_t *prc = &band->precincts[precno]; - - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - - if (band->bandno == 0) { - x = cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 1) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 2) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 3) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 4) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 5) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 6) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 7) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } - - if (tcp->tccps[compno].reversible == 1) { - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - t1->data[k][j][i] = - tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] << T1_NMSEDEC_FRACBITS; - } - } - } - } else if (tcp->tccps[compno].reversible == 0) { - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - t1->data[k][j][i] = fix_mul( - tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)], - 8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (13 - T1_NMSEDEC_FRACBITS); - } - } - } - } - orient = band->bandno; /* FIXME */ - for (i = 0; i < 3; i++) - level[i] = tilec->numresolution[i] - 1 - resno; - - t1_3d_encode_cblk(t1, cblk, orient, compno, level, tcp->tccps[compno].dwtid, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps, tile); - - } /* cblkno */ - } /* precno */ - } /* bandno */ - } /* resno */ - } /* compno */ -} - -void t1_3d_decode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { - int compno, resno, bandno, precno, cblkno; - - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - opj_tcd_precinct_t *prc = &band->precincts[precno]; - - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - int x, y, z, i, j, k, orient; - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - - orient = band->bandno; /* FIXME */ - - /*fprintf(stdout,"[INFO] t1_3d_decode_cblk(t1, cblk, orient(%d), tcp->tccps[compno].roishift (%d), tcp->tccps[compno].cblksty (%d));\n",orient,tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty);*/ - t1_3d_decode_cblk(t1, cblk, orient, tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty); - - if (band->bandno == 0) { - x = cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 1) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 2) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 3) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = cblk->z0 - band->z0; - } else if (band->bandno == 4) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 5) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 6) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } else if (band->bandno == 7) { - opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; - x = pres->x1 - pres->x0 + cblk->x0 - band->x0; - y = pres->y1 - pres->y0 + cblk->y0 - band->y0; - z = pres->z1 - pres->z0 + cblk->z0 - band->z0; - } - - if (tcp->tccps[compno].roishift) { - int thresh, val, mag; - thresh = 1 << tcp->tccps[compno].roishift; - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - val = t1->data[k][j][i]; - mag = int_abs(val); - if (mag >= thresh) { - mag >>= tcp->tccps[compno].roishift; - t1->data[k][j][i] = val < 0 ? -mag : mag; - } - } - } - } - } - - if (tcp->tccps[compno].reversible == 1) { - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - int tmp = t1->data[k][j][i]; - tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = tmp/2; - } - } - } - } else { /* if (tcp->tccps[compno].reversible == 0) */ - for (k = 0; k < cblk->z1 - cblk->z0; k++) { - for (j = 0; j < cblk->y1 - cblk->y0; j++) { - for (i = 0; i < cblk->x1 - cblk->x0; i++) { - double tmp = (double)(t1->data[k][j][i] * band->stepsize * 4096.0); - if (t1->data[k][j][i] >> 1 == 0) { - tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = 0; - } else { - int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); - tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = ((tmp<0)?-tmp2:tmp2); - } - } - } - } - } - } /* cblkno */ - } /* precno */ - } /* bandno */ - } /* resno */ - } /* compno */ -} +/* + * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain + * 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" + +/** @defgroup T1_3D T1_3D - Implementation of the tier-1 coding */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +static int t1_3d_getctxno_zc(unsigned int f, int orient); +static int t1_3d_getctxno_sc(unsigned int f); +static int t1_3d_getctxno_mag(unsigned int f, int fsvr); +static int t1_3d_getspb(unsigned int f); +static int t1_3d_getnmsedec_sig(opj_t1_3d_t *t1, int x, int bitpos); +static int t1_3d_getnmsedec_ref(opj_t1_3d_t *t1, int x, int bitpos); +static void t1_3d_updateflags(unsigned int *fp, int s); +/** +Encode significant pass +*/ +static void t1_3d_enc_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc); +/** +Decode significant pass +*/ +static void t1_3d_dec_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, char type, int vsc); +/** +Encode significant pass +*/ +static void t1_3d_enc_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty); +/** +Decode significant pass +*/ +static void t1_3d_dec_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty); +/** +Encode refinement pass +*/ +static void t1_3d_enc_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int bpno, int one, int *nmsedec, char type, int vsc); +/** +Decode refinement pass +*/ +static void t1_3d_dec_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int poshalf, int neghalf, char type, int vsc); +/** +Encode refinement pass +*/ +static void t1_3d_enc_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty); +/** +Decode refinement pass +*/ +static void t1_3d_dec_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, char type, int cblksty); +/** +Encode clean-up pass +*/ +static void t1_3d_enc_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc); +/** +Decode clean-up pass +*/ +static void t1_3d_dec_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, int partial, int vsc); +/** +Encode clean-up pass +*/ +static void t1_3d_enc_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty); +/** +Decode clean-up pass +*/ +static void t1_3d_dec_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int cblksty); +/** +Encode 1 code-block +@param t1 T1 handle +@param cblk Code-block coding parameters +@param orient +@param compno Component number +@param level[3] +@param dwtid[3] +@param stepsize +@param cblksty Code-block style +@param numcomps +@param tile +*/ +static void t1_3d_encode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile); +/** +Decode 1 code-block +@param t1 T1 handle +@param cblk Code-block coding parameters +@param orient +@param roishift Region of interest shifting value +@param cblksty Code-block style +*/ +static void t1_3d_decode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty); +static int t1_3d_init_ctxno_zc(unsigned int f, int orient); +static int t1_3d_init_ctxno_sc(unsigned int f); +static int t1_3d_init_ctxno_mag(unsigned int f, int f2); +static int t1_3d_init_spb(unsigned int f); +/** +Initialize the look-up tables of the Tier-1 coder/decoder +@param t1 T1 handle +*/ +static void t1_3d_init_luts(opj_t1_3d_t *t1); + +/*@}*/ + +/*@}*/ + +/* ----------------------------------------------------------------------- */ + +static int t1_3d_getctxno_zc(unsigned int f, int orient) { + return t1_3d_init_ctxno_zc((f & T1_3D_SIG_OTH), orient); +} + +static int t1_3d_getctxno_sc(unsigned int f) { + return t1_3d_init_ctxno_sc((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)); + /*return t1->lut_ctxno_sc[((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)) >> 4];*/ +} + +static int t1_3d_getctxno_mag(unsigned int f, int fsvr) { + return t1_3d_init_ctxno_mag((f & T1_3D_SIG_OTH), fsvr); +} + +static int t1_3d_getspb(unsigned int f) { + return t1_3d_init_spb((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)); + /*return t1->lut_spb[((f & T1_3D_SIG_PRIM) | ((f >> 16) & T1_3D_SGN)) >> 4];*/ +} + +static int t1_3d_getnmsedec_sig(opj_t1_3d_t *t1, int x, int bitpos) { + if (bitpos > T1_NMSEDEC_FRACBITS) { + return t1->lut_nmsedec_sig[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; + } + + return t1->lut_nmsedec_sig0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; +} + +static int t1_3d_getnmsedec_ref(opj_t1_3d_t *t1, int x, int bitpos) { + if (bitpos > T1_NMSEDEC_FRACBITS) { + return t1->lut_nmsedec_ref[(x >> (bitpos - T1_NMSEDEC_FRACBITS)) & ((1 << T1_NMSEDEC_BITS) - 1)]; + } + + return t1->lut_nmsedec_ref0[x & ((1 << T1_NMSEDEC_BITS) - 1)]; +} + +static void t1_3d_updateflags(unsigned int *fp, int s) { + unsigned int *np = fp - (T1_MAXCBLKW + 2); + unsigned int *sp = fp + (T1_MAXCBLKW + 2); + + unsigned int *bwp = fp + ((T1_MAXCBLKW + 2)*(T1_MAXCBLKH +2)); + unsigned int *bnp = bwp - (T1_MAXCBLKW + 2); + unsigned int *bsp = bwp + (T1_MAXCBLKW + 2); + + unsigned int *fwp = fp - ((T1_MAXCBLKW + 2)*(T1_MAXCBLKH +2)); + unsigned int *fnp = fwp - (T1_MAXCBLKW + 2); + unsigned int *fsp = fwp + (T1_MAXCBLKW + 2); + + np[-1] |= T1_3D_SIG_SE; + np[1] |= T1_3D_SIG_SW; + sp[-1] |= T1_3D_SIG_NE; + sp[1] |= T1_3D_SIG_NW; + *np |= T1_3D_SIG_S; + *sp |= T1_3D_SIG_N; + fp[-1] |= T1_3D_SIG_E; + fp[1] |= T1_3D_SIG_W; + + *fwp |= T1_3D_SIG_FC; + *bwp |= T1_3D_SIG_BC; + + fnp[-1] |= T1_3D_SIG_FSE; + fnp[1] |= T1_3D_SIG_FSW; + fsp[-1] |= T1_3D_SIG_FNE; + fsp[1] |= T1_3D_SIG_FNW; + *fnp |= T1_3D_SIG_FS; + *fsp |= T1_3D_SIG_FN; + fwp[-1] |= T1_3D_SIG_FE; + fwp[1] |= T1_3D_SIG_FW; + + bnp[-1] |= T1_3D_SIG_BSE; + bnp[1] |= T1_3D_SIG_BSW; + bsp[-1] |= T1_3D_SIG_BNE; + bsp[1] |= T1_3D_SIG_BNW; + *bnp |= T1_3D_SIG_BS; + *bsp |= T1_3D_SIG_BN; + bwp[-1] |= T1_3D_SIG_BE; + bwp[1] |= T1_3D_SIG_BW; + + if (s) { + *np |= (T1_3D_SGN_S << 16); + *sp |= (T1_3D_SGN_N << 16); + fp[-1] |= (T1_3D_SGN_E << 16); + fp[1] |= (T1_3D_SGN_W << 16); + *fwp |= (T1_3D_SGN_F << 16); + *bwp |= (T1_3D_SGN_B << 16); + } +} + +static void t1_3d_enc_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, char type, int vsc) { + int v, flagsvr; + unsigned int flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); + flagsvr = (*fsvr); + if ((flag & T1_3D_SIG_OTH) && !(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) { + v = int_abs(*dp) & one ? 1 : 0; + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); /* ESSAI */ + mqc_bypass_enc(mqc, v); + } else { + mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); + mqc_encode(mqc, v); + } + if (v) { + v = *dp < 0 ? 1 : 0; + *nmsedec += t1_3d_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); /* ESSAI */ + mqc_bypass_enc(mqc, v); + } else { + mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); + mqc_encode(mqc, v ^ t1_3d_getspb(flag)); + } + t1_3d_updateflags(fp, v); + *fsvr |= T1_3D_SIG; + } + *fsvr |= T1_3D_VISIT; + } +} + +static void t1_3d_dec_sigpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, char type, int vsc) { + int v, flagsvr; + unsigned int flag; + + opj_raw_t *raw = t1->raw; /* RAW component */ + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); + flagsvr = (*fsvr); + if ((flag & T1_3D_SIG_OTH) && !(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) { + if (type == T1_TYPE_RAW) { + if (raw_decode(raw)) { + v = raw_decode(raw); /* ESSAI */ + *dp = v ? -oneplushalf : oneplushalf; + t1_3d_updateflags(fp, v); + *fsvr |= T1_3D_SIG; + } + } else { + mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); + if (mqc_decode(mqc)) { + mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); + v = mqc_decode(mqc) ^ t1_3d_getspb(flag); + *dp = v ? -oneplushalf : oneplushalf; + t1_3d_updateflags(fp, v); + *fsvr |= T1_3D_SIG; + } + } + *fsvr |= T1_3D_VISIT; + } +} /* VSC and BYPASS by Antonin */ + +static void t1_3d_enc_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, char type, int cblksty) { + int i, j, k, m, one, vsc; + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + for (j = k; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_3d_enc_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, type, vsc); + } + } + } + } +} + +static void t1_3d_dec_sigpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, char type, int cblksty) { + int i, j, k, m, one, half, oneplushalf, vsc; + one = 1 << bpno; + half = one >> 1; + oneplushalf = one | half; + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + for (j = k; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_3d_dec_sigpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, type, vsc); + } + } + } + } +} /* VSC and BYPASS by Antonin */ + +static void t1_3d_enc_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int bpno, int one, int *nmsedec, char type, int vsc) { + int v, flagsvr; + unsigned int flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); + flagsvr = (*fsvr); + if ((flagsvr & (T1_3D_SIG | T1_3D_VISIT)) == T1_3D_SIG) { + *nmsedec += t1_3d_getnmsedec_ref(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + v = int_abs(*dp) & one ? 1 : 0; + if (type == T1_TYPE_RAW) { /* BYPASS/LAZY MODE */ + mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); /* ESSAI */ + mqc_bypass_enc(mqc, v); + } else { + mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); + mqc_encode(mqc, v); + } + *fsvr |= T1_3D_REFINE; + } +} + +static void t1_3d_dec_refpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int poshalf, int neghalf, char type, int vsc) { + int v, t, flagsvr; + unsigned int flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + opj_raw_t *raw = t1->raw; /* RAW component */ + + flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); + flagsvr = (*fsvr); + if ((flagsvr & (T1_3D_SIG | T1_3D_VISIT)) == T1_3D_SIG) { + if (type == T1_TYPE_RAW) { + mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); /* ESSAI */ + v = raw_decode(raw); + } else { + mqc_setcurctx(mqc, t1_3d_getctxno_mag(flag, flagsvr)); + v = mqc_decode(mqc); + } + t = v ? poshalf : neghalf; + *dp += *dp < 0 ? -t : t; + *fsvr |= T1_3D_REFINE; + } +} /* VSC and BYPASS by Antonin */ + +static void t1_3d_enc_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int *nmsedec, char type, int cblksty) { + int i, j, k, m, one, vsc; + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (m = 0; m < l; m++){ + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + for (j = k; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_3d_enc_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], bpno, one, nmsedec, type, vsc); + } + } + } + } +} + +static void t1_3d_dec_refpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, char type, int cblksty) { + int i, j, k, m, one, poshalf, neghalf; + int vsc; + one = 1 << bpno; + poshalf = one >> 1; + neghalf = bpno > 0 ? -poshalf : -1; + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + for (j = k; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_3d_dec_refpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], poshalf, neghalf, type, vsc); + } + } + } + } +} /* VSC and BYPASS by Antonin */ + +static void t1_3d_enc_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int bpno, int one, int *nmsedec, int partial, int vsc) { + int v, flagsvr; + unsigned int flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); + flagsvr = (*fsvr); + if (partial) { + goto LABEL_PARTIAL; + } + if (!(*fsvr & (T1_3D_SIG | T1_3D_VISIT))) { + mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); + v = int_abs(*dp) & one ? 1 : 0; + mqc_encode(mqc, v); + if (v) { +LABEL_PARTIAL: + *nmsedec += t1_3d_getnmsedec_sig(t1, int_abs(*dp), bpno + T1_NMSEDEC_FRACBITS); + mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); + v = *dp < 0 ? 1 : 0; + mqc_encode(mqc, v ^ t1_3d_getspb(flag)); + t1_3d_updateflags(fp, v); + *fsvr |= T1_3D_SIG; + } + } + *fsvr &= ~T1_3D_VISIT; +} + +static void t1_3d_dec_clnpass_step(opj_t1_3d_t *t1, unsigned int *fp, int *fsvr, int *dp, int orient, int oneplushalf, int partial, int vsc) { + int v, flagsvr; + unsigned int flag; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + flag = vsc ? ((*fp) & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) : (*fp); + flagsvr = (*fsvr); + if (partial) { + goto LABEL_PARTIAL; + } + if (!(flagsvr & (T1_3D_SIG | T1_3D_VISIT))) { + mqc_setcurctx(mqc, t1_3d_getctxno_zc(flag, orient)); + if (mqc_decode(mqc)) { +LABEL_PARTIAL: + mqc_setcurctx(mqc, t1_3d_getctxno_sc(flag)); + v = mqc_decode(mqc) ^ t1_3d_getspb(flag); + *dp = v ? -oneplushalf : oneplushalf; + t1_3d_updateflags(fp, v); + *fsvr |= T1_3D_SIG; + } + } + *fsvr &= ~T1_3D_VISIT; +} /* VSC and BYPASS by Antonin */ + +static void t1_3d_enc_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int *nmsedec, int cblksty) { + int i, j, k, m, one, agg, runlen, vsc; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + *nmsedec = 0; + one = 1 << (bpno + T1_NMSEDEC_FRACBITS); + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + if (k + 3 < h) { + if (cblksty & J3D_CCP_CBLKSTY_VSC) { + agg = !( ((t1->flagSVR[1 + m][1 + k][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] | (T1_3D_SIG | T1_3D_VISIT)) & ((t1->flags[1 + m][1 + k + 3][1 + i] & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) & (T1_3D_SIG_OTH))) + ); + } else { + agg = !( + ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 3][1 + i] & T1_3D_SIG_OTH)) + ); + } + } else { + agg = 0; + } + if (agg) { + for (runlen = 0; runlen < 4; runlen++) { + if (int_abs(t1->data[m][k + runlen][i]) & one) + break; + } + mqc_setcurctx(mqc, T1_CTXNO_AGG); + mqc_encode(mqc, runlen != 4); + if (runlen == 4) { + continue; + } + mqc_setcurctx(mqc, T1_CTXNO_UNI); + mqc_encode(mqc, runlen >> 1); + mqc_encode(mqc, runlen & 1); + } else { + runlen = 0; + } + for (j = k + runlen; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_3d_enc_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, bpno, one, nmsedec, agg && (j == k + runlen), vsc); + } + } + } + } +} + +static void t1_3d_dec_clnpass(opj_t1_3d_t *t1, int w, int h, int l, int bpno, int orient, int cblksty) { + int i, j, k, m, one, half, oneplushalf, agg, runlen, vsc; + int segsym = cblksty & J3D_CCP_CBLKSTY_SEGSYM; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + one = 1 << bpno; + half = one >> 1; + oneplushalf = one | half; + for (m = 0; m < l; m++) { + for (k = 0; k < h; k += 4) { + for (i = 0; i < w; i++) { + if (k + 3 < h) { + if (cblksty & J3D_CCP_CBLKSTY_VSC) { + agg = !( + ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | ((t1->flags[1 + m][1 + k + 3][1 + i] & (~(T1_3D_SIG_S | T1_3D_SIG_SE | T1_3D_SIG_SW | (T1_3D_SGN_S << 16)))) & (T1_3D_SIG_OTH))) + ); + } else { + agg = !( + ((t1->flagSVR[1 + m][1 + k][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 1][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 1][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 2][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 2][1 + i] & T1_3D_SIG_OTH)) + || ((t1->flagSVR[1 + m][1 + k + 3][1 + i] & (T1_3D_SIG | T1_3D_VISIT)) | (t1->flags[1 + m][1 + k + 3][1 + i] & T1_3D_SIG_OTH)) + ); + } + } else { + agg = 0; + } + if (agg) { + mqc_setcurctx(mqc, T1_CTXNO_AGG); + if (!mqc_decode(mqc)) { + continue; + } + mqc_setcurctx(mqc, T1_CTXNO_UNI); + runlen = mqc_decode(mqc); + runlen = (runlen << 1) | mqc_decode(mqc); + } else { + runlen = 0; + } + for (j = k + runlen; j < k + 4 && j < h; j++) { + vsc = ((cblksty & J3D_CCP_CBLKSTY_VSC) && (j == k + 3 || j == h - 1)) ? 1 : 0; + t1_3d_dec_clnpass_step(t1, &t1->flags[1 + m][1 + j][1 + i], &t1->flagSVR[1 + m][1 + j][1 + i], &t1->data[m][j][i], orient, oneplushalf, agg && (j == k + runlen), vsc); + } + } + } + } + if (segsym) { + int v = 0; + mqc_setcurctx(mqc, T1_CTXNO_UNI); + v = mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + v = (v << 1) | mqc_decode(mqc); + /* + if (v!=0xa) { + opj_event_msg(t1->cinfo, EVT_WARNING, "Bad segmentation symbol %x\n", v); + } + */ + } +} /* VSC and BYPASS by Antonin */ + + +static void t1_3d_encode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int compno, int level[3], int dwtid[3], double stepsize, int cblksty, int numcomps, opj_tcd_tile_t * tile) { + int i, j, k; + int w, h, l; + int passno; + int bpno, passtype; + int max; + int nmsedec = 0; + double cumwmsedec = 0; + char type = T1_TYPE_MQ; + + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + w = cblk->x1 - cblk->x0; + h = cblk->y1 - cblk->y0; + l = cblk->z1 - cblk->z0; + + max = 0; + for (k = 0; k < l; k++) { + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + max = int_max(max, int_abs(t1->data[k][j][i])); + } + } + } + for (k = 0; k <= l; k++) { + for (j = 0; j <= h; j++) { + for (i = 0; i <= w; i++) { + t1->flags[k][j][i] = 0; + t1->flagSVR[k][j][i] = 0; + } + } + } + + cblk->numbps = max ? (int_floorlog2(max) + 1) - T1_NMSEDEC_FRACBITS : 0; + + bpno = cblk->numbps - 1; + passtype = 2; + + mqc_reset_enc(mqc); + mqc_init_enc(mqc, cblk->data); + + for (passno = 0; bpno >= 0; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + int correction = 3; + double tmpwmsedec; + type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + + switch (passtype) { + case 0: + t1_3d_enc_sigpass(t1, w, h, l, bpno, orient, &nmsedec, type, cblksty); + break; + case 1: + t1_3d_enc_refpass(t1, w, h, l, bpno, &nmsedec, type, cblksty); + break; + case 2: + t1_3d_enc_clnpass(t1, w, h, l, bpno, orient, &nmsedec, cblksty); + /* code switch SEGMARK (i.e. SEGSYM) */ + if (cblksty & J3D_CCP_CBLKSTY_SEGSYM) + mqc_segmark_enc(mqc); + break; + } + + /* fixed_quality */ + tmpwmsedec = t1_getwmsedec(nmsedec, compno, level, orient, bpno, stepsize, numcomps, dwtid); + cumwmsedec += tmpwmsedec; + tile->distotile += tmpwmsedec; + + /* Code switch "RESTART" (i.e. TERMALL) */ + if ((cblksty & J3D_CCP_CBLKSTY_TERMALL) && !((passtype == 2) && (bpno - 1 < 0))) { + if (type == T1_TYPE_RAW) { + mqc_flush(mqc); + correction = 1; + /* correction = mqc_bypass_flush_enc(); */ + } else { /* correction = mqc_restart_enc(); */ + mqc_flush(mqc); + correction = 1; + } + pass->term = 1; + } else { + if (((bpno < (cblk->numbps - 4) && (passtype > 0)) + || ((bpno == (cblk->numbps - 4)) && (passtype == 2))) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) { + if (type == T1_TYPE_RAW) { + mqc_flush(mqc); + correction = 1; + } else { + mqc_flush(mqc); + correction = 1; + } + pass->term = 1; + } else { + pass->term = 0; + } + } + + if (++passtype == 3) { + passtype = 0; + bpno--; + } + + if (pass->term && bpno > 0) { + type = ((bpno < (cblk->numbps - 4)) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + if (type == T1_TYPE_RAW) + mqc_bypass_init_enc(mqc); + else + mqc_restart_init_enc(mqc); + } + + pass->distortiondec = cumwmsedec; + pass->rate = mqc_numbytes(mqc) + correction; /* FIXME */ + pass->len = pass->rate - (passno == 0 ? 0 : cblk->passes[passno - 1].rate); + + /* Code-switch "RESET" */ + if (cblksty & J3D_CCP_CBLKSTY_RESET) + mqc_reset_enc(mqc); + } + + /* Code switch "ERTERM" (i.e. PTERM) */ + if (cblksty & J3D_CCP_CBLKSTY_PTERM) + mqc_erterm_enc(mqc); + else /* Default coding */ if (!(cblksty & J3D_CCP_CBLKSTY_LAZY)) + mqc_flush(mqc); + + cblk->totalpasses = passno; +} + +static void t1_3d_decode_cblk(opj_t1_3d_t *t1, opj_tcd_cblk_t * cblk, int orient, int roishift, int cblksty) { + int i, j, k; + int w, h, l; + int bpno, passtype; + int segno, passno; + char type = T1_TYPE_MQ; /* BYPASS mode */ + opj_raw_t *raw = t1->raw; /* RAW component */ + opj_mqc_t *mqc = t1->mqc; /* MQC component */ + + w = cblk->x1 - cblk->x0; + h = cblk->y1 - cblk->y0; + l = cblk->z1 - cblk->z0; + + for (k = 0; k < l; k++) { + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + t1->data[k][j][i] = 0; + } + } + } + + for (k = 0; k <= l; k++) { + for (j = 0; j <= h; j++) { + for (i = 0; i <= w; i++) { + t1->flags[k][j][i] = 0; + t1->flagSVR[k][j][i] = 0; + } + } + } + + + bpno = roishift + cblk->numbps - 1; + passtype = 2; + + mqc_reset_enc(mqc); + + for (segno = 0; segno < cblk->numsegs; segno++) { + opj_tcd_seg_t *seg = &cblk->segs[segno]; + + /* BYPASS mode */ + type = ((bpno <= (cblk->numbps - 1) - 4) && (passtype < 2) && (cblksty & J3D_CCP_CBLKSTY_LAZY)) ? T1_TYPE_RAW : T1_TYPE_MQ; + if (type == T1_TYPE_RAW) { + raw_init_dec(raw, seg->data, seg->len); + } else { + mqc_init_dec(mqc, seg->data, seg->len); + } + + for (passno = 0; passno < seg->numpasses; passno++) { + switch (passtype) { + case 0: + t1_3d_dec_sigpass(t1, w, h, l, bpno+1, orient, type, cblksty); + break; + case 1: + t1_3d_dec_refpass(t1, w, h, l, bpno+1, type, cblksty); + break; + case 2: + t1_3d_dec_clnpass(t1, w, h, l, bpno+1, orient, cblksty); + break; + } + + if ((cblksty & J3D_CCP_CBLKSTY_RESET) && type == T1_TYPE_MQ) { + mqc_reset_enc(mqc); + } + if (++passtype == 3) { + passtype = 0; + bpno--; + } + + } + } +} + +static int t1_3d_init_ctxno_zc(unsigned int f, int orient) { + unsigned int h, v, c; + unsigned int d2xy, d2xz, d2yz, d3; + int n; + unsigned int hvc, hc, d2, d2xy2yz, d2xy2xz; + n = 0; + h = ((f & T1_3D_SIG_W) != 0) + ((f & T1_3D_SIG_E) != 0); + v = ((f & T1_3D_SIG_N) != 0) + ((f & T1_3D_SIG_S) != 0); + c = ((f & T1_3D_SIG_FC) != 0) + ((f & T1_3D_SIG_BC) != 0); + d2xy = ((f & T1_3D_SIG_NW) != 0) + ((f & T1_3D_SIG_NE) != 0) + ((f & T1_3D_SIG_SE) != 0) + ((f & T1_3D_SIG_SW) != 0); + d2xz = ((f & T1_3D_SIG_FW) != 0) + ((f & T1_3D_SIG_BW) != 0) + ((f & T1_3D_SIG_FE) != 0) + ((f & T1_3D_SIG_BE) != 0); + d2yz = ((f & T1_3D_SIG_FN) != 0) + ((f & T1_3D_SIG_FS) != 0) + ((f & T1_3D_SIG_BN) != 0) + ((f & T1_3D_SIG_BS) != 0); + d3 = ((f & T1_3D_SIG_FNW) != 0) + ((f & T1_3D_SIG_FNE) != 0) + ((f & T1_3D_SIG_FSE) != 0) + ((f & T1_3D_SIG_FSW) != 0) + + ((f & T1_3D_SIG_BNW) != 0) + ((f & T1_3D_SIG_BNE) != 0) + ((f & T1_3D_SIG_BSE) != 0) + ((f & T1_3D_SIG_BSW) != 0); + + switch (orient) { + case 0: /*LLL*/ + case 7: /*HHH*/ + hvc = h + v + c; + d2 = d2xy + d2xz + d2yz; + if (!hvc) { + if (!d2) { + n = (!d3) ? 0 : 1; + } else if (d2 == 1) { + n = (!d3) ? 2 : 3; + } else { + n = (!d3) ? 4 : 5; + } + } else if (hvc == 1) { + if (!d2) { + n = (!d3) ? 6 : 7; + } else if (d2 == 1) { + n = (!d3) ? 8 : 9; + } else { + n = 10; + } + } else if (hvc == 2) { + if (!d2) { + n = (!d3) ? 11 : 12; + } else { + n = 13; + } + } else if (hvc == 3) { + n = 14; + } else { + n = 15; + } + break; + /*LHL, HLL, LLH*/ + case 1: + case 2: + case 4: + hc = h + c; + d2xy2yz = d2xy + d2yz; + if (!hc) { + if (!v) { + if (!d2xy) { + n = (!d2xy2yz) ? ((!d3) ? 0 : 1) : ((!d3) ? 2 : 3); + } else if (d2xy == 1) { + n = (!d2xy2yz) ? ((!d3) ? 4 : 5) : 6; + } else { /*>=2*/ + n = 7; + } + } else { + n = (v == 1) ? 8 : 9; /* =1 or =2*/ + } + } else if (hc == 1) { + n = (!v) ? ( (!d2xy) ? ( (!d2xy2yz) ? ( (!d3) ? 10 : 11) : (12) ) : (13) ) : (14); + } else { /*if (hc >= 2)*/ + n = 15; + } + break; + /*HLH, HHL, LHH*/ + case 3: + case 5: + case 6: + hc = h + c; + d2xy2xz = d2xy + d2xz; + if (!v) { + if (!d2xz) { + if (!hc && !d2xy2xz) { + n = (!d3) ? 0 : 1; + } else if (hc == 1) { + n = (!d2xy2xz) ? 2 : 3; + } else { /*if >= 2*/ + n = 4; + } + } else if ( d2xz>=1 && !hc ) { + n = 5; + } else if ( hc>=1 ) { + n = (d2xz==1) ? 6 : 7; + } + } else if (v == 1) { + if (!d2xz) { + n = (!hc) ? 8 : 9; + } else if (d2xz == 1) { + n = (!hc) ? 10 : 11; + } else if (d2xz == 2) { + n = (!hc) ? 12 : 13; + } else { /* if (d2xz >= 3) {*/ + n = 14; + } + } else if (v == 2) { + n = 15; + } + break; + } + + return (T1_3D_CTXNO_ZC + n); +} + +static int t1_3d_init_ctxno_sc(unsigned int f) { + int hc, vc, cc; + int n = 0; + + hc = int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == T1_3D_SIG_E ) + + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W)) == T1_3D_SIG_W ) , 1) + - int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == (T1_3D_SIG_E | T1_3D_SGN_E) ) + + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W) ) == (T1_3D_SIG_W | T1_3D_SGN_W)), 1); + + vc = int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == T1_3D_SIG_N) + + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == T1_3D_SIG_S), 1) + - int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == (T1_3D_SIG_N | T1_3D_SGN_N)) + + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == (T1_3D_SIG_S | T1_3D_SGN_S)), 1); + + cc = int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == T1_3D_SIG_FC) + + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == T1_3D_SIG_BC), 1) + - int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == (T1_3D_SIG_FC | T1_3D_SGN_F)) + + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == (T1_3D_SIG_BC | T1_3D_SGN_B)), 1); + if (hc < 0) { + hc = -hc; + vc = -vc; + cc = -cc; + } + + if (!hc) { + if (!vc) + n = (!cc) ? 0 : 1; + else if (vc == -1) + n = (!cc) ? 1 : ( (cc>0) ? 2 : 4); + else if (vc == 1) + n = (!cc) ? 1 : ( (cc<0) ? 2 : 4); + } else if (hc == 1) { + if (!vc) + n = (!cc) ? 1 : ( (cc<0) ? 2 : 4); + else if (vc == 1) + n = (!cc) ? 4 : ( (cc>0) ? 5 : 3); + else if (vc == -1) + n = (!cc) ? 2 : 3; + } else if (hc == -1) { + if (!vc) + n = (!cc) ? 1 : ( (cc>0) ? 2 : 4); + else if (vc == 1) + n = (!cc) ? 2 : 3; + else if (vc == -1) + n = (!cc) ? 4 : ( (cc<0) ? 5 : 3); + } + + return (T1_3D_CTXNO_SC + n); +} + +static int t1_3d_init_ctxno_mag(unsigned int f, int f2) { + int n; + if (!(f2 & T1_3D_REFINE)) /*First refinement for this coefficient (no previous refinement)*/ + n = (f & (T1_3D_SIG_PRIM)) ? 1 : 0; + else + n = 2; + + return (T1_3D_CTXNO_MAG + n); +} + +static int t1_3d_init_spb(unsigned int f) { + int hc, vc, cc; + int n = 0; + + hc = int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == T1_3D_SIG_E ) + + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W)) == T1_3D_SIG_W ) , 1) + - int_min( ( (f & (T1_3D_SIG_E | T1_3D_SGN_E)) == (T1_3D_SIG_E | T1_3D_SGN_E) ) + + ( (f & (T1_3D_SIG_W | T1_3D_SGN_W) ) == (T1_3D_SIG_W | T1_3D_SGN_W)), 1); + + vc = int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == T1_3D_SIG_N) + + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == T1_3D_SIG_S), 1) + - int_min(((f & (T1_3D_SIG_N | T1_3D_SGN_N)) == (T1_3D_SIG_N | T1_3D_SGN_N)) + + ((f & (T1_3D_SIG_S | T1_3D_SGN_S)) == (T1_3D_SIG_S | T1_3D_SGN_S)), 1); + + cc = int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == T1_3D_SIG_FC) + + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == T1_3D_SIG_BC), 1) + - int_min(((f & (T1_3D_SIG_FC | T1_3D_SGN_F)) == (T1_3D_SIG_FC | T1_3D_SGN_F)) + + ((f & (T1_3D_SIG_BC | T1_3D_SGN_B)) == (T1_3D_SIG_BC | T1_3D_SGN_B)), 1); + + n = ((hc + vc + cc) < 0); + + return n; +} + +static void t1_3d_init_luts(opj_t1_3d_t *t1) { + int i; + double u, v, t; + /*for (j = 0; j < 4; j++) { + for (i = 0; i < 256; ++i) { + t1->lut_ctxno_zc[(j << 8) | i] = t1_3d_init_ctxno_zc(i, j); + } + } + for (i = 0; i < 4096; i++) { + t1->lut_ctxno_sc[i] = t1_3d_init_ctxno_sc(i << 4); + } + for (j = 0; j < 2; j++) { + for (i = 0; i < 2048; ++i) { + t1->lut_ctxno_mag[(j << 11) + i] = t1_3d_init_ctxno_mag((j ? T1_3D_REFINE : 0) | i); + } + } + for (i = 0; i < 4096; ++i) { + t1->lut_spb[i] = t1_3d_init_spb(i << 4); + }*/ + /* FIXME FIXME FIXME */ + for (i = 0; i < (1 << T1_NMSEDEC_BITS); i++) { + t = i / pow(2, T1_NMSEDEC_FRACBITS); + u = t; + v = t - 1.5; + t1->lut_nmsedec_sig[i] = + int_max(0, + (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + t1->lut_nmsedec_sig0[i] = + int_max(0, + (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + u = t - 1.0; + if (i & (1 << (T1_NMSEDEC_BITS - 1))) { + v = t - 1.5; + } else { + v = t - 0.5; + } + t1->lut_nmsedec_ref[i] = + int_max(0, + (int) (floor((u * u - v * v) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + t1->lut_nmsedec_ref0[i] = + int_max(0, + (int) (floor((u * u) * pow(2, T1_NMSEDEC_FRACBITS) + 0.5) / pow(2, T1_NMSEDEC_FRACBITS) * 8192.0)); + } +} + +/* ----------------------------------------------------------------------- */ + +opj_t1_3d_t* t1_3d_create(opj_common_ptr cinfo) { + opj_t1_3d_t *t1 = (opj_t1_3d_t*)opj_malloc(sizeof(opj_t1_3d_t)); + if(t1) { + t1->cinfo = cinfo; + /* create MQC and RAW handles */ + t1->mqc = mqc_create(); + t1->raw = raw_create(); + /* initialize the look-up tables of the Tier-1 coder/decoder */ + t1_3d_init_luts(t1); + } + return t1; +} + +void t1_3d_destroy(opj_t1_3d_t *t1) { + if(t1) { + /* destroy MQC and RAW handles */ + mqc_destroy(t1->mqc); + raw_destroy(t1->raw); + opj_free(t1); + } +} + +void t1_3d_encode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { + int compno, resno, bandno, precno, cblkno; + int x, y, z, i, j, k, orient; + int level[3]; + tile->distotile = 0; /* fixed_quality */ + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + + if (band->bandno == 0) { + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 1) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 2) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 3) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 4) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 5) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 6) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 7) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } + + if (tcp->tccps[compno].reversible == 1) { + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + t1->data[k][j][i] = + tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] << T1_NMSEDEC_FRACBITS; + } + } + } + } else if (tcp->tccps[compno].reversible == 0) { + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + t1->data[k][j][i] = fix_mul( + tilec->data[(x + i) + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)], + 8192 * 8192 / ((int) floor(band->stepsize * 8192))) >> (13 - T1_NMSEDEC_FRACBITS); + } + } + } + } + orient = band->bandno; /* FIXME */ + for (i = 0; i < 3; i++) + level[i] = tilec->numresolution[i] - 1 - resno; + + t1_3d_encode_cblk(t1, cblk, orient, compno, level, tcp->tccps[compno].dwtid, band->stepsize, tcp->tccps[compno].cblksty, tile->numcomps, tile); + + } /* cblkno */ + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ +} + +void t1_3d_decode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp) { + int compno, resno, bandno, precno, cblkno; + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + int x, y, z, i, j, k, orient; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + + orient = band->bandno; /* FIXME */ + + /*fprintf(stdout,"[INFO] t1_3d_decode_cblk(t1, cblk, orient(%d), tcp->tccps[compno].roishift (%d), tcp->tccps[compno].cblksty (%d));\n",orient,tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty);*/ + t1_3d_decode_cblk(t1, cblk, orient, tcp->tccps[compno].roishift, tcp->tccps[compno].cblksty); + + if (band->bandno == 0) { + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 1) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 2) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 3) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = cblk->z0 - band->z0; + } else if (band->bandno == 4) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 5) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 6) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } else if (band->bandno == 7) { + opj_tcd_resolution_t *pres = &tilec->resolutions[resno - 1]; + x = pres->x1 - pres->x0 + cblk->x0 - band->x0; + y = pres->y1 - pres->y0 + cblk->y0 - band->y0; + z = pres->z1 - pres->z0 + cblk->z0 - band->z0; + } + + if (tcp->tccps[compno].roishift) { + int thresh, val, mag; + thresh = 1 << tcp->tccps[compno].roishift; + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + val = t1->data[k][j][i]; + mag = int_abs(val); + if (mag >= thresh) { + mag >>= tcp->tccps[compno].roishift; + t1->data[k][j][i] = val < 0 ? -mag : mag; + } + } + } + } + } + + if (tcp->tccps[compno].reversible == 1) { + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + int tmp = t1->data[k][j][i]; + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = tmp/2; + } + } + } + } else { /* if (tcp->tccps[compno].reversible == 0) */ + for (k = 0; k < cblk->z1 - cblk->z0; k++) { + for (j = 0; j < cblk->y1 - cblk->y0; j++) { + for (i = 0; i < cblk->x1 - cblk->x0; i++) { + double tmp = (double)(t1->data[k][j][i] * band->stepsize * 4096.0); + if (t1->data[k][j][i] >> 1 == 0) { + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = 0; + } else { + int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); + tilec->data[x + i + (y + j) * (tilec->x1 - tilec->x0) + (z + k) * (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0)] = ((tmp<0)?-tmp2:tmp2); + } + } + } + } + } + } /* cblkno */ + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ +} diff --git a/src/lib/openjp3d/t1_3d.h b/src/lib/openjp3d/t1_3d.h old mode 100755 new mode 100644 index 6410bd5a..2974781f --- a/src/lib/openjp3d/t1_3d.h +++ b/src/lib/openjp3d/t1_3d.h @@ -1,173 +1,173 @@ -/* - * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __T1_3D_H -#define __T1_3D_H -/** -@file t1_3d.h -@brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1) - -The functions in T1_3D.C have for goal to realize the tier-1 coding operation of 3D-EBCOT. -The functions in T1_3D.C are used by some function in TCD.C. -*/ - -/** @defgroup T1_3D T1_3D - Implementation of the tier-1 coding */ -/*@{*/ - -/* ----------------------------------------------------------------------- */ - -/* Neighbourhood of 3D EBCOT (Significance context)*/ -#define T1_3D_SIG_NE 0x00000001 /*< Context orientation : North-East direction */ -#define T1_3D_SIG_SE 0x00000002 /*< Context orientation : South-East direction */ -#define T1_3D_SIG_SW 0x00000004 /*< Context orientation : South-West direction */ -#define T1_3D_SIG_NW 0x00000008 /* Context orientation : North-West direction */ -#define T1_3D_SIG_N 0x00000010 /*< Context orientation : North direction */ -#define T1_3D_SIG_E 0x00000020 /*< Context orientation : East direction */ -#define T1_3D_SIG_S 0x00000040 /*< Context orientation : South direction */ -#define T1_3D_SIG_W 0x00000080 /*< Context orientation : West direction */ -#define T1_3D_SIG_FC 0x00000100 /*< Context orientation : Forward Central direction */ -#define T1_3D_SIG_BC 0x00000200 /*< Context orientation : Backward Central direction */ -#define T1_3D_SIG_FNE 0x00000400 /*< Context orientation : Forward North-East direction */ -#define T1_3D_SIG_FSE 0x00000800 /*< Context orientation : Forward South-East direction */ -#define T1_3D_SIG_FSW 0x00001000 /*< Context orientation : Forward South-West direction */ -#define T1_3D_SIG_FNW 0x00002000 /*< Context orientation : Forward North-West direction */ -#define T1_3D_SIG_FN 0x00004000 /*< Context orientation : Forward North direction */ -#define T1_3D_SIG_FE 0x00008000 /*< Context orientation : Forward East direction */ -#define T1_3D_SIG_FS 0x00010000 /*< Context orientation : Forward South direction */ -#define T1_3D_SIG_FW 0x00020000 /*< Context orientation : Forward West direction */ -#define T1_3D_SIG_BNE 0x00040000 /*< Context orientation : Backward North-East direction */ -#define T1_3D_SIG_BSE 0x00080000 /*< Context orientation : Backward South-East direction */ -#define T1_3D_SIG_BSW 0x00100000 /*< Context orientation : Backward South-West direction */ -#define T1_3D_SIG_BNW 0x00200000 /*< Context orientation : Backward North-West direction */ -#define T1_3D_SIG_BN 0x00400000 /*< Context orientation : Backward North direction */ -#define T1_3D_SIG_BE 0x00800000 /*< Context orientation : Backward East direction */ -#define T1_3D_SIG_BS 0x01000000 /*< Context orientation : Backward South direction */ -#define T1_3D_SIG_BW 0x02000000 /*< Context orientation : Backward West direction */ -#define T1_3D_SIG_COTH (T1_3D_SIG_N|T1_3D_SIG_NE|T1_3D_SIG_E|T1_3D_SIG_SE|T1_3D_SIG_S|T1_3D_SIG_SW|T1_3D_SIG_W|T1_3D_SIG_NW) -#define T1_3D_SIG_BOTH (T1_3D_SIG_BN|T1_3D_SIG_BNE|T1_3D_SIG_BE|T1_3D_SIG_BSE|T1_3D_SIG_BS|T1_3D_SIG_BSW|T1_3D_SIG_BW|T1_3D_SIG_BNW|T1_3D_SIG_BC) -#define T1_3D_SIG_FOTH (T1_3D_SIG_FN|T1_3D_SIG_FNE|T1_3D_SIG_FE|T1_3D_SIG_FSE|T1_3D_SIG_FS|T1_3D_SIG_FSW|T1_3D_SIG_FW|T1_3D_SIG_FNW|T1_3D_SIG_FC) -#define T1_3D_SIG_OTH (T1_3D_SIG_FOTH|T1_3D_SIG_BOTH|T1_3D_SIG_COTH) -#define T1_3D_SIG_PRIM (T1_3D_SIG_N|T1_3D_SIG_E|T1_3D_SIG_S|T1_3D_SIG_W|T1_3D_SIG_FC|T1_3D_SIG_BC) - -#define T1_3D_SGN_N 0x0400 -#define T1_3D_SGN_E 0x0800 -#define T1_3D_SGN_S 0x1000 -#define T1_3D_SGN_W 0x2000 -#define T1_3D_SGN_F 0x4000 -#define T1_3D_SGN_B 0x8000 -#define T1_3D_SGN (T1_3D_SGN_N|T1_3D_SGN_E|T1_3D_SGN_S|T1_3D_SGN_W|T1_3D_SGN_F|T1_3D_SGN_B) - -#define T1_3D_SIG 0x0001 /*Significance state*/ -#define T1_3D_REFINE 0x0002 /*Delayed significance*/ -#define T1_3D_VISIT 0x0004 /*First-pass membership*/ - -#define T1_3D_NUMCTXS_AGG 1 -#define T1_3D_NUMCTXS_ZC 16 -#define T1_3D_NUMCTXS_MAG 3 -#define T1_3D_NUMCTXS_SC 6 -#define T1_3D_NUMCTXS_UNI 1 - -#define T1_3D_CTXNO_AGG 0 -#define T1_3D_CTXNO_ZC (T1_3D_CTXNO_AGG+T1_3D_NUMCTXS_AGG) /*1*/ -#define T1_3D_CTXNO_MAG (T1_3D_CTXNO_ZC+T1_3D_NUMCTXS_ZC) /*17*/ -#define T1_3D_CTXNO_SC (T1_3D_CTXNO_MAG+T1_3D_NUMCTXS_MAG) /*20*/ -#define T1_3D_CTXNO_UNI (T1_3D_CTXNO_SC+T1_3D_NUMCTXS_SC) /*26*/ -#define T1_3D_NUMCTXS (T1_3D_CTXNO_UNI+T1_3D_NUMCTXS_UNI) /*27*/ - - -/* ----------------------------------------------------------------------- */ - -/** -Tier-1 coding (coding of code-block coefficients) -*/ -typedef struct opj_t1_3d { - /** Codec context */ - opj_common_ptr cinfo; - /** MQC component */ - opj_mqc_t *mqc; - /** RAW component */ - opj_raw_t *raw; - /** LUTs for decoding normalised MSE */ - int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS]; - int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS]; - int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS]; - int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS]; - /** Codeblock data */ - int data[T1_CBLKD][T1_CBLKH][T1_CBLKW]; - /** Context information for each voxel in codeblock */ - unsigned int flags[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2]; - /** Voxel information (significance/visited/refined) */ - int flagSVR[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2]; -} opj_t1_3d_t; - -/** @name Exported functions */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Create a new T1_3D handle -and initialize the look-up tables of the Tier-1 coder/decoder -@return Returns a new T1 handle if successful, returns NULL otherwise -@see t1_init_luts -*/ -opj_t1_3d_t* t1_3d_create(opj_common_ptr cinfo); -/** -Destroy a previously created T1_3D handle -@param t1 T1_3D handle to destroy -*/ -void t1_3d_destroy(opj_t1_3d_t *t1); -/** -Encode the code-blocks of a tile -@param t1 T1_3D handle -@param tile The tile to encode -@param tcp Tile coding parameters -*/ -void t1_3d_encode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); -/** -Decode the code-blocks of a tile -@param t1 T1_3D handle -@param tile The tile to decode -@param tcp Tile coding parameters -*/ -void t1_3d_decode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); -/** -Get weigths of MSE decoding -@param nmsedec The normalized MSE reduction -@param compno -@param level -@param orient -@param bpno -@param reversible -@param stepsize -@param numcomps -@param dwtid -returns MSE associated to decoding pass -double t1_3d_getwmsedec(int nmsedec, int compno, int levelxy, int levelz, int orient, int bpno, int reversible, double stepsize, int numcomps, int dwtid); -*/ -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __T1_H */ +/* + * Copyrigth (c) 2006, Mónica Díez, LPI-UVA, Spain + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __T1_3D_H +#define __T1_3D_H +/** +@file t1_3d.h +@brief Implementation of the tier-1 coding (coding of code-block coefficients) (T1) + +The functions in T1_3D.C have for goal to realize the tier-1 coding operation of 3D-EBCOT. +The functions in T1_3D.C are used by some function in TCD.C. +*/ + +/** @defgroup T1_3D T1_3D - Implementation of the tier-1 coding */ +/*@{*/ + +/* ----------------------------------------------------------------------- */ + +/* Neighbourhood of 3D EBCOT (Significance context)*/ +#define T1_3D_SIG_NE 0x00000001 /*< Context orientation : North-East direction */ +#define T1_3D_SIG_SE 0x00000002 /*< Context orientation : South-East direction */ +#define T1_3D_SIG_SW 0x00000004 /*< Context orientation : South-West direction */ +#define T1_3D_SIG_NW 0x00000008 /* Context orientation : North-West direction */ +#define T1_3D_SIG_N 0x00000010 /*< Context orientation : North direction */ +#define T1_3D_SIG_E 0x00000020 /*< Context orientation : East direction */ +#define T1_3D_SIG_S 0x00000040 /*< Context orientation : South direction */ +#define T1_3D_SIG_W 0x00000080 /*< Context orientation : West direction */ +#define T1_3D_SIG_FC 0x00000100 /*< Context orientation : Forward Central direction */ +#define T1_3D_SIG_BC 0x00000200 /*< Context orientation : Backward Central direction */ +#define T1_3D_SIG_FNE 0x00000400 /*< Context orientation : Forward North-East direction */ +#define T1_3D_SIG_FSE 0x00000800 /*< Context orientation : Forward South-East direction */ +#define T1_3D_SIG_FSW 0x00001000 /*< Context orientation : Forward South-West direction */ +#define T1_3D_SIG_FNW 0x00002000 /*< Context orientation : Forward North-West direction */ +#define T1_3D_SIG_FN 0x00004000 /*< Context orientation : Forward North direction */ +#define T1_3D_SIG_FE 0x00008000 /*< Context orientation : Forward East direction */ +#define T1_3D_SIG_FS 0x00010000 /*< Context orientation : Forward South direction */ +#define T1_3D_SIG_FW 0x00020000 /*< Context orientation : Forward West direction */ +#define T1_3D_SIG_BNE 0x00040000 /*< Context orientation : Backward North-East direction */ +#define T1_3D_SIG_BSE 0x00080000 /*< Context orientation : Backward South-East direction */ +#define T1_3D_SIG_BSW 0x00100000 /*< Context orientation : Backward South-West direction */ +#define T1_3D_SIG_BNW 0x00200000 /*< Context orientation : Backward North-West direction */ +#define T1_3D_SIG_BN 0x00400000 /*< Context orientation : Backward North direction */ +#define T1_3D_SIG_BE 0x00800000 /*< Context orientation : Backward East direction */ +#define T1_3D_SIG_BS 0x01000000 /*< Context orientation : Backward South direction */ +#define T1_3D_SIG_BW 0x02000000 /*< Context orientation : Backward West direction */ +#define T1_3D_SIG_COTH (T1_3D_SIG_N|T1_3D_SIG_NE|T1_3D_SIG_E|T1_3D_SIG_SE|T1_3D_SIG_S|T1_3D_SIG_SW|T1_3D_SIG_W|T1_3D_SIG_NW) +#define T1_3D_SIG_BOTH (T1_3D_SIG_BN|T1_3D_SIG_BNE|T1_3D_SIG_BE|T1_3D_SIG_BSE|T1_3D_SIG_BS|T1_3D_SIG_BSW|T1_3D_SIG_BW|T1_3D_SIG_BNW|T1_3D_SIG_BC) +#define T1_3D_SIG_FOTH (T1_3D_SIG_FN|T1_3D_SIG_FNE|T1_3D_SIG_FE|T1_3D_SIG_FSE|T1_3D_SIG_FS|T1_3D_SIG_FSW|T1_3D_SIG_FW|T1_3D_SIG_FNW|T1_3D_SIG_FC) +#define T1_3D_SIG_OTH (T1_3D_SIG_FOTH|T1_3D_SIG_BOTH|T1_3D_SIG_COTH) +#define T1_3D_SIG_PRIM (T1_3D_SIG_N|T1_3D_SIG_E|T1_3D_SIG_S|T1_3D_SIG_W|T1_3D_SIG_FC|T1_3D_SIG_BC) + +#define T1_3D_SGN_N 0x0400 +#define T1_3D_SGN_E 0x0800 +#define T1_3D_SGN_S 0x1000 +#define T1_3D_SGN_W 0x2000 +#define T1_3D_SGN_F 0x4000 +#define T1_3D_SGN_B 0x8000 +#define T1_3D_SGN (T1_3D_SGN_N|T1_3D_SGN_E|T1_3D_SGN_S|T1_3D_SGN_W|T1_3D_SGN_F|T1_3D_SGN_B) + +#define T1_3D_SIG 0x0001 /*Significance state*/ +#define T1_3D_REFINE 0x0002 /*Delayed significance*/ +#define T1_3D_VISIT 0x0004 /*First-pass membership*/ + +#define T1_3D_NUMCTXS_AGG 1 +#define T1_3D_NUMCTXS_ZC 16 +#define T1_3D_NUMCTXS_MAG 3 +#define T1_3D_NUMCTXS_SC 6 +#define T1_3D_NUMCTXS_UNI 1 + +#define T1_3D_CTXNO_AGG 0 +#define T1_3D_CTXNO_ZC (T1_3D_CTXNO_AGG+T1_3D_NUMCTXS_AGG) /*1*/ +#define T1_3D_CTXNO_MAG (T1_3D_CTXNO_ZC+T1_3D_NUMCTXS_ZC) /*17*/ +#define T1_3D_CTXNO_SC (T1_3D_CTXNO_MAG+T1_3D_NUMCTXS_MAG) /*20*/ +#define T1_3D_CTXNO_UNI (T1_3D_CTXNO_SC+T1_3D_NUMCTXS_SC) /*26*/ +#define T1_3D_NUMCTXS (T1_3D_CTXNO_UNI+T1_3D_NUMCTXS_UNI) /*27*/ + + +/* ----------------------------------------------------------------------- */ + +/** +Tier-1 coding (coding of code-block coefficients) +*/ +typedef struct opj_t1_3d { + /** Codec context */ + opj_common_ptr cinfo; + /** MQC component */ + opj_mqc_t *mqc; + /** RAW component */ + opj_raw_t *raw; + /** LUTs for decoding normalised MSE */ + int lut_nmsedec_sig[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_sig0[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_ref[1 << T1_NMSEDEC_BITS]; + int lut_nmsedec_ref0[1 << T1_NMSEDEC_BITS]; + /** Codeblock data */ + int data[T1_CBLKD][T1_CBLKH][T1_CBLKW]; + /** Context information for each voxel in codeblock */ + unsigned int flags[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2]; + /** Voxel information (significance/visited/refined) */ + int flagSVR[T1_CBLKD + 2][T1_CBLKH + 2][T1_CBLKH + 2]; +} opj_t1_3d_t; + +/** @name Exported functions */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a new T1_3D handle +and initialize the look-up tables of the Tier-1 coder/decoder +@return Returns a new T1 handle if successful, returns NULL otherwise +@see t1_init_luts +*/ +opj_t1_3d_t* t1_3d_create(opj_common_ptr cinfo); +/** +Destroy a previously created T1_3D handle +@param t1 T1_3D handle to destroy +*/ +void t1_3d_destroy(opj_t1_3d_t *t1); +/** +Encode the code-blocks of a tile +@param t1 T1_3D handle +@param tile The tile to encode +@param tcp Tile coding parameters +*/ +void t1_3d_encode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); +/** +Decode the code-blocks of a tile +@param t1 T1_3D handle +@param tile The tile to decode +@param tcp Tile coding parameters +*/ +void t1_3d_decode_cblks(opj_t1_3d_t *t1, opj_tcd_tile_t *tile, opj_tcp_t *tcp); +/** +Get weigths of MSE decoding +@param nmsedec The normalized MSE reduction +@param compno +@param level +@param orient +@param bpno +@param reversible +@param stepsize +@param numcomps +@param dwtid +returns MSE associated to decoding pass +double t1_3d_getwmsedec(int nmsedec, int compno, int levelxy, int levelz, int orient, int bpno, int reversible, double stepsize, int numcomps, int dwtid); +*/ +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __T1_H */ diff --git a/src/lib/openjp3d/t2.c b/src/lib/openjp3d/t2.c old mode 100755 new mode 100644 index e902d60d..65d98c13 --- a/src/lib/openjp3d/t2.c +++ b/src/lib/openjp3d/t2.c @@ -1,675 +1,676 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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 "opj_includes.h" - -/** @defgroup T2 T2 - Implementation of a tier-2 coding */ -/*@{*/ - -/** @name Local static functions */ -/*@{*/ - -static void t2_putcommacode(opj_bio_t *bio, int n); -static int t2_getcommacode(opj_bio_t *bio); -/** -Variable length code for signalling delta Zil (truncation point) -@param bio Bit Input/Output component -@param n delta Zil -*/ -static void t2_putnumpasses(opj_bio_t *bio, int n); -static int t2_getnumpasses(opj_bio_t *bio); -/** -Encode a packet of a tile to a destination buffer -@param tile Tile for which to write the packets -@param tcp Tile coding parameters -@param pi Packet identity -@param dest Destination buffer -@param len Length of the destination buffer -@param volume_info Structure to create an index file -@param tileno Number of the tile encoded -@param cp Coding parameters -@return Number of bytes encoded from the packet -*/ -static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_volume_info_t *volume_info, int tileno, opj_cp_t *cp); -/** -Initialize the segment decoder -@param seg Segment instance -@param cblksty Codeblock style -@param first Is first segment -*/ -static void t2_init_seg(opj_tcd_seg_t *seg, int cblksty, int first); -/** -Decode a packet of a tile from a source buffer -@param t2 T2 handle -@param src Source buffer -@param len Length of the source buffer -@param tile Tile for which to write the packets -@param tcp Tile coding parameters -@param pi Packet identity -@return Number of bytes decoded from the packet -*/ -int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi); - -/*@}*/ - -/*@}*/ - -/* ----------------------------------------------------------------------- */ - -/* #define RESTART 0x04 */ -static void t2_putcommacode(opj_bio_t *bio, int n) { - while (--n >= 0) { - bio_write(bio, 1, 1); - } - bio_write(bio, 0, 1); -} - -static int t2_getcommacode(opj_bio_t *bio) { - int n; - for (n = 0; bio_read(bio, 1); n++) { - ; - } - return n; -} - -static void t2_putnumpasses(opj_bio_t *bio, int n) { - if (n == 1) { - bio_write(bio, 0, 1); - } else if (n == 2) { - bio_write(bio, 2, 2); - } else if (n <= 5) { - bio_write(bio, 0xc | (n - 3), 4); - } else if (n <= 36) { - bio_write(bio, 0x1e0 | (n - 6), 9); - } else if (n <= 164) { - bio_write(bio, 0xff80 | (n - 37), 16); - } -} - -static int t2_getnumpasses(opj_bio_t *bio) { - int n; - if (!bio_read(bio, 1)) - return 1; - if (!bio_read(bio, 1)) - return 2; - if ((n = bio_read(bio, 2)) != 3) - return (3 + n); - if ((n = bio_read(bio, 5)) != 31) - return (6 + n); - return (37 + bio_read(bio, 7)); -} - -static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_volume_info_t * volume_info, int tileno, opj_cp_t *cp) { - int bandno, cblkno; - unsigned char *sop = 0, *eph = 0; - unsigned char *c = dest; - - int compno = pi->compno; /* component value */ - int resno = pi->resno; /* resolution level value */ - int precno = pi->precno; /* precinct value */ - int layno = pi->layno; /* quality layer value */ - - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - - opj_bio_t *bio = NULL; /* BIO component */ - - /* */ - if ((tcp->csty & J3D_CP_CSTY_SOP)) { - sop = (unsigned char *) opj_malloc(6 * sizeof(unsigned char)); - sop[0] = 255; - sop[1] = 145; - sop[2] = 0; - sop[3] = 4; - sop[4] = (volume_info) ? (volume_info->num % 65536) / 256 : (0 % 65536) / 256 ; - sop[5] = (volume_info) ? (volume_info->num % 65536) % 256 : (0 % 65536) % 256 ; - memcpy(c, sop, 6); - opj_free(sop); - c += 6; - } - /* */ - - if (!layno) { - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - opj_tcd_precinct_t *prc = &band->precincts[precno]; - tgt_reset(prc->incltree); - tgt_reset(prc->imsbtree); - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - cblk->numpasses = 0; - tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps); - } - } - } - - bio = bio_create(); - bio_init_enc(bio, c, len); - bio_write(bio, 1, 1); /* Empty header bit */ - - /* Writing Packet header */ - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - opj_tcd_precinct_t *prc = &band->precincts[precno]; - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - opj_tcd_layer_t *layer = &cblk->layers[layno]; - if (!cblk->numpasses && layer->numpasses) { - tgt_setvalue(prc->incltree, cblkno, layno); - } - } - - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - opj_tcd_layer_t *layer = &cblk->layers[layno]; - int increment = 0; - int nump = 0; - int len = 0, passno; - /* cblk inclusion bits */ - if (!cblk->numpasses) { - tgt_encode(bio, prc->incltree, cblkno, layno + 1); - } else { - bio_write(bio, layer->numpasses != 0, 1); - } - /* if cblk not included, go to the next cblk */ - if (!layer->numpasses) { - continue; - } - /* if first instance of cblk --> zero bit-planes information */ - if (!cblk->numpasses) { - cblk->numlenbits = 3; - tgt_encode(bio, prc->imsbtree, cblkno, 999); - } - /* number of coding passes included */ - t2_putnumpasses(bio, layer->numpasses); - - /* computation of the increase of the length indicator and insertion in the header */ - for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { - opj_tcd_pass_t *pass = &cblk->passes[passno]; - nump++; - len += pass->len; - if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { - increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump))); - len = 0; - nump = 0; - } - } - t2_putcommacode(bio, increment); - - /* computation of the new Length indicator */ - cblk->numlenbits += increment; - - /* insertion of the codeword segment length */ - for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { - opj_tcd_pass_t *pass = &cblk->passes[passno]; - nump++; - len += pass->len; - if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { - bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump)); - len = 0; - nump = 0; - } - } - - } - } - - - if (bio_flush(bio)) { - return -999; /* modified to eliminate longjmp !! */ - } - - c += bio_numbytes(bio); - - bio_destroy(bio); - - /* */ - if (tcp->csty & J3D_CP_CSTY_EPH) { - eph = (unsigned char *) opj_malloc(2 * sizeof(unsigned char)); - eph[0] = 255; - eph[1] = 146; - memcpy(c, eph, 2); - opj_free(eph); - c += 2; - } - /* */ - - /* Writing the packet body */ - - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - opj_tcd_precinct_t *prc = &band->precincts[precno]; - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - opj_tcd_layer_t *layer = &cblk->layers[layno]; - if (!layer->numpasses) { - continue; - } - if (c + layer->len > dest + len) { - return -999; - } - - memcpy(c, layer->data, layer->len); - cblk->numpasses += layer->numpasses; - c += layer->len; - /* ADD for index Cfr. Marcela --> delta disto by packet */ - if(volume_info && volume_info->index_write && volume_info->index_on) { - opj_tile_info_t *info_TL = &volume_info->tile[tileno]; - opj_packet_info_t *info_PK = &info_TL->packet[volume_info->num]; - info_PK->disto += layer->disto; - if (volume_info->D_max < info_PK->disto) { - volume_info->D_max = info_PK->disto; - } - } - /* */ - } - } - - return (c - dest); -} - -static void t2_init_seg(opj_tcd_seg_t * seg, int cblksty, int first) { - seg->numpasses = 0; - seg->len = 0; - if (cblksty & J3D_CCP_CBLKSTY_TERMALL) { - seg->maxpasses = 1; - } - else if (cblksty & J3D_CCP_CBLKSTY_LAZY) { - if (first) { - seg->maxpasses = 10; - } else { - seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1; - } - } else { - seg->maxpasses = 109; - } -} - -int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi) { - int bandno, cblkno; - unsigned char *c = src; - - opj_cp_t *cp = t2->cp; - - int compno = pi->compno; /* component value */ - int resno = pi->resno; /* resolution level value */ - int precno = pi->precno; /* precinct value */ - int layno = pi->layno; /* quality layer value */ - - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - - unsigned char *hd = NULL; - int present; - - opj_bio_t *bio = NULL; /* BIO component */ - - if (layno == 0) { - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - opj_tcd_precinct_t *prc = &band->precincts[precno]; - - if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; - - tgt_reset(prc->incltree); - tgt_reset(prc->imsbtree); - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - cblk->numsegs = 0; - } - } - } - - /* SOP markers */ - - if (tcp->csty & J3D_CP_CSTY_SOP) { - if ((*c) != 0xff || (*(c + 1) != 0x91)) { - opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n"); - } else { - c += 6; - } - - /** TODO : check the Nsop value */ - } - - /* - When the marker PPT/PPM is used the packet header are store in PPT/PPM marker - This part deal with this caracteristic - step 1: Read packet header in the saved structure - step 2: Return to codestream for decoding - */ - - bio = bio_create(); - - if (cp->ppm == 1) { /* PPM */ - hd = cp->ppm_data; - bio_init_dec(bio, hd, cp->ppm_len); - } else if (tcp->ppt == 1) { /* PPT */ - hd = tcp->ppt_data; - bio_init_dec(bio, hd, tcp->ppt_len); - } else { /* Normal Case */ - hd = c; - bio_init_dec(bio, hd, src+len-hd); - } - - present = bio_read(bio, 1); - - if (!present) { - bio_inalign(bio); - hd += bio_numbytes(bio); - bio_destroy(bio); - - /* EPH markers */ - - if (tcp->csty & J3D_CP_CSTY_EPH) { - if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { - printf("Error : expected EPH marker\n"); - } else { - hd += 2; - } - } - - if (cp->ppm == 1) { /* PPM case */ - cp->ppm_len += cp->ppm_data-hd; - cp->ppm_data = hd; - return (c - src); - } - if (tcp->ppt == 1) { /* PPT case */ - tcp->ppt_len+=tcp->ppt_data-hd; - tcp->ppt_data = hd; - return (c - src); - } - - return (hd - src); - } - - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - opj_tcd_precinct_t *prc = &band->precincts[precno]; - - if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; - - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - int included, increment, n; - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - opj_tcd_seg_t *seg = NULL; - /* if cblk not yet included before --> inclusion tagtree */ - if (!cblk->numsegs) { - included = tgt_decode(bio, prc->incltree, cblkno, layno + 1); - /* else one bit */ - } else { - included = bio_read(bio, 1); - } - /* if cblk not included */ - if (!included) { - cblk->numnewpasses = 0; - continue; - } - /* if cblk not yet included --> zero-bitplane tagtree */ - if (!cblk->numsegs) { - int i, numimsbs; - for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++); - numimsbs = i - 1; - cblk->numbps = band->numbps - numimsbs; - cblk->numlenbits = 3; - } - /* number of coding passes */ - cblk->numnewpasses = t2_getnumpasses(bio); - increment = t2_getcommacode(bio); - /* length indicator increment */ - cblk->numlenbits += increment; - if (!cblk->numsegs) { - seg = &cblk->segs[0]; - t2_init_seg(seg, tcp->tccps[compno].cblksty, 1); - } else { - seg = &cblk->segs[cblk->numsegs - 1]; - if (seg->numpasses == seg->maxpasses) { - t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0); - } - } - n = cblk->numnewpasses; - - do { - seg->numnewpasses = int_min(seg->maxpasses - seg->numpasses, n); - seg->newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(seg->numnewpasses)); - n -= seg->numnewpasses; - if (n > 0) { - t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0); - } - } while (n > 0); - } - } - - if (bio_inalign(bio)) { - bio_destroy(bio); - return -999; - } - - hd += bio_numbytes(bio); - bio_destroy(bio); - - /* EPH markers */ - if (tcp->csty & J3D_CP_CSTY_EPH) { - if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { - opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n"); - } else { - hd += 2; - } - } - - if (cp->ppm==1) { - cp->ppm_len+=cp->ppm_data-hd; - cp->ppm_data = hd; - } else if (tcp->ppt == 1) { - tcp->ppt_len+=tcp->ppt_data-hd; - tcp->ppt_data = hd; - } else { - c=hd; - } - - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - opj_tcd_precinct_t *prc = &band->precincts[precno]; - - if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; - - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - opj_tcd_seg_t *seg = NULL; - if (!cblk->numnewpasses) - continue; - if (!cblk->numsegs) { - seg = &cblk->segs[0]; - cblk->numsegs++; - cblk->len = 0; - } else { - seg = &cblk->segs[cblk->numsegs - 1]; - if (seg->numpasses == seg->maxpasses) { - seg++; - cblk->numsegs++; - } - } - - do { - if (c + seg->newlen > src + len) { - return -999; - } - - memcpy(cblk->data + cblk->len, c, seg->newlen); - if (seg->numpasses == 0) { - seg->data = cblk->data + cblk->len; - } - c += seg->newlen; - cblk->len += seg->newlen; - seg->len += seg->newlen; - seg->numpasses += seg->numnewpasses; - cblk->numnewpasses -= seg->numnewpasses; - if (cblk->numnewpasses > 0) { - seg++; - cblk->numsegs++; - } - } while (cblk->numnewpasses > 0); - } - } - - return (c - src); -} - -/* ----------------------------------------------------------------------- */ - -int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_volume_info_t *volume_info) { - unsigned char *c = dest; - int e = 0; - opj_pi_iterator_t *pi = NULL; - int pino; - - opj_volume_t *volume = t2->volume; - opj_cp_t *cp = t2->cp; - - /* create a packet iterator */ - pi = pi_create(volume, cp, tileno); - if(!pi) { - fprintf(stdout,"[ERROR] Failed to create a pi structure\n"); - return -999; - } - - if(volume_info) { - volume_info->num = 0; - } - - for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { - while (pi_next(&pi[pino])) { - if (pi[pino].layno < maxlayers) { - e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, volume_info, tileno, cp); - /*opj_event_msg(t2->cinfo, EVT_INFO, " t2_encode_packet: %d bytes coded\n",e);*/ - if (e == -999) { - break; - } else { - c += e; - } - - /* INDEX >> */ - if(volume_info && volume_info->index_on) { - if(volume_info->index_write) { - opj_tile_info_t *info_TL = &volume_info->tile[tileno]; - opj_packet_info_t *info_PK = &info_TL->packet[volume_info->num]; - if (!volume_info->num) { - info_PK->start_pos = info_TL->end_header + 1; - } else { - info_PK->start_pos = info_TL->packet[volume_info->num - 1].end_pos + 1; - } - info_PK->end_pos = info_PK->start_pos + e - 1; - } - - volume_info->num++; - } - /* << INDEX */ - } - } - } - - /* don't forget to release pi */ - pi_destroy(pi, cp, tileno); - - if (e == -999) { - return e; - } - - return (c - dest); -} - -int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) { - unsigned char *c = src; - opj_pi_iterator_t *pi; - int pino, e = 0; - int n = 0,i; - - opj_volume_t *volume = t2->volume; - opj_cp_t *cp = t2->cp; - - /* create a packet iterator */ - pi = pi_create(volume, cp, tileno); - if(!pi) { - /* TODO: throw an error */ - return -999; - } - - for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { - while (pi_next(&pi[pino])) { - if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { - e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]); - } else { - e = 0; - } - - /* progression in resolution */ - for (i = 0; i < 3; i++){ - volume->comps[pi[pino].compno].resno_decoded[i] = (e > 0) ? int_max(pi[pino].resno, volume->comps[pi[pino].compno].resno_decoded[i]) : volume->comps[pi[pino].compno].resno_decoded[i]; - } - n++; - - if (e == -999) { /* ADD */ - break; - } else { - opj_event_msg(t2->cinfo, EVT_INFO, " t2_decode_packet: %d bytes decoded\n",e); - c += e; - } - } - } - - /* don't forget to release pi */ - pi_destroy(pi, cp, tileno); - - if (e == -999) { - return e; - } - - return (c - src); -} - -/* ----------------------------------------------------------------------- */ - -opj_t2_t* t2_create(opj_common_ptr cinfo, opj_volume_t *volume, opj_cp_t *cp) { - /* create the tcd structure */ - opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t)); - if(!t2) return NULL; - t2->cinfo = cinfo; - t2->volume = volume; - t2->cp = cp; - - return t2; -} - -void t2_destroy(opj_t2_t *t2) { - if(t2) { - opj_free(t2); - } -} - +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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 "opj_includes.h" + +/** @defgroup T2 T2 - Implementation of a tier-2 coding */ +/*@{*/ + +/** @name Local static functions */ +/*@{*/ + +static void t2_putcommacode(opj_bio_t *bio, int n); +static int t2_getcommacode(opj_bio_t *bio); +/** +Variable length code for signalling delta Zil (truncation point) +@param bio Bit Input/Output component +@param n delta Zil +*/ +static void t2_putnumpasses(opj_bio_t *bio, int n); +static int t2_getnumpasses(opj_bio_t *bio); +/** +Encode a packet of a tile to a destination buffer +@param tile Tile for which to write the packets +@param tcp Tile coding parameters +@param pi Packet identity +@param dest Destination buffer +@param len Length of the destination buffer +@param volume_info Structure to create an index file +@param tileno Number of the tile encoded +@param cp Coding parameters +@return Number of bytes encoded from the packet +*/ +static int t2_encode_packet(opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_volume_info_t *volume_info, int tileno, opj_cp_t *cp); +/** +Initialize the segment decoder +@param seg Segment instance +@param cblksty Codeblock style +@param first Is first segment +*/ +static void t2_init_seg(opj_tcd_seg_t *seg, int cblksty, int first); +/** +Decode a packet of a tile from a source buffer +@param t2 T2 handle +@param src Source buffer +@param len Length of the source buffer +@param tile Tile for which to write the packets +@param tcp Tile coding parameters +@param pi Packet identity +@return Number of bytes decoded from the packet +*/ +int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi); + +/*@}*/ + +/*@}*/ + +/* ----------------------------------------------------------------------- */ + +/* #define RESTART 0x04 */ +static void t2_putcommacode(opj_bio_t *bio, int n) { + while (--n >= 0) { + bio_write(bio, 1, 1); + } + bio_write(bio, 0, 1); +} + +static int t2_getcommacode(opj_bio_t *bio) { + int n; + for (n = 0; bio_read(bio, 1); n++) { + ; + } + return n; +} + +static void t2_putnumpasses(opj_bio_t *bio, int n) { + if (n == 1) { + bio_write(bio, 0, 1); + } else if (n == 2) { + bio_write(bio, 2, 2); + } else if (n <= 5) { + bio_write(bio, 0xc | (n - 3), 4); + } else if (n <= 36) { + bio_write(bio, 0x1e0 | (n - 6), 9); + } else if (n <= 164) { + bio_write(bio, 0xff80 | (n - 37), 16); + } +} + +static int t2_getnumpasses(opj_bio_t *bio) { + int n; + if (!bio_read(bio, 1)) + return 1; + if (!bio_read(bio, 1)) + return 2; + if ((n = bio_read(bio, 2)) != 3) + return (3 + n); + if ((n = bio_read(bio, 5)) != 31) + return (6 + n); + return (37 + bio_read(bio, 7)); +} + +static int t2_encode_packet(opj_tcd_tile_t * tile, opj_tcp_t * tcp, opj_pi_iterator_t *pi, unsigned char *dest, int len, opj_volume_info_t * volume_info, int tileno, opj_cp_t *cp) { + int bandno, cblkno; + unsigned char *sop = 0, *eph = 0; + unsigned char *c = dest; + + int compno = pi->compno; /* component value */ + int resno = pi->resno; /* resolution level value */ + int precno = pi->precno; /* precinct value */ + int layno = pi->layno; /* quality layer value */ + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + opj_bio_t *bio = NULL; /* BIO component */ + + /* */ + if ((tcp->csty & J3D_CP_CSTY_SOP)) { + sop = (unsigned char *) opj_malloc(6 * sizeof(unsigned char)); + sop[0] = 255; + sop[1] = 145; + sop[2] = 0; + sop[3] = 4; + sop[4] = (volume_info) ? (volume_info->num % 65536) / 256 : (0 % 65536) / 256 ; + sop[5] = (volume_info) ? (volume_info->num % 65536) % 256 : (0 % 65536) % 256 ; + memcpy(c, sop, 6); + opj_free(sop); + c += 6; + } + /* */ + + if (!layno) { + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + tgt_reset(prc->incltree); + tgt_reset(prc->imsbtree); + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + cblk->numpasses = 0; + tgt_setvalue(prc->imsbtree, cblkno, band->numbps - cblk->numbps); + } + } + } + + bio = bio_create(); + bio_init_enc(bio, c, len); + bio_write(bio, 1, 1); /* Empty header bit */ + + /* Writing Packet header */ + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + if (!cblk->numpasses && layer->numpasses) { + tgt_setvalue(prc->incltree, cblkno, layno); + } + } + + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + int increment = 0; + int nump = 0; + int len = 0, passno; + /* cblk inclusion bits */ + if (!cblk->numpasses) { + tgt_encode(bio, prc->incltree, cblkno, layno + 1); + } else { + bio_write(bio, layer->numpasses != 0, 1); + } + /* if cblk not included, go to the next cblk */ + if (!layer->numpasses) { + continue; + } + /* if first instance of cblk --> zero bit-planes information */ + if (!cblk->numpasses) { + cblk->numlenbits = 3; + tgt_encode(bio, prc->imsbtree, cblkno, 999); + } + /* number of coding passes included */ + t2_putnumpasses(bio, layer->numpasses); + + /* computation of the increase of the length indicator and insertion in the header */ + for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + nump++; + len += pass->len; + if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { + increment = int_max(increment, int_floorlog2(len) + 1 - (cblk->numlenbits + int_floorlog2(nump))); + len = 0; + nump = 0; + } + } + t2_putcommacode(bio, increment); + + /* computation of the new Length indicator */ + cblk->numlenbits += increment; + + /* insertion of the codeword segment length */ + for (passno = cblk->numpasses; passno < cblk->numpasses + layer->numpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + nump++; + len += pass->len; + if (pass->term || passno == (cblk->numpasses + layer->numpasses) - 1) { + bio_write(bio, len, cblk->numlenbits + int_floorlog2(nump)); + len = 0; + nump = 0; + } + } + + } + } + + + if (bio_flush(bio)) { + return -999; /* modified to eliminate longjmp !! */ + } + + c += bio_numbytes(bio); + + bio_destroy(bio); + + /* */ + if (tcp->csty & J3D_CP_CSTY_EPH) { + eph = (unsigned char *) opj_malloc(2 * sizeof(unsigned char)); + eph[0] = 255; + eph[1] = 146; + memcpy(c, eph, 2); + opj_free(eph); + c += 2; + } + /* */ + + /* Writing the packet body */ + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + if (!layer->numpasses) { + continue; + } + if (c + layer->len > dest + len) { + return -999; + } + + memcpy(c, layer->data, layer->len); + cblk->numpasses += layer->numpasses; + c += layer->len; + /* ADD for index Cfr. Marcela --> delta disto by packet */ + if(volume_info && volume_info->index_write && volume_info->index_on) { + opj_tile_info_t *info_TL = &volume_info->tile[tileno]; + opj_packet_info_t *info_PK = &info_TL->packet[volume_info->num]; + info_PK->disto += layer->disto; + if (volume_info->D_max < info_PK->disto) { + volume_info->D_max = info_PK->disto; + } + } + /* */ + } + } + + return (c - dest); +} + +static void t2_init_seg(opj_tcd_seg_t * seg, int cblksty, int first) { + seg->numpasses = 0; + seg->len = 0; + if (cblksty & J3D_CCP_CBLKSTY_TERMALL) { + seg->maxpasses = 1; + } + else if (cblksty & J3D_CCP_CBLKSTY_LAZY) { + if (first) { + seg->maxpasses = 10; + } else { + seg->maxpasses = (((seg - 1)->maxpasses == 1) || ((seg - 1)->maxpasses == 10)) ? 2 : 1; + } + } else { + seg->maxpasses = 109; + } +} + +int t2_decode_packet(opj_t2_t* t2, unsigned char *src, int len, opj_tcd_tile_t *tile, opj_tcp_t *tcp, opj_pi_iterator_t *pi) { + int bandno, cblkno; + unsigned char *c = src; + + opj_cp_t *cp = t2->cp; + + int compno = pi->compno; /* component value */ + int resno = pi->resno; /* resolution level value */ + int precno = pi->precno; /* precinct value */ + int layno = pi->layno; /* quality layer value */ + + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + + unsigned char *hd = NULL; + int present; + + opj_bio_t *bio = NULL; /* BIO component */ + + if (layno == 0) { + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; + + tgt_reset(prc->incltree); + tgt_reset(prc->imsbtree); + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + cblk->numsegs = 0; + } + } + } + + /* SOP markers */ + + if (tcp->csty & J3D_CP_CSTY_SOP) { + if ((*c) != 0xff || (*(c + 1) != 0x91)) { + opj_event_msg(t2->cinfo, EVT_WARNING, "Expected SOP marker\n"); + } else { + c += 6; + } + + /** TODO : check the Nsop value */ + } + + /* + When the marker PPT/PPM is used the packet header are store in PPT/PPM marker + This part deal with this caracteristic + step 1: Read packet header in the saved structure + step 2: Return to codestream for decoding + */ + + bio = bio_create(); + + if (cp->ppm == 1) { /* PPM */ + hd = cp->ppm_data; + bio_init_dec(bio, hd, cp->ppm_len); + } else if (tcp->ppt == 1) { /* PPT */ + hd = tcp->ppt_data; + bio_init_dec(bio, hd, tcp->ppt_len); + } else { /* Normal Case */ + hd = c; + bio_init_dec(bio, hd, src+len-hd); + } + + present = bio_read(bio, 1); + + if (!present) { + bio_inalign(bio); + hd += bio_numbytes(bio); + bio_destroy(bio); + + /* EPH markers */ + + if (tcp->csty & J3D_CP_CSTY_EPH) { + if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { + printf("Error : expected EPH marker\n"); + } else { + hd += 2; + } + } + + if (cp->ppm == 1) { /* PPM case */ + cp->ppm_len += cp->ppm_data-hd; + cp->ppm_data = hd; + return (c - src); + } + if (tcp->ppt == 1) { /* PPT case */ + tcp->ppt_len+=tcp->ppt_data-hd; + tcp->ppt_data = hd; + return (c - src); + } + + return (hd - src); + } + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; + + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + int included, increment, n; + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_seg_t *seg = NULL; + /* if cblk not yet included before --> inclusion tagtree */ + if (!cblk->numsegs) { + included = tgt_decode(bio, prc->incltree, cblkno, layno + 1); + /* else one bit */ + } else { + included = bio_read(bio, 1); + } + /* if cblk not included */ + if (!included) { + cblk->numnewpasses = 0; + continue; + } + /* if cblk not yet included --> zero-bitplane tagtree */ + if (!cblk->numsegs) { + int i, numimsbs; + for (i = 0; !tgt_decode(bio, prc->imsbtree, cblkno, i); i++); + numimsbs = i - 1; + cblk->numbps = band->numbps - numimsbs; + cblk->numlenbits = 3; + } + /* number of coding passes */ + cblk->numnewpasses = t2_getnumpasses(bio); + increment = t2_getcommacode(bio); + /* length indicator increment */ + cblk->numlenbits += increment; + if (!cblk->numsegs) { + seg = &cblk->segs[0]; + t2_init_seg(seg, tcp->tccps[compno].cblksty, 1); + } else { + seg = &cblk->segs[cblk->numsegs - 1]; + if (seg->numpasses == seg->maxpasses) { + t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0); + } + } + n = cblk->numnewpasses; + + do { + seg->numnewpasses = int_min(seg->maxpasses - seg->numpasses, n); + seg->newlen = bio_read(bio, cblk->numlenbits + int_floorlog2(seg->numnewpasses)); + n -= seg->numnewpasses; + if (n > 0) { + t2_init_seg(++seg, tcp->tccps[compno].cblksty, 0); + } + } while (n > 0); + } + } + + if (bio_inalign(bio)) { + bio_destroy(bio); + return -999; + } + + hd += bio_numbytes(bio); + bio_destroy(bio); + + /* EPH markers */ + if (tcp->csty & J3D_CP_CSTY_EPH) { + if ((*hd) != 0xff || (*(hd + 1) != 0x92)) { + opj_event_msg(t2->cinfo, EVT_ERROR, "Expected EPH marker\n"); + return -999; + } else { + hd += 2; + } + } + + if (cp->ppm==1) { + cp->ppm_len+=cp->ppm_data-hd; + cp->ppm_data = hd; + } else if (tcp->ppt == 1) { + tcp->ppt_len+=tcp->ppt_data-hd; + tcp->ppt_data = hd; + } else { + c=hd; + } + + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + opj_tcd_precinct_t *prc = &band->precincts[precno]; + + if ((band->x1-band->x0 == 0)||(band->y1-band->y0 == 0)||(band->z1-band->z0 == 0)) continue; + + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_seg_t *seg = NULL; + if (!cblk->numnewpasses) + continue; + if (!cblk->numsegs) { + seg = &cblk->segs[0]; + cblk->numsegs++; + cblk->len = 0; + } else { + seg = &cblk->segs[cblk->numsegs - 1]; + if (seg->numpasses == seg->maxpasses) { + seg++; + cblk->numsegs++; + } + } + + do { + if (c + seg->newlen > src + len) { + return -999; + } + + memcpy(cblk->data + cblk->len, c, seg->newlen); + if (seg->numpasses == 0) { + seg->data = cblk->data + cblk->len; + } + c += seg->newlen; + cblk->len += seg->newlen; + seg->len += seg->newlen; + seg->numpasses += seg->numnewpasses; + cblk->numnewpasses -= seg->numnewpasses; + if (cblk->numnewpasses > 0) { + seg++; + cblk->numsegs++; + } + } while (cblk->numnewpasses > 0); + } + } + + return (c - src); +} + +/* ----------------------------------------------------------------------- */ + +int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_volume_info_t *volume_info) { + unsigned char *c = dest; + int e = 0; + opj_pi_iterator_t *pi = NULL; + int pino; + + opj_volume_t *volume = t2->volume; + opj_cp_t *cp = t2->cp; + + /* create a packet iterator */ + pi = pi_create(volume, cp, tileno); + if(!pi) { + fprintf(stdout,"[ERROR] Failed to create a pi structure\n"); + return -999; + } + + if(volume_info) { + volume_info->num = 0; + } + + for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { + while (pi_next(&pi[pino])) { + if (pi[pino].layno < maxlayers) { + e = t2_encode_packet(tile, &cp->tcps[tileno], &pi[pino], c, dest + len - c, volume_info, tileno, cp); + /*opj_event_msg(t2->cinfo, EVT_INFO, " t2_encode_packet: %d bytes coded\n",e);*/ + if (e == -999) { + break; + } else { + c += e; + } + + /* INDEX >> */ + if(volume_info && volume_info->index_on) { + if(volume_info->index_write) { + opj_tile_info_t *info_TL = &volume_info->tile[tileno]; + opj_packet_info_t *info_PK = &info_TL->packet[volume_info->num]; + if (!volume_info->num) { + info_PK->start_pos = info_TL->end_header + 1; + } else { + info_PK->start_pos = info_TL->packet[volume_info->num - 1].end_pos + 1; + } + info_PK->end_pos = info_PK->start_pos + e - 1; + } + + volume_info->num++; + } + /* << INDEX */ + } + } + } + + /* don't forget to release pi */ + pi_destroy(pi, cp, tileno); + + if (e == -999) { + return e; + } + + return (c - dest); +} + +int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile) { + unsigned char *c = src; + opj_pi_iterator_t *pi; + int pino, e = 0; + int n = 0,i; + + opj_volume_t *volume = t2->volume; + opj_cp_t *cp = t2->cp; + + /* create a packet iterator */ + pi = pi_create(volume, cp, tileno); + if(!pi) { + /* TODO: throw an error */ + return -999; + } + + for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) { + while (pi_next(&pi[pino])) { + if ((cp->layer==0) || (cp->layer>=((pi[pino].layno)+1))) { + e = t2_decode_packet(t2, c, src + len - c, tile, &cp->tcps[tileno], &pi[pino]); + } else { + e = 0; + } + + /* progression in resolution */ + for (i = 0; i < 3; i++){ + volume->comps[pi[pino].compno].resno_decoded[i] = (e > 0) ? int_max(pi[pino].resno, volume->comps[pi[pino].compno].resno_decoded[i]) : volume->comps[pi[pino].compno].resno_decoded[i]; + } + n++; + + if (e == -999) { /* ADD */ + break; + } else { + opj_event_msg(t2->cinfo, EVT_INFO, " t2_decode_packet: %d bytes decoded\n",e); + c += e; + } + } + } + + /* don't forget to release pi */ + pi_destroy(pi, cp, tileno); + + if (e == -999) { + return e; + } + + return (c - src); +} + +/* ----------------------------------------------------------------------- */ + +opj_t2_t* t2_create(opj_common_ptr cinfo, opj_volume_t *volume, opj_cp_t *cp) { + /* create the tcd structure */ + opj_t2_t *t2 = (opj_t2_t*)opj_malloc(sizeof(opj_t2_t)); + if(!t2) return NULL; + t2->cinfo = cinfo; + t2->volume = volume; + t2->cp = cp; + + return t2; +} + +void t2_destroy(opj_t2_t *t2) { + if(t2) { + opj_free(t2); + } +} + diff --git a/src/lib/openjp3d/t2.h b/src/lib/openjp3d/t2.h old mode 100755 new mode 100644 index b937290b..9aaecb14 --- a/src/lib/openjp3d/t2.h +++ b/src/lib/openjp3d/t2.h @@ -1,101 +1,101 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __T2_H -#define __T2_H -/** -@file t2.h -@brief Implementation of a tier-2 coding (packetization of code-block data) (T2) - -*/ - -/** @defgroup T2 T2 - Implementation of a tier-2 coding */ -/*@{*/ - -/** -Tier-2 coding -*/ -typedef struct opj_t2 { -/** Codec context */ - opj_common_ptr cinfo; -/** Encoding: pointer to the src volume. Decoding: pointer to the dst volume. */ - opj_volume_t *volume; -/** Pointer to the volume coding parameters */ - opj_cp_t *cp; -} opj_t2_t; - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ - -/** -Encode the packets of a tile to a destination buffer -@param t2 T2 handle -@param tileno number of the tile encoded -@param tile the tile for which to write the packets -@param maxlayers maximum number of layers -@param dest the destination buffer -@param len the length of the destination buffer -@param volume_info structure to create an index file -@return Number of bytes written from packets -*/ -int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_volume_info_t *volume_info); - -/** -Decode the packets of a tile from a source buffer -@param t2 T2 handle -@param src the source buffer -@param len length of the source buffer -@param tileno number that identifies the tile for which to decode the packets -@param tile tile for which to decode the packets -@return Number of bytes read from packets - */ -int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile); - -/** -Create a T2 handle -@param cinfo Codec context info -@param volume Source or destination volume -@param cp Volume coding parameters -@return Returns a new T2 handle if successful, returns NULL otherwise -*/ -opj_t2_t* t2_create(opj_common_ptr cinfo, opj_volume_t *volume, opj_cp_t *cp); -/** -Destroy a T2 handle -@param t2 T2 handle to destroy -*/ -void t2_destroy(opj_t2_t *t2); - -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __T2_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __T2_H +#define __T2_H +/** +@file t2.h +@brief Implementation of a tier-2 coding (packetization of code-block data) (T2) + +*/ + +/** @defgroup T2 T2 - Implementation of a tier-2 coding */ +/*@{*/ + +/** +Tier-2 coding +*/ +typedef struct opj_t2 { +/** Codec context */ + opj_common_ptr cinfo; +/** Encoding: pointer to the src volume. Decoding: pointer to the dst volume. */ + opj_volume_t *volume; +/** Pointer to the volume coding parameters */ + opj_cp_t *cp; +} opj_t2_t; + +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ + +/** +Encode the packets of a tile to a destination buffer +@param t2 T2 handle +@param tileno number of the tile encoded +@param tile the tile for which to write the packets +@param maxlayers maximum number of layers +@param dest the destination buffer +@param len the length of the destination buffer +@param volume_info structure to create an index file +@return Number of bytes written from packets +*/ +int t2_encode_packets(opj_t2_t* t2, int tileno, opj_tcd_tile_t *tile, int maxlayers, unsigned char *dest, int len, opj_volume_info_t *volume_info); + +/** +Decode the packets of a tile from a source buffer +@param t2 T2 handle +@param src the source buffer +@param len length of the source buffer +@param tileno number that identifies the tile for which to decode the packets +@param tile tile for which to decode the packets +@return Number of bytes read from packets + */ +int t2_decode_packets(opj_t2_t *t2, unsigned char *src, int len, int tileno, opj_tcd_tile_t *tile); + +/** +Create a T2 handle +@param cinfo Codec context info +@param volume Source or destination volume +@param cp Volume coding parameters +@return Returns a new T2 handle if successful, returns NULL otherwise +*/ +opj_t2_t* t2_create(opj_common_ptr cinfo, opj_volume_t *volume, opj_cp_t *cp); +/** +Destroy a T2 handle +@param t2 T2 handle to destroy +*/ +void t2_destroy(opj_t2_t *t2); + +/* ----------------------------------------------------------------------- */ +/*@}*/ + +/*@}*/ + +#endif /* __T2_H */ diff --git a/src/lib/openjp3d/tcd.c b/src/lib/openjp3d/tcd.c old mode 100755 new mode 100644 index 84c1ed1e..e13a4af6 --- a/src/lib/openjp3d/tcd.c +++ b/src/lib/openjp3d/tcd.c @@ -1,1739 +1,1739 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyright (c) 2006, Mónica Díez, LPI-UVA, Spain - * 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" - -void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_volume_t * vol) { - int tileno, compno, resno, bandno, precno, cblkno; - - fprintf(fd, "volume {\n"); - fprintf(fd, " tw=%d, th=%d, tl=%d, x0=%d x1=%d y0=%d y1=%d z0=%d z1=%d\n", - vol->tw, vol->th, vol->tl, tcd->volume->x0, tcd->volume->x1, tcd->volume->y0, tcd->volume->y1, tcd->volume->z0, tcd->volume->z1); - - for (tileno = 0; tileno < vol->th * vol->tw * vol->tl; tileno++) { - opj_tcd_tile_t *tile = &tcd->tcd_volume->tiles[tileno]; - fprintf(fd, " tile {\n"); - fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numcomps=%d\n", - tile->x0, tile->y0, tile->z0, tile->x1, tile->y1, tile->z1, tile->numcomps); - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - fprintf(fd, " tilecomp %d {\n",compno); - fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numresx=%d, numresy=%d, numresz=%d\n", - tilec->x0, tilec->y0, tilec->z0, tilec->x1, tilec->y1, tilec->z1, tilec->numresolution[0], tilec->numresolution[1], tilec->numresolution[2]); - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - fprintf(fd, " res %d{\n",resno); - fprintf(fd," x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, pw=%d, ph=%d, pl=%d, numbands=%d\n", - res->x0, res->y0, res->z0, res->x1, res->y1, res->z1, res->prctno[0], res->prctno[1], res->prctno[2], res->numbands); - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - fprintf(fd, " band %d{\n", bandno); - fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, stepsize=%f, numbps=%d\n", - band->x0, band->y0, band->z0, band->x1, band->y1, band->z1, band->stepsize, band->numbps); - for (precno = 0; precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); precno++) { - opj_tcd_precinct_t *prec = &band->precincts[precno]; - fprintf(fd, " prec %d{\n",precno); - fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, cw=%d, ch=%d, cl=%d,\n", - prec->x0, prec->y0, prec->z0, prec->x1, prec->y1, prec->z1, prec->cblkno[0], prec->cblkno[1], prec->cblkno[2]); - for (cblkno = 0; cblkno < (prec->cblkno[0] * prec->cblkno[1] * prec->cblkno[2]); cblkno++) { - opj_tcd_cblk_t *cblk = &prec->cblks[cblkno]; - fprintf(fd, " cblk %d{\n",cblkno); - fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", cblk->x0, cblk->y0, cblk->z0, cblk->x1, cblk->y1, cblk->z1); - fprintf(fd, " }\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, "}\n"); -} - -static void tilec_dump(FILE *fd, opj_tcd_tilecomp_t *tilec) { - - int i=0,k; - int datalen; - int *a; - - fprintf(fd, " tilecomp{\n"); - fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numresx=%d, numresy=%d, numresz=%d\n", - tilec->x0, tilec->y0, tilec->z0, tilec->x1, tilec->y1, tilec->z1, tilec->numresolution[0], tilec->numresolution[1], tilec->numresolution[2]); - fprintf(fd, " data {\n"); - datalen = (tilec->z1 - tilec->z0) * (tilec->y1 - tilec->y0) * (tilec->x1 - tilec->x0); - a = tilec->data; - for (k = 0; k < datalen; k++) { - if (!(k % tilec->x1)){ - fprintf(fd, "\n"); - } - if (!(k % (tilec->y1 * tilec->x1))){ - fprintf(fd, "Slice %d\n",i++); - } - fprintf(fd," %d",a[k]); - - - } - fprintf(fd, " }\n"); - /*i=0; - fprintf(fd, "Slice %d\n"); - if (tilec->prediction->prederr) { - fprintf(fd, " prederror {\n"); - a = tilec->prediction->prederr; - for (k = 0; k < datalen; k++) { - fprintf(fd," %d",*(a++)); - if (!(k % (tilec->y1 - tilec->y0) * (tilec->x1 - tilec->x0))){ - fprintf(fd, "\n");fprintf(fd, "Slice %d\n",i++); - } - if (!(k % (tilec->x1 - tilec->x0))){ - fprintf(fd, "\n"); - } - } - } - fprintf(fd, " }\n");*/ - fprintf(fd, "}\n"); -} - -/* ----------------------------------------------------------------------- */ - -/** -Create a new TCD handle -*/ -opj_tcd_t* tcd_create(opj_common_ptr cinfo) { - /* create the tcd structure */ - opj_tcd_t *tcd = (opj_tcd_t*)opj_malloc(sizeof(opj_tcd_t)); - if(!tcd) return NULL; - tcd->cinfo = cinfo; - tcd->tcd_volume = (opj_tcd_volume_t*)opj_malloc(sizeof(opj_tcd_volume_t)); - if(!tcd->tcd_volume) { - opj_free(tcd); - return NULL; - } - - return tcd; -} - -/** -Destroy a previously created TCD handle -*/ -void tcd_destroy(opj_tcd_t *tcd) { - if(tcd) { - opj_free(tcd->tcd_volume); - opj_free(tcd); - } -} - -/* ----------------------------------------------------------------------- */ -void tcd_malloc_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno) { - int compno, resno, bandno, precno, cblkno, i, j;/*, k;*/ - - opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ - opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ - opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ - opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ - opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ - opj_tcd_cblk_t *cblk = NULL; /* pointer to tcd->cblk */ - opj_tcp_t *tcp = &cp->tcps[curtileno]; - int p,q,r; - - tcd->volume = volume; - tcd->cp = cp; - tcd->tcd_volume->tw = cp->tw; - tcd->tcd_volume->th = cp->th; - tcd->tcd_volume->tl = cp->tl; - tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t)); - tcd->tile = tcd->tcd_volume->tiles; - tile = tcd->tile; - - - /* p61 ISO/IEC IS15444-1 : 2002 */ - /* curtileno --> raster scanned index of tiles */ - /* p,q,r --> matricial index of tiles */ - p = curtileno % cp->tw; - q = curtileno / cp->tw; - r = curtileno / (cp->tw * cp->th); /* extension to 3-D */ - - /* 4 borders of the tile rescale on the volume if necessary (B.3)*/ - tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); - tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); - tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); - tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); - tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); - tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); - tile->numcomps = volume->numcomps; - - /* Modification of the RATE >> */ - for (j = 0; j < tcp->numlayers; j++) { - if (tcp->rates[j] <= 1) { - tcp->rates[j] = 0; - } else { - float num = (float) (tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec); - float den = (float) (8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz); - den = tcp->rates[j] * den; - tcp->rates[j] = (num + den - 1) / den; - } - /*tcp->rates[j] = tcp->rates[j] ? int_ceildiv( - tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec, - (tcp->rates[j] * 8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz)) : 0;*/ - if (tcp->rates[j]) { - if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { - tcp->rates[j] = tcp->rates[j - 1] + 20; - } else if (!j && tcp->rates[j] < 30){ - tcp->rates[j] = 30; - } - } - } - /* << Modification of the RATE */ - - tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t)); - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tccp_t *tccp = &tcp->tccps[compno]; - int res_max; - int prevnumbands = 0; - - /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */ - tcd->tilec = &tile->comps[compno]; - tilec = tcd->tilec; - - /* border of each tile component (global) (B.3) */ - tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx); - tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy); - tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz); - tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx); - tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy); - tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz); - - tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int)); - - res_max = 0; - for (i = 0;i < 3; i++){ - tilec->numresolution[i] = tccp->numresolution[i]; - /*Greater of 3 resolutions contains all information*/ - res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max; - } - - - tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t)); - for (resno = 0; resno < res_max; resno++) { - - int pdx, pdy, pdz; - int tlprcxstart, tlprcystart, tlprczstart; - int brprcxend, brprcyend, brprczend; - int tlcbgxstart, tlcbgystart, tlcbgzstart; - int brcbgxend, brcbgyend, brcbgzend; - int cbgwidthexpn, cbgheightexpn, cbglengthexpn; - int cblkwidthexpn, cblkheightexpn, cblklengthexpn; - - int diff = tccp->numresolution[0] - tccp->numresolution[2]; - int levelnox = tilec->numresolution[0] - 1 - resno; - int levelnoy = tilec->numresolution[1] - 1 - resno; - int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff)); - if (levelnoz < 0) levelnoz = 0; - - /* opj_tcd_resolution_t *res=&tilec->resolutions[resno]; */ - tcd->res = &tilec->resolutions[resno]; - res = tcd->res; - - /* border for each resolution level (global) (B.14)*/ - res->x0 = int_ceildivpow2(tilec->x0, levelnox); - res->y0 = int_ceildivpow2(tilec->y0, levelnoy); - res->z0 = int_ceildivpow2(tilec->z0, levelnoz); - res->x1 = int_ceildivpow2(tilec->x1, levelnox); - res->y1 = int_ceildivpow2(tilec->y1, levelnoy); - res->z1 = int_ceildivpow2(tilec->z1, levelnoz); - /*if (res->z1 < 0)fprintf(stdout,"Res: %d %d/%d --> %d\n",resno,tilec->z1, levelnoz, int_ceildivpow2(tilec->z1, levelnoz));*/ - - res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */ - - /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */ - if (tccp->csty & J3D_CCP_CSTY_PRT) { - pdx = tccp->prctsiz[0][resno]; - pdy = tccp->prctsiz[1][resno]; - pdz = tccp->prctsiz[2][resno]; - } else { - pdx = 15; - pdy = 15; - pdz = 15; - } - - /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */ - tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; - tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; - tlprczstart = int_floordivpow2(res->z0, pdz) << pdz; - brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; - brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; - brprczend = int_ceildivpow2(res->z1, pdz) << pdz; - - res->prctno[0] = (brprcxend - tlprcxstart) >> pdx; - res->prctno[1] = (brprcyend - tlprcystart) >> pdy; - res->prctno[2] = (brprczend - tlprczstart) >> pdz; - if (res->prctno[2] == 0) res->prctno[2] = 1; - - /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */ - if (resno == 0) { - tlcbgxstart = tlprcxstart; - tlcbgystart = tlprcystart; - tlcbgzstart = tlprczstart; - brcbgxend = brprcxend; - brcbgyend = brprcyend; - brcbgzend = brprczend; - cbgwidthexpn = pdx; - cbgheightexpn = pdy; - cbglengthexpn = pdz; - } else { - tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); - tlcbgystart = int_ceildivpow2(tlprcystart, 1); - tlcbgzstart = int_ceildivpow2(tlprczstart, 1); - brcbgxend = int_ceildivpow2(brprcxend, 1); - brcbgyend = int_ceildivpow2(brprcyend, 1); - brcbgzend = int_ceildivpow2(brprczend, 1); - cbgwidthexpn = pdx - 1; - cbgheightexpn = pdy - 1; - cbglengthexpn = pdz - 1; - } - - cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); /*6*/ - cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); /*6*/ - cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); /*6*/ - - res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t)); - for (bandno = 0; bandno < res->numbands; bandno++) { - int x0b, y0b, z0b, i; - int gain, numbps; - opj_stepsize_t *ss = NULL; - - tcd->band = &res->bands[bandno]; - band = tcd->band; - - band->bandno = (resno == 0) ? 0 : bandno + 1; - /* Bandno: 0 - LLL 2 - LHL - 1 - HLL 3 - HHL - 4 - LLH 6 - LHH - 5 - HLH 7 - HHH */ - x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; - y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; - z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; - - /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */ - if (band->bandno == 0) { - /* band border (global) */ - band->x0 = int_ceildivpow2(tilec->x0, levelnox); - band->y0 = int_ceildivpow2(tilec->y0, levelnoy); - band->z0 = int_ceildivpow2(tilec->z0, levelnoz); - band->x1 = int_ceildivpow2(tilec->x1, levelnox); - band->y1 = int_ceildivpow2(tilec->y1, levelnoy); - band->z1 = int_ceildivpow2(tilec->z1, levelnoz); - } else { - band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1); - band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1); - band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); - band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1); - band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1); - band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); - } - - ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)]; - if (bandno == (res->numbands - 1)) - prevnumbands += (resno == 0) ? 0 : res->numbands; - gain = dwt_getgain(band->bandno,tccp->reversible); - numbps = volume->comps[compno].prec + gain; - band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); - band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ - - band->precincts = (opj_tcd_precinct_t *) opj_malloc((res->prctno[0] * res->prctno[1] * res->prctno[2]) * sizeof(opj_tcd_precinct_t)); - - for (i = 0; i < (res->prctno[0] * res->prctno[1] * res->prctno[2]); i++) { - band->precincts[i].imsbtree = NULL; - band->precincts[i].incltree = NULL; - } - - for (precno = 0; precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); precno++) { - int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend; - int cbgxstart, cbgystart, cbgzstart, cbgxend, cbgyend, cbgzend; - - cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn); - cbgystart = tlcbgystart + ((precno % (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn); - cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn); - cbgxend = cbgxstart + (1 << cbgwidthexpn); - cbgyend = cbgystart + (1 << cbgheightexpn); - cbgzend = cbgzstart + (1 << cbglengthexpn); - - tcd->prc = &band->precincts[precno]; - prc = tcd->prc; - - /* precinct size (global) */ - prc->x0 = int_max(cbgxstart, band->x0); - prc->y0 = int_max(cbgystart, band->y0); - prc->z0 = int_max(cbgzstart, band->z0); - prc->x1 = int_min(cbgxend, band->x1); - prc->y1 = int_min(cbgyend, band->y1); - prc->z1 = int_min(cbgzend, band->z1); - - tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; - tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; - tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn; - brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; - brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; - brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn; - prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; - prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn; - prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn; - prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2]; - - prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t)); - prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); - prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); - /*tgt_tree_dump(stdout,prc->incltree);*/ - for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) { - int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn); - int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn); - int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn); - int cblkxend = cblkxstart + (1 << cblkwidthexpn); - int cblkyend = cblkystart + (1 << cblkheightexpn); - int cblkzend = cblkzstart + (1 << cblklengthexpn); - int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1)); - - tcd->cblk = &prc->cblks[cblkno]; - cblk = tcd->cblk; - - /* code-block size (global) */ - cblk->x0 = int_max(cblkxstart, prc->x0); - cblk->y0 = int_max(cblkystart, prc->y0); - cblk->z0 = int_max(cblkzstart, prc->z0); - cblk->x1 = int_min(cblkxend, prc->x1); - cblk->y1 = int_min(cblkyend, prc->y1); - cblk->z1 = int_min(cblkzend, prc->z1); - } - } - } - } - } - /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/ - -} -void tcd_init_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno) { - int compno, resno, bandno, precno, cblkno; - int j, p, q, r; - - opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ - opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ - opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ - opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ - opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ - opj_tcd_cblk_t *cblk = NULL; /* pointer to tcd->cblk */ - opj_tcp_t *tcp = &cp->tcps[curtileno]; - - tcd->tile = tcd->tcd_volume->tiles; - tile = tcd->tile; - - /* p61 ISO/IEC IS15444-1 : 2002 */ - /* curtileno --> raster scanned index of tiles */ - /* p,q,r --> matricial index of tiles */ - p = curtileno % cp->tw; - q = curtileno / cp->tw; - r = curtileno / (cp->tw * cp->th); /* extension to 3-D */ - - /* 4 borders of the tile rescale on the volume if necessary (B.3)*/ - tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); - tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); - tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); - tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); - tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); - tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); - tile->numcomps = volume->numcomps; - - /* Modification of the RATE >> */ - for (j = 0; j < tcp->numlayers; j++) { - if (tcp->rates[j] <= 1) { - tcp->rates[j] = 0; - } else { - float num = (float) (tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec); - float den = (float) (8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz); - den = tcp->rates[j] * den; - tcp->rates[j] = (num + den - 1) / den; - } - /*tcp->rates[j] = tcp->rates[j] ? int_ceildiv( - tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec, - (tcp->rates[j] * 8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz)) : 0;*/ - if (tcp->rates[j]) { - if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { - tcp->rates[j] = tcp->rates[j - 1] + 20; - } else if (!j && tcp->rates[j] < 30){ - tcp->rates[j] = 30; - } - } - } - /* << Modification of the RATE */ - - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tccp_t *tccp = &tcp->tccps[compno]; - int res_max, i; - int prevnumbands = 0; - - /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */ - tcd->tilec = &tile->comps[compno]; - tilec = tcd->tilec; - - /* border of each tile component (global) (B.3) */ - tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx); - tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy); - tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz); - tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx); - tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy); - tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz); - - tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int)); - - res_max = 0; - for (i = 0;i < 3; i++){ - tilec->numresolution[i] = tccp->numresolution[i]; - /*Greater of 3 resolutions contains all information*/ - res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max; - } - - tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t)); - for (resno = 0; resno < res_max; resno++) { - int pdx, pdy, pdz; - int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend; - int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend; - int cbgwidthexpn, cbgheightexpn, cbglengthexpn; - int cblkwidthexpn, cblkheightexpn, cblklengthexpn; - - int levelnox = tilec->numresolution[0] - 1 - resno; - int levelnoy = tilec->numresolution[1] - 1 - resno; - int diff = tccp->numresolution[0] - tccp->numresolution[2]; - int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff)); - if (levelnoz < 0) levelnoz = 0; - - tcd->res = &tilec->resolutions[resno]; - res = tcd->res; - - /* border for each resolution level (global) (B.14)*/ - res->x0 = int_ceildivpow2(tilec->x0, levelnox); - res->y0 = int_ceildivpow2(tilec->y0, levelnoy); - res->z0 = int_ceildivpow2(tilec->z0, levelnoz); - res->x1 = int_ceildivpow2(tilec->x1, levelnox); - res->y1 = int_ceildivpow2(tilec->y1, levelnoy); - res->z1 = int_ceildivpow2(tilec->z1, levelnoz); - - /* res->numbands = resno == 0 ? 1 : 3; *//* --> 2D */ - - res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */ - - /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */ - if (tccp->csty & J3D_CCP_CSTY_PRT) { - pdx = tccp->prctsiz[0][resno]; - pdy = tccp->prctsiz[1][resno]; - pdz = tccp->prctsiz[2][resno]; - } else { - pdx = 15; - pdy = 15; - pdz = 15; - } - /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */ - tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; - tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; - tlprczstart = int_floordivpow2(res->z0, pdz) << pdz; - brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; - brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; - brprczend = int_ceildivpow2(res->z1, pdz) << pdz; - - res->prctno[0] = (brprcxend - tlprcxstart) >> pdx; - res->prctno[1] = (brprcyend - tlprcystart) >> pdy; - res->prctno[2] = (brprczend - tlprczstart) >> pdz; - if (res->prctno[2] == 0) res->prctno[2] = 1; - - /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */ - if (resno == 0) { - tlcbgxstart = tlprcxstart; - tlcbgystart = tlprcystart; - tlcbgzstart = tlprczstart; - brcbgxend = brprcxend; - brcbgyend = brprcyend; - brcbgzend = brprczend; - cbgwidthexpn = pdx; - cbgheightexpn = pdy; - cbglengthexpn = pdz; - } else { - tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); - tlcbgystart = int_ceildivpow2(tlprcystart, 1); - tlcbgzstart = int_ceildivpow2(tlprczstart, 1); - brcbgxend = int_ceildivpow2(brprcxend, 1); - brcbgyend = int_ceildivpow2(brprcyend, 1); - brcbgzend = int_ceildivpow2(brprczend, 1); - cbgwidthexpn = pdx - 1; - cbgheightexpn = pdy - 1; - cbglengthexpn = pdz - 1; - } - - cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); - cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); - cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); - - res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t)); - for (bandno = 0; bandno < res->numbands; bandno++) { - int x0b, y0b, z0b; - int gain, numbps; - opj_stepsize_t *ss = NULL; - - tcd->band = &res->bands[bandno]; - band = tcd->band; - - band->bandno = resno == 0 ? 0 : bandno + 1; - /* Bandno: 0 - LLL 2 - LHL - 1 - HLL 3 - HHL - 4 - LLH 6 - LHH - 5 - HLH 7 - HHH */ - x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; - y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; - z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; - - /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */ - if (band->bandno == 0) { - /* band border (global) */ - band->x0 = int_ceildivpow2(tilec->x0, levelnox); - band->y0 = int_ceildivpow2(tilec->y0, levelnoy); - band->z0 = int_ceildivpow2(tilec->z0, levelnoz); - band->x1 = int_ceildivpow2(tilec->x1, levelnox); - band->y1 = int_ceildivpow2(tilec->y1, levelnoy); - band->z1 = int_ceildivpow2(tilec->z1, levelnoz); - } else { - band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1); - band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1); - band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); - band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1); - band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1); - band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); - } - - ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)]; - if (bandno == (res->numbands - 1)) - prevnumbands += (resno == 0) ? 0 : res->numbands; - gain = dwt_getgain(band->bandno,tccp->reversible); - numbps = volume->comps[compno].prec + gain; - - band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); - band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ - - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend; - - int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn); - int cbgystart = tlcbgystart + ((precno / (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn); - int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn); - int cbgxend = cbgxstart + (1 << cbgwidthexpn); - int cbgyend = cbgystart + (1 << cbgheightexpn); - int cbgzend = cbgzstart + (1 << cbglengthexpn); - - /* opj_tcd_precinct_t *prc=&band->precincts[precno]; */ - tcd->prc = &band->precincts[precno]; - prc = tcd->prc; - - /* precinct size (global) */ - prc->x0 = int_max(cbgxstart, band->x0); - prc->y0 = int_max(cbgystart, band->y0); - prc->z0 = int_max(cbgzstart, band->z0); - prc->x1 = int_min(cbgxend, band->x1); - prc->y1 = int_min(cbgyend, band->y1); - prc->z1 = int_min(cbgzend, band->z1); - - tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; - tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; - tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn; - brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; - brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; - brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn; - prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; - prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn; - prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn; - prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2]; - - opj_free(prc->cblks); - prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t)); - prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); - prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); - - for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) { - int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn); - int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn); - int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn); - int cblkxend = cblkxstart + (1 << cblkwidthexpn); - int cblkyend = cblkystart + (1 << cblkheightexpn); - int cblkzend = cblkzstart + (1 << cblklengthexpn); - int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1)); - - tcd->cblk = &prc->cblks[cblkno]; - cblk = tcd->cblk; - - /* code-block size (global) */ - cblk->x0 = int_max(cblkxstart, prc->x0); - cblk->y0 = int_max(cblkystart, prc->y0); - cblk->z0 = int_max(cblkzstart, prc->z0); - cblk->x1 = int_min(cblkxend, prc->x1); - cblk->y1 = int_min(cblkyend, prc->y1); - cblk->z1 = int_min(cblkzend, prc->z1); - } - } /* precno */ - } /* bandno */ - } /* resno */ - } /* compno */ - /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/ -} - - -void tcd_free_encode(opj_tcd_t *tcd) { - int tileno, compno, resno, bandno, precno; - - opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ -/* opj_tcd_slice_t *slice = NULL; */ /* pointer to tcd->slice */ - opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ - opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ - opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ - opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ - - for (tileno = 0; tileno < 1; tileno++) { - tcd->tile = tcd->tcd_volume->tiles; - tile = tcd->tile; - - for (compno = 0; compno < tile->numcomps; compno++) { - tcd->tilec = &tile->comps[compno]; - tilec = tcd->tilec; - - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - tcd->res = &tilec->resolutions[resno]; - res = tcd->res; - - for (bandno = 0; bandno < res->numbands; bandno++) { - tcd->band = &res->bands[bandno]; - band = tcd->band; - - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - tcd->prc = &band->precincts[precno]; - prc = tcd->prc; - - if (prc->incltree != NULL) { - tgt_destroy(prc->incltree); - prc->incltree = NULL; - } - if (prc->imsbtree != NULL) { - tgt_destroy(prc->imsbtree); - prc->imsbtree = NULL; - } - opj_free(prc->cblks); - prc->cblks = NULL; - } /* for (precno */ - opj_free(band->precincts); - band->precincts = NULL; - } /* for (bandno */ - } /* for (resno */ - opj_free(tilec->resolutions); - tilec->resolutions = NULL; - } /* for (compno */ - opj_free(tile->comps); - tile->comps = NULL; - } /* for (tileno */ - opj_free(tcd->tcd_volume->tiles); - tcd->tcd_volume->tiles = NULL; -} - -/* ----------------------------------------------------------------------- */ -void tcd_malloc_decode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp) { - int tileno, compno, resno, bandno, precno, cblkno, res_max, - i, j, p, q, r; - unsigned int x0 = 0, y0 = 0, z0 = 0, - x1 = 0, y1 = 0, z1 = 0, - w, h, l; - - tcd->volume = volume; - tcd->cp = cp; - tcd->tcd_volume->tw = cp->tw; - tcd->tcd_volume->th = cp->th; - tcd->tcd_volume->tl = cp->tl; - tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcd_tile_t)); - - for (i = 0; i < cp->tileno_size; i++) { - opj_tcp_t *tcp = &(cp->tcps[cp->tileno[i]]); - opj_tcd_tile_t *tile = &(tcd->tcd_volume->tiles[cp->tileno[i]]); - - /* p61 ISO/IEC IS15444-1 : 2002 */ - /* curtileno --> raster scanned index of tiles */ - /* p,q,r --> matricial index of tiles */ - tileno = cp->tileno[i]; - p = tileno % cp->tw; - q = tileno / cp->tw; - r = tileno / (cp->tw * cp->th); /* extension to 3-D */ - - /* 4 borders of the tile rescale on the volume if necessary (B.3)*/ - tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); - tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); - tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); - tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); - tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); - tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); - tile->numcomps = volume->numcomps; - - tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t)); - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - int prevnumbands = 0; - - /* border of each tile component (global) */ - tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx); - tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy); - tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz); - tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx); - tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy); - tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz); - - tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int)); - - res_max = 0; - for (i = 0;i < 3; i++){ - tilec->numresolution[i] = tccp->numresolution[i]; - /*Greater of 3 resolutions contains all information*/ - res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max; - } - - tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t)); - - for (resno = 0; resno < res_max; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - int pdx, pdy, pdz; - int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend; - int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend; - int cbgwidthexpn, cbgheightexpn, cbglengthexpn; - int cblkwidthexpn, cblkheightexpn, cblklengthexpn; - int levelnox = tilec->numresolution[0] - 1 - resno; - int levelnoy = tilec->numresolution[1] - 1 - resno; - int diff = tccp->numresolution[0] - tccp->numresolution[2]; - int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff)); - if (levelnoz < 0) levelnoz = 0; - - /* border for each resolution level (global) */ - res->x0 = int_ceildivpow2(tilec->x0, levelnox); - res->y0 = int_ceildivpow2(tilec->y0, levelnoy); - res->z0 = int_ceildivpow2(tilec->z0, levelnoz); - res->x1 = int_ceildivpow2(tilec->x1, levelnox); - res->y1 = int_ceildivpow2(tilec->y1, levelnoy); - res->z1 = int_ceildivpow2(tilec->z1, levelnoz); - res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */ - - /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */ - if (tccp->csty & J3D_CCP_CSTY_PRT) { - pdx = tccp->prctsiz[0][resno]; - pdy = tccp->prctsiz[1][resno]; - pdz = tccp->prctsiz[2][resno]; - } else { - pdx = 15; - pdy = 15; - pdz = 15; - } - - /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */ - tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; - tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; - tlprczstart = int_floordivpow2(res->z0, pdz) << pdz; - brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; - brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; - brprczend = int_ceildivpow2(res->z1, pdz) << pdz; - - res->prctno[0] = (brprcxend - tlprcxstart) >> pdx; - res->prctno[1] = (brprcyend - tlprcystart) >> pdy; - res->prctno[2] = (brprczend - tlprczstart) >> pdz; - - /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */ - if (resno == 0) { - tlcbgxstart = tlprcxstart;/*0*/ - tlcbgystart = tlprcystart; - tlcbgzstart = tlprczstart; - brcbgxend = brprcxend;/*1*/ - brcbgyend = brprcyend; - brcbgzend = brprczend; - cbgwidthexpn = pdx; /*15*/ - cbgheightexpn = pdy; - cbglengthexpn = pdz; - } else { - tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); - tlcbgystart = int_ceildivpow2(tlprcystart, 1); - tlcbgzstart = int_ceildivpow2(tlprczstart, 1); - brcbgxend = int_ceildivpow2(brprcxend, 1); - brcbgyend = int_ceildivpow2(brprcyend, 1); - brcbgzend = int_ceildivpow2(brprczend, 1); - cbgwidthexpn = pdx - 1; - cbgheightexpn = pdy - 1; - cbglengthexpn = pdz - 1; - } - - cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); /*6*/ - cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); /*6*/ - cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); /*6*/ - - res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t)); - for (bandno = 0; bandno < res->numbands; bandno++) { - int x0b, y0b, z0b; - int gain, numbps; - opj_stepsize_t *ss = NULL; - - opj_tcd_band_t *band = &res->bands[bandno]; - band->bandno = resno == 0 ? 0 : bandno + 1; - /* Bandno: 0 - LLL 2 - LHL - 1 - HLL 3 - HHL - 4 - LLH 6 - LHH - 5 - HLH 7 - HHH */ - x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; - y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; - z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; - - /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */ - if (band->bandno == 0) { - /* band border (global) */ - band->x0 = int_ceildivpow2(tilec->x0, levelnox); - band->y0 = int_ceildivpow2(tilec->y0, levelnoy); - band->z0 = int_ceildivpow2(tilec->z0, levelnoz); - band->x1 = int_ceildivpow2(tilec->x1, levelnox); - band->y1 = int_ceildivpow2(tilec->y1, levelnoy); - band->z1 = int_ceildivpow2(tilec->z1, levelnoz); - } else { - band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1); - band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1); - band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); - band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1); - band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1); - band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); - } - - ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)]; - if (bandno == (res->numbands - 1)) - prevnumbands += (resno == 0) ? 0 : res->numbands; - gain = dwt_getgain(band->bandno,tccp->reversible); - numbps = volume->comps[compno].prec + gain; - - band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); - band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ - - band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->prctno[0] * res->prctno[1] * res->prctno[2] * sizeof(opj_tcd_precinct_t)); - - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend; - - int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn); - int cbgystart = tlcbgystart + (precno / res->prctno[0]) * (1 << cbgheightexpn); - int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn); - int cbgxend = cbgxstart + (1 << cbgwidthexpn); - int cbgyend = cbgystart + (1 << cbgheightexpn); - int cbgzend = cbgzstart + (1 << cbglengthexpn); - - opj_tcd_precinct_t *prc = &band->precincts[precno]; - /* precinct size (global) */ - prc->x0 = int_max(cbgxstart, band->x0); - prc->y0 = int_max(cbgystart, band->y0); - prc->z0 = int_max(cbgzstart, band->z0); - prc->x1 = int_min(cbgxend, band->x1); - prc->y1 = int_min(cbgyend, band->y1); - prc->z1 = int_min(cbgzend, band->z1); - - tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; - tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; - tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn; - brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; - brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; - brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn; - prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; - prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn; - prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn; - prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2]; - - prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t)); - prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); - prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); - - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn); - int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn); - int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn); - int cblkxend = cblkxstart + (1 << cblkwidthexpn); - int cblkyend = cblkystart + (1 << cblkheightexpn); - int cblkzend = cblkzstart + (1 << cblklengthexpn); - int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1)); - /* code-block size (global) */ - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - - /* code-block size (global) */ - cblk->x0 = int_max(cblkxstart, prc->x0); - cblk->y0 = int_max(cblkystart, prc->y0); - cblk->z0 = int_max(cblkzstart, prc->z0); - cblk->x1 = int_min(cblkxend, prc->x1); - cblk->y1 = int_min(cblkyend, prc->y1); - cblk->z1 = int_min(cblkzend, prc->z1); - } - } /* precno */ - } /* bandno */ - } /* resno */ - } /* compno */ - } /* i = 0..cp->tileno_size */ - - /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/ - - /* - Allocate place to store the decoded data = final volume - Place limited by the tile really present in the codestream - */ - - for (i = 0; i < volume->numcomps; i++) { - for (j = 0; j < cp->tileno_size; j++) { - tileno = cp->tileno[j]; - x0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].x0 : int_min(x0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].x0); - y0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].y0 : int_min(y0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].y0); - z0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].z0 : int_min(z0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].z0); - x1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].x1 : int_max(x1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].x1); - y1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].y1 : int_max(y1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].y1); - z1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].z1 : int_max(z1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].z1); - } - - w = x1 - x0; - h = y1 - y0; - l = z1 - z0; - - volume->comps[i].data = (int *) opj_malloc(w * h * l * sizeof(int)); - volume->comps[i].w = w; - volume->comps[i].h = h; - volume->comps[i].l = l; - volume->comps[i].x0 = x0; - volume->comps[i].y0 = y0; - volume->comps[i].z0 = z0; - volume->comps[i].bigendian = cp->bigendian; - } -} - -void tcd_free_decode(opj_tcd_t *tcd) { - int tileno,compno,resno,bandno,precno; - - opj_tcd_volume_t *tcd_volume = tcd->tcd_volume; - - for (tileno = 0; tileno < tcd_volume->tw * tcd_volume->th * tcd_volume->tl; tileno++) { - opj_tcd_tile_t *tile = &tcd_volume->tiles[tileno]; - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - for (precno = 0; precno < res->prctno[1] * res->prctno[0] * res->prctno[2]; precno++) { - opj_tcd_precinct_t *prec = &band->precincts[precno]; - if (prec->cblks != NULL) opj_free(prec->cblks); - if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); - if (prec->incltree != NULL) tgt_destroy(prec->incltree); - /*for (treeno = 0; treeno < prec->numtrees; treeno++){ - if (prec->imsbtree[treeno] != NULL) tgt_destroy(prec->imsbtree[treeno]); - if (prec->incltree[treeno] != NULL) tgt_destroy(prec->incltree[treeno]); - }*/ - } - if (band->precincts != NULL) opj_free(band->precincts); - } - } - if (tilec->resolutions != NULL) opj_free(tilec->resolutions); - } - if (tile->comps != NULL) opj_free(tile->comps); - } - - if (tcd_volume->tiles != NULL) opj_free(tcd_volume->tiles); -} - - - -/* ----------------------------------------------------------------------- */ -void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final) { - int compno, resno, bandno, precno, cblkno; - int value; /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolution[0]][3]; */ - int matrice[10][10][3]; - int i, j, k; - - opj_cp_t *cp = tcd->cp; - opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; - opj_tcp_t *tcd_tcp = tcd->tcp; - - /*matrice=(int*)opj_malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolution[0]*3*sizeof(int)); */ - - for (compno = 0; compno < tcd_tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; - for (i = 0; i < tcd_tcp->numlayers; i++) { - for (j = 0; j < tilec->numresolution[0]; j++) { - for (k = 0; k < 3; k++) { - matrice[i][j][k] = - (int) (cp->matrice[i * tilec->numresolution[0] * 3 + j * 3 + k] - * (float) (tcd->volume->comps[compno].prec / 16.0)); - } - } - } - - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - opj_tcd_precinct_t *prc = &band->precincts[precno]; - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - opj_tcd_layer_t *layer = &cblk->layers[layno]; - int n; - int imsb = tcd->volume->comps[compno].prec - cblk->numbps; /* number of bit-plan equal to zero */ - /* Correction of the matrix of coefficient to include the IMSB information */ - if (layno == 0) { - value = matrice[layno][resno][bandno]; - if (imsb >= value) { - value = 0; - } else { - value -= imsb; - } - } else { - value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno]; - if (imsb >= matrice[layno - 1][resno][bandno]) { - value -= (imsb - matrice[layno - 1][resno][bandno]); - if (value < 0) { - value = 0; - } - } - } - - if (layno == 0) { - cblk->numpassesinlayers = 0; - } - - n = cblk->numpassesinlayers; - if (cblk->numpassesinlayers == 0) { - if (value != 0) { - n = 3 * value - 2 + cblk->numpassesinlayers; - } else { - n = cblk->numpassesinlayers; - } - } else { - n = 3 * value + cblk->numpassesinlayers; - } - - layer->numpasses = n - cblk->numpassesinlayers; - - if (!layer->numpasses) - continue; - - if (cblk->numpassesinlayers == 0) { - layer->len = cblk->passes[n - 1].rate; - layer->data = cblk->data; - } else { - layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate; - layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate; - } - if (final) - cblk->numpassesinlayers = n; - } - } - } - } - } -} - -void tcd_rateallocate_fixed(opj_tcd_t *tcd) { - int layno; - for (layno = 0; layno < tcd->tcp->numlayers; layno++) { - tcd_makelayer_fixed(tcd, layno, 1); - } -} - -void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) { - int compno, resno, bandno, precno, cblkno, passno; - - opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; - - tcd_tile->distolayer[layno] = 0; /* fixed_quality */ - - for (compno = 0; compno < tcd_tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - opj_tcd_precinct_t *prc = &band->precincts[precno]; - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - opj_tcd_layer_t *layer = &cblk->layers[layno]; - - int n; - if (layno == 0) { - cblk->numpassesinlayers = 0; - } - n = cblk->numpassesinlayers; - for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) { - int dr; - double dd; - opj_tcd_pass_t *pass = &cblk->passes[passno]; - if (n == 0) { - dr = pass->rate; - dd = pass->distortiondec; - } else { - dr = pass->rate - cblk->passes[n - 1].rate; - dd = pass->distortiondec - cblk->passes[n - 1].distortiondec; - } - if (!dr) { - if (dd) - n = passno + 1; - continue; - } - if (dd / dr >= thresh){ - n = passno + 1; - } - } - layer->numpasses = n - cblk->numpassesinlayers; - - if (!layer->numpasses) { - layer->disto = 0; - continue; - } - if (cblk->numpassesinlayers == 0) { - layer->len = cblk->passes[n - 1].rate; - layer->data = cblk->data; - layer->disto = cblk->passes[n - 1].distortiondec; - } else { - layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate; - layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate; - layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec; - } - - tcd_tile->distolayer[layno] += layer->disto; /* fixed_quality */ - - if (final) - cblk->numpassesinlayers = n; - - /* fprintf(stdout,"MakeLayer : %d %f %d %d \n",layer->len, layer->disto, layer->numpasses, n);*/ - } - } - } - } - } -} - -bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_volume_info_t * volume_info) { - int compno, resno, bandno, precno, cblkno, passno, layno; - double min, max; - double cumdisto[100]; /* fixed_quality */ - const double K = 1; /* 1.1; // fixed_quality */ - double maxSE = 0; - - opj_cp_t *cp = tcd->cp; - opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; - opj_tcp_t *tcd_tcp = tcd->tcp; - - min = DBL_MAX; - max = 0; - - tcd_tile->nbpix = 0; /* fixed_quality */ - - for (compno = 0; compno < tcd_tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; - tilec->nbpix = 0; - for (resno = 0; resno < tilec->numresolution[0]; resno++) { - opj_tcd_resolution_t *res = &tilec->resolutions[resno]; - for (bandno = 0; bandno < res->numbands; bandno++) { - opj_tcd_band_t *band = &res->bands[bandno]; - for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { - opj_tcd_precinct_t *prc = &band->precincts[precno]; - for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { - opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; - for (passno = 0; passno < cblk->totalpasses; passno++) { - opj_tcd_pass_t *pass = &cblk->passes[passno]; - int dr; - double dd, rdslope; - if (passno == 0) { - dr = pass->rate; - dd = pass->distortiondec; - } else { - dr = pass->rate - cblk->passes[passno - 1].rate; - dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec; - } - if (dr == 0) { - continue; - } - rdslope = dd / dr; - if (rdslope < min) { - min = rdslope; - } - if (rdslope > max) { - max = rdslope; - } - - } /* passno */ - - /* fixed_quality */ - tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0)); - tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0)); - } /* cbklno */ - } /* precno */ - } /* bandno */ - } /* resno */ - - maxSE += (((double)(1 << tcd->volume->comps[compno].prec) - 1.0) - * ((double)(1 << tcd->volume->comps[compno].prec) -1.0)) - * ((double)(tilec->nbpix)); - } /* compno */ - - /* add antonin index */ - if(volume_info && volume_info->index_on) { - opj_tile_info_t *info_TL = &volume_info->tile[tcd->tcd_tileno]; - info_TL->nbpix = tcd_tile->nbpix; - info_TL->distotile = tcd_tile->distotile; - info_TL->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double)); - } - /* dda */ - - for (layno = 0; layno < tcd_tcp->numlayers; layno++) { - double lo = min; - double hi = max; - int success = 0; - int maxlen = tcd_tcp->rates[layno] ? int_min(((int) tcd_tcp->rates[layno]), len) : len; - double goodthresh; - double distotarget; /* fixed_quality */ - int i = 0; - - /* fixed_quality */ - distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10)); - - if ((tcd_tcp->rates[layno]) || (cp->disto_alloc==0)) { - opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->volume, cp); - int oldl = 0, oldoldl = 0; - for (i = 0; i < 128; i++) { - double thresh = (lo + hi) / 2; - int l = 0; - double distoachieved = 0; /* fixed_quality -q */ - - tcd_makelayer(tcd, layno, thresh, 0); - - if (cp->fixed_quality) { /* fixed_quality -q */ - distoachieved = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno]; - if (distoachieved < distotarget) { - hi = thresh; - continue; - } - lo = thresh; - } else { /* disto_alloc -r, fixed_alloc -f */ - l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, volume_info); - /*fprintf(stdout, "layno %d i %d len=%d max=%d \n",layno,i,l,maxlen);*/ - if (l == -999) { - lo = thresh; - continue; - } else if (l == oldl && oldl == oldoldl && tcd_tile->distolayer[layno] > 0.0 && i>32) - break; - hi = thresh; - oldoldl = oldl; - oldl = l; - } - success = 1; - goodthresh = thresh; - } - t2_destroy(t2); - } else { - success = 1; - goodthresh = min; - } - if (!success) { - return false; - } - - if(volume_info && volume_info->index_on) { /* Threshold for Marcela Index */ - volume_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh; - } - tcd_makelayer(tcd, layno, goodthresh, 1); - - /* fixed_quality */ - cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno]; - } - - return true; -} - -/* ----------------------------------------------------------------------- */ -int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_volume_info_t * volume_info) { - int compno; - int l, i, npck = 0; - double encoding_time; - - opj_tcd_tile_t *tile = NULL; - opj_tcp_t *tcd_tcp = NULL; - opj_cp_t *cp = NULL; - - opj_tcp_t *tcp = &tcd->cp->tcps[0]; - opj_tccp_t *tccp = &tcp->tccps[0]; - opj_volume_t *volume = tcd->volume; - opj_t2_t *t2 = NULL; /* T2 component */ - - tcd->tcd_tileno = tileno; /* current encoded/decoded tile */ - - tcd->tcd_tile = tcd->tcd_volume->tiles; /* tile information */ - tile = tcd->tcd_tile; - - tcd->tcp = &tcd->cp->tcps[tileno]; /* coding/decoding params of tileno */ - tcd_tcp = tcd->tcp; - - cp = tcd->cp; /* coding parameters */ - - /* INDEX >> */ - if(volume_info && volume_info->index_on) { - opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */ - for (i = 0; i < tilec_idx->numresolution[0]; i++) { - opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; - - volume_info->tile[tileno].prctno[0][i] = res_idx->prctno[0]; - volume_info->tile[tileno].prctno[1][i] = res_idx->prctno[1]; - volume_info->tile[tileno].prctno[2][i] = res_idx->prctno[2]; - - npck += res_idx->prctno[0] * res_idx->prctno[1] * res_idx->prctno[2]; - - volume_info->tile[tileno].prctsiz[0][i] = tccp->prctsiz[0][i]; - volume_info->tile[tileno].prctsiz[1][i] = tccp->prctsiz[1][i]; - volume_info->tile[tileno].prctsiz[2][i] = tccp->prctsiz[2][i]; - } - volume_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(volume_info->comp * volume_info->layer * npck * sizeof(opj_packet_info_t)); - } - /* << INDEX */ - - /*---------------TILE-------------------*/ - encoding_time = opj_clock(); /* time needed to encode a tile */ - - for (compno = 0; compno < tile->numcomps; compno++) { - int x, y, z; - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - - int adjust; - int offset_x = int_ceildiv(volume->x0, volume->comps[compno].dx); /*ceil(x0 / subsampling_dx)*/ - int offset_y = int_ceildiv(volume->y0, volume->comps[compno].dy); - int offset_z = int_ceildiv(volume->z0, volume->comps[compno].dz); - - int tw = tilec->x1 - tilec->x0; - int w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx); - int th = tilec->y1 - tilec->y0; - int h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy); - int tl = tilec->z1 - tilec->z0; - int l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz); - - - - /* extract tile data from volume.comps[0].data to tile.comps[0].data */ - /*fprintf(stdout,"[INFO] Extract tile data\n");*/ - if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) { - adjust = 0; - } else { - adjust = volume->comps[compno].sgnd ? 0 : 1 << (volume->comps[compno].prec - 1); /*sign=='+' --> 2^(prec-1)*/ - if (volume->comps[compno].dcoffset != 0){ - adjust += volume->comps[compno].dcoffset; - fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",volume->comps[compno].dcoffset,adjust); - } - } - - if (tcd_tcp->tccps[compno].reversible == 1) { /*IF perfect reconstruction (DWT.5-3)*/ - for (z = tilec->z0; z < tilec->z1; z++) { - for (y = tilec->y0; y < tilec->y1; y++) { - /* start of the src tile scanline */ - int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h]; - /* start of the dst tile scanline */ - int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th]; - for (x = tilec->x0; x < tilec->x1; x++) { - *tile_data++ = *data++ - adjust; - } - } - } - } else if (tcd_tcp->tccps[compno].reversible == 0) { /*IF not (DWT.9-7)*/ - for (z = tilec->z0; z < tilec->z1; z++) { - for (y = tilec->y0; y < tilec->y1; y++) { - /* start of the src tile scanline */ - int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h]; - /* start of the dst tile scanline */ - int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th]; - for (x = tilec->x0; x < tilec->x1; x++) { - *tile_data++ = (*data++ - adjust) << 13; - } - } - } - } - - } - - /*----------------MCT-------------------*/ - if (tcd_tcp->mct) { - int samples = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) * (tile->comps[0].z1 - tile->comps[0].z0); - fprintf(stdout,"[INFO] Tcd_encode_tile: mct\n"); - if (tcd_tcp->tccps[0].reversible == 0) { - mct_encode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples); - } else { - mct_encode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples); - } - } - /*----------------TRANSFORM---------------------------------*/ - fprintf(stdout,"[INFO] Tcd_encode_tile: Transform\n"); - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - dwt_encode(tilec, tcd_tcp->tccps[compno].dwtid); - } - - /*-------------------ENTROPY CODING-----------------------------*/ - fprintf(stdout,"[INFO] Tcd_encode_tile: Entropy coding\n"); - if ((cp->encoding_format == ENCOD_2EB)||(cp->encoding_format == ENCOD_3EB)) - { - if (cp->encoding_format == ENCOD_2EB) { - opj_t1_t *t1 = NULL; - t1 = t1_create(tcd->cinfo); - t1_encode_cblks(t1, tile, tcd_tcp); - t1_destroy(t1); - } else if (cp->encoding_format == ENCOD_3EB) { - opj_t1_3d_t *t1 = NULL; - t1 = t1_3d_create(tcd->cinfo); - t1_3d_encode_cblks(t1, tile, tcd_tcp); - t1_3d_destroy(t1); - } - /*-----------RATE-ALLOCATE------------------*/ - /* INDEX */ - if(volume_info) { - volume_info->index_write = 0; - } - if (cp->disto_alloc || cp->fixed_quality) { - fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate\n"); - tcd_rateallocate(tcd, dest, len, volume_info); /* Normal Rate/distortion allocation */ - } else {/* fixed_alloc */ - fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate fixed\n"); - tcd_rateallocate_fixed(tcd); /* Fixed layer allocation */ - } - - /*--------------TIER2------------------*/ - /* INDEX */ - if(volume_info) { - volume_info->index_write = 1; - } - fprintf(stdout,"[INFO] Tcd_encode_tile: Tier - 2\n"); - t2 = t2_create(tcd->cinfo, volume, cp); - l = t2_encode_packets(t2, tileno, tile, tcd_tcp->numlayers, dest, len, volume_info); - t2_destroy(t2); - } else if ((cp->encoding_format == ENCOD_2GR)||(cp->encoding_format == ENCOD_3GR)) { - /*if(volume_info) { - volume_info->index_write = 1; - } - gr = golomb_create(tcd->cinfo, volume, cp); - l = golomb_encode(gr, tileno, tile, dest, len, volume_info); - golomb_destroy(gr);*/ - } - - - /*---------------CLEAN-------------------*/ - fprintf(stdout,"[INFO] Tcd_encode_tile: %d bytes coded\n",l); - encoding_time = opj_clock() - encoding_time; - opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time); - - /* cleaning memory */ - for (compno = 0; compno < tile->numcomps; compno++) { - tcd->tilec = &tile->comps[compno]; - opj_free(tcd->tilec->data); - } - - if (l == -999){ - fprintf(stdout,"[ERROR] Unable to perform T2 tier. Return -999.\n"); - return 0; - } - - return l; -} - - -bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno) { - int l, i; - int compno, eof = 0; - double tile_time, t1_time, dwt_time; - - opj_tcd_tile_t *tile = NULL; - opj_t2_t *t2 = NULL; /* T2 component */ - - tcd->tcd_tileno = tileno; - tcd->tcd_tile = &(tcd->tcd_volume->tiles[tileno]); - tcd->tcp = &(tcd->cp->tcps[tileno]); - tile = tcd->tcd_tile; - - tile_time = opj_clock(); /* time needed to decode a tile */ - opj_event_msg(tcd->cinfo, EVT_INFO, "tile %d / %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th * tcd->cp->tl); - - if ((tcd->cp->encoding_format == ENCOD_2EB) || (tcd->cp->encoding_format == ENCOD_3EB)) { - /*--------------TIER2------------------*/ - t2 = t2_create(tcd->cinfo, tcd->volume, tcd->cp); - l = t2_decode_packets(t2, src, len, tileno, tile); - t2_destroy(t2); - opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: %d bytes decoded\n",l); - - if (l == -999) { - eof = 1; - opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n"); - } - - /*------------------TIER1-----------------*/ - opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding %d \n",tcd->cp->encoding_format); - t1_time = opj_clock(); /* time needed to decode a tile */ - if (tcd->cp->encoding_format == ENCOD_2EB) { - opj_t1_t *t1 = NULL; /* T1 component */ - t1 = t1_create(tcd->cinfo); - t1_decode_cblks(t1, tile, tcd->tcp); - t1_destroy(t1); - }else if (tcd->cp->encoding_format == ENCOD_3EB) { - opj_t1_3d_t *t1 = NULL; /* T1 component */ - t1 = t1_3d_create(tcd->cinfo); - t1_3d_decode_cblks(t1, tile, tcd->tcp); - t1_3d_destroy(t1); - } - - t1_time = opj_clock() - t1_time; - #ifdef VERBOSE - opj_event_msg(tcd->cinfo, EVT_INFO, "- tier-1 took %f s\n", t1_time); - #endif - } else if ((tcd->cp->encoding_format == ENCOD_2GR)||(tcd->cp->encoding_format == ENCOD_3GR)) { - opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding -- Does nothing :-D\n"); - /* - gr = golomb_create(tcd->cinfo, tcd->volume, tcd->cp); - l = golomb_decode(gr, tileno, tile, src, len); - golomb_destroy(gr); - if (l == -999) { - eof = 1; - opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n"); - } - */ - } - - /*----------------DWT---------------------*/ - fprintf(stdout,"[INFO] Tcd_decode_tile: Inverse DWT\n"); - dwt_time = opj_clock(); /* time needed to decode a tile */ - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - int stops[3], dwtid[3]; - - for (i = 0; i < 3; i++) { - if (tcd->cp->reduce[i] != 0) - tcd->volume->comps[compno].resno_decoded[i] = tile->comps[compno].numresolution[i] - tcd->cp->reduce[i] - 1; - stops[i] = tilec->numresolution[i] - 1 - tcd->volume->comps[compno].resno_decoded[i]; - if (stops[i] < 0) stops[i]=0; - dwtid[i] = tcd->cp->tcps->tccps[compno].dwtid[i]; - } - - dwt_decode(tilec, stops, dwtid); - - for (i = 0; i < 3; i++) { - if (tile->comps[compno].numresolution[i] > 0) { - tcd->volume->comps[compno].factor[i] = tile->comps[compno].numresolution[i] - (tcd->volume->comps[compno].resno_decoded[i] + 1); - if ( (tcd->volume->comps[compno].factor[i]) < 0 ) - tcd->volume->comps[compno].factor[i] = 0; - } - } - } - dwt_time = opj_clock() - dwt_time; - #ifdef VERBOSE - opj_event_msg(tcd->cinfo, EVT_INFO, "- dwt took %f s\n", dwt_time); - #endif - - /*----------------MCT-------------------*/ - - if (tcd->tcp->mct) { - if (tcd->tcp->tccps[0].reversible == 1) { - mct_decode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, - (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) * (tile->comps[0].z1 - tile->comps[0].z0)); - } else { - mct_decode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, - (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0)* (tile->comps[0].z1 - tile->comps[0].z0)); - } - } - - /*---------------TILE-------------------*/ - - for (compno = 0; compno < tile->numcomps; compno++) { - opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; - opj_tcd_resolution_t *res = &tilec->resolutions[tcd->volume->comps[compno].resno_decoded[0]]; - int adjust; - int minval = tcd->volume->comps[compno].sgnd ? -(1 << (tcd->volume->comps[compno].prec - 1)) : 0; - int maxval = tcd->volume->comps[compno].sgnd ? (1 << (tcd->volume->comps[compno].prec - 1)) - 1 : (1 << tcd->volume->comps[compno].prec) - 1; - - int tw = tilec->x1 - tilec->x0; - int w = tcd->volume->comps[compno].w; - int th = tilec->y1 - tilec->y0; - int h = tcd->volume->comps[compno].h; - - int i, j, k; - int offset_x = int_ceildivpow2(tcd->volume->comps[compno].x0, tcd->volume->comps[compno].factor[0]); - int offset_y = int_ceildivpow2(tcd->volume->comps[compno].y0, tcd->volume->comps[compno].factor[1]); - int offset_z = int_ceildivpow2(tcd->volume->comps[compno].z0, tcd->volume->comps[compno].factor[2]); - - if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) { - adjust = 0; - } else { - adjust = tcd->volume->comps[compno].sgnd ? 0 : 1 << (tcd->volume->comps[compno].prec - 1); /*sign=='+' --> 2^(prec-1)*/ - if (tcd->volume->comps[compno].dcoffset != 0){ - adjust += tcd->volume->comps[compno].dcoffset; - fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",tcd->volume->comps[compno].dcoffset,adjust); - } - } - - for (k = res->z0; k < res->z1; k++) { - for (j = res->y0; j < res->y1; j++) { - for (i = res->x0; i < res->x1; i++) { - int v; - float tmp = (float)((tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th]) / 8192.0); - - if (tcd->tcp->tccps[compno].reversible == 1) { - v = tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th]; - } else { - int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); - v = ((tmp < 0) ? -tmp2:tmp2); - } - v += adjust; - - tcd->volume->comps[compno].data[(i - offset_x) + (j - offset_y) * w + (k - offset_z) * w * h] = int_clamp(v, minval, maxval); - } - } - } - } - - tile_time = opj_clock() - tile_time; /* time needed to decode a tile */ - opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time); - - for (compno = 0; compno < tile->numcomps; compno++) { - opj_free(tcd->tcd_volume->tiles[tileno].comps[compno].data); - tcd->tcd_volume->tiles[tileno].comps[compno].data = NULL; - } - - if (eof) { - return false; - } - - return true; -} - +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2006, Mónica Díez, LPI-UVA, Spain + * 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" + +void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_volume_t * vol) { + int tileno, compno, resno, bandno, precno, cblkno; + + fprintf(fd, "volume {\n"); + fprintf(fd, " tw=%d, th=%d, tl=%d, x0=%d x1=%d y0=%d y1=%d z0=%d z1=%d\n", + vol->tw, vol->th, vol->tl, tcd->volume->x0, tcd->volume->x1, tcd->volume->y0, tcd->volume->y1, tcd->volume->z0, tcd->volume->z1); + + for (tileno = 0; tileno < vol->th * vol->tw * vol->tl; tileno++) { + opj_tcd_tile_t *tile = &tcd->tcd_volume->tiles[tileno]; + fprintf(fd, " tile {\n"); + fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numcomps=%d\n", + tile->x0, tile->y0, tile->z0, tile->x1, tile->y1, tile->z1, tile->numcomps); + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + fprintf(fd, " tilecomp %d {\n",compno); + fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numresx=%d, numresy=%d, numresz=%d\n", + tilec->x0, tilec->y0, tilec->z0, tilec->x1, tilec->y1, tilec->z1, tilec->numresolution[0], tilec->numresolution[1], tilec->numresolution[2]); + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + fprintf(fd, " res %d{\n",resno); + fprintf(fd," x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, pw=%d, ph=%d, pl=%d, numbands=%d\n", + res->x0, res->y0, res->z0, res->x1, res->y1, res->z1, res->prctno[0], res->prctno[1], res->prctno[2], res->numbands); + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + fprintf(fd, " band %d{\n", bandno); + fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, stepsize=%f, numbps=%d\n", + band->x0, band->y0, band->z0, band->x1, band->y1, band->z1, band->stepsize, band->numbps); + for (precno = 0; precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); precno++) { + opj_tcd_precinct_t *prec = &band->precincts[precno]; + fprintf(fd, " prec %d{\n",precno); + fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, cw=%d, ch=%d, cl=%d,\n", + prec->x0, prec->y0, prec->z0, prec->x1, prec->y1, prec->z1, prec->cblkno[0], prec->cblkno[1], prec->cblkno[2]); + for (cblkno = 0; cblkno < (prec->cblkno[0] * prec->cblkno[1] * prec->cblkno[2]); cblkno++) { + opj_tcd_cblk_t *cblk = &prec->cblks[cblkno]; + fprintf(fd, " cblk %d{\n",cblkno); + fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d\n", cblk->x0, cblk->y0, cblk->z0, cblk->x1, cblk->y1, cblk->z1); + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, " }\n"); + } + fprintf(fd, "}\n"); +} + +static void tilec_dump(FILE *fd, opj_tcd_tilecomp_t *tilec) { + + int i=0,k; + int datalen; + int *a; + + fprintf(fd, " tilecomp{\n"); + fprintf(fd, " x0=%d, y0=%d, z0=%d, x1=%d, y1=%d, z1=%d, numresx=%d, numresy=%d, numresz=%d\n", + tilec->x0, tilec->y0, tilec->z0, tilec->x1, tilec->y1, tilec->z1, tilec->numresolution[0], tilec->numresolution[1], tilec->numresolution[2]); + fprintf(fd, " data {\n"); + datalen = (tilec->z1 - tilec->z0) * (tilec->y1 - tilec->y0) * (tilec->x1 - tilec->x0); + a = tilec->data; + for (k = 0; k < datalen; k++) { + if (!(k % tilec->x1)){ + fprintf(fd, "\n"); + } + if (!(k % (tilec->y1 * tilec->x1))){ + fprintf(fd, "Slice %d\n",i++); + } + fprintf(fd," %d",a[k]); + + + } + fprintf(fd, " }\n"); + /*i=0; + fprintf(fd, "Slice %d\n"); + if (tilec->prediction->prederr) { + fprintf(fd, " prederror {\n"); + a = tilec->prediction->prederr; + for (k = 0; k < datalen; k++) { + fprintf(fd," %d",*(a++)); + if (!(k % (tilec->y1 - tilec->y0) * (tilec->x1 - tilec->x0))){ + fprintf(fd, "\n");fprintf(fd, "Slice %d\n",i++); + } + if (!(k % (tilec->x1 - tilec->x0))){ + fprintf(fd, "\n"); + } + } + } + fprintf(fd, " }\n");*/ + fprintf(fd, "}\n"); +} + +/* ----------------------------------------------------------------------- */ + +/** +Create a new TCD handle +*/ +opj_tcd_t* tcd_create(opj_common_ptr cinfo) { + /* create the tcd structure */ + opj_tcd_t *tcd = (opj_tcd_t*)opj_malloc(sizeof(opj_tcd_t)); + if(!tcd) return NULL; + tcd->cinfo = cinfo; + tcd->tcd_volume = (opj_tcd_volume_t*)opj_malloc(sizeof(opj_tcd_volume_t)); + if(!tcd->tcd_volume) { + opj_free(tcd); + return NULL; + } + + return tcd; +} + +/** +Destroy a previously created TCD handle +*/ +void tcd_destroy(opj_tcd_t *tcd) { + if(tcd) { + opj_free(tcd->tcd_volume); + opj_free(tcd); + } +} + +/* ----------------------------------------------------------------------- */ +void tcd_malloc_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno) { + int compno, resno, bandno, precno, cblkno, i, j;/*, k;*/ + + opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ + opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ + opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ + opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ + opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ + opj_tcd_cblk_t *cblk = NULL; /* pointer to tcd->cblk */ + opj_tcp_t *tcp = &cp->tcps[curtileno]; + int p,q,r; + + tcd->volume = volume; + tcd->cp = cp; + tcd->tcd_volume->tw = cp->tw; + tcd->tcd_volume->th = cp->th; + tcd->tcd_volume->tl = cp->tl; + tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(sizeof(opj_tcd_tile_t)); + tcd->tile = tcd->tcd_volume->tiles; + tile = tcd->tile; + + + /* p61 ISO/IEC IS15444-1 : 2002 */ + /* curtileno --> raster scanned index of tiles */ + /* p,q,r --> matricial index of tiles */ + p = curtileno % cp->tw; + q = curtileno / cp->tw; + r = curtileno / (cp->tw * cp->th); /* extension to 3-D */ + + /* 4 borders of the tile rescale on the volume if necessary (B.3)*/ + tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); + tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); + tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); + tile->numcomps = volume->numcomps; + + /* Modification of the RATE >> */ + for (j = 0; j < tcp->numlayers; j++) { + if (tcp->rates[j] <= 1) { + tcp->rates[j] = 0; + } else { + float num = (float) (tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec); + float den = (float) (8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz); + den = tcp->rates[j] * den; + tcp->rates[j] = (num + den - 1) / den; + } + /*tcp->rates[j] = tcp->rates[j] ? int_ceildiv( + tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec, + (tcp->rates[j] * 8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz)) : 0;*/ + if (tcp->rates[j]) { + if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { + tcp->rates[j] = tcp->rates[j - 1] + 20; + } else if (!j && tcp->rates[j] < 30){ + tcp->rates[j] = 30; + } + } + } + /* << Modification of the RATE */ + + tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t)); + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + int res_max; + int prevnumbands = 0; + + /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */ + tcd->tilec = &tile->comps[compno]; + tilec = tcd->tilec; + + /* border of each tile component (global) (B.3) */ + tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy); + tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz); + tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy); + tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz); + + tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int)); + + res_max = 0; + for (i = 0;i < 3; i++){ + tilec->numresolution[i] = tccp->numresolution[i]; + /*Greater of 3 resolutions contains all information*/ + res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max; + } + + + tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t)); + for (resno = 0; resno < res_max; resno++) { + + int pdx, pdy, pdz; + int tlprcxstart, tlprcystart, tlprczstart; + int brprcxend, brprcyend, brprczend; + int tlcbgxstart, tlcbgystart, tlcbgzstart; + int brcbgxend, brcbgyend, brcbgzend; + int cbgwidthexpn, cbgheightexpn, cbglengthexpn; + int cblkwidthexpn, cblkheightexpn, cblklengthexpn; + + int diff = tccp->numresolution[0] - tccp->numresolution[2]; + int levelnox = tilec->numresolution[0] - 1 - resno; + int levelnoy = tilec->numresolution[1] - 1 - resno; + int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff)); + if (levelnoz < 0) levelnoz = 0; + + /* opj_tcd_resolution_t *res=&tilec->resolutions[resno]; */ + tcd->res = &tilec->resolutions[resno]; + res = tcd->res; + + /* border for each resolution level (global) (B.14)*/ + res->x0 = int_ceildivpow2(tilec->x0, levelnox); + res->y0 = int_ceildivpow2(tilec->y0, levelnoy); + res->z0 = int_ceildivpow2(tilec->z0, levelnoz); + res->x1 = int_ceildivpow2(tilec->x1, levelnox); + res->y1 = int_ceildivpow2(tilec->y1, levelnoy); + res->z1 = int_ceildivpow2(tilec->z1, levelnoz); + /*if (res->z1 < 0)fprintf(stdout,"Res: %d %d/%d --> %d\n",resno,tilec->z1, levelnoz, int_ceildivpow2(tilec->z1, levelnoz));*/ + + res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */ + + /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */ + if (tccp->csty & J3D_CCP_CSTY_PRT) { + pdx = tccp->prctsiz[0][resno]; + pdy = tccp->prctsiz[1][resno]; + pdz = tccp->prctsiz[2][resno]; + } else { + pdx = 15; + pdy = 15; + pdz = 15; + } + + /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */ + tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; + tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; + tlprczstart = int_floordivpow2(res->z0, pdz) << pdz; + brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; + brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; + brprczend = int_ceildivpow2(res->z1, pdz) << pdz; + + res->prctno[0] = (brprcxend - tlprcxstart) >> pdx; + res->prctno[1] = (brprcyend - tlprcystart) >> pdy; + res->prctno[2] = (brprczend - tlprczstart) >> pdz; + if (res->prctno[2] == 0) res->prctno[2] = 1; + + /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */ + if (resno == 0) { + tlcbgxstart = tlprcxstart; + tlcbgystart = tlprcystart; + tlcbgzstart = tlprczstart; + brcbgxend = brprcxend; + brcbgyend = brprcyend; + brcbgzend = brprczend; + cbgwidthexpn = pdx; + cbgheightexpn = pdy; + cbglengthexpn = pdz; + } else { + tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); + tlcbgystart = int_ceildivpow2(tlprcystart, 1); + tlcbgzstart = int_ceildivpow2(tlprczstart, 1); + brcbgxend = int_ceildivpow2(brprcxend, 1); + brcbgyend = int_ceildivpow2(brprcyend, 1); + brcbgzend = int_ceildivpow2(brprczend, 1); + cbgwidthexpn = pdx - 1; + cbgheightexpn = pdy - 1; + cbglengthexpn = pdz - 1; + } + + cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); /*6*/ + cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); /*6*/ + cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); /*6*/ + + res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t)); + for (bandno = 0; bandno < res->numbands; bandno++) { + int x0b, y0b, z0b, i; + int gain, numbps; + opj_stepsize_t *ss = NULL; + + tcd->band = &res->bands[bandno]; + band = tcd->band; + + band->bandno = (resno == 0) ? 0 : bandno + 1; + /* Bandno: 0 - LLL 2 - LHL + 1 - HLL 3 - HHL + 4 - LLH 6 - LHH + 5 - HLH 7 - HHH */ + x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; + y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; + z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; + + /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */ + if (band->bandno == 0) { + /* band border (global) */ + band->x0 = int_ceildivpow2(tilec->x0, levelnox); + band->y0 = int_ceildivpow2(tilec->y0, levelnoy); + band->z0 = int_ceildivpow2(tilec->z0, levelnoz); + band->x1 = int_ceildivpow2(tilec->x1, levelnox); + band->y1 = int_ceildivpow2(tilec->y1, levelnoy); + band->z1 = int_ceildivpow2(tilec->z1, levelnoz); + } else { + band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1); + band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1); + band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); + band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1); + band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1); + band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); + } + + ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)]; + if (bandno == (res->numbands - 1)) + prevnumbands += (resno == 0) ? 0 : res->numbands; + gain = dwt_getgain(band->bandno,tccp->reversible); + numbps = volume->comps[compno].prec + gain; + band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + band->precincts = (opj_tcd_precinct_t *) opj_malloc((res->prctno[0] * res->prctno[1] * res->prctno[2]) * sizeof(opj_tcd_precinct_t)); + + for (i = 0; i < (res->prctno[0] * res->prctno[1] * res->prctno[2]); i++) { + band->precincts[i].imsbtree = NULL; + band->precincts[i].incltree = NULL; + } + + for (precno = 0; precno < (res->prctno[0] * res->prctno[1] * res->prctno[2]); precno++) { + int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend; + int cbgxstart, cbgystart, cbgzstart, cbgxend, cbgyend, cbgzend; + + cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn); + cbgystart = tlcbgystart + ((precno % (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn); + cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn); + cbgxend = cbgxstart + (1 << cbgwidthexpn); + cbgyend = cbgystart + (1 << cbgheightexpn); + cbgzend = cbgzstart + (1 << cbglengthexpn); + + tcd->prc = &band->precincts[precno]; + prc = tcd->prc; + + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->z0 = int_max(cbgzstart, band->z0); + prc->x1 = int_min(cbgxend, band->x1); + prc->y1 = int_min(cbgyend, band->y1); + prc->z1 = int_min(cbgzend, band->z1); + + tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; + tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; + tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn; + brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; + brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; + brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn; + prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; + prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn; + prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn; + prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2]; + + prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t)); + prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); + prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); + /*tgt_tree_dump(stdout,prc->incltree);*/ + for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) { + int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn); + int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn); + int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn); + int cblkxend = cblkxstart + (1 << cblkwidthexpn); + int cblkyend = cblkystart + (1 << cblkheightexpn); + int cblkzend = cblkzstart + (1 << cblklengthexpn); + int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1)); + + tcd->cblk = &prc->cblks[cblkno]; + cblk = tcd->cblk; + + /* code-block size (global) */ + cblk->x0 = int_max(cblkxstart, prc->x0); + cblk->y0 = int_max(cblkystart, prc->y0); + cblk->z0 = int_max(cblkzstart, prc->z0); + cblk->x1 = int_min(cblkxend, prc->x1); + cblk->y1 = int_min(cblkyend, prc->y1); + cblk->z1 = int_min(cblkzend, prc->z1); + } + } + } + } + } + /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/ + +} +void tcd_init_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno) { + int compno, resno, bandno, precno, cblkno; + int j, p, q, r; + + opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ + opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ + opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ + opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ + opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ + opj_tcd_cblk_t *cblk = NULL; /* pointer to tcd->cblk */ + opj_tcp_t *tcp = &cp->tcps[curtileno]; + + tcd->tile = tcd->tcd_volume->tiles; + tile = tcd->tile; + + /* p61 ISO/IEC IS15444-1 : 2002 */ + /* curtileno --> raster scanned index of tiles */ + /* p,q,r --> matricial index of tiles */ + p = curtileno % cp->tw; + q = curtileno / cp->tw; + r = curtileno / (cp->tw * cp->th); /* extension to 3-D */ + + /* 4 borders of the tile rescale on the volume if necessary (B.3)*/ + tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); + tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); + tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); + tile->numcomps = volume->numcomps; + + /* Modification of the RATE >> */ + for (j = 0; j < tcp->numlayers; j++) { + if (tcp->rates[j] <= 1) { + tcp->rates[j] = 0; + } else { + float num = (float) (tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec); + float den = (float) (8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz); + den = tcp->rates[j] * den; + tcp->rates[j] = (num + den - 1) / den; + } + /*tcp->rates[j] = tcp->rates[j] ? int_ceildiv( + tile->numcomps * (tile->x1 - tile->x0) * (tile->y1 - tile->y0) * (tile->z1 - tile->z0) * volume->comps[0].prec, + (tcp->rates[j] * 8 * volume->comps[0].dx * volume->comps[0].dy * volume->comps[0].dz)) : 0;*/ + if (tcp->rates[j]) { + if (j && tcp->rates[j] < tcp->rates[j - 1] + 10) { + tcp->rates[j] = tcp->rates[j - 1] + 20; + } else if (!j && tcp->rates[j] < 30){ + tcp->rates[j] = 30; + } + } + } + /* << Modification of the RATE */ + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + int res_max, i; + int prevnumbands = 0; + + /* opj_tcd_tilecomp_t *tilec=&tile->comps[compno]; */ + tcd->tilec = &tile->comps[compno]; + tilec = tcd->tilec; + + /* border of each tile component (global) (B.3) */ + tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy); + tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz); + tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy); + tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz); + + tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int)); + + res_max = 0; + for (i = 0;i < 3; i++){ + tilec->numresolution[i] = tccp->numresolution[i]; + /*Greater of 3 resolutions contains all information*/ + res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max; + } + + tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t)); + for (resno = 0; resno < res_max; resno++) { + int pdx, pdy, pdz; + int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend; + int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend; + int cbgwidthexpn, cbgheightexpn, cbglengthexpn; + int cblkwidthexpn, cblkheightexpn, cblklengthexpn; + + int levelnox = tilec->numresolution[0] - 1 - resno; + int levelnoy = tilec->numresolution[1] - 1 - resno; + int diff = tccp->numresolution[0] - tccp->numresolution[2]; + int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff)); + if (levelnoz < 0) levelnoz = 0; + + tcd->res = &tilec->resolutions[resno]; + res = tcd->res; + + /* border for each resolution level (global) (B.14)*/ + res->x0 = int_ceildivpow2(tilec->x0, levelnox); + res->y0 = int_ceildivpow2(tilec->y0, levelnoy); + res->z0 = int_ceildivpow2(tilec->z0, levelnoz); + res->x1 = int_ceildivpow2(tilec->x1, levelnox); + res->y1 = int_ceildivpow2(tilec->y1, levelnoy); + res->z1 = int_ceildivpow2(tilec->z1, levelnoz); + + /* res->numbands = resno == 0 ? 1 : 3; *//* --> 2D */ + + res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */ + + /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */ + if (tccp->csty & J3D_CCP_CSTY_PRT) { + pdx = tccp->prctsiz[0][resno]; + pdy = tccp->prctsiz[1][resno]; + pdz = tccp->prctsiz[2][resno]; + } else { + pdx = 15; + pdy = 15; + pdz = 15; + } + /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */ + tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; + tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; + tlprczstart = int_floordivpow2(res->z0, pdz) << pdz; + brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; + brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; + brprczend = int_ceildivpow2(res->z1, pdz) << pdz; + + res->prctno[0] = (brprcxend - tlprcxstart) >> pdx; + res->prctno[1] = (brprcyend - tlprcystart) >> pdy; + res->prctno[2] = (brprczend - tlprczstart) >> pdz; + if (res->prctno[2] == 0) res->prctno[2] = 1; + + /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */ + if (resno == 0) { + tlcbgxstart = tlprcxstart; + tlcbgystart = tlprcystart; + tlcbgzstart = tlprczstart; + brcbgxend = brprcxend; + brcbgyend = brprcyend; + brcbgzend = brprczend; + cbgwidthexpn = pdx; + cbgheightexpn = pdy; + cbglengthexpn = pdz; + } else { + tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); + tlcbgystart = int_ceildivpow2(tlprcystart, 1); + tlcbgzstart = int_ceildivpow2(tlprczstart, 1); + brcbgxend = int_ceildivpow2(brprcxend, 1); + brcbgyend = int_ceildivpow2(brprcyend, 1); + brcbgzend = int_ceildivpow2(brprczend, 1); + cbgwidthexpn = pdx - 1; + cbgheightexpn = pdy - 1; + cbglengthexpn = pdz - 1; + } + + cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); + cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); + cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); + + res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t)); + for (bandno = 0; bandno < res->numbands; bandno++) { + int x0b, y0b, z0b; + int gain, numbps; + opj_stepsize_t *ss = NULL; + + tcd->band = &res->bands[bandno]; + band = tcd->band; + + band->bandno = resno == 0 ? 0 : bandno + 1; + /* Bandno: 0 - LLL 2 - LHL + 1 - HLL 3 - HHL + 4 - LLH 6 - LHH + 5 - HLH 7 - HHH */ + x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; + y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; + z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; + + /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */ + if (band->bandno == 0) { + /* band border (global) */ + band->x0 = int_ceildivpow2(tilec->x0, levelnox); + band->y0 = int_ceildivpow2(tilec->y0, levelnoy); + band->z0 = int_ceildivpow2(tilec->z0, levelnoz); + band->x1 = int_ceildivpow2(tilec->x1, levelnox); + band->y1 = int_ceildivpow2(tilec->y1, levelnoy); + band->z1 = int_ceildivpow2(tilec->z1, levelnoz); + } else { + band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1); + band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1); + band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); + band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1); + band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1); + band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); + } + + ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)]; + if (bandno == (res->numbands - 1)) + prevnumbands += (resno == 0) ? 0 : res->numbands; + gain = dwt_getgain(band->bandno,tccp->reversible); + numbps = volume->comps[compno].prec + gain; + + band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend; + + int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn); + int cbgystart = tlcbgystart + ((precno / (res->prctno[0] * res->prctno[1])) / res->prctno[0]) * (1 << cbgheightexpn); + int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn); + int cbgxend = cbgxstart + (1 << cbgwidthexpn); + int cbgyend = cbgystart + (1 << cbgheightexpn); + int cbgzend = cbgzstart + (1 << cbglengthexpn); + + /* opj_tcd_precinct_t *prc=&band->precincts[precno]; */ + tcd->prc = &band->precincts[precno]; + prc = tcd->prc; + + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->z0 = int_max(cbgzstart, band->z0); + prc->x1 = int_min(cbgxend, band->x1); + prc->y1 = int_min(cbgyend, band->y1); + prc->z1 = int_min(cbgzend, band->z1); + + tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; + tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; + tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn; + brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; + brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; + brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn; + prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; + prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn; + prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn; + prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2]; + + opj_free(prc->cblks); + prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t)); + prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); + prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); + + for (cblkno = 0; cblkno < (prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]); cblkno++) { + int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn); + int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn); + int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn); + int cblkxend = cblkxstart + (1 << cblkwidthexpn); + int cblkyend = cblkystart + (1 << cblkheightexpn); + int cblkzend = cblkzstart + (1 << cblklengthexpn); + int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1)); + + tcd->cblk = &prc->cblks[cblkno]; + cblk = tcd->cblk; + + /* code-block size (global) */ + cblk->x0 = int_max(cblkxstart, prc->x0); + cblk->y0 = int_max(cblkystart, prc->y0); + cblk->z0 = int_max(cblkzstart, prc->z0); + cblk->x1 = int_min(cblkxend, prc->x1); + cblk->y1 = int_min(cblkyend, prc->y1); + cblk->z1 = int_min(cblkzend, prc->z1); + } + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ + /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/ +} + + +void tcd_free_encode(opj_tcd_t *tcd) { + int tileno, compno, resno, bandno, precno; + + opj_tcd_tile_t *tile = NULL; /* pointer to tcd->tile */ +/* opj_tcd_slice_t *slice = NULL; */ /* pointer to tcd->slice */ + opj_tcd_tilecomp_t *tilec = NULL; /* pointer to tcd->tilec */ + opj_tcd_resolution_t *res = NULL; /* pointer to tcd->res */ + opj_tcd_band_t *band = NULL; /* pointer to tcd->band */ + opj_tcd_precinct_t *prc = NULL; /* pointer to tcd->prc */ + + for (tileno = 0; tileno < 1; tileno++) { + tcd->tile = tcd->tcd_volume->tiles; + tile = tcd->tile; + + for (compno = 0; compno < tile->numcomps; compno++) { + tcd->tilec = &tile->comps[compno]; + tilec = tcd->tilec; + + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + tcd->res = &tilec->resolutions[resno]; + res = tcd->res; + + for (bandno = 0; bandno < res->numbands; bandno++) { + tcd->band = &res->bands[bandno]; + band = tcd->band; + + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + tcd->prc = &band->precincts[precno]; + prc = tcd->prc; + + if (prc->incltree != NULL) { + tgt_destroy(prc->incltree); + prc->incltree = NULL; + } + if (prc->imsbtree != NULL) { + tgt_destroy(prc->imsbtree); + prc->imsbtree = NULL; + } + opj_free(prc->cblks); + prc->cblks = NULL; + } /* for (precno */ + opj_free(band->precincts); + band->precincts = NULL; + } /* for (bandno */ + } /* for (resno */ + opj_free(tilec->resolutions); + tilec->resolutions = NULL; + } /* for (compno */ + opj_free(tile->comps); + tile->comps = NULL; + } /* for (tileno */ + opj_free(tcd->tcd_volume->tiles); + tcd->tcd_volume->tiles = NULL; +} + +/* ----------------------------------------------------------------------- */ +void tcd_malloc_decode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp) { + int tileno, compno, resno, bandno, precno, cblkno, res_max, + i, j, p, q, r; + unsigned int x0 = 0, y0 = 0, z0 = 0, + x1 = 0, y1 = 0, z1 = 0, + w, h, l; + + tcd->volume = volume; + tcd->cp = cp; + tcd->tcd_volume->tw = cp->tw; + tcd->tcd_volume->th = cp->th; + tcd->tcd_volume->tl = cp->tl; + tcd->tcd_volume->tiles = (opj_tcd_tile_t *) opj_malloc(cp->tw * cp->th * cp->tl * sizeof(opj_tcd_tile_t)); + + for (i = 0; i < cp->tileno_size; i++) { + opj_tcp_t *tcp = &(cp->tcps[cp->tileno[i]]); + opj_tcd_tile_t *tile = &(tcd->tcd_volume->tiles[cp->tileno[i]]); + + /* p61 ISO/IEC IS15444-1 : 2002 */ + /* curtileno --> raster scanned index of tiles */ + /* p,q,r --> matricial index of tiles */ + tileno = cp->tileno[i]; + p = tileno % cp->tw; + q = tileno / cp->tw; + r = tileno / (cp->tw * cp->th); /* extension to 3-D */ + + /* 4 borders of the tile rescale on the volume if necessary (B.3)*/ + tile->x0 = int_max(cp->tx0 + p * cp->tdx, volume->x0); + tile->y0 = int_max(cp->ty0 + q * cp->tdy, volume->y0); + tile->z0 = int_max(cp->tz0 + r * cp->tdz, volume->z0); + tile->x1 = int_min(cp->tx0 + (p + 1) * cp->tdx, volume->x1); + tile->y1 = int_min(cp->ty0 + (q + 1) * cp->tdy, volume->y1); + tile->z1 = int_min(cp->tz0 + (r + 1) * cp->tdz, volume->z1); + tile->numcomps = volume->numcomps; + + tile->comps = (opj_tcd_tilecomp_t *) opj_malloc(volume->numcomps * sizeof(opj_tcd_tilecomp_t)); + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tccp_t *tccp = &tcp->tccps[compno]; + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + int prevnumbands = 0; + + /* border of each tile component (global) */ + tilec->x0 = int_ceildiv(tile->x0, volume->comps[compno].dx); + tilec->y0 = int_ceildiv(tile->y0, volume->comps[compno].dy); + tilec->z0 = int_ceildiv(tile->z0, volume->comps[compno].dz); + tilec->x1 = int_ceildiv(tile->x1, volume->comps[compno].dx); + tilec->y1 = int_ceildiv(tile->y1, volume->comps[compno].dy); + tilec->z1 = int_ceildiv(tile->z1, volume->comps[compno].dz); + + tilec->data = (int *) opj_malloc((tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0) * (tilec->z1 - tilec->z0) * sizeof(int)); + + res_max = 0; + for (i = 0;i < 3; i++){ + tilec->numresolution[i] = tccp->numresolution[i]; + /*Greater of 3 resolutions contains all information*/ + res_max = (tilec->numresolution[i] > res_max) ? tilec->numresolution[i] : res_max; + } + + tilec->resolutions = (opj_tcd_resolution_t *) opj_malloc(res_max * sizeof(opj_tcd_resolution_t)); + + for (resno = 0; resno < res_max; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + int pdx, pdy, pdz; + int tlprcxstart, tlprcystart, tlprczstart, brprcxend, brprcyend, brprczend; + int tlcbgxstart, tlcbgystart, tlcbgzstart, brcbgxend, brcbgyend, brcbgzend; + int cbgwidthexpn, cbgheightexpn, cbglengthexpn; + int cblkwidthexpn, cblkheightexpn, cblklengthexpn; + int levelnox = tilec->numresolution[0] - 1 - resno; + int levelnoy = tilec->numresolution[1] - 1 - resno; + int diff = tccp->numresolution[0] - tccp->numresolution[2]; + int levelnoz = tilec->numresolution[2] - 1 - ((resno <= diff) ? 0 : (resno - diff)); + if (levelnoz < 0) levelnoz = 0; + + /* border for each resolution level (global) */ + res->x0 = int_ceildivpow2(tilec->x0, levelnox); + res->y0 = int_ceildivpow2(tilec->y0, levelnoy); + res->z0 = int_ceildivpow2(tilec->z0, levelnoz); + res->x1 = int_ceildivpow2(tilec->x1, levelnox); + res->y1 = int_ceildivpow2(tilec->y1, levelnoy); + res->z1 = int_ceildivpow2(tilec->z1, levelnoz); + res->numbands = (resno == 0) ? 1 : (resno <= diff) ? 3 : 7; /* --> 3D */ + + /* p. 30, table A-13, ISO/IEC IS154444-1 : 2002 */ + if (tccp->csty & J3D_CCP_CSTY_PRT) { + pdx = tccp->prctsiz[0][resno]; + pdy = tccp->prctsiz[1][resno]; + pdz = tccp->prctsiz[2][resno]; + } else { + pdx = 15; + pdy = 15; + pdz = 15; + } + + /* p. 66, B.16, ISO/IEC IS15444-1 : 2002 */ + tlprcxstart = int_floordivpow2(res->x0, pdx) << pdx; + tlprcystart = int_floordivpow2(res->y0, pdy) << pdy; + tlprczstart = int_floordivpow2(res->z0, pdz) << pdz; + brprcxend = int_ceildivpow2(res->x1, pdx) << pdx; + brprcyend = int_ceildivpow2(res->y1, pdy) << pdy; + brprczend = int_ceildivpow2(res->z1, pdz) << pdz; + + res->prctno[0] = (brprcxend - tlprcxstart) >> pdx; + res->prctno[1] = (brprcyend - tlprcystart) >> pdy; + res->prctno[2] = (brprczend - tlprczstart) >> pdz; + + /* p. 67, B.17 & B.18, ISO/IEC IS15444-1 : 2002 */ + if (resno == 0) { + tlcbgxstart = tlprcxstart;/*0*/ + tlcbgystart = tlprcystart; + tlcbgzstart = tlprczstart; + brcbgxend = brprcxend;/*1*/ + brcbgyend = brprcyend; + brcbgzend = brprczend; + cbgwidthexpn = pdx; /*15*/ + cbgheightexpn = pdy; + cbglengthexpn = pdz; + } else { + tlcbgxstart = int_ceildivpow2(tlprcxstart, 1); + tlcbgystart = int_ceildivpow2(tlprcystart, 1); + tlcbgzstart = int_ceildivpow2(tlprczstart, 1); + brcbgxend = int_ceildivpow2(brprcxend, 1); + brcbgyend = int_ceildivpow2(brprcyend, 1); + brcbgzend = int_ceildivpow2(brprczend, 1); + cbgwidthexpn = pdx - 1; + cbgheightexpn = pdy - 1; + cbglengthexpn = pdz - 1; + } + + cblkwidthexpn = int_min(tccp->cblk[0], cbgwidthexpn); /*6*/ + cblkheightexpn = int_min(tccp->cblk[1], cbgheightexpn); /*6*/ + cblklengthexpn = int_min(tccp->cblk[2], cbglengthexpn); /*6*/ + + res->bands = (opj_tcd_band_t *) opj_malloc(res->numbands * sizeof(opj_tcd_band_t)); + for (bandno = 0; bandno < res->numbands; bandno++) { + int x0b, y0b, z0b; + int gain, numbps; + opj_stepsize_t *ss = NULL; + + opj_tcd_band_t *band = &res->bands[bandno]; + band->bandno = resno == 0 ? 0 : bandno + 1; + /* Bandno: 0 - LLL 2 - LHL + 1 - HLL 3 - HHL + 4 - LLH 6 - LHH + 5 - HLH 7 - HHH */ + x0b = (band->bandno == 1) || (band->bandno == 3) || (band->bandno == 5 ) || (band->bandno == 7 ) ? 1 : 0; + y0b = (band->bandno == 2) || (band->bandno == 3) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; + z0b = (band->bandno == 4) || (band->bandno == 5) || (band->bandno == 6 ) || (band->bandno == 7 ) ? 1 : 0; + + /* p. 65, B.15, ISO/IEC IS15444-1 : 2002 */ + if (band->bandno == 0) { + /* band border (global) */ + band->x0 = int_ceildivpow2(tilec->x0, levelnox); + band->y0 = int_ceildivpow2(tilec->y0, levelnoy); + band->z0 = int_ceildivpow2(tilec->z0, levelnoz); + band->x1 = int_ceildivpow2(tilec->x1, levelnox); + band->y1 = int_ceildivpow2(tilec->y1, levelnoy); + band->z1 = int_ceildivpow2(tilec->z1, levelnoz); + } else { + band->x0 = int_ceildivpow2(tilec->x0 - (1 << levelnox) * x0b, levelnox + 1); + band->y0 = int_ceildivpow2(tilec->y0 - (1 << levelnoy) * y0b, levelnoy + 1); + band->z0 = int_ceildivpow2(tilec->z0 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); + band->x1 = int_ceildivpow2(tilec->x1 - (1 << levelnox) * x0b, levelnox + 1); + band->y1 = int_ceildivpow2(tilec->y1 - (1 << levelnoy) * y0b, levelnoy + 1); + band->z1 = int_ceildivpow2(tilec->z1 - (1 << levelnoz) * z0b, (resno <= diff) ? levelnoz : levelnoz + 1); + } + + ss = &tccp->stepsizes[(resno == 0) ? 0 : (prevnumbands + bandno + 1)]; + if (bandno == (res->numbands - 1)) + prevnumbands += (resno == 0) ? 0 : res->numbands; + gain = dwt_getgain(band->bandno,tccp->reversible); + numbps = volume->comps[compno].prec + gain; + + band->stepsize = (float)((1.0 + ss->mant / 2048.0) * pow(2.0, numbps - ss->expn)); + band->numbps = ss->expn + tccp->numgbits - 1; /* WHY -1 ? */ + + band->precincts = (opj_tcd_precinct_t *) opj_malloc(res->prctno[0] * res->prctno[1] * res->prctno[2] * sizeof(opj_tcd_precinct_t)); + + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + int tlcblkxstart, tlcblkystart, tlcblkzstart, brcblkxend, brcblkyend, brcblkzend; + + int cbgxstart = tlcbgxstart + (precno % res->prctno[0]) * (1 << cbgwidthexpn); + int cbgystart = tlcbgystart + (precno / res->prctno[0]) * (1 << cbgheightexpn); + int cbgzstart = tlcbgzstart + (precno / (res->prctno[0] * res->prctno[1])) * (1 << cbglengthexpn); + int cbgxend = cbgxstart + (1 << cbgwidthexpn); + int cbgyend = cbgystart + (1 << cbgheightexpn); + int cbgzend = cbgzstart + (1 << cbglengthexpn); + + opj_tcd_precinct_t *prc = &band->precincts[precno]; + /* precinct size (global) */ + prc->x0 = int_max(cbgxstart, band->x0); + prc->y0 = int_max(cbgystart, band->y0); + prc->z0 = int_max(cbgzstart, band->z0); + prc->x1 = int_min(cbgxend, band->x1); + prc->y1 = int_min(cbgyend, band->y1); + prc->z1 = int_min(cbgzend, band->z1); + + tlcblkxstart = int_floordivpow2(prc->x0, cblkwidthexpn) << cblkwidthexpn; + tlcblkystart = int_floordivpow2(prc->y0, cblkheightexpn) << cblkheightexpn; + tlcblkzstart = int_floordivpow2(prc->z0, cblklengthexpn) << cblklengthexpn; + brcblkxend = int_ceildivpow2(prc->x1, cblkwidthexpn) << cblkwidthexpn; + brcblkyend = int_ceildivpow2(prc->y1, cblkheightexpn) << cblkheightexpn; + brcblkzend = int_ceildivpow2(prc->z1, cblklengthexpn) << cblklengthexpn; + prc->cblkno[0] = (brcblkxend - tlcblkxstart) >> cblkwidthexpn; + prc->cblkno[1] = (brcblkyend - tlcblkystart) >> cblkheightexpn; + prc->cblkno[2] = (brcblkzend - tlcblkzstart) >> cblklengthexpn; + prc->cblkno[2] = (prc->cblkno[2] == 0) ? 1 : prc->cblkno[2]; + + prc->cblks = (opj_tcd_cblk_t *) opj_malloc((prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]) * sizeof(opj_tcd_cblk_t)); + prc->incltree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); + prc->imsbtree = tgt_create(prc->cblkno[0], prc->cblkno[1], prc->cblkno[2]); + + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + int cblkxstart = tlcblkxstart + (cblkno % prc->cblkno[0]) * (1 << cblkwidthexpn); + int cblkystart = tlcblkystart + ((cblkno % (prc->cblkno[0] * prc->cblkno[1])) / prc->cblkno[0]) * (1 << cblkheightexpn); + int cblkzstart = tlcblkzstart + (cblkno / (prc->cblkno[0] * prc->cblkno[1])) * (1 << cblklengthexpn); + int cblkxend = cblkxstart + (1 << cblkwidthexpn); + int cblkyend = cblkystart + (1 << cblkheightexpn); + int cblkzend = cblkzstart + (1 << cblklengthexpn); + int prec = ((tilec->bpp > 16) ? 3 : ((tilec->bpp > 8) ? 2 : 1)); + /* code-block size (global) */ + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + + /* code-block size (global) */ + cblk->x0 = int_max(cblkxstart, prc->x0); + cblk->y0 = int_max(cblkystart, prc->y0); + cblk->z0 = int_max(cblkzstart, prc->z0); + cblk->x1 = int_min(cblkxend, prc->x1); + cblk->y1 = int_min(cblkyend, prc->y1); + cblk->z1 = int_min(cblkzend, prc->z1); + } + } /* precno */ + } /* bandno */ + } /* resno */ + } /* compno */ + } /* i = 0..cp->tileno_size */ + + /*tcd_dump(stdout, tcd, tcd->tcd_volume);*/ + + /* + Allocate place to store the decoded data = final volume + Place limited by the tile really present in the codestream + */ + + for (i = 0; i < volume->numcomps; i++) { + for (j = 0; j < cp->tileno_size; j++) { + tileno = cp->tileno[j]; + x0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].x0 : int_min(x0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].x0); + y0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].y0 : int_min(y0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].y0); + z0 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].z0 : int_min(z0,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].z0); + x1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].x1 : int_max(x1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].x1); + y1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].y1 : int_max(y1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].y1); + z1 = (j == 0) ? tcd->tcd_volume->tiles[tileno].comps[i].z1 : int_max(z1,(unsigned int) tcd->tcd_volume->tiles[tileno].comps[i].z1); + } + + w = x1 - x0; + h = y1 - y0; + l = z1 - z0; + + volume->comps[i].data = (int *) opj_malloc(w * h * l * sizeof(int)); + volume->comps[i].w = w; + volume->comps[i].h = h; + volume->comps[i].l = l; + volume->comps[i].x0 = x0; + volume->comps[i].y0 = y0; + volume->comps[i].z0 = z0; + volume->comps[i].bigendian = cp->bigendian; + } +} + +void tcd_free_decode(opj_tcd_t *tcd) { + int tileno,compno,resno,bandno,precno; + + opj_tcd_volume_t *tcd_volume = tcd->tcd_volume; + + for (tileno = 0; tileno < tcd_volume->tw * tcd_volume->th * tcd_volume->tl; tileno++) { + opj_tcd_tile_t *tile = &tcd_volume->tiles[tileno]; + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->prctno[1] * res->prctno[0] * res->prctno[2]; precno++) { + opj_tcd_precinct_t *prec = &band->precincts[precno]; + if (prec->cblks != NULL) opj_free(prec->cblks); + if (prec->imsbtree != NULL) tgt_destroy(prec->imsbtree); + if (prec->incltree != NULL) tgt_destroy(prec->incltree); + /*for (treeno = 0; treeno < prec->numtrees; treeno++){ + if (prec->imsbtree[treeno] != NULL) tgt_destroy(prec->imsbtree[treeno]); + if (prec->incltree[treeno] != NULL) tgt_destroy(prec->incltree[treeno]); + }*/ + } + if (band->precincts != NULL) opj_free(band->precincts); + } + } + if (tilec->resolutions != NULL) opj_free(tilec->resolutions); + } + if (tile->comps != NULL) opj_free(tile->comps); + } + + if (tcd_volume->tiles != NULL) opj_free(tcd_volume->tiles); +} + + + +/* ----------------------------------------------------------------------- */ +void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final) { + int compno, resno, bandno, precno, cblkno; + int value; /*, matrice[tcd_tcp->numlayers][tcd_tile->comps[0].numresolution[0]][3]; */ + int matrice[10][10][3]; + int i, j, k; + + opj_cp_t *cp = tcd->cp; + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + opj_tcp_t *tcd_tcp = tcd->tcp; + + /*matrice=(int*)opj_malloc(tcd_tcp->numlayers*tcd_tile->comps[0].numresolution[0]*3*sizeof(int)); */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + for (i = 0; i < tcd_tcp->numlayers; i++) { + for (j = 0; j < tilec->numresolution[0]; j++) { + for (k = 0; k < 3; k++) { + matrice[i][j][k] = + (int) (cp->matrice[i * tilec->numresolution[0] * 3 + j * 3 + k] + * (float) (tcd->volume->comps[compno].prec / 16.0)); + } + } + } + + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + int n; + int imsb = tcd->volume->comps[compno].prec - cblk->numbps; /* number of bit-plan equal to zero */ + /* Correction of the matrix of coefficient to include the IMSB information */ + if (layno == 0) { + value = matrice[layno][resno][bandno]; + if (imsb >= value) { + value = 0; + } else { + value -= imsb; + } + } else { + value = matrice[layno][resno][bandno] - matrice[layno - 1][resno][bandno]; + if (imsb >= matrice[layno - 1][resno][bandno]) { + value -= (imsb - matrice[layno - 1][resno][bandno]); + if (value < 0) { + value = 0; + } + } + } + + if (layno == 0) { + cblk->numpassesinlayers = 0; + } + + n = cblk->numpassesinlayers; + if (cblk->numpassesinlayers == 0) { + if (value != 0) { + n = 3 * value - 2 + cblk->numpassesinlayers; + } else { + n = cblk->numpassesinlayers; + } + } else { + n = 3 * value + cblk->numpassesinlayers; + } + + layer->numpasses = n - cblk->numpassesinlayers; + + if (!layer->numpasses) + continue; + + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + } else { + layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate; + } + if (final) + cblk->numpassesinlayers = n; + } + } + } + } + } +} + +void tcd_rateallocate_fixed(opj_tcd_t *tcd) { + int layno; + for (layno = 0; layno < tcd->tcp->numlayers; layno++) { + tcd_makelayer_fixed(tcd, layno, 1); + } +} + +void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final) { + int compno, resno, bandno, precno, cblkno, passno; + + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + + tcd_tile->distolayer[layno] = 0; /* fixed_quality */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + opj_tcd_layer_t *layer = &cblk->layers[layno]; + + int n; + if (layno == 0) { + cblk->numpassesinlayers = 0; + } + n = cblk->numpassesinlayers; + for (passno = cblk->numpassesinlayers; passno < cblk->totalpasses; passno++) { + int dr; + double dd; + opj_tcd_pass_t *pass = &cblk->passes[passno]; + if (n == 0) { + dr = pass->rate; + dd = pass->distortiondec; + } else { + dr = pass->rate - cblk->passes[n - 1].rate; + dd = pass->distortiondec - cblk->passes[n - 1].distortiondec; + } + if (!dr) { + if (dd) + n = passno + 1; + continue; + } + if (dd / dr >= thresh){ + n = passno + 1; + } + } + layer->numpasses = n - cblk->numpassesinlayers; + + if (!layer->numpasses) { + layer->disto = 0; + continue; + } + if (cblk->numpassesinlayers == 0) { + layer->len = cblk->passes[n - 1].rate; + layer->data = cblk->data; + layer->disto = cblk->passes[n - 1].distortiondec; + } else { + layer->len = cblk->passes[n - 1].rate - cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->data = cblk->data + cblk->passes[cblk->numpassesinlayers - 1].rate; + layer->disto = cblk->passes[n - 1].distortiondec - cblk->passes[cblk->numpassesinlayers - 1].distortiondec; + } + + tcd_tile->distolayer[layno] += layer->disto; /* fixed_quality */ + + if (final) + cblk->numpassesinlayers = n; + + /* fprintf(stdout,"MakeLayer : %d %f %d %d \n",layer->len, layer->disto, layer->numpasses, n);*/ + } + } + } + } + } +} + +bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_volume_info_t * volume_info) { + int compno, resno, bandno, precno, cblkno, passno, layno; + double min, max; + double cumdisto[100]; /* fixed_quality */ + const double K = 1; /* 1.1; // fixed_quality */ + double maxSE = 0; + + opj_cp_t *cp = tcd->cp; + opj_tcd_tile_t *tcd_tile = tcd->tcd_tile; + opj_tcp_t *tcd_tcp = tcd->tcp; + + min = DBL_MAX; + max = 0; + + tcd_tile->nbpix = 0; /* fixed_quality */ + + for (compno = 0; compno < tcd_tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tcd_tile->comps[compno]; + tilec->nbpix = 0; + for (resno = 0; resno < tilec->numresolution[0]; resno++) { + opj_tcd_resolution_t *res = &tilec->resolutions[resno]; + for (bandno = 0; bandno < res->numbands; bandno++) { + opj_tcd_band_t *band = &res->bands[bandno]; + for (precno = 0; precno < res->prctno[0] * res->prctno[1] * res->prctno[2]; precno++) { + opj_tcd_precinct_t *prc = &band->precincts[precno]; + for (cblkno = 0; cblkno < prc->cblkno[0] * prc->cblkno[1] * prc->cblkno[2]; cblkno++) { + opj_tcd_cblk_t *cblk = &prc->cblks[cblkno]; + for (passno = 0; passno < cblk->totalpasses; passno++) { + opj_tcd_pass_t *pass = &cblk->passes[passno]; + int dr; + double dd, rdslope; + if (passno == 0) { + dr = pass->rate; + dd = pass->distortiondec; + } else { + dr = pass->rate - cblk->passes[passno - 1].rate; + dd = pass->distortiondec - cblk->passes[passno - 1].distortiondec; + } + if (dr == 0) { + continue; + } + rdslope = dd / dr; + if (rdslope < min) { + min = rdslope; + } + if (rdslope > max) { + max = rdslope; + } + + } /* passno */ + + /* fixed_quality */ + tcd_tile->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0)); + tilec->nbpix += ((cblk->x1 - cblk->x0) * (cblk->y1 - cblk->y0) * (cblk->z1 - cblk->z0)); + } /* cbklno */ + } /* precno */ + } /* bandno */ + } /* resno */ + + maxSE += (((double)(1 << tcd->volume->comps[compno].prec) - 1.0) + * ((double)(1 << tcd->volume->comps[compno].prec) -1.0)) + * ((double)(tilec->nbpix)); + } /* compno */ + + /* add antonin index */ + if(volume_info && volume_info->index_on) { + opj_tile_info_t *info_TL = &volume_info->tile[tcd->tcd_tileno]; + info_TL->nbpix = tcd_tile->nbpix; + info_TL->distotile = tcd_tile->distotile; + info_TL->thresh = (double *) opj_malloc(tcd_tcp->numlayers * sizeof(double)); + } + /* dda */ + + for (layno = 0; layno < tcd_tcp->numlayers; layno++) { + double lo = min; + double hi = max; + int success = 0; + int maxlen = tcd_tcp->rates[layno] ? int_min(((int) tcd_tcp->rates[layno]), len) : len; + double goodthresh; + double distotarget; /* fixed_quality */ + int i = 0; + + /* fixed_quality */ + distotarget = tcd_tile->distotile - ((K * maxSE) / pow((float)10, tcd_tcp->distoratio[layno] / 10)); + + if ((tcd_tcp->rates[layno]) || (cp->disto_alloc==0)) { + opj_t2_t *t2 = t2_create(tcd->cinfo, tcd->volume, cp); + int oldl = 0, oldoldl = 0; + for (i = 0; i < 128; i++) { + double thresh = (lo + hi) / 2; + int l = 0; + double distoachieved = 0; /* fixed_quality -q */ + + tcd_makelayer(tcd, layno, thresh, 0); + + if (cp->fixed_quality) { /* fixed_quality -q */ + distoachieved = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno]; + if (distoachieved < distotarget) { + hi = thresh; + continue; + } + lo = thresh; + } else { /* disto_alloc -r, fixed_alloc -f */ + l = t2_encode_packets(t2, tcd->tcd_tileno, tcd_tile, layno + 1, dest, maxlen, volume_info); + /*fprintf(stdout, "layno %d i %d len=%d max=%d \n",layno,i,l,maxlen);*/ + if (l == -999) { + lo = thresh; + continue; + } else if (l == oldl && oldl == oldoldl && tcd_tile->distolayer[layno] > 0.0 && i>32) + break; + hi = thresh; + oldoldl = oldl; + oldl = l; + } + success = 1; + goodthresh = thresh; + } + t2_destroy(t2); + } else { + success = 1; + goodthresh = min; + } + if (!success) { + return false; + } + + if(volume_info && volume_info->index_on) { /* Threshold for Marcela Index */ + volume_info->tile[tcd->tcd_tileno].thresh[layno] = goodthresh; + } + tcd_makelayer(tcd, layno, goodthresh, 1); + + /* fixed_quality */ + cumdisto[layno] = (layno == 0) ? tcd_tile->distolayer[0] : cumdisto[layno - 1] + tcd_tile->distolayer[layno]; + } + + return true; +} + +/* ----------------------------------------------------------------------- */ +int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_volume_info_t * volume_info) { + int compno; + int l, i, npck = 0; + double encoding_time; + + opj_tcd_tile_t *tile = NULL; + opj_tcp_t *tcd_tcp = NULL; + opj_cp_t *cp = NULL; + + opj_tcp_t *tcp = &tcd->cp->tcps[0]; + opj_tccp_t *tccp = &tcp->tccps[0]; + opj_volume_t *volume = tcd->volume; + opj_t2_t *t2 = NULL; /* T2 component */ + + tcd->tcd_tileno = tileno; /* current encoded/decoded tile */ + + tcd->tcd_tile = tcd->tcd_volume->tiles; /* tile information */ + tile = tcd->tcd_tile; + + tcd->tcp = &tcd->cp->tcps[tileno]; /* coding/decoding params of tileno */ + tcd_tcp = tcd->tcp; + + cp = tcd->cp; /* coding parameters */ + + /* INDEX >> */ + if(volume_info && volume_info->index_on) { + opj_tcd_tilecomp_t *tilec_idx = &tile->comps[0]; /* based on component 0 */ + for (i = 0; i < tilec_idx->numresolution[0]; i++) { + opj_tcd_resolution_t *res_idx = &tilec_idx->resolutions[i]; + + volume_info->tile[tileno].prctno[0][i] = res_idx->prctno[0]; + volume_info->tile[tileno].prctno[1][i] = res_idx->prctno[1]; + volume_info->tile[tileno].prctno[2][i] = res_idx->prctno[2]; + + npck += res_idx->prctno[0] * res_idx->prctno[1] * res_idx->prctno[2]; + + volume_info->tile[tileno].prctsiz[0][i] = tccp->prctsiz[0][i]; + volume_info->tile[tileno].prctsiz[1][i] = tccp->prctsiz[1][i]; + volume_info->tile[tileno].prctsiz[2][i] = tccp->prctsiz[2][i]; + } + volume_info->tile[tileno].packet = (opj_packet_info_t *) opj_malloc(volume_info->comp * volume_info->layer * npck * sizeof(opj_packet_info_t)); + } + /* << INDEX */ + + /*---------------TILE-------------------*/ + encoding_time = opj_clock(); /* time needed to encode a tile */ + + for (compno = 0; compno < tile->numcomps; compno++) { + int x, y, z; + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + + int adjust; + int offset_x = int_ceildiv(volume->x0, volume->comps[compno].dx); /*ceil(x0 / subsampling_dx)*/ + int offset_y = int_ceildiv(volume->y0, volume->comps[compno].dy); + int offset_z = int_ceildiv(volume->z0, volume->comps[compno].dz); + + int tw = tilec->x1 - tilec->x0; + int w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx); + int th = tilec->y1 - tilec->y0; + int h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy); + int tl = tilec->z1 - tilec->z0; + int l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz); + + + + /* extract tile data from volume.comps[0].data to tile.comps[0].data */ + /*fprintf(stdout,"[INFO] Extract tile data\n");*/ + if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) { + adjust = 0; + } else { + adjust = volume->comps[compno].sgnd ? 0 : 1 << (volume->comps[compno].prec - 1); /*sign=='+' --> 2^(prec-1)*/ + if (volume->comps[compno].dcoffset != 0){ + adjust += volume->comps[compno].dcoffset; + fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",volume->comps[compno].dcoffset,adjust); + } + } + + if (tcd_tcp->tccps[compno].reversible == 1) { /*IF perfect reconstruction (DWT.5-3)*/ + for (z = tilec->z0; z < tilec->z1; z++) { + for (y = tilec->y0; y < tilec->y1; y++) { + /* start of the src tile scanline */ + int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h]; + /* start of the dst tile scanline */ + int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th]; + for (x = tilec->x0; x < tilec->x1; x++) { + *tile_data++ = *data++ - adjust; + } + } + } + } else if (tcd_tcp->tccps[compno].reversible == 0) { /*IF not (DWT.9-7)*/ + for (z = tilec->z0; z < tilec->z1; z++) { + for (y = tilec->y0; y < tilec->y1; y++) { + /* start of the src tile scanline */ + int *data = &volume->comps[compno].data[(tilec->x0 - offset_x) + (y - offset_y) * w + (z - offset_z) * w * h]; + /* start of the dst tile scanline */ + int *tile_data = &tilec->data[(y - tilec->y0) * tw + (z - tilec->z0) * tw * th]; + for (x = tilec->x0; x < tilec->x1; x++) { + *tile_data++ = (*data++ - adjust) << 13; + } + } + } + } + + } + + /*----------------MCT-------------------*/ + if (tcd_tcp->mct) { + int samples = (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) * (tile->comps[0].z1 - tile->comps[0].z0); + fprintf(stdout,"[INFO] Tcd_encode_tile: mct\n"); + if (tcd_tcp->tccps[0].reversible == 0) { + mct_encode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples); + } else { + mct_encode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, samples); + } + } + /*----------------TRANSFORM---------------------------------*/ + fprintf(stdout,"[INFO] Tcd_encode_tile: Transform\n"); + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + dwt_encode(tilec, tcd_tcp->tccps[compno].dwtid); + } + + /*-------------------ENTROPY CODING-----------------------------*/ + fprintf(stdout,"[INFO] Tcd_encode_tile: Entropy coding\n"); + if ((cp->encoding_format == ENCOD_2EB)||(cp->encoding_format == ENCOD_3EB)) + { + if (cp->encoding_format == ENCOD_2EB) { + opj_t1_t *t1 = NULL; + t1 = t1_create(tcd->cinfo); + t1_encode_cblks(t1, tile, tcd_tcp); + t1_destroy(t1); + } else if (cp->encoding_format == ENCOD_3EB) { + opj_t1_3d_t *t1 = NULL; + t1 = t1_3d_create(tcd->cinfo); + t1_3d_encode_cblks(t1, tile, tcd_tcp); + t1_3d_destroy(t1); + } + /*-----------RATE-ALLOCATE------------------*/ + /* INDEX */ + if(volume_info) { + volume_info->index_write = 0; + } + if (cp->disto_alloc || cp->fixed_quality) { + fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate\n"); + tcd_rateallocate(tcd, dest, len, volume_info); /* Normal Rate/distortion allocation */ + } else {/* fixed_alloc */ + fprintf(stdout,"[INFO] Tcd_encode_tile: Rate-allocate fixed\n"); + tcd_rateallocate_fixed(tcd); /* Fixed layer allocation */ + } + + /*--------------TIER2------------------*/ + /* INDEX */ + if(volume_info) { + volume_info->index_write = 1; + } + fprintf(stdout,"[INFO] Tcd_encode_tile: Tier - 2\n"); + t2 = t2_create(tcd->cinfo, volume, cp); + l = t2_encode_packets(t2, tileno, tile, tcd_tcp->numlayers, dest, len, volume_info); + t2_destroy(t2); + } else if ((cp->encoding_format == ENCOD_2GR)||(cp->encoding_format == ENCOD_3GR)) { + /*if(volume_info) { + volume_info->index_write = 1; + } + gr = golomb_create(tcd->cinfo, volume, cp); + l = golomb_encode(gr, tileno, tile, dest, len, volume_info); + golomb_destroy(gr);*/ + } + + + /*---------------CLEAN-------------------*/ + fprintf(stdout,"[INFO] Tcd_encode_tile: %d bytes coded\n",l); + encoding_time = opj_clock() - encoding_time; + opj_event_msg(tcd->cinfo, EVT_INFO, "- tile encoded in %f s\n", encoding_time); + + /* cleaning memory */ + for (compno = 0; compno < tile->numcomps; compno++) { + tcd->tilec = &tile->comps[compno]; + opj_free(tcd->tilec->data); + } + + if (l == -999){ + fprintf(stdout,"[ERROR] Unable to perform T2 tier. Return -999.\n"); + return 0; + } + + return l; +} + + +bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno) { + int l, i; + int compno, eof = 0; + double tile_time, t1_time, dwt_time; + + opj_tcd_tile_t *tile = NULL; + opj_t2_t *t2 = NULL; /* T2 component */ + + tcd->tcd_tileno = tileno; + tcd->tcd_tile = &(tcd->tcd_volume->tiles[tileno]); + tcd->tcp = &(tcd->cp->tcps[tileno]); + tile = tcd->tcd_tile; + + tile_time = opj_clock(); /* time needed to decode a tile */ + opj_event_msg(tcd->cinfo, EVT_INFO, "tile %d / %d\n", tileno + 1, tcd->cp->tw * tcd->cp->th * tcd->cp->tl); + + if ((tcd->cp->encoding_format == ENCOD_2EB) || (tcd->cp->encoding_format == ENCOD_3EB)) { + /*--------------TIER2------------------*/ + t2 = t2_create(tcd->cinfo, tcd->volume, tcd->cp); + l = t2_decode_packets(t2, src, len, tileno, tile); + t2_destroy(t2); + opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: %d bytes decoded\n",l); + + if (l == -999) { + eof = 1; + opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n"); + } + + /*------------------TIER1-----------------*/ + opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding %d \n",tcd->cp->encoding_format); + t1_time = opj_clock(); /* time needed to decode a tile */ + if (tcd->cp->encoding_format == ENCOD_2EB) { + opj_t1_t *t1 = NULL; /* T1 component */ + t1 = t1_create(tcd->cinfo); + t1_decode_cblks(t1, tile, tcd->tcp); + t1_destroy(t1); + }else if (tcd->cp->encoding_format == ENCOD_3EB) { + opj_t1_3d_t *t1 = NULL; /* T1 component */ + t1 = t1_3d_create(tcd->cinfo); + t1_3d_decode_cblks(t1, tile, tcd->tcp); + t1_3d_destroy(t1); + } + + t1_time = opj_clock() - t1_time; + #ifdef VERBOSE + opj_event_msg(tcd->cinfo, EVT_INFO, "- tier-1 took %f s\n", t1_time); + #endif + } else if ((tcd->cp->encoding_format == ENCOD_2GR)||(tcd->cp->encoding_format == ENCOD_3GR)) { + opj_event_msg(tcd->cinfo, EVT_INFO, "Tcd_decode_tile: Entropy decoding -- Does nothing :-D\n"); + /* + gr = golomb_create(tcd->cinfo, tcd->volume, tcd->cp); + l = golomb_decode(gr, tileno, tile, src, len); + golomb_destroy(gr); + if (l == -999) { + eof = 1; + opj_event_msg(tcd->cinfo, EVT_ERROR, "Tcd_decode_tile: incomplete bistream\n"); + } + */ + } + + /*----------------DWT---------------------*/ + fprintf(stdout,"[INFO] Tcd_decode_tile: Inverse DWT\n"); + dwt_time = opj_clock(); /* time needed to decode a tile */ + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + int stops[3], dwtid[3]; + + for (i = 0; i < 3; i++) { + if (tcd->cp->reduce[i] != 0) + tcd->volume->comps[compno].resno_decoded[i] = tile->comps[compno].numresolution[i] - tcd->cp->reduce[i] - 1; + stops[i] = tilec->numresolution[i] - 1 - tcd->volume->comps[compno].resno_decoded[i]; + if (stops[i] < 0) stops[i]=0; + dwtid[i] = tcd->cp->tcps->tccps[compno].dwtid[i]; + } + + dwt_decode(tilec, stops, dwtid); + + for (i = 0; i < 3; i++) { + if (tile->comps[compno].numresolution[i] > 0) { + tcd->volume->comps[compno].factor[i] = tile->comps[compno].numresolution[i] - (tcd->volume->comps[compno].resno_decoded[i] + 1); + if ( (tcd->volume->comps[compno].factor[i]) < 0 ) + tcd->volume->comps[compno].factor[i] = 0; + } + } + } + dwt_time = opj_clock() - dwt_time; + #ifdef VERBOSE + opj_event_msg(tcd->cinfo, EVT_INFO, "- dwt took %f s\n", dwt_time); + #endif + + /*----------------MCT-------------------*/ + + if (tcd->tcp->mct) { + if (tcd->tcp->tccps[0].reversible == 1) { + mct_decode(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, + (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0) * (tile->comps[0].z1 - tile->comps[0].z0)); + } else { + mct_decode_real(tile->comps[0].data, tile->comps[1].data, tile->comps[2].data, + (tile->comps[0].x1 - tile->comps[0].x0) * (tile->comps[0].y1 - tile->comps[0].y0)* (tile->comps[0].z1 - tile->comps[0].z0)); + } + } + + /*---------------TILE-------------------*/ + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_tcd_tilecomp_t *tilec = &tile->comps[compno]; + opj_tcd_resolution_t *res = &tilec->resolutions[tcd->volume->comps[compno].resno_decoded[0]]; + int adjust; + int minval = tcd->volume->comps[compno].sgnd ? -(1 << (tcd->volume->comps[compno].prec - 1)) : 0; + int maxval = tcd->volume->comps[compno].sgnd ? (1 << (tcd->volume->comps[compno].prec - 1)) - 1 : (1 << tcd->volume->comps[compno].prec) - 1; + + int tw = tilec->x1 - tilec->x0; + int w = tcd->volume->comps[compno].w; + int th = tilec->y1 - tilec->y0; + int h = tcd->volume->comps[compno].h; + + int i, j, k; + int offset_x = int_ceildivpow2(tcd->volume->comps[compno].x0, tcd->volume->comps[compno].factor[0]); + int offset_y = int_ceildivpow2(tcd->volume->comps[compno].y0, tcd->volume->comps[compno].factor[1]); + int offset_z = int_ceildivpow2(tcd->volume->comps[compno].z0, tcd->volume->comps[compno].factor[2]); + + if (tcd->cp->transform_format == TRF_3D_RLS || tcd->cp->transform_format == TRF_3D_LSE) { + adjust = 0; + } else { + adjust = tcd->volume->comps[compno].sgnd ? 0 : 1 << (tcd->volume->comps[compno].prec - 1); /*sign=='+' --> 2^(prec-1)*/ + if (tcd->volume->comps[compno].dcoffset != 0){ + adjust += tcd->volume->comps[compno].dcoffset; + fprintf(stdout,"[INFO] DC Offset applied: DCO = %d -> adjust = %d\n",tcd->volume->comps[compno].dcoffset,adjust); + } + } + + for (k = res->z0; k < res->z1; k++) { + for (j = res->y0; j < res->y1; j++) { + for (i = res->x0; i < res->x1; i++) { + int v; + float tmp = (float)((tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th]) / 8192.0); + + if (tcd->tcp->tccps[compno].reversible == 1) { + v = tilec->data[i - res->x0 + (j - res->y0) * tw + (k - res->z0) * tw * th]; + } else { + int tmp2 = ((int) (floor(fabs(tmp)))) + ((int) floor(fabs(tmp*2))%2); + v = ((tmp < 0) ? -tmp2:tmp2); + } + v += adjust; + + tcd->volume->comps[compno].data[(i - offset_x) + (j - offset_y) * w + (k - offset_z) * w * h] = int_clamp(v, minval, maxval); + } + } + } + } + + tile_time = opj_clock() - tile_time; /* time needed to decode a tile */ + opj_event_msg(tcd->cinfo, EVT_INFO, "- tile decoded in %f s\n", tile_time); + + for (compno = 0; compno < tile->numcomps; compno++) { + opj_free(tcd->tcd_volume->tiles[tileno].comps[compno].data); + tcd->tcd_volume->tiles[tileno].comps[compno].data = NULL; + } + + if (eof) { + return false; + } + + return true; +} + diff --git a/src/lib/openjp3d/tcd.h b/src/lib/openjp3d/tcd.h old mode 100755 new mode 100644 diff --git a/src/lib/openjp3d/tgt.c b/src/lib/openjp3d/tgt.c old mode 100755 new mode 100644 index 77a751a6..8792995e --- a/src/lib/openjp3d/tgt.c +++ b/src/lib/openjp3d/tgt.c @@ -1,256 +1,251 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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 "opj_includes.h" - -/* -========================================================== - Tag-tree coder interface -========================================================== -*/ -void tgt_tree_dump (FILE *fd, opj_tgt_tree_t * tree){ - int nodesno; - - fprintf(fd, "TGT_TREE {\n"); - fprintf(fd, " numnodes: %d \n", tree->numnodes); - fprintf(fd, " numleafsh: %d, numleafsv: %d, numleafsz: %d,\n", tree->numleafsh, tree->numleafsv, tree->numleafsz); - - for (nodesno = 0; nodesno < tree->numnodes; nodesno++) { - fprintf(fd, "tgt_node %d {\n", nodesno); - fprintf(fd, " value: %d \n", tree->nodes[nodesno].value); - fprintf(fd, " low: %d \n", tree->nodes[nodesno].low); - fprintf(fd, " known: %d \n", tree->nodes[nodesno].known); - if (tree->nodes[nodesno].parent) { - fprintf(fd, " parent.value: %d \n", tree->nodes[nodesno].parent->value); - fprintf(fd, " parent.low: %d \n", tree->nodes[nodesno].parent->low); - fprintf(fd, " parent.known: %d \n", tree->nodes[nodesno].parent->known); - } - fprintf(fd, "}\n"); - - } - fprintf(fd, "}\n"); - -} - - -opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv, int numleafsz) { - - int nplh[32]; - int nplv[32]; - int nplz[32]; - opj_tgt_node_t *node = NULL; - opj_tgt_node_t *parentnode = NULL; - opj_tgt_node_t *parentnode0 = NULL; - opj_tgt_tree_t *tree = NULL; - int i, j, k, p, p0; - int numlvls; - int n, z = 0; - - tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); - if(!tree) - return NULL; - tree->numleafsh = numleafsh; - tree->numleafsv = numleafsv; - tree->numleafsz = numleafsz; - - numlvls = 0; - nplh[0] = numleafsh; - nplv[0] = numleafsv; - nplz[0] = numleafsz; - tree->numnodes = 0; - do { - n = nplh[numlvls] * nplv[numlvls] * nplz[numlvls]; - nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; - nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; - nplz[numlvls + 1] = (nplz[numlvls] + 1) / 2; - tree->numnodes += n; - ++numlvls; - } while (n > 1); - - if (tree->numnodes == 0) { - opj_free(tree); - return NULL; - } - - tree->nodes = (opj_tgt_node_t *) opj_malloc(tree->numnodes * sizeof(opj_tgt_node_t)); - if(!tree->nodes) { - opj_free(tree); - return NULL; - } - - node = tree->nodes; - parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv * tree->numleafsz]; - parentnode0 = parentnode; - - p = tree->numleafsh * tree->numleafsv * tree->numleafsz; - p0 = p; - n = 0; - /*fprintf(stdout,"\nH %d V %d Z %d numlvls %d nodes %d\n",tree->numleafsh,tree->numleafsv,tree->numleafsz,numlvls,tree->numnodes);*/ - for (i = 0; i < numlvls - 1; ++i) { - for (j = 0; j < nplv[i]; ++j) { - k = nplh[i]*nplz[i]; - while (--k >= 0) { - node->parent = parentnode; /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/ - ++node; ++n; - if (--k >= 0 && n < p) { - node->parent = parentnode; /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/ - ++node; ++n; - } - if (nplz[i] != 1){ /*2D operation vs 3D operation*/ - if (--k >= 0 && n < p) { - node->parent = parentnode; /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/ - ++node; ++n; - } - if (--k >= 0 && n < p) { - node->parent = parentnode; /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/ - ++node; ++n; - } - } - ++parentnode; ++p; - } - if ((j & 1) || j == nplv[i] - 1) { - parentnode0 = parentnode; p0 = p; /*fprintf(stdout,"parent = node[%d] \n",p);*/ - } else { - parentnode = parentnode0; p = p0; /*fprintf(stdout,"parent = node[%d] \n",p);*/ - parentnode0 += nplh[i]*nplz[i]; p0 += nplh[i]*nplz[i]; - } - } - } - node->parent = 0; - - - tgt_reset(tree); - - return tree; -} - -void tgt_destroy(opj_tgt_tree_t *tree) { - opj_free(tree->nodes); - opj_free(tree); -} - -void tgt_reset(opj_tgt_tree_t *tree) { - int i; - - if (NULL == tree) - return; - - for (i = 0; i < tree->numnodes; i++) { - tree->nodes[i].value = 999; - tree->nodes[i].low = 0; - tree->nodes[i].known = 0; - } -} - -void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value) { - opj_tgt_node_t *node; - node = &tree->nodes[leafno]; - while (node && node->value > value) { - node->value = value; - node = node->parent; - } -} - -void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { - opj_tgt_node_t *stk[31]; - opj_tgt_node_t **stkptr; - opj_tgt_node_t *node; - int low; - - stkptr = stk; - node = &tree->nodes[leafno]; - while (node->parent) { - *stkptr++ = node; - node = node->parent; - } - - low = 0; - for (;;) { - if (low > node->low) { - node->low = low; - } else { - low = node->low; - } - - while (low < threshold) { - if (low >= node->value) { - if (!node->known) { - bio_write(bio, 1, 1); - node->known = 1; - } - break; - } - bio_write(bio, 0, 1); - ++low; - } - - node->low = low; - if (stkptr == stk) - break; - node = *--stkptr; - } -} - -int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { - opj_tgt_node_t *stk[31]; - opj_tgt_node_t **stkptr; - opj_tgt_node_t *node; - int low; - - stkptr = stk; - node = &tree->nodes[leafno]; - while (node->parent) { - *stkptr++ = node; - node = node->parent; - } - - low = 0; - for (;;) { - if (low > node->low) { - node->low = low; - } else { - low = node->low; - } - while (low < threshold && low < node->value) { - if (bio_read(bio, 1)) { - node->value = low; - } else { - ++low; - } - } - node->low = low; - if (stkptr == stk) { - break; - } - node = *--stkptr; - } - - return (node->value < threshold) ? 1 : 0; -} +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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 "opj_includes.h" + +/* +========================================================== + Tag-tree coder interface +========================================================== +*/ +void tgt_tree_dump (FILE *fd, opj_tgt_tree_t * tree){ + int nodesno; + + fprintf(fd, "TGT_TREE {\n"); + fprintf(fd, " numnodes: %d \n", tree->numnodes); + fprintf(fd, " numleafsh: %d, numleafsv: %d, numleafsz: %d,\n", tree->numleafsh, tree->numleafsv, tree->numleafsz); + + for (nodesno = 0; nodesno < tree->numnodes; nodesno++) { + fprintf(fd, "tgt_node %d {\n", nodesno); + fprintf(fd, " value: %d \n", tree->nodes[nodesno].value); + fprintf(fd, " low: %d \n", tree->nodes[nodesno].low); + fprintf(fd, " known: %d \n", tree->nodes[nodesno].known); + if (tree->nodes[nodesno].parent) { + fprintf(fd, " parent.value: %d \n", tree->nodes[nodesno].parent->value); + fprintf(fd, " parent.low: %d \n", tree->nodes[nodesno].parent->low); + fprintf(fd, " parent.known: %d \n", tree->nodes[nodesno].parent->known); + } + fprintf(fd, "}\n"); + + } + fprintf(fd, "}\n"); + +} + + +opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv, int numleafsz) { + + int nplh[32]; + int nplv[32]; + int nplz[32]; + opj_tgt_node_t *node = NULL; + opj_tgt_node_t *parentnode = NULL; + opj_tgt_node_t *parentnode0 = NULL; + opj_tgt_node_t *parentnode1 = NULL; + opj_tgt_tree_t *tree = NULL; + int i, j, k, p, p0; + int numlvls; + int n, z = 0; + + tree = (opj_tgt_tree_t *) opj_malloc(sizeof(opj_tgt_tree_t)); + if(!tree) + return NULL; + tree->numleafsh = numleafsh; + tree->numleafsv = numleafsv; + tree->numleafsz = numleafsz; + + numlvls = 0; + nplh[0] = numleafsh; + nplv[0] = numleafsv; + nplz[0] = numleafsz; + tree->numnodes = 0; + do { + n = nplh[numlvls] * nplv[numlvls] * nplz[numlvls]; + nplh[numlvls + 1] = (nplh[numlvls] + 1) / 2; + nplv[numlvls + 1] = (nplv[numlvls] + 1) / 2; + nplz[numlvls + 1] = (nplz[numlvls] + 1) / 2; + tree->numnodes += n; + ++numlvls; + } while (n > 1); + + if (tree->numnodes == 0) { + opj_free(tree); + return NULL; + } + + tree->nodes = (opj_tgt_node_t *) opj_malloc(tree->numnodes * sizeof(opj_tgt_node_t)); + if(!tree->nodes) { + opj_free(tree); + return NULL; + } + + node = tree->nodes; + parentnode = &tree->nodes[tree->numleafsh * tree->numleafsv * tree->numleafsz]; + parentnode0 = parentnode; + parentnode1 = parentnode; + /*fprintf(stdout,"\nH %d V %d Z %d numlvls %d nodes %d\n",tree->numleafsh,tree->numleafsv,tree->numleafsz,numlvls,tree->numnodes);*/ + for (i = 0; i < numlvls - 1; ++i) { + for (z = 0; z < nplz[i]; ++z) { + for (j = 0; j < nplv[i]; ++j) { + k = nplh[i]; + while(--k >= 0) { + node->parent = parentnode; /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/ + ++node; + if(--k >= 0) { + node->parent = parentnode; /*fprintf(stdout,"node[%d].parent = node[%d]\n",n,p);*/ + ++node; + } + ++parentnode; + } + if((j & 1) || j == nplv[i] - 1) { + parentnode0 = parentnode; + } else { + parentnode = parentnode0; + } + } + if ((z & 1) || z == nplz[i] - 1) { + parentnode1 = parentnode; + } else { + parentnode0 = parentnode1; + parentnode = parentnode1; + } + } + } + node->parent = 0; + + + tgt_reset(tree); + + return tree; +} + +void tgt_destroy(opj_tgt_tree_t *tree) { + opj_free(tree->nodes); + opj_free(tree); +} + +void tgt_reset(opj_tgt_tree_t *tree) { + int i; + + if (NULL == tree) + return; + + for (i = 0; i < tree->numnodes; i++) { + tree->nodes[i].value = 999; + tree->nodes[i].low = 0; + tree->nodes[i].known = 0; + } +} + +void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value) { + opj_tgt_node_t *node; + node = &tree->nodes[leafno]; + while (node && node->value > value) { + node->value = value; + node = node->parent; + } +} + +void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { + opj_tgt_node_t *stk[31]; + opj_tgt_node_t **stkptr; + opj_tgt_node_t *node; + int low; + + stkptr = stk; + node = &tree->nodes[leafno]; + while (node->parent) { + *stkptr++ = node; + node = node->parent; + } + + low = 0; + for (;;) { + if (low > node->low) { + node->low = low; + } else { + low = node->low; + } + + while (low < threshold) { + if (low >= node->value) { + if (!node->known) { + bio_write(bio, 1, 1); + node->known = 1; + } + break; + } + bio_write(bio, 0, 1); + ++low; + } + + node->low = low; + if (stkptr == stk) + break; + node = *--stkptr; + } +} + +int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold) { + opj_tgt_node_t *stk[31]; + opj_tgt_node_t **stkptr; + opj_tgt_node_t *node; + int low; + + stkptr = stk; + node = &tree->nodes[leafno]; + while (node->parent) { + *stkptr++ = node; + node = node->parent; + } + + low = 0; + for (;;) { + if (low > node->low) { + node->low = low; + } else { + low = node->low; + } + while (low < threshold && low < node->value) { + if (bio_read(bio, 1)) { + node->value = low; + } else { + ++low; + } + } + node->low = low; + if (stkptr == stk) { + break; + } + node = *--stkptr; + } + + return (node->value < threshold) ? 1 : 0; +} diff --git a/src/lib/openjp3d/tgt.h b/src/lib/openjp3d/tgt.h old mode 100755 new mode 100644 index 2b54baf9..4565ad22 --- a/src/lib/openjp3d/tgt.h +++ b/src/lib/openjp3d/tgt.h @@ -1,125 +1,125 @@ -/* - * Copyright (c) 2001-2003, David Janssens - * Copyright (c) 2002-2003, Yannick Verschueren - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2002-2005, 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. - */ - -#ifndef __TGT_H -#define __TGT_H -/** -@file tgt.h -@brief Implementation of a tag-tree coder (TGT) - -The functions in TGT.C have for goal to realize a tag-tree coder. The functions in TGT.C -are used by some function in T2.C. -*/ - -/** @defgroup TGT TGT - Implementation of a tag-tree coder */ -/*@{*/ - -/** -Tag node -*/ -typedef struct opj_tgt_node { -/** Node parent reference */ - struct opj_tgt_node *parent; -/** */ - int value; -/** */ - int low; -/** */ - int known; -} opj_tgt_node_t; - -/** -Tag tree -*/ -typedef struct opj_tgt_tree { -/** Number of leaves from horizontal axis */ - int numleafsh; -/** Number of leaves from vertical axis */ - int numleafsv; -/** Number of leaves from axial axis */ - int numleafsz; -/** Number of nodes */ - int numnodes; -/** Reference to each node instance */ - opj_tgt_node_t *nodes; -} opj_tgt_tree_t; - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Create a tag-tree -@param numleafsh Width of the array of leafs of the tree -@param numleafsv Height of the array of leafs of the tree -@param numleafsz Depth of the array of leafs of the tree -@return Returns a new tag-tree if successful, returns NULL otherwise -*/ -opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv, int numleafsz); -/** -Destroy a tag-tree, liberating memory -@param tree Tag-tree to destroy -*/ -void tgt_destroy(opj_tgt_tree_t *tree); -/** -Reset a tag-tree (set all leaves to 0) -@param tree Tag-tree to reset -*/ -void tgt_reset(opj_tgt_tree_t *tree); -/** -Set the value of a leaf of a tag-tree -@param tree Tag-tree to modify -@param leafno Number that identifies the leaf to modify -@param value New value of the leaf -*/ -void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value); -/** -Encode the value of a leaf of the tag-tree up to a given threshold -@param bio Pointer to a BIO handle -@param tree Tag-tree to modify -@param leafno Number that identifies the leaf to encode -@param threshold Threshold to use when encoding value of the leaf -*/ -void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold); -/** -Decode the value of a leaf of the tag-tree up to a given threshold -@param bio Pointer to a BIO handle -@param tree Tag-tree to decode -@param leafno Number that identifies the leaf to decode -@param threshold Threshold to use when decoding value of the leaf -@return Returns 1 if the node's value < threshold, returns 0 otherwise -*/ -int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold); - -/*@}*/ -/* ----------------------------------------------------------------------- */ -void tgt_tree_dump (FILE *fd, opj_tgt_tree_t * tree); -/*@}*/ - -#endif /* __TGT_H */ +/* + * Copyright (c) 2001-2003, David Janssens + * Copyright (c) 2002-2003, Yannick Verschueren + * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2002-2005, 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. + */ + +#ifndef __TGT_H +#define __TGT_H +/** +@file tgt.h +@brief Implementation of a tag-tree coder (TGT) + +The functions in TGT.C have for goal to realize a tag-tree coder. The functions in TGT.C +are used by some function in T2.C. +*/ + +/** @defgroup TGT TGT - Implementation of a tag-tree coder */ +/*@{*/ + +/** +Tag node +*/ +typedef struct opj_tgt_node { +/** Node parent reference */ + struct opj_tgt_node *parent; +/** */ + int value; +/** */ + int low; +/** */ + int known; +} opj_tgt_node_t; + +/** +Tag tree +*/ +typedef struct opj_tgt_tree { +/** Number of leaves from horizontal axis */ + int numleafsh; +/** Number of leaves from vertical axis */ + int numleafsv; +/** Number of leaves from axial axis */ + int numleafsz; +/** Number of nodes */ + int numnodes; +/** Reference to each node instance */ + opj_tgt_node_t *nodes; +} opj_tgt_tree_t; + +/** @name Funciones generales */ +/*@{*/ +/* ----------------------------------------------------------------------- */ +/** +Create a tag-tree +@param numleafsh Width of the array of leafs of the tree +@param numleafsv Height of the array of leafs of the tree +@param numleafsz Depth of the array of leafs of the tree +@return Returns a new tag-tree if successful, returns NULL otherwise +*/ +opj_tgt_tree_t *tgt_create(int numleafsh, int numleafsv, int numleafsz); +/** +Destroy a tag-tree, liberating memory +@param tree Tag-tree to destroy +*/ +void tgt_destroy(opj_tgt_tree_t *tree); +/** +Reset a tag-tree (set all leaves to 0) +@param tree Tag-tree to reset +*/ +void tgt_reset(opj_tgt_tree_t *tree); +/** +Set the value of a leaf of a tag-tree +@param tree Tag-tree to modify +@param leafno Number that identifies the leaf to modify +@param value New value of the leaf +*/ +void tgt_setvalue(opj_tgt_tree_t *tree, int leafno, int value); +/** +Encode the value of a leaf of the tag-tree up to a given threshold +@param bio Pointer to a BIO handle +@param tree Tag-tree to modify +@param leafno Number that identifies the leaf to encode +@param threshold Threshold to use when encoding value of the leaf +*/ +void tgt_encode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold); +/** +Decode the value of a leaf of the tag-tree up to a given threshold +@param bio Pointer to a BIO handle +@param tree Tag-tree to decode +@param leafno Number that identifies the leaf to decode +@param threshold Threshold to use when decoding value of the leaf +@return Returns 1 if the node's value < threshold, returns 0 otherwise +*/ +int tgt_decode(opj_bio_t *bio, opj_tgt_tree_t *tree, int leafno, int threshold); + +/*@}*/ +/* ----------------------------------------------------------------------- */ +void tgt_tree_dump (FILE *fd, opj_tgt_tree_t * tree); +/*@}*/ + +#endif /* __TGT_H */ diff --git a/src/lib/openjp3d/volume.c b/src/lib/openjp3d/volume.c old mode 100755 new mode 100644 index 065a7a34..669b613b --- a/src/lib/openjp3d/volume.c +++ b/src/lib/openjp3d/volume.c @@ -1,91 +1,91 @@ -/* - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * 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 "volume.h" -#include "openjp3d.h" - -opj_volume_t* OPJ_CALLCONV opj_volume_create(int numcmpts, opj_volume_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) { - int compno; - opj_volume_t *volume = NULL; - - volume = (opj_volume_t*)opj_malloc(sizeof(opj_volume_t)); - if(volume) { - volume->color_space = clrspc; - volume->numcomps = numcmpts; - /* allocate memory for the per-component information */ - volume->comps = (opj_volume_comp_t*)opj_malloc(volume->numcomps * sizeof(opj_volume_comp_t)); - if(!volume->comps) { - opj_volume_destroy(volume); - return NULL; - } - /* create the individual volume components */ - for(compno = 0; compno < numcmpts; compno++) { - opj_volume_comp_t *comp = &volume->comps[compno]; - comp->dx = cmptparms[compno].dx; - comp->dy = cmptparms[compno].dy; - comp->dz = cmptparms[compno].dz; - comp->w = cmptparms[compno].w; - comp->h = cmptparms[compno].h; - comp->l = cmptparms[compno].l; - comp->x0 = cmptparms[compno].x0; - comp->y0 = cmptparms[compno].y0; - comp->z0 = cmptparms[compno].z0; - comp->prec = cmptparms[compno].prec; - comp->bpp = cmptparms[compno].bpp; - comp->sgnd = cmptparms[compno].sgnd; - comp->bigendian = cmptparms[compno].bigendian; - comp->dcoffset = cmptparms[compno].dcoffset; - comp->data = (int*)opj_malloc(comp->w * comp->h * comp->l * sizeof(int)); - if(!comp->data) { - fprintf(stdout,"Unable to malloc comp->data (%d x %d x %d x bytes)",comp->w,comp->h,comp->l); - opj_volume_destroy(volume); - return NULL; - } - /*fprintf(stdout,"%d %d %d %d %d %d %d %d %d", comp->w,comp->h, comp->l, comp->dx, comp->dy, comp->dz, comp->prec, comp->bpp, comp->sgnd);*/ - } - } - - return volume; -} - -void OPJ_CALLCONV opj_volume_destroy(opj_volume_t *volume) { - int i; - if(volume) { - if(volume->comps) { - /* volume components */ - for(i = 0; i < volume->numcomps; i++) { - opj_volume_comp_t *volume_comp = &volume->comps[i]; - if(volume_comp->data) { - opj_free(volume_comp->data); - } - } - opj_free(volume->comps); - } - opj_free(volume); - } -} - +/* + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * 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 "volume.h" +#include "openjp3d.h" + +opj_volume_t* OPJ_CALLCONV opj_volume_create(int numcmpts, opj_volume_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) { + int compno; + opj_volume_t *volume = NULL; + + volume = (opj_volume_t*)opj_malloc(sizeof(opj_volume_t)); + if(volume) { + volume->color_space = clrspc; + volume->numcomps = numcmpts; + /* allocate memory for the per-component information */ + volume->comps = (opj_volume_comp_t*)opj_malloc(volume->numcomps * sizeof(opj_volume_comp_t)); + if(!volume->comps) { + opj_volume_destroy(volume); + return NULL; + } + /* create the individual volume components */ + for(compno = 0; compno < numcmpts; compno++) { + opj_volume_comp_t *comp = &volume->comps[compno]; + comp->dx = cmptparms[compno].dx; + comp->dy = cmptparms[compno].dy; + comp->dz = cmptparms[compno].dz; + comp->w = cmptparms[compno].w; + comp->h = cmptparms[compno].h; + comp->l = cmptparms[compno].l; + comp->x0 = cmptparms[compno].x0; + comp->y0 = cmptparms[compno].y0; + comp->z0 = cmptparms[compno].z0; + comp->prec = cmptparms[compno].prec; + comp->bpp = cmptparms[compno].bpp; + comp->sgnd = cmptparms[compno].sgnd; + comp->bigendian = cmptparms[compno].bigendian; + comp->dcoffset = cmptparms[compno].dcoffset; + comp->data = (int*)opj_malloc(comp->w * comp->h * comp->l * sizeof(int)); + if(!comp->data) { + fprintf(stdout,"Unable to malloc comp->data (%d x %d x %d x bytes)",comp->w,comp->h,comp->l); + opj_volume_destroy(volume); + return NULL; + } + /*fprintf(stdout,"%d %d %d %d %d %d %d %d %d", comp->w,comp->h, comp->l, comp->dx, comp->dy, comp->dz, comp->prec, comp->bpp, comp->sgnd);*/ + } + } + + return volume; +} + +void OPJ_CALLCONV opj_volume_destroy(opj_volume_t *volume) { + int i; + if(volume) { + if(volume->comps) { + /* volume components */ + for(i = 0; i < volume->numcomps; i++) { + opj_volume_comp_t *volume_comp = &volume->comps[i]; + if(volume_comp->data) { + opj_free(volume_comp->data); + } + } + opj_free(volume->comps); + } + opj_free(volume); + } +} + diff --git a/src/lib/openjp3d/volume.h b/src/lib/openjp3d/volume.h old mode 100755 new mode 100644 index 02f28d2a..a0cad370 --- a/src/lib/openjp3d/volume.h +++ b/src/lib/openjp3d/volume.h @@ -1,43 +1,43 @@ -/* - * Copyright (c) 2005, Herve Drolon, FreeImage Team - * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef __VOLUME_H -#define __VOLUME_H -/** -@file volume.h -@brief Implementation of operations on volumes (VOLUME) - -The functions in VOLUME.C have for goal to realize operations on volumes. -*/ - -/** @defgroup VOLUME VOLUME - Implementation of operations on volumes */ -/*@{*/ - - -/*@}*/ - -#endif /* __VOLUME_H */ - +/* + * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2006, Mónica Díez García, Image Processing Laboratory, University of Valladolid, Spain + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ +#ifndef __VOLUME_H +#define __VOLUME_H +/** +@file volume.h +@brief Implementation of operations on volumes (VOLUME) + +The functions in VOLUME.C have for goal to realize operations on volumes. +*/ + +/** @defgroup VOLUME VOLUME - Implementation of operations on volumes */ +/*@{*/ + + +/*@}*/ + +#endif /* __VOLUME_H */ + diff --git a/src/lib/openjpip/index_manager.c b/src/lib/openjpip/index_manager.c index 5ca3f043..573deb26 100644 --- a/src/lib/openjpip/index_manager.c +++ b/src/lib/openjpip/index_manager.c @@ -646,7 +646,7 @@ OPJ_BOOL set_CODmkrdata( markeridx_param_t *codmkidx, codestream_param_t codestr COD->XPsiz = (Byte4_t *)opj_malloc( sizeof(Byte4_t)); COD->YPsiz = (Byte4_t *)opj_malloc( sizeof(Byte4_t)); - COD->XPsiz[0] = COD->YPsiz[0] = pow(2,15); + COD->XPsiz[0] = COD->YPsiz[0] = 1 << 15; /* pow(2,15); */ } return OPJ_TRUE; } diff --git a/src/lib/openjpip/j2kheader_manager.c b/src/lib/openjpip/j2kheader_manager.c index 7b78368d..e8422573 100644 --- a/src/lib/openjpip/j2kheader_manager.c +++ b/src/lib/openjpip/j2kheader_manager.c @@ -139,7 +139,7 @@ CODmarker_param_t get_CODmkrdata_from_j2kstream( Byte_t *CODstream) else{ COD.XPsiz = (Byte4_t *)opj_malloc( sizeof(Byte4_t)); COD.YPsiz = (Byte4_t *)opj_malloc( sizeof(Byte4_t)); - COD.XPsiz[0] = COD.YPsiz[0] = pow(2,15); + COD.XPsiz[0] = COD.YPsiz[0] = 1<<15; /*pow(2,15)*/ } return COD; } diff --git a/src/lib/openjpip/jp2k_decoder.c b/src/lib/openjpip/jp2k_decoder.c index 9bbfe00d..d9bd5516 100644 --- a/src/lib/openjpip/jp2k_decoder.c +++ b/src/lib/openjpip/jp2k_decoder.c @@ -51,8 +51,6 @@ Byte_t * j2k_to_pnm( FILE *fp, ihdrbox_param_t **ihdrbox) opj_codec_t *l_codec = NULL; /* handle to a decompressor */ opj_stream_t *l_stream = NULL; - - /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); diff --git a/src/lib/openjpip/jp2k_encoder.c b/src/lib/openjpip/jp2k_encoder.c index a80b037f..f73a1f5a 100644 --- a/src/lib/openjpip/jp2k_encoder.c +++ b/src/lib/openjpip/jp2k_encoder.c @@ -608,14 +608,14 @@ Byte8_t comp_seqID( Byte8_t tileID, SIZmarker_param_t SIZ, CODmarker_param_t COD return seqID; } -Byte8_t get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn, OPJ_BOOL isJPPstream) +Byte8_t get_last_tileID( msgqueue_param_t *msgqueue, Byte8_t csn, OPJ_BOOL isjppstream) { Byte8_t last_tileID = 0; message_param_t *msg; msg = msgqueue->first; while( msg){ - if( isJPPstream){ + if( isjppstream){ if((msg->class_id == TILE_HEADER_MSG) && msg->csn == csn && last_tileID < msg->in_class_id) last_tileID = msg->in_class_id; } diff --git a/src/lib/openjpip/msgqueue_manager.c b/src/lib/openjpip/msgqueue_manager.c index 6cb19544..fab9a59c 100644 --- a/src/lib/openjpip/msgqueue_manager.c +++ b/src/lib/openjpip/msgqueue_manager.c @@ -692,7 +692,7 @@ placeholder_param_t * parse_phld( Byte_t *datastream, Byte8_t metalength) phld = (placeholder_param_t *)opj_malloc( sizeof(placeholder_param_t)); phld->LBox = big4( datastream); - strcpy( phld->TBox, "phld"); + strncpy( phld->TBox, "phld", 4); phld->Flags = big4( datastream+8); phld->OrigID = big8( datastream+12); phld->OrigBHlen = (Byte_t)(metalength - 20); diff --git a/src/lib/openmj2/j2k.c b/src/lib/openmj2/j2k.c index c9293730..7c22ca7c 100644 --- a/src/lib/openmj2/j2k.c +++ b/src/lib/openmj2/j2k.c @@ -1538,24 +1538,6 @@ static void j2k_read_sod(opj_j2k_t *j2k) { truncate = 1; /* Case of a truncate codestream */ } - {/* chop padding bytes: */ - unsigned char *s, *e; - - s = cio_getbp(cio); - e = s + len; - - if(len > 8) s = e - 8; - - if(e[-2] == 0x00 && e[-1] == 0x00) /* padding bytes */ - { - while(e > s) - { - if(e[-2] == 0xff && e[-1] == 0xd9) break; - --len; --e; truncate = 1; - } - } - } - data = j2k->tile_data[curtileno]; data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char)); diff --git a/src/lib/openmj2/openjpeg.c b/src/lib/openmj2/openjpeg.c index b9fb0743..ab53472e 100644 --- a/src/lib/openmj2/openjpeg.c +++ b/src/lib/openmj2/openjpeg.c @@ -28,7 +28,7 @@ #include #endif /* _WIN32 */ -#include "opj_config.h" +#include "opj_config_private.h" #include "opj_includes.h" /* ---------------------------------------------------------------------- */ diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 7184d681..a62ceaf9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,6 +1,7 @@ # Tests include_directories( ${OPENJPEG_BINARY_DIR}/src/lib/openjp2 # opj_config.h + ${OPENJPEG_BINARY_DIR}/src/bin/common # opj_apps_config.h ${OPENJPEG_SOURCE_DIR}/src/lib/openjp2 ${OPENJPEG_SOURCE_DIR}/src/bin/jp2 ${OPENJPEG_SOURCE_DIR}/src/bin/common @@ -10,7 +11,7 @@ include_directories( ) # First thing define the common source: -set(comparePGXimages_SRCS comparePGXimages.c +set(compare_images_SRCS compare_images.c ${OPENJPEG_SOURCE_DIR}/src/bin/jp2/convert.c ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c ) @@ -18,19 +19,19 @@ set(comparePGXimages_SRCS comparePGXimages.c set(compare_dump_files_SRCS compare_dump_files.c ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c) -set(compareRAWimages_SRCS compareRAWimages.c +set(compare_raw_files_SRCS compare_raw_files.c ${OPENJPEG_SOURCE_DIR}/src/bin/common/opj_getopt.c) -add_executable(comparePGXimages ${comparePGXimages_SRCS}) -target_link_libraries(comparePGXimages +add_executable(compare_images ${compare_images_SRCS}) +target_link_libraries(compare_images ${OPENJPEG_LIBRARY_NAME} ${PNG_LIBNAME} ${TIFF_LIBNAME} ) # To support universal exe: if(ZLIB_FOUND AND APPLE) - target_link_libraries(comparePGXimages z) + target_link_libraries(compare_images z) else(ZLIB_FOUND AND APPLE) - target_link_libraries(comparePGXimages ${Z_LIBNAME}) + target_link_libraries(compare_images ${Z_LIBNAME}) endif() add_executable(compare_dump_files ${compare_dump_files_SRCS}) @@ -38,48 +39,48 @@ add_executable(compare_dump_files ${compare_dump_files_SRCS}) add_executable(j2k_random_tile_access j2k_random_tile_access.c) target_link_libraries(j2k_random_tile_access ${OPENJPEG_LIBRARY_NAME}) -add_executable(compareRAWimages ${compareRAWimages_SRCS}) +add_executable(compare_raw_files ${compare_raw_files_SRCS}) add_executable(test_tile_encoder test_tile_encoder.c) target_link_libraries(test_tile_encoder ${OPENJPEG_LIBRARY_NAME}) # Let's try a couple of possibilities: -add_test(tte0 ${EXECUTABLE_OUTPUT_PATH}/test_tile_encoder) -add_test(tte1 ${EXECUTABLE_OUTPUT_PATH}/test_tile_encoder 3 2048 2048 1024 1024 8 1 tte1.j2k) -add_test(tte2 ${EXECUTABLE_OUTPUT_PATH}/test_tile_encoder 3 2048 2048 1024 1024 8 1 tte2.jp2) -add_test(tte3 ${EXECUTABLE_OUTPUT_PATH}/test_tile_encoder 1 2048 2048 1024 1024 8 1 tte3.j2k) -add_test(tte4 ${EXECUTABLE_OUTPUT_PATH}/test_tile_encoder 1 256 256 128 128 8 0 tte4.j2k) -add_test(tte5 ${EXECUTABLE_OUTPUT_PATH}/test_tile_encoder 1 512 512 256 256 8 0 tte5.j2k) -#add_test(tte6 ${EXECUTABLE_OUTPUT_PATH}/test_tile_encoder 1 8192 8192 512 512 8 0 tte6.j2k) -#add_test(tte7 ${EXECUTABLE_OUTPUT_PATH}/test_tile_encoder 1 32768 32768 512 512 8 0 tte7.jp2) +add_test(NAME tte0 COMMAND test_tile_encoder) +add_test(NAME tte1 COMMAND test_tile_encoder 3 2048 2048 1024 1024 8 1 tte1.j2k) +add_test(NAME tte2 COMMAND test_tile_encoder 3 2048 2048 1024 1024 8 1 tte2.jp2) +add_test(NAME tte3 COMMAND test_tile_encoder 1 2048 2048 1024 1024 8 1 tte3.j2k) +add_test(NAME tte4 COMMAND test_tile_encoder 1 256 256 128 128 8 0 tte4.j2k) +add_test(NAME tte5 COMMAND test_tile_encoder 1 512 512 256 256 8 0 tte5.j2k) +#add_test(NAME tte6 COMMAND test_tile_encoder 1 8192 8192 512 512 8 0 tte6.j2k) +#add_test(NAME tte7 COMMAND test_tile_encoder 1 32768 32768 512 512 8 0 tte7.jp2) add_executable(test_tile_decoder test_tile_decoder.c) target_link_libraries(test_tile_decoder ${OPENJPEG_LIBRARY_NAME}) -add_test(ttd0 ${EXECUTABLE_OUTPUT_PATH}/test_tile_decoder) +add_test(NAME ttd0 COMMAND test_tile_decoder) set_property(TEST ttd0 APPEND PROPERTY DEPENDS tte0) -add_test(ttd1 ${EXECUTABLE_OUTPUT_PATH}/test_tile_decoder 0 0 1024 1024 tte1.j2k) +add_test(NAME ttd1 COMMAND test_tile_decoder 0 0 1024 1024 tte1.j2k) set_property(TEST ttd1 APPEND PROPERTY DEPENDS tte1) -add_test(ttd2 ${EXECUTABLE_OUTPUT_PATH}/test_tile_decoder 0 0 1024 1024 tte2.jp2) +add_test(NAME ttd2 COMMAND test_tile_decoder 0 0 1024 1024 tte2.jp2) set_property(TEST ttd2 APPEND PROPERTY DEPENDS tte2) -#add_test(ttd6 ${EXECUTABLE_OUTPUT_PATH}/test_tile_decoder 0 0 512 512 tte6.j2k) +#add_test(NAME ttd6 COMMAND test_tile_decoder 0 0 512 512 tte6.j2k) #set_property(TEST ttd6 APPEND PROPERTY DEPENDS tte6) -#add_test(ttd7 ${EXECUTABLE_OUTPUT_PATH}/test_tile_decoder 0 0 512 512 tte7.jp2) +#add_test(NAME ttd7 COMMAND test_tile_decoder 0 0 512 512 tte7.jp2) #set_property(TEST ttd7 APPEND PROPERTY DEPENDS tte7) -add_test(rta1 ${EXECUTABLE_OUTPUT_PATH}/j2k_random_tile_access tte1.j2k) +add_test(NAME rta1 COMMAND j2k_random_tile_access tte1.j2k) set_property(TEST rta1 APPEND PROPERTY DEPENDS tte1) -add_test(rta2 ${EXECUTABLE_OUTPUT_PATH}/j2k_random_tile_access tte2.jp2) +add_test(NAME rta2 COMMAND j2k_random_tile_access tte2.jp2) set_property(TEST rta2 APPEND PROPERTY DEPENDS tte2) -add_test(rta3 ${EXECUTABLE_OUTPUT_PATH}/j2k_random_tile_access tte3.j2k) +add_test(NAME rta3 COMMAND j2k_random_tile_access tte3.j2k) set_property(TEST rta3 APPEND PROPERTY DEPENDS tte3) -add_test(rta4 ${EXECUTABLE_OUTPUT_PATH}/j2k_random_tile_access tte4.j2k) +add_test(NAME rta4 COMMAND j2k_random_tile_access tte4.j2k) set_property(TEST rta4 APPEND PROPERTY DEPENDS tte4) -add_test(rta5 ${EXECUTABLE_OUTPUT_PATH}/j2k_random_tile_access tte5.j2k) +add_test(NAME rta5 COMMAND j2k_random_tile_access tte5.j2k) set_property(TEST rta5 APPEND PROPERTY DEPENDS tte5) # No image send to the dashboard if lib PNG is not available. -if(NOT HAVE_LIBPNG) +if(NOT OPJ_HAVE_LIBPNG) message(WARNING "Lib PNG seems to be not available: if you want run the non-regression tests with images reported to the dashboard, you need it (try BUILD_THIRDPARTY)") endif() @@ -92,8 +93,10 @@ if(BUILD_JPIP) #set(s "http://jpip.example.com/myFCGI?target=16.jp2&fsiz=170,170&cnew=http&type=jpp-stream") set(s "${JPIP_SERVER}?target=16.jp2&fsiz=170,170&cnew=http&type=jpp-stream") set(p "${CMAKE_CURRENT_BINARY_DIR}/jpip.dat") - set(md5 "62b00c620fb0a600c5ffd413cada4674") - add_test(TestJPIP1 ${CMAKE_COMMAND} -DD_URL:STRING=${s} -DD_FILE:PATH=${p} - -DEXPECTED_MD5=${md5} -P ${PROJECT_SOURCE_DIR}/CMake/JPIPTestDriver.cmake) + set(md5 "d41d8cd98f00b204e9800998ecf8427e") + add_test(NAME TestJPIP1 COMMAND ${CMAKE_COMMAND} -DD_URL:STRING=${s} -DD_FILE:PATH=${p} + -DEXPECTED_MD5=${md5} -P ${PROJECT_SOURCE_DIR}/cmake/JPIPTestDriver.cmake) endif() endif() + +add_executable(ppm2rgb3 ppm2rgb3.c) diff --git a/tests/compareRAWimages.c b/tests/compareRAWimages.c deleted file mode 100644 index 32575c68..00000000 --- a/tests/compareRAWimages.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France - * 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. - */ - -/* - * compareRAWimages.c - * - * Created on: 31 August 2011 - * Author: mickael - */ - -#include -#include -#include -#include - -#include "opj_getopt.h" - -void compareRAWimages_help_display(void); - -typedef struct test_cmp_parameters -{ - /** */ - char* base_filename; - /** */ - char* test_filename; -} test_cmp_parameters; - -/******************************************************************************* - * Command line help function - *******************************************************************************/ -void compareRAWimages_help_display(void) { - fprintf(stdout,"\nList of parameters for the comparePGX function \n"); - fprintf(stdout,"\n"); - fprintf(stdout," -b \t REQUIRED \t filename to the reference/baseline RAW image \n"); - fprintf(stdout," -t \t REQUIRED \t filename to the test RAW image\n"); - fprintf(stdout,"\n"); -} - -/******************************************************************************* - * Parse command line - *******************************************************************************/ -static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) -{ - int sizemembasefile, sizememtestfile; - int index; - const char optlist[] = "b:t:"; - int c; - - /* Init parameters*/ - param->base_filename = NULL; - param->test_filename = NULL; - - opj_opterr = 0; - while ((c = opj_getopt(argc, argv, optlist)) != -1) - switch (c) - { - case 'b': - sizemembasefile = (int)strlen(opj_optarg)+1; - param->base_filename = (char*) malloc(sizemembasefile); - param->base_filename[0] = '\0'; - strncpy(param->base_filename, opj_optarg, strlen(opj_optarg)); - param->base_filename[strlen(opj_optarg)] = '\0'; - /*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/ - break; - case 't': - sizememtestfile = (int) strlen(opj_optarg) + 1; - param->test_filename = (char*) malloc(sizememtestfile); - param->test_filename[0] = '\0'; - strncpy(param->test_filename, opj_optarg, strlen(opj_optarg)); - param->test_filename[strlen(opj_optarg)] = '\0'; - /*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/ - break; - case '?': - if ((opj_optopt == 'b') || (opj_optopt == 't')) - fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt); - else - if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt); - else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt); - return 1; - default: - fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg); - break; - } - - if (opj_optind != argc) { - for (index = opj_optind; index < argc; index++) - fprintf(stderr,"Non-option argument %s\n", argv[index]); - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} - -/******************************************************************************* - * MAIN - *******************************************************************************/ -int main(int argc, char **argv) -{ - test_cmp_parameters inParam; - FILE *file_test=NULL, *file_base=NULL; - unsigned char equal = 1; - - /* Get parameters from command line*/ - if (parse_cmdline_cmp(argc, argv, &inParam) == EXIT_FAILURE) - { - compareRAWimages_help_display(); - - /* Free Memory */ - if (inParam.base_filename){ - free(inParam.base_filename); - inParam.base_filename = NULL; - } - if (inParam.test_filename){ - free(inParam.test_filename); - inParam.test_filename = NULL; - } - - return EXIT_FAILURE; - } - - file_test = fopen(inParam.test_filename, "rb"); - if (!file_test) { - fprintf(stderr, "Failed to open %s for reading !!\n", inParam.test_filename); - - /* Free Memory */ - if (inParam.base_filename){ - free(inParam.base_filename); - inParam.base_filename = NULL; - } - if (inParam.test_filename){ - free(inParam.test_filename); - inParam.test_filename = NULL; - } - - return EXIT_FAILURE; - } - - file_base = fopen(inParam.base_filename, "rb"); - if (!file_base) { - fprintf(stderr, "Failed to open %s for reading !!\n", inParam.base_filename); - - /* Free Memory */ - if (inParam.base_filename){ - free(inParam.base_filename); - inParam.base_filename = NULL; - } - if (inParam.test_filename){ - free(inParam.test_filename); - inParam.test_filename = NULL; - } - - fclose(file_test); - return EXIT_FAILURE; - } - - /* Read simultaneously the two files*/ - while (equal) - { - unsigned char value_test = 0; - unsigned char eof_test = 0; - unsigned char value_base = 0; - unsigned char eof_base = 0; - - /* Read one byte*/ - if (!fread(&value_test, 1, 1, file_test)) { - eof_test = 1; - } - - /* Read one byte*/ - if (!fread(&value_base, 1, 1, file_base)) { - eof_base = 1;; - } - - /* End of file reached by the two files?*/ - if (eof_test && eof_base) - break; - - /* End of file reached only by one file?*/ - if (eof_test || eof_base) - { - fprintf(stdout,"Files have different sizes.\n"); - equal = 0; - } - - /* Binary values are equal?*/ - if (value_test != value_base) - { - fprintf(stdout,"Binary values read in the file are different.\n"); - equal = 0; - } - } - - /* Free Memory */ - if (inParam.base_filename){ - free(inParam.base_filename); - inParam.base_filename = NULL; - } - if (inParam.test_filename){ - free(inParam.test_filename); - inParam.test_filename = NULL; - } - - fclose(file_test); - fclose(file_base); - - if (equal) - { - fprintf(stdout,"---- TEST SUCCEED: Files are equal ----\n"); - return EXIT_SUCCESS; - } - else - return EXIT_FAILURE; -} diff --git a/tests/compare_dump_files.c b/tests/compare_dump_files.c index 6bc5145b..946c92a5 100644 --- a/tests/compare_dump_files.c +++ b/tests/compare_dump_files.c @@ -29,13 +29,13 @@ * * Created on: 25 juil. 2011 * Author: mickael - * BASELINE MUST BE GENERATED BY UNIX PLATFORM REGARDING TO THE CRLF PROBLEM */ #include #include #include #include +#include #include "opj_getopt.h" @@ -62,7 +62,7 @@ static void compare_dump_files_help_display(void) { *******************************************************************************/ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) { - int sizemembasefile, sizememtestfile; + size_t sizemembasefile, sizememtestfile; int index; const char optlist[] = "b:t:"; int c; @@ -76,43 +76,40 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) while ((c = opj_getopt(argc, argv, optlist)) != -1) switch (c) { - case 'b': - sizemembasefile = (int)strlen(opj_optarg)+1; - param->base_filename = (char*) malloc(sizemembasefile); - param->base_filename[0] = '\0'; - strncpy(param->base_filename, opj_optarg, strlen(opj_optarg)); - param->base_filename[strlen(opj_optarg)] = '\0'; - /*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/ - break; - case 't': - sizememtestfile = (int) strlen(opj_optarg) + 1; - param->test_filename = (char*) malloc(sizememtestfile); - param->test_filename[0] = '\0'; - strncpy(param->test_filename, opj_optarg, strlen(opj_optarg)); - param->test_filename[strlen(opj_optarg)] = '\0'; - /*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/ - break; - case '?': - if ( (opj_optopt == 'b') || (opj_optopt == 't') ) - fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt); - else - if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt); - else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt); - return 1; - default: - fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg); - break; + case 'b': + sizemembasefile = strlen(opj_optarg) + 1; + param->base_filename = (char*) malloc(sizemembasefile); + strcpy(param->base_filename, opj_optarg); + /*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/ + break; + case 't': + sizememtestfile = strlen(opj_optarg) + 1; + param->test_filename = (char*) malloc(sizememtestfile); + strcpy(param->test_filename, opj_optarg); + /*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/ + break; + case '?': + if ( (opj_optopt == 'b') || (opj_optopt == 't') ) + fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt); + else + if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt); + else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt); + return 1; + default: + fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg); + break; } if (opj_optind != argc) { for (index = opj_optind; index < argc; index++) fprintf(stderr,"Non-option argument %s\n", argv[index]); - return EXIT_FAILURE; + return 1; } - return EXIT_SUCCESS; + return 0; } + /******************************************************************************* * MAIN *******************************************************************************/ @@ -120,33 +117,30 @@ int main(int argc, char **argv) { test_cmp_parameters inParam; FILE *fbase=NULL, *ftest=NULL; - int chbase, chtest; - int same = 1; - unsigned long l=1, pos; + int same = 0; + char lbase[256]; + char strbase[256]; + char ltest[256]; + char strtest[256]; - if( parse_cmdline_cmp(argc, argv, &inParam) == EXIT_FAILURE ) + if( parse_cmdline_cmp(argc, argv, &inParam) == 1 ) { compare_dump_files_help_display(); - if (!inParam.base_filename) free(inParam.base_filename); - if (!inParam.test_filename) free(inParam.test_filename); - return EXIT_FAILURE; + goto cleanup; } /* Display Parameters*/ printf("******Parameters********* \n"); printf(" base_filename = %s\n" - " test_filename = %s\n", - inParam.base_filename, inParam.test_filename); + " test_filename = %s\n", + inParam.base_filename, inParam.test_filename); printf("************************* \n"); /* open base file */ printf("Try to open: %s for reading ... ", inParam.base_filename); if((fbase = fopen(inParam.base_filename, "rb"))==NULL) { - printf("Failed.\n"); - free(inParam.base_filename); - free(inParam.test_filename); - return EXIT_FAILURE; + goto cleanup; } printf("Ok.\n"); @@ -154,105 +148,37 @@ int main(int argc, char **argv) printf("Try to open: %s for reading ... ", inParam.test_filename); if((ftest = fopen(inParam.test_filename, "rb"))==NULL) { - printf("Failed.\n"); - fclose(fbase); - free(inParam.base_filename); - free(inParam.test_filename); - return EXIT_FAILURE; + goto cleanup; } printf("Ok.\n"); - pos=ftell(fbase); - - while(!feof(fbase)) + while (fgets(lbase, sizeof(lbase), fbase) && fgets(ltest,sizeof(ltest),ftest)) { - chbase = fgetc(fbase); - if(ferror(fbase)) + int nbase = sscanf(lbase, "%255[^\r\n]", strbase); + int ntest = sscanf(ltest, "%255[^\r\n]", strtest); + assert( nbase != 255 && ntest != 255 ); + if( nbase != 1 || ntest != 1 ) { - printf("Error reading base file.\n"); - return EXIT_FAILURE; + fprintf(stderr, "could not parse line from files\n" ); + goto cleanup; } - - chtest = fgetc(ftest); - if(ferror(ftest)) + if( strcmp( strbase, strtest ) != 0 ) { - printf("Error reading test file.\n"); - return EXIT_FAILURE; - } - - /* CRLF problem (Baseline must be always generated by unix platform)*/ - if (chbase == '\n' && chtest == '\r') - if (fgetc(ftest) == '\n') - chtest = '\n'; - - if(chbase != chtest) - { - size_t nbytes = 2048; - int CRLF_shift=1; - char *strbase, *strtest, *strbase_d, *strtest_d; - - printf("Files differ at line %lu:\n", l); - fseek(fbase,pos,SEEK_SET); - - /* Take into account CRLF characters when we write \n into - // dump file when we used WIN platform*/ -#ifdef _WIN32 - CRLF_shift = 2; - fseek(ftest,pos + l - 1,SEEK_SET); -#else - fseek(ftest,pos,SEEK_SET); -#endif - - strbase = (char *) malloc(nbytes + 1); - strtest = (char *) malloc(nbytes + 1); - - if (fgets(strbase, nbytes, fbase) == NULL) - fprintf(stderr,"\nWARNING: fgets return a NULL value"); - else - { - if (fgets(strtest, nbytes, ftest) == NULL) - fprintf(stderr,"\nWARNING: fgets return a NULL value"); - else - { - strbase_d = (char *) malloc(strlen(strbase)+1); - strtest_d = (char *) malloc(strlen(strtest)+1); - strncpy(strbase_d, strbase, strlen(strbase)-1); - strncpy(strtest_d, strtest, strlen(strtest)-CRLF_shift); - strbase_d[strlen(strbase)-1] = '\0'; - strtest_d[strlen(strtest)-CRLF_shift] = '\0'; - printf("<%s> vs. <%s>\n", strbase_d, strtest_d); - free(strbase_d);free(strtest_d); - } - } - - free(strbase);free(strtest); - - same = 0; - - break; - } - else - { - if (chbase == '\n') - { - l++; - pos = ftell(fbase); - } + fprintf(stderr,"<%s> vs. <%s>\n", strbase, strtest); + goto cleanup; } } + same = 1; + printf("\n***** TEST SUCCEED: Files are the same. *****\n"); +cleanup: /*Close File*/ - fclose(fbase); - fclose(ftest); + if(fbase) fclose(fbase); + if(ftest) fclose(ftest); /* Free memory*/ free(inParam.base_filename); free(inParam.test_filename); - if(same) - { - printf("\n***** TEST SUCCEED: Files are the same. *****\n"); - return EXIT_SUCCESS; - } - else return EXIT_FAILURE; + return same ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/tests/comparePGXimages.c b/tests/compare_images.c similarity index 57% rename from tests/comparePGXimages.c rename to tests/compare_images.c index 7a6d4ae7..cb1b1301 100644 --- a/tests/comparePGXimages.c +++ b/tests/compare_images.c @@ -25,7 +25,7 @@ */ /* - * comparePGXimages.c + * compare_images.c * * Created on: 8 juil. 2011 * Author: mickael @@ -36,19 +36,370 @@ #include #include #include +#include -#include "opj_config.h" +#include "opj_apps_config.h" #include "opj_getopt.h" #include "openjpeg.h" #include "format_defs.h" #include "convert.h" -double* parseToleranceValues( char* inArg, const int nbcomp); -void comparePGXimages_help_display(void); -opj_image_t* readImageFromFilePGX(char* filename, int nbFilenamePGX, char *separator); -#ifdef HAVE_LIBPNG -int imageToPNG(const opj_image_t* image, const char* filename, int num_comp_select); +#ifdef OPJ_HAVE_LIBTIFF +#include /* TIFFSetWarningHandler */ +#endif /* OPJ_HAVE_LIBTIFF */ + +/******************************************************************************* + * Parse MSE and PEAK input values ( + * separator = ":" + *******************************************************************************/ +static double* parseToleranceValues( char* inArg, const int nbcomp) +{ + double* outArgs= malloc((size_t)nbcomp * sizeof(double)); + int it_comp = 0; + const char delims[] = ":"; + char *result = strtok( inArg, delims ); + + while( (result != NULL) && (it_comp < nbcomp )) + { + outArgs[it_comp] = atof(result); + result = strtok( NULL, delims ); + it_comp++; + } + + if (it_comp != nbcomp) + { + free(outArgs); + return NULL; + } + /* else */ + return outArgs; +} + +/******************************************************************************* + * Command line help function + *******************************************************************************/ +static void compare_images_help_display(void) +{ + fprintf(stdout,"\nList of parameters for the compare_images function \n"); + fprintf(stdout,"\n"); + fprintf(stdout," -b \t REQUIRED \t filename to the reference/baseline PGX/TIF/PNM image \n"); + fprintf(stdout," -t \t REQUIRED \t filename to the test PGX/TIF/PNM image\n"); + fprintf(stdout," -n \t REQUIRED \t number of component of the image (used to generate correct filename)\n"); + fprintf(stdout," -m \t OPTIONAL \t list of MSE tolerances, separated by : (size must correspond to the number of component) of \n"); + fprintf(stdout," -p \t OPTIONAL \t list of PEAK tolerances, separated by : (size must correspond to the number of component) \n"); + fprintf(stdout," -s \t OPTIONAL \t 1 or 2 filename separator to take into account PGX/PNM image with different components, " + "please indicate b or t before separator to indicate respectively the separator " + "for ref/base file and for test file. \n"); + fprintf(stdout," -d \t OPTIONAL \t indicate if you want to run this function as conformance test or as non regression test\n"); + fprintf(stdout,"\n"); +} + +static int get_decod_format_from_string(const char *filename) +{ + const int dot = '.'; + char * ext = strrchr(filename, dot); + if( strcmp(ext,".pgx") == 0 ) return PGX_DFMT; + if( strcmp(ext,".tif") == 0 ) return TIF_DFMT; + if( strcmp(ext,".ppm") == 0 ) return PXM_DFMT; + return -1; +} + + +/******************************************************************************* + * Create filenames from a filename using separator and nb components + * (begin from 0) + *******************************************************************************/ +static char* createMultiComponentsFilename(const char* inFilename, const int indexF, const char* separator) +{ + char s[255]; + char *outFilename, *ptr; + const char token = '.'; + size_t posToken = 0; + int decod_format; + + /*printf("inFilename = %s\n", inFilename);*/ + if ((ptr = strrchr(inFilename, token)) != NULL) + { + posToken = strlen(inFilename) - strlen(ptr); + /*printf("Position of %c character inside inFilename = %d\n", token, posToken);*/ + } + else + { + /*printf("Token %c not found\n", token);*/ + outFilename = (char*)malloc(1); + outFilename[0] = '\0'; + return outFilename; + } + + outFilename = (char*)malloc((posToken + 7) * sizeof(char)); /*6*/ + + strncpy(outFilename, inFilename, posToken); + outFilename[posToken] = '\0'; + strcat(outFilename, separator); + sprintf(s, "%i", indexF); + strcat(outFilename, s); + + decod_format = get_decod_format_from_string(inFilename); + if( decod_format == PGX_DFMT ) + { + strcat(outFilename, ".pgx"); + } + else if( decod_format == PXM_DFMT ) + { + strcat(outFilename, ".pgm"); + } + + /*printf("outfilename: %s\n", outFilename);*/ + return outFilename; +} + +/******************************************************************************* + * + *******************************************************************************/ +static opj_image_t* readImageFromFilePPM(const char* filename, int nbFilenamePGX, const char *separator) +{ + int it_file; + opj_image_t* image_read = NULL; + opj_image_t* image = NULL; + opj_cparameters_t parameters; + opj_image_cmptparm_t* param_image_read; + int** data; + + /* If separator is empty => nb file to read is equal to one*/ + if ( strlen(separator) == 0 ) + nbFilenamePGX = 1; + + /* set encoding parameters to default values */ + opj_set_default_encoder_parameters(¶meters); + parameters.decod_format = PXM_DFMT; + strcpy(parameters.infile, filename); + + /* Allocate memory*/ + param_image_read = malloc((size_t)nbFilenamePGX * sizeof(opj_image_cmptparm_t)); + data = malloc((size_t)nbFilenamePGX * sizeof(*data)); + + for (it_file = 0; it_file < nbFilenamePGX; it_file++) + { + /* Create the right filename*/ + char *filenameComponentPGX; + if (strlen(separator) == 0) + { + filenameComponentPGX = malloc((strlen(filename) + 1) * sizeof(*filenameComponentPGX)); + strcpy(filenameComponentPGX, filename); + } + else + filenameComponentPGX = createMultiComponentsFilename(filename, it_file, separator); + + /* Read the tif file corresponding to the component */ + image_read = pnmtoimage(filenameComponentPGX, ¶meters); + if (!image_read) + { + int it_free_data; + fprintf(stderr, "Unable to load ppm file: %s\n", filenameComponentPGX); + + free(param_image_read); + + for (it_free_data = 0; it_free_data < it_file; it_free_data++) { + free(data[it_free_data]); + } + free(data); + + free(filenameComponentPGX); + + return NULL; + } + + /* Set the image_read parameters*/ + param_image_read[it_file].x0 = 0; + param_image_read[it_file].y0 = 0; + param_image_read[it_file].dx = 0; + param_image_read[it_file].dy = 0; + param_image_read[it_file].h = image_read->comps->h; + param_image_read[it_file].w = image_read->comps->w; + param_image_read[it_file].bpp = image_read->comps->bpp; + param_image_read[it_file].prec = image_read->comps->prec; + param_image_read[it_file].sgnd = image_read->comps->sgnd; + + /* Copy data*/ + data[it_file] = malloc(param_image_read[it_file].h * param_image_read[it_file].w * sizeof(int)); + memcpy(data[it_file], image_read->comps->data, image_read->comps->h * image_read->comps->w * sizeof(int)); + + /* Free memory*/ + opj_image_destroy(image_read); + free(filenameComponentPGX); + } + + image = opj_image_create((OPJ_UINT32)nbFilenamePGX, param_image_read, OPJ_CLRSPC_UNSPECIFIED); + for (it_file = 0; it_file < nbFilenamePGX; it_file++) + { + /* Copy data into output image and free memory*/ + memcpy(image->comps[it_file].data, data[it_file], image->comps[it_file].h * image->comps[it_file].w * sizeof(int)); + free(data[it_file]); + } + + /* Free memory*/ + free(param_image_read); + free(data); + + return image; +} + +static opj_image_t* readImageFromFileTIF(const char* filename, int nbFilenamePGX, const char *separator) +{ + opj_image_t* image_read = NULL; + opj_cparameters_t parameters; + (void)nbFilenamePGX; + (void)separator; + + /* conformance test suite produce annoying warning/error: + * TIFFReadDirectory: Warning, /.../data/baseline/conformance/jp2_1.tif: unknown field with tag 37724 (0x935c) encountered. + * TIFFOpen: /.../data/baseline/nonregression/opj_jp2_1.tif: Cannot open. + * On Win32 this open a message box by default, so remove it from the test suite: + */ +#ifdef OPJ_HAVE_LIBTIFF + TIFFSetWarningHandler(NULL); + TIFFSetErrorHandler(NULL); +#endif + + if ( strlen(separator) != 0 ) return NULL; + + /* set encoding parameters to default values */ + opj_set_default_encoder_parameters(¶meters); + parameters.decod_format = TIF_DFMT; + strcpy(parameters.infile, filename); + + /* Read the tif file corresponding to the component */ +#ifdef OPJ_HAVE_LIBTIFF + image_read = tiftoimage(filename, ¶meters); +#endif + if (!image_read) + { + fprintf(stderr, "Unable to load TIF file\n"); + return NULL; + } + + /* \postconditions */ + assert( image_read->numcomps == 1 || image_read->numcomps == 3 ); + return image_read; +} + +static opj_image_t* readImageFromFilePGX(const char* filename, int nbFilenamePGX, const char *separator) +{ + int it_file; + opj_image_t* image_read = NULL; + opj_image_t* image = NULL; + opj_cparameters_t parameters; + opj_image_cmptparm_t* param_image_read; + int** data; + + /* If separator is empty => nb file to read is equal to one*/ + if ( strlen(separator) == 0 ) + nbFilenamePGX = 1; + + /* set encoding parameters to default values */ + opj_set_default_encoder_parameters(¶meters); + parameters.decod_format = PGX_DFMT; + strcpy(parameters.infile, filename); + + /* Allocate memory*/ + param_image_read = malloc((size_t)nbFilenamePGX * sizeof(opj_image_cmptparm_t)); + data = malloc((size_t)nbFilenamePGX * sizeof(*data)); + + for (it_file = 0; it_file < nbFilenamePGX; it_file++) + { + /* Create the right filename*/ + char *filenameComponentPGX; + if (strlen(separator) == 0) + { + filenameComponentPGX = malloc((strlen(filename) + 1) * sizeof(*filenameComponentPGX)); + strcpy(filenameComponentPGX, filename); + } + else + filenameComponentPGX = createMultiComponentsFilename(filename, it_file, separator); + + /* Read the pgx file corresponding to the component */ + image_read = pgxtoimage(filenameComponentPGX, ¶meters); + if (!image_read) + { + int it_free_data; + fprintf(stderr, "Unable to load pgx file\n"); + + free(param_image_read); + + for (it_free_data = 0; it_free_data < it_file; it_free_data++) { + free(data[it_free_data]); + } + free(data); + + free(filenameComponentPGX); + + return NULL; + } + + /* Set the image_read parameters*/ + param_image_read[it_file].x0 = 0; + param_image_read[it_file].y0 = 0; + param_image_read[it_file].dx = 0; + param_image_read[it_file].dy = 0; + param_image_read[it_file].h = image_read->comps->h; + param_image_read[it_file].w = image_read->comps->w; + param_image_read[it_file].bpp = image_read->comps->bpp; + param_image_read[it_file].prec = image_read->comps->prec; + param_image_read[it_file].sgnd = image_read->comps->sgnd; + + /* Copy data*/ + data[it_file] = malloc(param_image_read[it_file].h * param_image_read[it_file].w * sizeof(int)); + memcpy(data[it_file], image_read->comps->data, image_read->comps->h * image_read->comps->w * sizeof(int)); + + /* Free memory*/ + opj_image_destroy(image_read); + free(filenameComponentPGX); + } + + image = opj_image_create((OPJ_UINT32)nbFilenamePGX, param_image_read, OPJ_CLRSPC_UNSPECIFIED); + for (it_file = 0; it_file < nbFilenamePGX; it_file++) + { + /* Copy data into output image and free memory*/ + memcpy(image->comps[it_file].data, data[it_file], image->comps[it_file].h * image->comps[it_file].w * sizeof(int)); + free(data[it_file]); + } + + /* Free memory*/ + free(param_image_read); + free(data); + + return image; +} + +#if defined(OPJ_HAVE_LIBPNG) && 0 /* remove for now */ +/******************************************************************************* + * + *******************************************************************************/ +static int imageToPNG(const opj_image_t* image, const char* filename, int num_comp_select) +{ + opj_image_cmptparm_t param_image_write; + opj_image_t* image_write = NULL; + + param_image_write.x0 = 0; + param_image_write.y0 = 0; + param_image_write.dx = 0; + param_image_write.dy = 0; + param_image_write.h = image->comps[num_comp_select].h; + param_image_write.w = image->comps[num_comp_select].w; + param_image_write.bpp = image->comps[num_comp_select].bpp; + param_image_write.prec = image->comps[num_comp_select].prec; + param_image_write.sgnd = image->comps[num_comp_select].sgnd; + + image_write = opj_image_create(1u, ¶m_image_write, OPJ_CLRSPC_GRAY); + memcpy(image_write->comps->data, image->comps[num_comp_select].data, param_image_write.h * param_image_write.w * sizeof(int)); + + imagetopng(image_write, filename); + + opj_image_destroy(image_write); + + return EXIT_SUCCESS; +} #endif typedef struct test_cmp_parameters @@ -72,22 +423,14 @@ typedef struct test_cmp_parameters } test_cmp_parameters; -/******************************************************************************* - * Command line help function - *******************************************************************************/ -void comparePGXimages_help_display(void) { - fprintf(stdout,"\nList of parameters for the comparePGX function \n"); - fprintf(stdout,"\n"); - fprintf(stdout," -b \t REQUIRED \t filename to the reference/baseline PGX image \n"); - fprintf(stdout," -t \t REQUIRED \t filename to the test PGX image\n"); - fprintf(stdout," -n \t REQUIRED \t number of component of the image (used to generate correct filename)\n"); - fprintf(stdout," -m \t OPTIONAL \t list of MSE tolerances, separated by : (size must correspond to the number of component) of \n"); - fprintf(stdout," -p \t OPTIONAL \t list of PEAK tolerances, separated by : (size must correspond to the number of component) \n"); - fprintf(stdout," -s \t OPTIONAL \t 1 or 2 filename separator to take into account PGX image with different components, " - "please indicate b or t before separator to indicate respectively the separator " - "for ref/base file and for test file. \n"); - fprintf(stdout," -r \t OPTIONAL \t indicate if you want to run this function as conformance test or as non regression test\n"); - fprintf(stdout,"\n"); +/* return decode format PGX / TIF / PPM , return -1 on error */ +static int get_decod_format(test_cmp_parameters* param) +{ + int base_format = get_decod_format_from_string( param->base_filename ); + int test_format = get_decod_format_from_string( param->test_filename ); + if( base_format != test_format ) return -1; + /* handle case -1: */ + return base_format; } /******************************************************************************* @@ -97,7 +440,7 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) { char *MSElistvalues = NULL; char *PEAKlistvalues= NULL; char *separatorList = NULL; - int sizemembasefile, sizememtestfile; + size_t sizemembasefile, sizememtestfile; int index, flagM=0, flagP=0; const char optlist[] = "b:t:n:m:p:s:d"; int c; @@ -109,6 +452,8 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) param->tabMSEvalues = NULL; param->tabPEAKvalues = NULL; param->nr_flag = 0; + param->separator_base[0] = 0; + param->separator_test[0] = 0; opj_opterr = 0; @@ -116,19 +461,15 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) switch (c) { case 'b': - sizemembasefile = (int)strlen(opj_optarg)+1; + sizemembasefile = strlen(opj_optarg) + 1; param->base_filename = (char*) malloc(sizemembasefile); - param->base_filename[0] = '\0'; - strncpy(param->base_filename, opj_optarg, strlen(opj_optarg)); - param->base_filename[strlen(opj_optarg)] = '\0'; + strcpy(param->base_filename, opj_optarg); /*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/ break; case 't': - sizememtestfile = (int) strlen(opj_optarg) + 1; + sizememtestfile = strlen(opj_optarg) + 1; param->test_filename = (char*) malloc(sizememtestfile); - param->test_filename[0] = '\0'; - strncpy(param->test_filename, opj_optarg, strlen(opj_optarg)); - param->test_filename[strlen(opj_optarg)] = '\0'; + strcpy(param->test_filename, opj_optarg); /*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/ break; case 'n': @@ -165,30 +506,24 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) { for (index = opj_optind; index < argc; index++) fprintf(stderr,"Non-option argument %s\n", argv[index]); - return EXIT_FAILURE; + return 1; } if (param->nbcomp == 0) { fprintf(stderr,"Need to indicate the number of components !\n"); - return EXIT_FAILURE; + return 1; } - else + /* else */ + if ( flagM && flagP ) { - if ( flagM && flagP ) + param->tabMSEvalues = parseToleranceValues( MSElistvalues, param->nbcomp); + param->tabPEAKvalues = parseToleranceValues( PEAKlistvalues, param->nbcomp); + if ( (param->tabMSEvalues == NULL) || (param->tabPEAKvalues == NULL)) { - param->tabMSEvalues = parseToleranceValues( MSElistvalues, param->nbcomp); - param->tabPEAKvalues = parseToleranceValues( PEAKlistvalues, param->nbcomp); - if ( (param->tabMSEvalues == NULL) || (param->tabPEAKvalues == NULL)) - { - fprintf(stderr,"MSE and PEAK values are not correct (respectively need %d values)\n",param->nbcomp); - return EXIT_FAILURE; - } + fprintf(stderr,"MSE and PEAK values are not correct (respectively need %d values)\n",param->nbcomp); + return 1; } - /*else - { - - }*/ } /* Get separators after corresponding letter (b or t)*/ @@ -197,11 +532,9 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) if( (strlen(separatorList) ==2) || (strlen(separatorList) ==4) ) { /* keep original string*/ - int sizeseplist = (int)strlen(separatorList)+1; + size_t sizeseplist = strlen(separatorList)+1; char* separatorList2 = (char*)malloc( sizeseplist ); - separatorList2[0] = '\0'; - strncpy(separatorList2, separatorList, strlen(separatorList)); - separatorList2[strlen(separatorList)] = '\0'; + strcpy(separatorList2, separatorList); /*printf("separatorList2 = %s [%d / %d]\n", separatorList2, strlen(separatorList2), sizeseplist);*/ if (strlen(separatorList) == 2) /* one separator behind b or t*/ @@ -214,19 +547,21 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) resultB = strtok(resultT, "b"); if (strlen(resultB) == 1) { - param->separator_base[0] = separatorList[1];param->separator_base[1] = '\0'; - param->separator_test[0] ='\0'; + param->separator_base[0] = separatorList[1]; + param->separator_base[1] = 0; + param->separator_test[0] = 0; } else /* not found b*/ { free(separatorList2); - return EXIT_FAILURE; + return 1; } } else /* found t*/ { - param->separator_base[0] ='\0'; - param->separator_test[0] = separatorList[1];param->separator_test[1] = '\0'; + param->separator_base[0] = 0; + param->separator_test[0] = separatorList[1]; + param->separator_test[1] = 0; } /*printf("sep b = %s [%d] and sep t = %s [%d]\n",param->separator_base, strlen(param->separator_base), param->separator_test, strlen(param->separator_test) );*/ } @@ -240,13 +575,15 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) resultB = strtok(resultT, "b"); if (strlen(resultB) == 1) /* found b after t*/ { - param->separator_test[0] = separatorList[1];param->separator_test[1] = '\0'; - param->separator_base[0] = separatorList[3];param->separator_base[1] = '\0'; + param->separator_test[0] = separatorList[1]; + param->separator_test[1] = 0; + param->separator_base[0] = separatorList[3]; + param->separator_base[1] = 0; } else /* didn't find b after t*/ { free(separatorList2); - return EXIT_FAILURE; + return 1; } } else /* == 2, didn't find t in first place*/ @@ -255,13 +592,15 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) resultB = strtok(resultT, "b"); if (strlen(resultB) == 1) /* found b in first place*/ { - param->separator_base[0] = separatorList[1]; param->separator_base[1] = '\0'; - param->separator_test[0] = separatorList[3]; param->separator_test[1] = '\0'; + param->separator_base[0] = separatorList[1]; + param->separator_base[1] = 0; + param->separator_test[0] = separatorList[3]; + param->separator_test[1] = 0; } else /* didn't found b in first place => problem*/ { free(separatorList2); - return EXIT_FAILURE; + return 1; } } } @@ -269,20 +608,20 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) } else /* wrong number of argument after -s*/ { - return EXIT_FAILURE; + return 1; } } else { if (param->nbcomp == 1) { - param->separator_base[0] = '\0'; - param->separator_test[0] = '\0'; + assert( param->separator_base[0] == 0 ); + assert( param->separator_test[0] == 0 ); } else { fprintf(stderr,"If number of component is > 1, we need separator\n"); - return EXIT_FAILURE; + return 1; } } @@ -290,207 +629,17 @@ static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) if ( (param->nr_flag) && (flagP || flagM) ) { fprintf(stderr,"Wrong input parameters list: it is non-regression test or tolerance comparison\n"); - return EXIT_FAILURE; + return 1; } if ( (!param->nr_flag) && (!flagP || !flagM) ) { fprintf(stderr,"Wrong input parameters list: it is non-regression test or tolerance comparison\n"); - return EXIT_FAILURE; + return 1; } - return EXIT_SUCCESS; + return 0; } -/******************************************************************************* - * Parse MSE and PEAK input values ( - * separator = ":" - *******************************************************************************/ -double* parseToleranceValues( char* inArg, const int nbcomp) -{ - double* outArgs= malloc(nbcomp * sizeof(double)); - int it_comp = 0; - char delims[] = ":"; - char *result = NULL; - result = strtok( inArg, delims ); - - while( (result != NULL) && (it_comp < nbcomp )) - { - outArgs[it_comp] = atof(result); - result = strtok( NULL, delims ); - it_comp++; - } - - if (it_comp != nbcomp) - { - free(outArgs); - return NULL; - } - else - return outArgs; -} -/******************************************************************************* - * Create filenames from a filename by used separator and nb components - * (begin to 0) - *******************************************************************************/ -static char* createMultiComponentsFilename(const char* inFilename, const int indexF, const char* separator) -{ - char s[255]; - char *outFilename, *ptr; - char token = '.'; - int posToken = 0; - - /*printf("inFilename = %s\n", inFilename);*/ - if ((ptr = strrchr(inFilename, token)) != NULL) - { - posToken = (int) (strlen(inFilename) - strlen(ptr)); - /*printf("Position of %c character inside inFilename = %d\n", token, posToken);*/ - } - else - { - /*printf("Token %c not found\n", token);*/ - outFilename = (char*)malloc(1); - outFilename[0] = '\0'; - return outFilename; - } - - outFilename = (char*)malloc((posToken + 7) * sizeof(char)); /*6*/ - - strncpy(outFilename, inFilename, posToken); - - outFilename[posToken] = '\0'; - - strcat(outFilename, separator); - - sprintf(s, "%i", indexF); - strcat(outFilename, s); - - strcat(outFilename, ".pgx"); - - /*printf("outfilename: %s\n", outFilename);*/ - return outFilename; -} -/******************************************************************************* - * - *******************************************************************************/ -opj_image_t* readImageFromFilePGX(char* filename, int nbFilenamePGX, char *separator) -{ - int it_file; - opj_image_t* image_read = NULL; - opj_image_t* image = NULL; - opj_cparameters_t parameters; - opj_image_cmptparm_t* param_image_read; - int** data; - - /* If separator is empty => nb file to read is equal to one*/ - if ( strlen(separator) == 0 ) - nbFilenamePGX = 1; - - /* set encoding parameters to default values */ - opj_set_default_encoder_parameters(¶meters); - parameters.decod_format = PGX_DFMT; - strncpy(parameters.infile, filename, sizeof(parameters.infile)-1); - - /* Allocate memory*/ - param_image_read = malloc(nbFilenamePGX * sizeof(opj_image_cmptparm_t)); - data = malloc(nbFilenamePGX * sizeof(*data)); - - it_file = 0; - for (it_file = 0; it_file < nbFilenamePGX; it_file++) - { - /* Create the right filename*/ - char *filenameComponentPGX; - if (strlen(separator) == 0) - { - filenameComponentPGX = malloc((strlen(filename) + 1) * sizeof(*filenameComponentPGX)); - strcpy(filenameComponentPGX, filename); - } - else - filenameComponentPGX = createMultiComponentsFilename(filename, it_file, separator); - - /* Read the pgx file corresponding to the component */ - image_read = pgxtoimage(filenameComponentPGX, ¶meters); - if (!image_read) - { - int it_free_data; - fprintf(stderr, "Unable to load pgx file\n"); - - free(param_image_read); - - for (it_free_data = 0; it_free_data < it_file; it_free_data++) { - free(data[it_free_data]); - } - free(data); - - free(filenameComponentPGX); - - return NULL; - } - - /* Set the image_read parameters*/ - param_image_read[it_file].x0 = 0; - param_image_read[it_file].y0 = 0; - param_image_read[it_file].dx = 0; - param_image_read[it_file].dy = 0; - param_image_read[it_file].h = image_read->comps->h; - param_image_read[it_file].w = image_read->comps->w; - param_image_read[it_file].bpp = image_read->comps->bpp; - param_image_read[it_file].prec = image_read->comps->prec; - param_image_read[it_file].sgnd = image_read->comps->sgnd; - - /* Copy data*/ - data[it_file] = malloc(param_image_read[it_file].h * param_image_read[it_file].w * sizeof(int)); - memcpy(data[it_file], image_read->comps->data, image_read->comps->h * image_read->comps->w * sizeof(int)); - - /* Free memory*/ - opj_image_destroy(image_read); - free(filenameComponentPGX); - } - - image = opj_image_create(nbFilenamePGX, param_image_read, OPJ_CLRSPC_UNSPECIFIED); - for (it_file = 0; it_file < nbFilenamePGX; it_file++) - { - /* Copy data into output image and free memory*/ - memcpy(image->comps[it_file].data, data[it_file], image->comps[it_file].h * image->comps[it_file].w * sizeof(int)); - free(data[it_file]); - } - - /* Free memory*/ - free(param_image_read); - free(data); - - return image; -} - -/******************************************************************************* - * - *******************************************************************************/ -#ifdef HAVE_LIBPNG -int imageToPNG(const opj_image_t* image, const char* filename, int num_comp_select) -{ - opj_image_cmptparm_t param_image_write; - opj_image_t* image_write = NULL; - - param_image_write.x0 = 0; - param_image_write.y0 = 0; - param_image_write.dx = 0; - param_image_write.dy = 0; - param_image_write.h = image->comps[num_comp_select].h; - param_image_write.w = image->comps[num_comp_select].w; - param_image_write.bpp = image->comps[num_comp_select].bpp; - param_image_write.prec = image->comps[num_comp_select].prec; - param_image_write.sgnd = image->comps[num_comp_select].sgnd; - - image_write = opj_image_create(1, ¶m_image_write, OPJ_CLRSPC_GRAY); - memcpy(image_write->comps->data, image->comps[num_comp_select].data, param_image_write.h * param_image_write.w * sizeof(int)); - - imagetopng(image_write, filename); - - opj_image_destroy(image_write); - - return EXIT_SUCCESS; -} -#endif - /******************************************************************************* * MAIN *******************************************************************************/ @@ -498,25 +647,23 @@ int main(int argc, char **argv) { test_cmp_parameters inParam; OPJ_UINT32 it_comp, itpxl; - int failed = 0; - int nbFilenamePGXbase, nbFilenamePGXtest; + int failed = 1; + int nbFilenamePGXbase = 0, nbFilenamePGXtest = 0; char *filenamePNGtest= NULL, *filenamePNGbase = NULL, *filenamePNGdiff = NULL; - int memsizebasefilename, memsizetestfilename, memsizedifffilename; + size_t memsizebasefilename, memsizetestfilename; + size_t memsizedifffilename; int valueDiff = 0, nbPixelDiff = 0; double sumDiff = 0.0; /* Structures to store image parameters and data*/ opj_image_t *imageBase = NULL, *imageTest = NULL, *imageDiff = NULL; - opj_image_cmptparm_t* param_image_diff; + opj_image_cmptparm_t* param_image_diff = NULL; + int decod_format; /* Get parameters from command line*/ - if( parse_cmdline_cmp(argc, argv, &inParam) == EXIT_FAILURE ) + if( parse_cmdline_cmp(argc, argv, &inParam) ) { - comparePGXimages_help_display(); - if (inParam.tabMSEvalues) free(inParam.tabMSEvalues); - if (inParam.tabPEAKvalues) free(inParam.tabPEAKvalues); - if (inParam.base_filename) free(inParam.base_filename); - if (inParam.test_filename) free(inParam.test_filename); - return EXIT_FAILURE; + compare_images_help_display(); + goto cleanup; } /* Display Parameters*/ @@ -532,26 +679,22 @@ int main(int argc, char **argv) if ( (inParam.tabMSEvalues != NULL) && (inParam.tabPEAKvalues != NULL)) { - int it_comp; + int it_comp2; printf(" MSE values = ["); - for (it_comp = 0; it_comp < inParam.nbcomp; it_comp++) - printf(" %f ", inParam.tabMSEvalues[it_comp]); + for (it_comp2 = 0; it_comp2 < inParam.nbcomp; it_comp2++) + printf(" %f ", inParam.tabMSEvalues[it_comp2]); printf("]\n"); printf(" PEAK values = ["); - for (it_comp = 0; it_comp < inParam.nbcomp; it_comp++) - printf(" %f ", inParam.tabPEAKvalues[it_comp]); + for (it_comp2 = 0; it_comp2 < inParam.nbcomp; it_comp2++) + printf(" %f ", inParam.tabPEAKvalues[it_comp2]); printf("]\n"); printf(" Non-regression test = %d\n", inParam.nr_flag); } - if (strlen(inParam.separator_base) == 0) - nbFilenamePGXbase = 0; - else + if (strlen(inParam.separator_base) != 0) nbFilenamePGXbase = inParam.nbcomp; - if (strlen(inParam.separator_test) == 0) - nbFilenamePGXtest = 0; - else + if (strlen(inParam.separator_test) != 0) nbFilenamePGXtest = inParam.nbcomp; printf(" NbFilename to generate from base filename = %d\n", nbFilenamePGXbase); @@ -559,49 +702,66 @@ int main(int argc, char **argv) printf("************************* \n"); /*----------BASELINE IMAGE--------*/ - memsizebasefilename = (int)strlen(inParam.test_filename) + 1 + 5 + 2 + 4; - memsizetestfilename = (int)strlen(inParam.test_filename) + 1 + 5 + 2 + 4; + memsizebasefilename = strlen(inParam.test_filename) + 1 + 5 + 2 + 4; + memsizetestfilename = strlen(inParam.test_filename) + 1 + 5 + 2 + 4; - imageBase = readImageFromFilePGX( inParam.base_filename, nbFilenamePGXbase, inParam.separator_base); - if ( imageBase != NULL) + decod_format = get_decod_format(&inParam); + if( decod_format == -1 ) { - filenamePNGbase = (char*) malloc(memsizebasefilename); - filenamePNGbase[0] = '\0'; - strncpy(filenamePNGbase, inParam.test_filename, strlen(inParam.test_filename)); - filenamePNGbase[strlen(inParam.test_filename)] = '\0'; - strcat(filenamePNGbase, ".base"); - /*printf("filenamePNGbase = %s [%d / %d octets]\n",filenamePNGbase, strlen(filenamePNGbase),memsizebasefilename );*/ + fprintf( stderr, "Unhandled file format\n" ); + goto cleanup; } - else + assert( decod_format == PGX_DFMT || decod_format == TIF_DFMT || decod_format == PXM_DFMT ); + + if( decod_format == PGX_DFMT ) { - if (inParam.tabMSEvalues) free(inParam.tabMSEvalues); - if (inParam.tabPEAKvalues) free(inParam.tabPEAKvalues); - if (inParam.base_filename) free(inParam.base_filename); - if (inParam.test_filename) free(inParam.test_filename); - return EXIT_FAILURE; + imageBase = readImageFromFilePGX( inParam.base_filename, nbFilenamePGXbase, inParam.separator_base); + if ( imageBase == NULL ) + goto cleanup; } + else if( decod_format == TIF_DFMT ) + { + imageBase = readImageFromFileTIF( inParam.base_filename, nbFilenamePGXbase, ""); + if ( imageBase == NULL ) + goto cleanup; + } + else if( decod_format == PXM_DFMT ) + { + imageBase = readImageFromFilePPM( inParam.base_filename, nbFilenamePGXbase, inParam.separator_base); + if ( imageBase == NULL ) + goto cleanup; + } + + filenamePNGbase = (char*) malloc(memsizebasefilename); + strcpy(filenamePNGbase, inParam.test_filename); + strcat(filenamePNGbase, ".base"); + /*printf("filenamePNGbase = %s [%d / %d octets]\n",filenamePNGbase, strlen(filenamePNGbase),memsizebasefilename );*/ /*----------TEST IMAGE--------*/ - imageTest = readImageFromFilePGX(inParam.test_filename, nbFilenamePGXtest, inParam.separator_test); - if ( imageTest != NULL) + if( decod_format == PGX_DFMT ) { - filenamePNGtest = (char*) malloc(memsizetestfilename); - filenamePNGtest[0] = '\0'; - strncpy(filenamePNGtest, inParam.test_filename, strlen(inParam.test_filename)); - filenamePNGtest[strlen(inParam.test_filename)] = '\0'; - strcat(filenamePNGtest, ".test"); - /*printf("filenamePNGtest = %s [%d / %d octets]\n",filenamePNGtest, strlen(filenamePNGtest),memsizetestfilename );*/ + imageTest = readImageFromFilePGX(inParam.test_filename, nbFilenamePGXtest, inParam.separator_test); + if ( imageTest == NULL ) + goto cleanup; } - else + else if( decod_format == TIF_DFMT ) { - if (inParam.tabMSEvalues) free(inParam.tabMSEvalues); - if (inParam.tabPEAKvalues) free(inParam.tabPEAKvalues); - if (inParam.base_filename) free(inParam.base_filename); - if (inParam.test_filename) free(inParam.test_filename); - free(filenamePNGbase); - return EXIT_FAILURE; + imageTest = readImageFromFileTIF(inParam.test_filename, nbFilenamePGXtest, ""); + if ( imageTest == NULL ) + goto cleanup; } + else if( decod_format == PXM_DFMT ) + { + imageTest = readImageFromFilePPM(inParam.test_filename, nbFilenamePGXtest, inParam.separator_test); + if ( imageTest == NULL ) + goto cleanup; + } + + filenamePNGtest = (char*) malloc(memsizetestfilename); + strcpy(filenamePNGtest, inParam.test_filename); + strcat(filenamePNGtest, ".test"); + /*printf("filenamePNGtest = %s [%d / %d octets]\n",filenamePNGtest, strlen(filenamePNGtest),memsizetestfilename );*/ /*----------DIFF IMAGE--------*/ @@ -611,85 +771,66 @@ int main(int argc, char **argv) /* Comparison of header parameters*/ printf("Step 1 -> Header comparison\n"); + /* check dimensions (issue 286)*/ + if(imageBase->numcomps != imageTest->numcomps ) + { + printf("ERROR: dim mismatch (%d><%d)\n", imageBase->numcomps, imageTest->numcomps); + goto cleanup; + } + for (it_comp = 0; it_comp < imageBase->numcomps; it_comp++) { param_image_diff[it_comp].x0 = 0; param_image_diff[it_comp].y0 = 0; param_image_diff[it_comp].dx = 0; param_image_diff[it_comp].dy = 0; + param_image_diff[it_comp].sgnd = 0; + param_image_diff[it_comp].prec = 8; + param_image_diff[it_comp].bpp = 1; + param_image_diff[it_comp].h = imageBase->comps[it_comp].h; + param_image_diff[it_comp].w = imageBase->comps[it_comp].w; if (imageBase->comps[it_comp].sgnd != imageTest->comps[it_comp].sgnd) { printf("ERROR: sign mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).sgnd, ((imageTest->comps)[it_comp]).sgnd); - failed = 1; + goto cleanup; } - else - param_image_diff[it_comp].sgnd = 0 ; if (((imageBase->comps)[it_comp]).prec != ((imageTest->comps)[it_comp]).prec) { printf("ERROR: prec mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).prec, ((imageTest->comps)[it_comp]).prec); - failed = 1; + goto cleanup; } - else - param_image_diff[it_comp].prec = 8 ; if (((imageBase->comps)[it_comp]).bpp != ((imageTest->comps)[it_comp]).bpp) { printf("ERROR: byte per pixel mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).bpp, ((imageTest->comps)[it_comp]).bpp); - failed = 1; + goto cleanup; } - else - param_image_diff[it_comp].bpp = 1 ; if (((imageBase->comps)[it_comp]).h != ((imageTest->comps)[it_comp]).h) { printf("ERROR: height mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).h, ((imageTest->comps)[it_comp]).h); - failed = 1; + goto cleanup; } - else - param_image_diff[it_comp].h = imageBase->comps[it_comp].h ; if (((imageBase->comps)[it_comp]).w != ((imageTest->comps)[it_comp]).w) { printf("ERROR: width mismatch [comp %d] (%d><%d)\n", it_comp, ((imageBase->comps)[it_comp]).w, ((imageTest->comps)[it_comp]).w); - failed = 1; + goto cleanup; } - else - param_image_diff[it_comp].w = imageBase->comps[it_comp].w ; } - /* If only one parameter is different, we stop the test*/ - if (failed) - { - free(inParam.tabMSEvalues); - free(inParam.tabPEAKvalues); - free(inParam.base_filename); - free(inParam.test_filename); - - free(filenamePNGbase); - free(filenamePNGtest); - - opj_image_destroy(imageBase); - opj_image_destroy(imageTest); - - free(param_image_diff); - - return EXIT_FAILURE; - } - imageDiff = opj_image_create(imageBase->numcomps, param_image_diff, OPJ_CLRSPC_UNSPECIFIED); /* Free memory*/ - free(param_image_diff); + free(param_image_diff); param_image_diff = NULL; /* Measurement computation*/ printf("Step 2 -> measurement comparison\n"); memsizedifffilename = strlen(inParam.test_filename) + 1 + 5 + 2 + 4; filenamePNGdiff = (char*) malloc(memsizedifffilename); - filenamePNGdiff[0] = '\0'; - strncpy(filenamePNGdiff, inParam.test_filename, strlen(inParam.test_filename)); - filenamePNGdiff[strlen(inParam.test_filename)] = '\0'; + strcpy(filenamePNGdiff, inParam.test_filename); strcat(filenamePNGdiff, ".diff"); /*printf("filenamePNGdiff = %s [%d / %d octets]\n",filenamePNGdiff, strlen(filenamePNGdiff),memsizedifffilename );*/ @@ -698,33 +839,16 @@ int main(int argc, char **argv) { double SE=0,PEAK=0; double MSE=0; - char *filenamePNGbase_it_comp, *filenamePNGtest_it_comp, *filenamePNGdiff_it_comp; - - filenamePNGbase_it_comp = (char*) malloc(memsizebasefilename); - filenamePNGbase_it_comp[0] = '\0'; - strncpy(filenamePNGbase_it_comp,filenamePNGbase,strlen(filenamePNGbase)); - filenamePNGbase_it_comp[strlen(filenamePNGbase)] = '\0'; - - filenamePNGtest_it_comp = (char*) malloc(memsizetestfilename); - filenamePNGtest_it_comp[0] = '\0'; - strncpy(filenamePNGtest_it_comp,filenamePNGtest,strlen(filenamePNGtest)); - filenamePNGtest_it_comp[strlen(filenamePNGtest)] = '\0'; - - filenamePNGdiff_it_comp = (char*) malloc(memsizedifffilename); - filenamePNGdiff_it_comp[0] = '\0'; - strncpy(filenamePNGdiff_it_comp,filenamePNGdiff,strlen(filenamePNGdiff)); - filenamePNGdiff_it_comp[strlen(filenamePNGdiff)] = '\0'; - for (itpxl = 0; itpxl < ((imageDiff->comps)[it_comp]).w * ((imageDiff->comps)[it_comp]).h; itpxl++) { if (abs( ((imageBase->comps)[it_comp]).data[itpxl] - ((imageTest->comps)[it_comp]).data[itpxl] ) > 0) { valueDiff = ((imageBase->comps)[it_comp]).data[itpxl] - ((imageTest->comps)[it_comp]).data[itpxl]; ((imageDiff->comps)[it_comp]).data[itpxl] = abs(valueDiff); - sumDiff += (double)valueDiff; + sumDiff += valueDiff; nbPixelDiff++; - SE += (double)(valueDiff * valueDiff); + SE += (double)valueDiff * valueDiff; PEAK = (PEAK > abs(valueDiff)) ? PEAK : abs(valueDiff); } else @@ -741,9 +865,9 @@ int main(int argc, char **argv) if ( (MSE > inParam.tabMSEvalues[it_comp]) || (PEAK > inParam.tabPEAKvalues[it_comp]) ) { printf("ERROR: MSE (%f) or PEAK (%f) values produced by the decoded file are greater " - "than the allowable error (respectively %f and %f) \n", - MSE, PEAK, inParam.tabMSEvalues[it_comp], inParam.tabPEAKvalues[it_comp]); - failed = 1; + "than the allowable error (respectively %f and %f) \n", + MSE, PEAK, inParam.tabMSEvalues[it_comp], inParam.tabPEAKvalues[it_comp]); + goto cleanup; } } else /* Non regression-test */ @@ -751,45 +875,65 @@ int main(int argc, char **argv) if ( nbPixelDiff > 0) { char it_compc[255]; - it_compc[0] = '\0'; + it_compc[0] = 0; printf(" %d \n", it_comp, nbPixelDiff); printf(" %f \n", it_comp, sumDiff); -#ifdef HAVE_LIBPNG - sprintf(it_compc, "_%i", it_comp); - strcat(it_compc,".png"); - strcat(filenamePNGbase_it_comp, it_compc); - /*printf("filenamePNGbase_it = %s [%d / %d octets]\n",filenamePNGbase_it_comp, strlen(filenamePNGbase_it_comp),memsizebasefilename );*/ - strcat(filenamePNGtest_it_comp, it_compc); - /*printf("filenamePNGtest_it = %s [%d / %d octets]\n",filenamePNGtest_it_comp, strlen(filenamePNGtest_it_comp),memsizetestfilename );*/ - strcat(filenamePNGdiff_it_comp, it_compc); - /*printf("filenamePNGdiff_it = %s [%d / %d octets]\n",filenamePNGdiff_it_comp, strlen(filenamePNGdiff_it_comp),memsizedifffilename );*/ +#ifdef OPJ_HAVE_LIBPNG + { + char *filenamePNGbase_it_comp, *filenamePNGtest_it_comp, *filenamePNGdiff_it_comp; - if ( imageToPNG(imageBase, filenamePNGbase_it_comp, it_comp) == EXIT_SUCCESS ) + filenamePNGbase_it_comp = (char*) malloc(memsizebasefilename); + strcpy(filenamePNGbase_it_comp,filenamePNGbase); + + filenamePNGtest_it_comp = (char*) malloc(memsizetestfilename); + strcpy(filenamePNGtest_it_comp,filenamePNGtest); + + filenamePNGdiff_it_comp = (char*) malloc(memsizedifffilename); + strcpy(filenamePNGdiff_it_comp,filenamePNGdiff); + + sprintf(it_compc, "_%i", it_comp); + strcat(it_compc,".png"); + strcat(filenamePNGbase_it_comp, it_compc); + /*printf("filenamePNGbase_it = %s [%d / %d octets]\n",filenamePNGbase_it_comp, strlen(filenamePNGbase_it_comp),memsizebasefilename );*/ + strcat(filenamePNGtest_it_comp, it_compc); + /*printf("filenamePNGtest_it = %s [%d / %d octets]\n",filenamePNGtest_it_comp, strlen(filenamePNGtest_it_comp),memsizetestfilename );*/ + strcat(filenamePNGdiff_it_comp, it_compc); + /*printf("filenamePNGdiff_it = %s [%d / %d octets]\n",filenamePNGdiff_it_comp, strlen(filenamePNGdiff_it_comp),memsizedifffilename );*/ + + /* + if ( imageToPNG(imageBase, filenamePNGbase_it_comp, it_comp) == EXIT_SUCCESS ) { printf(" %s \n", it_comp, filenamePNGbase_it_comp); } - if ( imageToPNG(imageTest, filenamePNGtest_it_comp, it_comp) == EXIT_SUCCESS ) + if ( imageToPNG(imageTest, filenamePNGtest_it_comp, it_comp) == EXIT_SUCCESS ) { printf(" %s \n", it_comp, filenamePNGtest_it_comp); } - if ( imageToPNG(imageDiff, filenamePNGdiff_it_comp, it_comp) == EXIT_SUCCESS ) + if ( imageToPNG(imageDiff, filenamePNGdiff_it_comp, it_comp) == EXIT_SUCCESS ) { printf(" %s \n", it_comp, filenamePNGdiff_it_comp); } + */ + + free(filenamePNGbase_it_comp); + free(filenamePNGtest_it_comp); + free(filenamePNGdiff_it_comp); + } #endif - failed = 1; + goto cleanup; } } - free(filenamePNGbase_it_comp); - free(filenamePNGtest_it_comp); - free(filenamePNGdiff_it_comp); } /* it_comp loop */ + printf("---- TEST SUCCEED ----\n"); + failed = 0; +cleanup: /*-----------------------------*/ + free(param_image_diff); /* Free memory */ opj_image_destroy(imageBase); opj_image_destroy(imageTest); @@ -804,11 +948,5 @@ int main(int argc, char **argv) free(inParam.base_filename); free(inParam.test_filename); - if (failed) - return EXIT_FAILURE; - else - { - printf("---- TEST SUCCEED ----\n"); - return EXIT_SUCCESS; - } + return failed ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/tests/compare_raw_files.c b/tests/compare_raw_files.c new file mode 100644 index 00000000..e7ab8c94 --- /dev/null +++ b/tests/compare_raw_files.c @@ -0,0 +1,192 @@ +/* + * Copyright (c) 2011-2012, Centre National d'Etudes Spatiales (CNES), France + * 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. + */ + +/* + * compare_raw_files.c + * + * Created on: 31 August 2011 + * Author: mickael + * + * This is equivalent to the UNIX `cmp` command + */ + +#include +#include +#include +#include + +#include "opj_getopt.h" + +typedef struct test_cmp_parameters +{ + /** */ + char* base_filename; + /** */ + char* test_filename; +} test_cmp_parameters; + +/******************************************************************************* + * Command line help function + *******************************************************************************/ +static void compare_raw_files_help_display(void) { + fprintf(stdout,"\nList of parameters for the compare_raw_files function \n"); + fprintf(stdout,"\n"); + fprintf(stdout," -b \t REQUIRED \t filename to the reference/baseline RAW image \n"); + fprintf(stdout," -t \t REQUIRED \t filename to the test RAW image\n"); + fprintf(stdout,"\n"); +} + +/******************************************************************************* + * Parse command line + *******************************************************************************/ +static int parse_cmdline_cmp(int argc, char **argv, test_cmp_parameters* param) +{ + size_t sizemembasefile, sizememtestfile; + int index; + const char optlist[] = "b:t:"; + int c; + + /* Init parameters*/ + param->base_filename = NULL; + param->test_filename = NULL; + + opj_opterr = 0; + while ((c = opj_getopt(argc, argv, optlist)) != -1) + switch (c) + { + case 'b': + sizemembasefile = strlen(opj_optarg)+1; + free(param->base_filename); /* handle dup option */ + param->base_filename = (char*) malloc(sizemembasefile); + strcpy(param->base_filename, opj_optarg); + /*printf("param->base_filename = %s [%d / %d]\n", param->base_filename, strlen(param->base_filename), sizemembasefile );*/ + break; + case 't': + sizememtestfile = strlen(opj_optarg) + 1; + free(param->test_filename); /* handle dup option */ + param->test_filename = (char*) malloc(sizememtestfile); + strcpy(param->test_filename, opj_optarg); + /*printf("param->test_filename = %s [%d / %d]\n", param->test_filename, strlen(param->test_filename), sizememtestfile);*/ + break; + case '?': + if ((opj_optopt == 'b') || (opj_optopt == 't')) + fprintf(stderr, "Option -%c requires an argument.\n", opj_optopt); + else + if (isprint(opj_optopt)) fprintf(stderr, "Unknown option `-%c'.\n", opj_optopt); + else fprintf(stderr, "Unknown option character `\\x%x'.\n", opj_optopt); + return 1; + default: + fprintf(stderr, "WARNING -> this option is not valid \"-%c %s\"\n", c, opj_optarg); + break; + } + + if (opj_optind != argc) { + for (index = opj_optind; index < argc; index++) + fprintf(stderr,"Non-option argument %s\n", argv[index]); + return 1; + } + + return 0; +} + +/******************************************************************************* + * MAIN + *******************************************************************************/ +int main(int argc, char **argv) +{ + int pos = 0; + test_cmp_parameters inParam; + FILE *file_test=NULL, *file_base=NULL; + unsigned char equal = 1; + + /* Get parameters from command line*/ + if (parse_cmdline_cmp(argc, argv, &inParam)) + { + compare_raw_files_help_display(); + goto cleanup; + } + + file_test = fopen(inParam.test_filename, "rb"); + if (!file_test) { + fprintf(stderr, "Failed to open %s for reading !!\n", inParam.test_filename); + goto cleanup; + } + + file_base = fopen(inParam.base_filename, "rb"); + if (!file_base) { + fprintf(stderr, "Failed to open %s for reading !!\n", inParam.base_filename); + goto cleanup; + } + + /* Read simultaneously the two files*/ + while (equal) + { + unsigned char value_test = 0; + unsigned char eof_test = 0; + unsigned char value_base = 0; + unsigned char eof_base = 0; + + /* Read one byte*/ + if (!fread(&value_test, 1, 1, file_test)) { + eof_test = 1; + } + + /* Read one byte*/ + if (!fread(&value_base, 1, 1, file_base)) { + eof_base = 1; + } + + /* End of file reached by the two files?*/ + if (eof_test && eof_base) + break; + + /* End of file reached only by one file?*/ + if (eof_test || eof_base) + { + fprintf(stdout,"Files have different sizes.\n"); + equal = 0; + } + + /* Binary values are equal?*/ + if (value_test != value_base) + { + fprintf(stdout,"Binary values read in the file are different %x vs %x at position %d.\n", value_test, value_base, pos); + equal = 0; + } + pos++; + } + + if(equal) fprintf(stdout,"---- TEST SUCCEED: Files are equal ----\n"); +cleanup: + if(file_test) fclose(file_test); + if(file_base) fclose(file_base); + + /* Free Memory */ + free(inParam.base_filename); + free(inParam.test_filename); + + return equal ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/conformance/CMakeLists.txt b/tests/conformance/CMakeLists.txt index 9af8d059..0b2ed0a0 100644 --- a/tests/conformance/CMakeLists.txt +++ b/tests/conformance/CMakeLists.txt @@ -16,284 +16,288 @@ set( CP1_nbC_list "not_used;1;3;4;1;3;3;2") set(COMMENTCODEVAR FALSE) -#-------------------------------------------------------------------------- -# Tests about class 0 profile 0 -# try to decode -# compare to ref file provided by the Executable Test Suite -# non regression comparison +##-------------------------------------------------------------------------- +## Tests about class 0 profile 0 +## try to decode +## compare to ref file provided by the Executable Test Suite +## non regression comparison -# Parameters and tolerances given by Table C.1 -set( C0P0_ResFactor_list "not_used;0;0;0;3;3;3;0;5;2;0;0;0;0;2;0;0") -set( C0P0_PEAK_list "not_used;0;0;0;33;54;109;10;7;4;10;0;0;0;0;0;0") -set( C0P0_MSE_list "not_used;0;0;0;55.8;68;743;0.34;6.72;1.47;2.84;0;0;0;0;0;0") +## Parameters and tolerances given by Table C.1 +#set( C0P0_ResFactor_list "not_used;0;0;0;3;3;3;0;5;2;0;0;0;0;2;0;0") +#set( C0P0_PEAK_list "not_used;0;0;0;33;54;109;10;7;4;10;0;0;0;0;0;0") +#set( C0P0_MSE_list "not_used;0;0;0;55.8;68;743;0.34;6.72;1.47;2.84;0;0;0;0;0;0") -foreach(numFileC0P0 RANGE 1 16) +#foreach(numFileC0P0 RANGE 1 16) - # Build filenames - if(${numFileC0P0} LESS 10) - set( filenameInput p0_0${numFileC0P0}.j2k ) - set( filenameRef c0p0_0${numFileC0P0}.pgx ) - else() - set( filenameInput p0_${numFileC0P0}.j2k ) - set( filenameRef c0p0_${numFileC0P0}.pgx ) - endif() +# # Build filenames +# if(${numFileC0P0} LESS 10) +# set( filenameInput p0_0${numFileC0P0}.j2k ) +# set( filenameRef c0p0_0${numFileC0P0}.pgx ) +# else() +# set( filenameInput p0_${numFileC0P0}.j2k ) +# set( filenameRef c0p0_${numFileC0P0}.pgx ) +# endif() - # Get corresponding tests parameters - list(GET C0P0_ResFactor_list ${numFileC0P0} ResFactor) - list(GET CP0_nbC_list ${numFileC0P0} nbComponents) - list(GET C0P0_PEAK_list ${numFileC0P0} PEAK_limit) - list(GET C0P0_MSE_list ${numFileC0P0} MSE_limit) +# # Get corresponding tests parameters +# list(GET C0P0_ResFactor_list ${numFileC0P0} ResFactor) +# #For Class-0 testing, we always focus on the first component only +# #list(GET CP0_nbC_list ${numFileC0P0} nbComponents) +# set( nbComponents "1") +# list(GET C0P0_PEAK_list ${numFileC0P0} PEAK_limit) +# list(GET C0P0_MSE_list ${numFileC0P0} MSE_limit) - # Manage cases which need to try different resolution reduction - if (numFileC0P0 EQUAL 3 OR numFileC0P0 EQUAL 15) - get_filename_component(filenameRefSub ${filenameRef} NAME_WE) - #r = 0 +# # Manage cases which need to try different resolution reduction +# if (numFileC0P0 EQUAL 3 OR numFileC0P0 EQUAL 15) +# get_filename_component(filenameRefSub ${filenameRef} NAME_WE) +# #r = 0 - add_test(ETS-C0P0-${filenameInput}-r0-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress - -i ${INPUT_CONF}/${filenameInput} - -o ${TEMP}/c0${filenameInput}-r0.pgx - -r 0 - ) +# add_test(ETS-C0P0-${filenameInput}-r0-decode +# ${EXECUTABLE_OUTPUT_PATH}/opj_decompress +# -i ${INPUT_CONF}/${filenameInput} +# -o ${TEMP}/c0${filenameInput}-r0.pgx +# -r 0 +# ) - add_test(ETS-C0P0-${filenameInput}-r0-compare2ref - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_CONF}/${filenameRefSub}r0.pgx - -t ${TEMP}/c0${filenameInput}-r0.pgx - -n ${nbComponents} - -p ${PEAK_limit} - -m ${MSE_limit} - -s t_ - ) +# add_test(ETS-C0P0-${filenameInput}-r0-compare2ref +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_CONF}/${filenameRefSub}r0.pgx +# -t ${TEMP}/c0${filenameInput}-r0.pgx +# -n ${nbComponents} +# -p ${PEAK_limit} +# -m ${MSE_limit} +# -s t_ +# ) - set_tests_properties(ETS-C0P0-${filenameInput}-r0-compare2ref - PROPERTIES DEPENDS - ETS-C0P0-${filenameInput}-r0-decode) +# set_tests_properties(ETS-C0P0-${filenameInput}-r0-compare2ref +# PROPERTIES DEPENDS +# ETS-C0P0-${filenameInput}-r0-decode) - add_test(NR-C0P0-${filenameInput}-r0-compare2base - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_NR}/opj_${filenameRefSub}-r0.pgx - -t ${TEMP}/c0${filenameInput}-r0.pgx - -n ${nbComponents} - -d - -s b_t_ - ) +# add_test(NR-C0P0-${filenameInput}-r0-compare2base +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_NR}/opj_${filenameRefSub}-r0.pgx +# -t ${TEMP}/c0${filenameInput}-r0.pgx +# -n ${nbComponents} +# -d +# -s b_t_ +# ) - set_tests_properties(NR-C0P0-${filenameInput}-r0-compare2base - PROPERTIES DEPENDS - ETS-C0P0-${filenameInput}-r0-decode) +# set_tests_properties(NR-C0P0-${filenameInput}-r0-compare2base +# PROPERTIES DEPENDS +# ETS-C0P0-${filenameInput}-r0-decode) - #r = 1 - add_test(ETS-C0P0-${filenameInput}-r1-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress - -i ${INPUT_CONF}/${filenameInput} - -o ${TEMP}/c0${filenameInput}-r1.pgx - -r 1 - ) +# #r = 1 +# add_test(ETS-C0P0-${filenameInput}-r1-decode +# ${EXECUTABLE_OUTPUT_PATH}/opj_decompress +# -i ${INPUT_CONF}/${filenameInput} +# -o ${TEMP}/c0${filenameInput}-r1.pgx +# -r 1 +# ) - add_test(ETS-C0P0-${filenameInput}-r1-compare2ref - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_CONF}/${filenameRefSub}r1.pgx - -t ${TEMP}/c0${filenameInput}-r1.pgx - -n ${nbComponents} - -p ${PEAK_limit} - -m ${MSE_limit} - -s t_ - ) +# add_test(ETS-C0P0-${filenameInput}-r1-compare2ref +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_CONF}/${filenameRefSub}r1.pgx +# -t ${TEMP}/c0${filenameInput}-r1.pgx +# -n ${nbComponents} +# -p ${PEAK_limit} +# -m ${MSE_limit} +# -s t_ +# ) - set_tests_properties(ETS-C0P0-${filenameInput}-r1-compare2ref - PROPERTIES DEPENDS - ETS-C0P0-${filenameInput}-r1-decode) +# set_tests_properties(ETS-C0P0-${filenameInput}-r1-compare2ref +# PROPERTIES DEPENDS +# ETS-C0P0-${filenameInput}-r1-decode) - add_test(NR-C0P0-${filenameInput}-r1-compare2base - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_NR}/opj_${filenameRefSub}-r1.pgx - -t ${TEMP}/c0${filenameInput}-r1.pgx - -n ${nbComponents} - -d - -s b_t_ - ) +# add_test(NR-C0P0-${filenameInput}-r1-compare2base +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_NR}/opj_${filenameRefSub}-r1.pgx +# -t ${TEMP}/c0${filenameInput}-r1.pgx +# -n ${nbComponents} +# -d +# -s b_t_ +# ) - set_tests_properties(NR-C0P0-${filenameInput}-r1-compare2base - PROPERTIES DEPENDS - ETS-C0P0-${filenameInput}-r1-decode) +# set_tests_properties(NR-C0P0-${filenameInput}-r1-compare2base +# PROPERTIES DEPENDS +# ETS-C0P0-${filenameInput}-r1-decode) - else() +# else() - add_test(ETS-C0P0-${filenameInput}-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress - -i ${INPUT_CONF}/${filenameInput} - -o ${TEMP}/c0${filenameInput}.pgx - -r ${ResFactor} - ) +# add_test(ETS-C0P0-${filenameInput}-decode +# ${EXECUTABLE_OUTPUT_PATH}/opj_decompress +# -i ${INPUT_CONF}/${filenameInput} +# -o ${TEMP}/c0${filenameInput}.pgx +# -r ${ResFactor} +# ) - add_test(ETS-C0P0-${filenameInput}-compare2ref - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_CONF}/${filenameRef} - -t ${TEMP}/c0${filenameInput}.pgx - -n ${nbComponents} - -p ${PEAK_limit} - -m ${MSE_limit} - -s t_ - ) +# add_test(ETS-C0P0-${filenameInput}-compare2ref +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_CONF}/${filenameRef} +# -t ${TEMP}/c0${filenameInput}.pgx +# -n ${nbComponents} +# -p ${PEAK_limit} +# -m ${MSE_limit} +# -s t_ +# ) - set_tests_properties(ETS-C0P0-${filenameInput}-compare2ref - PROPERTIES DEPENDS - ETS-C0P0-${filenameInput}-decode) +# set_tests_properties(ETS-C0P0-${filenameInput}-compare2ref +# PROPERTIES DEPENDS +# ETS-C0P0-${filenameInput}-decode) - add_test(NR-C0P0-${filenameInput}-compare2base - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_NR}/opj_${filenameRef} - -t ${TEMP}/c0${filenameInput}.pgx - -n ${nbComponents} - -d - -s b_t_ - ) +# add_test(NR-C0P0-${filenameInput}-compare2base +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_NR}/opj_${filenameRef} +# -t ${TEMP}/c0${filenameInput}.pgx +# -n ${nbComponents} +# -d +# -s b_t_ +# ) - set_tests_properties(NR-C0P0-${filenameInput}-compare2base - PROPERTIES DEPENDS - ETS-C0P0-${filenameInput}-decode) +# set_tests_properties(NR-C0P0-${filenameInput}-compare2base +# PROPERTIES DEPENDS +# ETS-C0P0-${filenameInput}-decode) - endif() +# endif() -endforeach() +#endforeach() -#-------------------------------------------------------------------------- -# Tests about class 0 profile 1 -# try to decode -# compare to ref file -# non regression comparison +##-------------------------------------------------------------------------- +## Tests about class 0 profile 1 +## try to decode +## compare to ref file +## non regression comparison -# Parameters and tolerances given by Table C.4 -set( C0P1_ResFactor_list "not_used;0;3;3;0;4;1;0") -set( C0P1_PEAK_list "not_used;0;35;28;2;128;128;0") -set( C0P1_MSE_list "not_used;0;74;18.8;0.550;16384;16384;0") +## Parameters and tolerances given by Table C.4 +#set( C0P1_ResFactor_list "not_used;0;3;3;0;4;1;0") +#set( C0P1_PEAK_list "not_used;0;35;28;2;128;128;0") +#set( C0P1_MSE_list "not_used;0;74;18.8;0.550;16384;16384;0") -foreach(numFileC0P1 RANGE 1 7) +#foreach(numFileC0P1 RANGE 1 7) - # Build filenames - set( filenameInput p1_0${numFileC0P1}.j2k ) - set( filenameRef c0p1_0${numFileC0P1}.pgx ) +# # Build filenames +# set( filenameInput p1_0${numFileC0P1}.j2k ) +# set( filenameRef c0p1_0${numFileC0P1}.pgx ) - # Get corresponding tests parameters - list(GET C0P1_ResFactor_list ${numFileC0P1} ResFactor) - list(GET CP1_nbC_list ${numFileC0P1} nbComponents) - list(GET C0P1_PEAK_list ${numFileC0P1} PEAK_limit) - list(GET C0P1_MSE_list ${numFileC0P1} MSE_limit) +# # Get corresponding tests parameters +# list(GET C0P1_ResFactor_list ${numFileC0P1} ResFactor) +# #For Class-0 testing, we always focus on the first component only +# #list(GET CP0_nbC_list ${numFileC0P0} nbComponents) +# set( nbComponents "1") +# list(GET C0P1_PEAK_list ${numFileC0P1} PEAK_limit) +# list(GET C0P1_MSE_list ${numFileC0P1} MSE_limit) - # Manage cases which need to try different resolution reduction - if (numFileC0P1 EQUAL 4 ) - get_filename_component(filenameRefSub ${filenameRef} NAME_WE) +# # Manage cases which need to try different resolution reduction +# if (numFileC0P1 EQUAL 4 ) +# get_filename_component(filenameRefSub ${filenameRef} NAME_WE) - #r = 0 - add_test(ETS-C0P1-${filenameInput}-r0-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress - -i ${INPUT_CONF}/${filenameInput} - -o ${TEMP}/c0${filenameInput}-r0.pgx - -r 0 - ) +# #r = 0 +# add_test(ETS-C0P1-${filenameInput}-r0-decode +# ${EXECUTABLE_OUTPUT_PATH}/opj_decompress +# -i ${INPUT_CONF}/${filenameInput} +# -o ${TEMP}/c0${filenameInput}-r0.pgx +# -r 0 +# ) - add_test(ETS-C0P1-${filenameInput}-r0-compare2ref - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_CONF}/${filenameRefSub}r0.pgx - -t ${TEMP}/c0${filenameInput}-r0.pgx - -n ${nbComponents} - -p ${PEAK_limit} - -m ${MSE_limit} - -s t_ - ) +# add_test(ETS-C0P1-${filenameInput}-r0-compare2ref +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_CONF}/${filenameRefSub}r0.pgx +# -t ${TEMP}/c0${filenameInput}-r0.pgx +# -n ${nbComponents} +# -p ${PEAK_limit} +# -m ${MSE_limit} +# -s t_ +# ) - set_tests_properties(ETS-C0P1-${filenameInput}-r0-compare2ref - PROPERTIES DEPENDS - ETS-C0P1-${filenameInput}-r0-decode) +# set_tests_properties(ETS-C0P1-${filenameInput}-r0-compare2ref +# PROPERTIES DEPENDS +# ETS-C0P1-${filenameInput}-r0-decode) - add_test(NR-C0P1-${filenameInput}-r0-compare2base - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_NR}/opj_${filenameRefSub}-r0.pgx - -t ${TEMP}/c0${filenameInput}-r0.pgx - -n ${nbComponents} - -d - -s b_t_ - ) +# add_test(NR-C0P1-${filenameInput}-r0-compare2base +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_NR}/opj_${filenameRefSub}-r0.pgx +# -t ${TEMP}/c0${filenameInput}-r0.pgx +# -n ${nbComponents} +# -d +# -s b_t_ +# ) - set_tests_properties(NR-C0P1-${filenameInput}-r0-compare2base - PROPERTIES DEPENDS - ETS-C0P1-${filenameInput}-r0-decode) +# set_tests_properties(NR-C0P1-${filenameInput}-r0-compare2base +# PROPERTIES DEPENDS +# ETS-C0P1-${filenameInput}-r0-decode) - #r = 3 - add_test(ETS-C0P1-${filenameInput}-r3-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress - -i ${INPUT_CONF}/${filenameInput} - -o ${TEMP}/c0${filenameInput}-r3.pgx - -r 3 - ) +# #r = 3 +# add_test(ETS-C0P1-${filenameInput}-r3-decode +# ${EXECUTABLE_OUTPUT_PATH}/opj_decompress +# -i ${INPUT_CONF}/${filenameInput} +# -o ${TEMP}/c0${filenameInput}-r3.pgx +# -r 3 +# ) - add_test(ETS-C0P1-${filenameInput}-r3-compare2ref - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_CONF}/${filenameRefSub}r3.pgx - -t ${TEMP}/c0${filenameInput}-r3.pgx - -n ${nbComponents} - -p ${PEAK_limit} - -m ${MSE_limit} - -s t_ - ) +# add_test(ETS-C0P1-${filenameInput}-r3-compare2ref +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_CONF}/${filenameRefSub}r3.pgx +# -t ${TEMP}/c0${filenameInput}-r3.pgx +# -n ${nbComponents} +# -p ${PEAK_limit} +# -m ${MSE_limit} +# -s t_ +# ) - set_tests_properties(ETS-C0P1-${filenameInput}-r3-compare2ref - PROPERTIES DEPENDS - ETS-C0P1-${filenameInput}-r3-decode) +# set_tests_properties(ETS-C0P1-${filenameInput}-r3-compare2ref +# PROPERTIES DEPENDS +# ETS-C0P1-${filenameInput}-r3-decode) - add_test(NR-C0P1-${filenameInput}-r3-compare2base - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_NR}/opj_${filenameRefSub}-r3.pgx - -t ${TEMP}/c0${filenameInput}-r3.pgx - -n ${nbComponents} - -d - -s b_t_ - ) +# add_test(NR-C0P1-${filenameInput}-r3-compare2base +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_NR}/opj_${filenameRefSub}-r3.pgx +# -t ${TEMP}/c0${filenameInput}-r3.pgx +# -n ${nbComponents} +# -d +# -s b_t_ +# ) - set_tests_properties(NR-C0P1-${filenameInput}-r3-compare2base - PROPERTIES DEPENDS - ETS-C0P1-${filenameInput}-r3-decode) +# set_tests_properties(NR-C0P1-${filenameInput}-r3-compare2base +# PROPERTIES DEPENDS +# ETS-C0P1-${filenameInput}-r3-decode) - else() +# else() - add_test(ETS-C0P1-${filenameInput}-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress - -i ${INPUT_CONF}/${filenameInput} - -o ${TEMP}/c0${filenameInput}.pgx - -r ${ResFactor} - ) +# add_test(ETS-C0P1-${filenameInput}-decode +# ${EXECUTABLE_OUTPUT_PATH}/opj_decompress +# -i ${INPUT_CONF}/${filenameInput} +# -o ${TEMP}/c0${filenameInput}.pgx +# -r ${ResFactor} +# ) - add_test(ETS-C0P1-${filenameInput}-compare2ref - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_CONF}/${filenameRef} - -t ${TEMP}/c0${filenameInput}.pgx - -n ${nbComponents} - -p ${PEAK_limit} - -m ${MSE_limit} - -s t_ - ) +# add_test(ETS-C0P1-${filenameInput}-compare2ref +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_CONF}/${filenameRef} +# -t ${TEMP}/c0${filenameInput}.pgx +# -n ${nbComponents} +# -p ${PEAK_limit} +# -m ${MSE_limit} +# -s t_ +# ) - set_tests_properties(ETS-C0P1-${filenameInput}-compare2ref - PROPERTIES DEPENDS - ETS-C0P1-${filenameInput}-decode) +# set_tests_properties(ETS-C0P1-${filenameInput}-compare2ref +# PROPERTIES DEPENDS +# ETS-C0P1-${filenameInput}-decode) - add_test(NR-C0P1-${filenameInput}-compare2base - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages - -b ${BASELINE_NR}/opj_${filenameRef} - -t ${TEMP}/c0${filenameInput}.pgx - -n ${nbComponents} - -d - -s b_t_ - ) +# add_test(NR-C0P1-${filenameInput}-compare2base +# ${EXECUTABLE_OUTPUT_PATH}/compare_images +# -b ${BASELINE_NR}/opj_${filenameRef} +# -t ${TEMP}/c0${filenameInput}.pgx +# -n ${nbComponents} +# -d +# -s b_t_ +# ) - set_tests_properties(NR-C0P1-${filenameInput}-compare2base - PROPERTIES DEPENDS - ETS-C0P1-${filenameInput}-decode) +# set_tests_properties(NR-C0P1-${filenameInput}-compare2base +# PROPERTIES DEPENDS +# ETS-C0P1-${filenameInput}-decode) - endif() +# endif() -endforeach() +#endforeach() #-------------------------------------------------------------------------- # Tests about class 1 profile 0 @@ -323,15 +327,15 @@ foreach(numFileC1P0 RANGE 1 16) list(GET C1P0_PEAK_list ${numFileC1P0} PEAK_limit) list(GET C1P0_MSE_list ${numFileC1P0} MSE_limit) - add_test(ETS-C1P0-${filenameInput}-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress + add_test(NAME ETS-C1P0-${filenameInput}-decode + COMMAND opj_decompress -i ${INPUT_CONF}/${filenameInput} -o ${TEMP}/c1${filenameInput}.pgx -r ${ResFactor} ) - add_test(ETS-C1P0-${filenameInput}-compare2ref - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages + add_test(NAME ETS-C1P0-${filenameInput}-compare2ref + COMMAND compare_images -b ${BASELINE_CONF}/${filenameRef} -t ${TEMP}/c1${filenameInput}.pgx -n ${nbComponents} @@ -344,8 +348,8 @@ foreach(numFileC1P0 RANGE 1 16) PROPERTIES DEPENDS ETS-C1P0-${filenameInput}-decode) - add_test(NR-C1P0-${filenameInput}-compare2base - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages + add_test(NAME NR-C1P0-${filenameInput}-compare2base + COMMAND compare_images -b ${BASELINE_NR}/opj_${filenameRef} -t ${TEMP}/c1${filenameInput}.pgx -n ${nbComponents} @@ -380,15 +384,15 @@ foreach(numFileC1P1 RANGE 1 7) list(GET C1P1_PEAK_list ${numFileC1P1} PEAK_limit) list(GET C1P1_MSE_list ${numFileC1P1} MSE_limit) - add_test(ETS-C1P1-${filenameInput}-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress + add_test(NAME ETS-C1P1-${filenameInput}-decode + COMMAND opj_decompress -i ${INPUT_CONF}/${filenameInput} -o ${TEMP}/c1${filenameInput}.pgx -r 0 ) - add_test(ETS-C1P1-${filenameInput}-compare2ref - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages + add_test(NAME ETS-C1P1-${filenameInput}-compare2ref + COMMAND compare_images -b ${BASELINE_CONF}/${filenameRef} -t ${TEMP}/c1${filenameInput}.pgx -n ${nbComponents} @@ -401,8 +405,8 @@ foreach(numFileC1P1 RANGE 1 7) PROPERTIES DEPENDS ETS-C1P1-${filenameInput}-decode) - add_test(NR-C1P1-${filenameInput}-compare2base - ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages + add_test(NAME NR-C1P1-${filenameInput}-compare2base + COMMAND compare_images -b ${BASELINE_NR}/opj_${filenameRef} -t ${TEMP}/c1${filenameInput}.pgx -n ${nbComponents} @@ -422,7 +426,8 @@ endforeach() # compare to ref file # non regression comparison -# Tolerances given by Table G.1 +# Tolerances given by Part 4 - Table G.1 +# Peak is set to 4 only foreach(numFileJP2 RANGE 1 9) @@ -430,39 +435,171 @@ foreach(numFileJP2 RANGE 1 9) set( filenameInput "file${numFileJP2}.jp2" ) set( filenameRef jp2_${numFileJP2}.tif ) - # Get corresponding tests parameters - list(GET JP2_PEAK_list ${numFileJP2} PEAK_limit) + add_test(NAME ETS-JP2-${filenameInput}-decode + COMMAND opj_decompress + -i ${INPUT_CONF}/${filenameInput} + -o ${TEMP}/${filenameInput}.tif + ) - add_test(ETS-JP2-${filenameInput}-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress - -i ${INPUT_CONF}/${filenameInput} - -o ${TEMP}/${filenameInput}.tif - ) -# -# FIXME: Need to implement a compare tif images function -# -# add_test(ETS-JP2-${filenameInput}-compare2ref -# ${EXECUTABLE_OUTPUT_PATH}/compareTIFimages -# -b ${BASELINE_CONF}/${filenameRef_tif} -# -t ${TEMP}/${filenameInput}.pgx -# -p 4 -# ) -# -# set_tests_properties(ETS-JP2-${filenameInput}-compare2ref -# PROPERTIES DEPENDS -# ETS-JP2-${filenameInput}-decode) -# -# add_test(NR-JP2-${filenameInput}-compare2base -# ${EXECUTABLE_OUTPUT_PATH}/compareTIFimages -# -b ${BASELINE_NR}/opj_${filenameRef} -# -t ${TEMP}/${filenameInput}.tif -# -d -# ) -# -# set_tests_properties(NR-JP2-${filenameInput}-compare2base -# PROPERTIES DEPENDS -# ETS-JP2-${filenameInput}-decode) + add_test(NAME ETS-JP2-${filenameInput}-compare2ref + COMMAND compare_images + -b ${BASELINE_CONF}/${filenameRef} + -t ${TEMP}/${filenameInput}.tif + -n 3 + -p 4:4:4 + -m 1:1:1 + -s b_t_ + ) + set_tests_properties(ETS-JP2-${filenameInput}-compare2ref + PROPERTIES DEPENDS + ETS-JP2-${filenameInput}-decode) + + add_test(NAME NR-JP2-${filenameInput}-compare2base + COMMAND compare_images + -b ${BASELINE_NR}/opj_${filenameRef} + -t ${TEMP}/${filenameInput}.tif + -n 3 + -d + -s b_t_ + ) + + set_tests_properties(NR-JP2-${filenameInput}-compare2base + PROPERTIES DEPENDS + ETS-JP2-${filenameInput}-decode) + +endforeach() + +#-------------------------------------------------------------------------- +# Tests about Kakadu/J2K file +# try to decode +# compare to ref file +# non regression comparison + +# Tolerances given by ??? + +set(kdu_j2k_conf_files + a1_mono + a2_colr + a3_mono + a4_colr + a5_mono + a6_mono_colr + b1_mono + b2_mono + b3_mono + c1_mono + c2_mono + d1_colr + d2_colr + e1_colr + e2_colr + f1_mono + f2_mono + g1_colr + g2_colr + g3_colr + g4_colr +) + +foreach(kdu_file ${kdu_j2k_conf_files}) + + # Build filenames + set( filenameInput "${kdu_file}.j2c" ) + set( filenameRef "${kdu_file}.ppm" ) + + add_test(NAME ETS-KDU-${filenameInput}-decode + COMMAND opj_decompress + -i ${INPUT_CONF}/${filenameInput} + -o ${TEMP}/${filenameInput}.ppm + ) + + if("${kdu_file}" STREQUAL "a6_mono_colr") + set(kdu_test_args -n 4 -s b_t_ ) + set(kdu_test_args_tol -p 4:4:4:4 -m 1:1:1:1) + else() + set(kdu_test_args -n 1 ) + set(kdu_test_args_tol -p 4:4:4 -m 1:1:1) + endif() + + add_test(NAME ETS-KDU-${filenameInput}-compare2ref + COMMAND compare_images + -b ${BASELINE_CONF}/${filenameRef} + -t ${TEMP}/${filenameInput}.ppm + ${kdu_test_args} + ${kdu_test_args_tol} + ) + + set_tests_properties(ETS-KDU-${filenameInput}-compare2ref + PROPERTIES DEPENDS + ETS-KDU-${filenameInput}-decode) + + add_test(NAME NR-KDU-${filenameInput}-compare2base + COMMAND compare_images + -b ${BASELINE_NR}/opj_${filenameRef} + -t ${TEMP}/${filenameInput}.ppm + ${kdu_test_args} + -d + ) + + set_tests_properties(NR-KDU-${filenameInput}-compare2base + PROPERTIES DEPENDS + ETS-KDU-${filenameInput}-decode) +endforeach() + +#-------------------------------------------------------------------------- +# Tests about Richter/J2K file +# try to decode +# compare to ref file +# non regression comparison + +# Tolerances given by ??? + +set(richter_jp2_conf_files + subsampling_1 + subsampling_2 + zoo1 + zoo2 +) + +foreach(r_file ${richter_jp2_conf_files}) + + # Build filenames + set( filenameInput "${r_file}.jp2" ) + set( filenameRef "${r_file}.ppm" ) + + add_test(NAME ETS-RIC-${filenameInput}-decode + COMMAND opj_decompress + -i ${INPUT_CONF}/${filenameInput} + -o ${TEMP}/${filenameInput}.ppm + ) + + set(ric_test_args -n 1) + + add_test(NAME ETS-RIC-${filenameInput}-compare2ref + COMMAND compare_images + -b ${BASELINE_CONF}/${filenameRef} + -t ${TEMP}/${filenameInput}.ppm + ${ric_test_args} + -p 4:4:4 + -m 2:2:2 + ) + + set_tests_properties(ETS-RIC-${filenameInput}-compare2ref + PROPERTIES DEPENDS + ETS-RIC-${filenameInput}-decode) + + add_test(NAME NR-RIC-${filenameInput}-compare2base + COMMAND compare_images + -b ${BASELINE_NR}/opj_${filenameRef} + -t ${TEMP}/${filenameInput}.ppm + ${ric_test_args} + -d + ) + + set_tests_properties(NR-RIC-${filenameInput}-compare2base + PROPERTIES DEPENDS + ETS-RIC-${filenameInput}-decode) endforeach() #--------------------------------------------------------------------------# @@ -485,14 +622,14 @@ foreach(numFileP0 RANGE 1 16) get_filename_component(filenameRefSub ${filenameInput} NAME_WE) - add_test(NR-${filenameInput}-dump - ${EXECUTABLE_OUTPUT_PATH}/opj_dump + add_test(NAME NR-${filenameInput}-dump + COMMAND opj_dump -i ${INPUT_CONF}/${filenameInput} -o ${TEMP}/${filenameInput}.txt ) - add_test(NR-${filenameInput}-compare_dump2base - ${EXECUTABLE_OUTPUT_PATH}/compare_dump_files + add_test(NAME NR-${filenameInput}-compare_dump2base + COMMAND compare_dump_files -b ${BASELINE_NR}/opj_v2_${filenameRefSub}.txt -t ${TEMP}/${filenameInput}.txt ) @@ -514,14 +651,14 @@ foreach(numFileP1 RANGE 1 7) set( filenameInput p1_0${numFileP1}.j2k ) get_filename_component(filenameInputSub ${filenameInput} NAME_WE) - add_test(NR-${filenameInput}-dump - ${EXECUTABLE_OUTPUT_PATH}/opj_dump + add_test(NAME NR-${filenameInput}-dump + COMMAND opj_dump -i ${INPUT_CONF}/${filenameInput} -o ${TEMP}/${filenameInput}.txt ) - add_test(NR-${filenameInput}-compare_dump2base - ${EXECUTABLE_OUTPUT_PATH}/compare_dump_files + add_test(NAME NR-${filenameInput}-compare_dump2base + COMMAND compare_dump_files -b ${BASELINE_NR}/opj_v2_${filenameInputSub}.txt -t ${TEMP}/${filenameInput}.txt ) @@ -543,14 +680,14 @@ foreach(numFileJP2 RANGE 1 9) set( filenameInput "file${numFileJP2}.jp2" ) get_filename_component(filenameInputSub ${filenameInput} NAME_WE) - add_test(NR-${filenameInput}-dump - ${EXECUTABLE_OUTPUT_PATH}/opj_dump + add_test(NAME NR-${filenameInput}-dump + COMMAND opj_dump -i ${INPUT_CONF}/${filenameInput} -o ${TEMP}/${filenameInput}.txt ) - add_test(NR-${filenameInput}-compare_dump2base - ${EXECUTABLE_OUTPUT_PATH}/compare_dump_files + add_test(NAME NR-${filenameInput}-compare_dump2base + COMMAND compare_dump_files -b ${BASELINE_NR}/opj_v2_${filenameInputSub}.txt -t ${TEMP}/${filenameInput}.txt ) diff --git a/tests/j2k_random_tile_access.c b/tests/j2k_random_tile_access.c index afe4bd41..1c24a5cd 100644 --- a/tests/j2k_random_tile_access.c +++ b/tests/j2k_random_tile_access.c @@ -221,7 +221,7 @@ int main(int argc, char **argv) l_stream = opj_stream_create_default_file_stream(fsrc,1); if (!l_stream){ fclose(fsrc); - fprintf(stderr, "ERROR -> failed to create the stream from the file\n"); + fprintf(stderr, "ERROR -> failed to create the stream from the file\n"); return EXIT_FAILURE; } diff --git a/tests/nonregression/CMakeLists.txt b/tests/nonregression/CMakeLists.txt index d03eb6aa..ee5209e3 100644 --- a/tests/nonregression/CMakeLists.txt +++ b/tests/nonregression/CMakeLists.txt @@ -18,8 +18,35 @@ find_package(KAKADU) # GENERATION OF THE TEST SUITE (DUMP) # Dump all files with the selected extension inside the input directory +# technically opj_dump should simply parse these one, since syntax is ok. +set(BLACKLIST_JPEG2000_TMP + 2539.pdf.SIGFPE.706.1712.jp2 + 0290cb77c5df21828fa74cf2ab2c84d8.SIGFPE.d25.31.jp2 + 26ccf3651020967f7778238ef5af08af.SIGFPE.d25.527.jp2 + 4035.pdf.SIGSEGV.d8b.3375.jp2 + 3635.pdf.asan.77.2930.jp2 + issue165.jp2 + #edf_c2_1103421.jp2 + edf_c2_1178956.jp2 + edf_c2_1000290.jp2 + #edf_c2_1000691.jp2 # ok + #edf_c2_20.jp2 #looks ok as per kdu_jp2info + edf_c2_1377017.jp2 + edf_c2_1002767.jp2 + #edf_c2_10025.jp2 + edf_c2_1000234.jp2 + edf_c2_225881.jp2 + edf_c2_1000671.jp2 + #edf_c2_1013627.jp2 # weird box, but kdu_jp2info ok + edf_c2_1015644.jp2 + edf_c2_101463.jp2 + edf_c2_1674177.jp2 + edf_c2_1673169.jp2 + ) + # Define a list of file which should be gracefully rejected: set(BLACKLIST_JPEG2000 + ${BLACKLIST_JPEG2000_TMP} broken.jp2 broken2.jp2 broken3.jp2 @@ -28,23 +55,30 @@ set(BLACKLIST_JPEG2000 gdal_fuzzer_check_comp_dx_dy.jp2 gdal_fuzzer_check_number_of_tiles.jp2 gdal_fuzzer_unchecked_numresolutions.jp2 + mem-b2ace68c-1381.jp2 + 1851.pdf.SIGSEGV.ce9.948.jp2 ) file(GLOB_RECURSE OPJ_DATA_NR_LIST "${INPUT_NR}/*.j2k" "${INPUT_NR}/*.j2c" "${INPUT_NR}/*.jp2" + "${INPUT_NR}/*.jpc" #"${INPUT_NR}/*.jpx" ) foreach(INPUT_FILENAME ${OPJ_DATA_NR_LIST}) get_filename_component(INPUT_FILENAME_NAME ${INPUT_FILENAME} NAME) - get_filename_component(INPUT_FILENAME_NAME_WE ${INPUT_FILENAME_NAME} NAME_WE) + #get_filename_component(INPUT_FILENAME_NAME_WE ${INPUT_FILENAME_NAME} NAME_WE) + # cannot use longest extension function, since some name contains multiples + # dots. Instead write out own shortest extension function: + string(FIND ${INPUT_FILENAME_NAME} "." SHORTEST_EXT_POS REVERSE) + string(SUBSTRING ${INPUT_FILENAME_NAME} 0 ${SHORTEST_EXT_POS} INPUT_FILENAME_NAME_WE) string(REGEX MATCH ${INPUT_FILENAME_NAME} bad_jpeg2000 ${BLACKLIST_JPEG2000}) # Dump the input image - add_test(NR-${INPUT_FILENAME_NAME}-dump - ${EXECUTABLE_OUTPUT_PATH}/opj_dump + add_test(NAME NR-${INPUT_FILENAME_NAME}-dump + COMMAND opj_dump -i ${INPUT_FILENAME} -o ${TEMP}/${INPUT_FILENAME_NAME}.txt -v @@ -57,8 +91,8 @@ foreach(INPUT_FILENAME ${OPJ_DATA_NR_LIST}) else() # Compare the dump output with the baseline - add_test(NR-${INPUT_FILENAME_NAME}-compare_dump2base - ${EXECUTABLE_OUTPUT_PATH}/compare_dump_files + add_test(NAME NR-${INPUT_FILENAME_NAME}-compare_dump2base + COMMAND compare_dump_files -b ${BASELINE_NR}/opj_v2_${INPUT_FILENAME_NAME_WE}.txt -t ${TEMP}/${INPUT_FILENAME_NAME}.txt ) @@ -116,6 +150,7 @@ else() endif() +set(nonregression_filenames_used) # Parse the command line found in the file(s) set(IT_TEST_ENC 0) set(IT_TEST_DEC 0) @@ -223,14 +258,13 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST}) #----- # Now we can add the test suite corresponding to a line command in the file #----- - # ENCODER TEST SUITE if(ENC_TEST_FOUND) math(EXPR IT_TEST_ENC "${IT_TEST_ENC}+1" ) # Encode an image into the jpeg2000 format - add_test(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode - ${EXECUTABLE_OUTPUT_PATH}/opj_compress + add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode + COMMAND opj_compress ${CMD_ARG_LIST_2} ) @@ -239,8 +273,8 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST}) else() # Dump the encoding file - add_test(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump - ${EXECUTABLE_OUTPUT_PATH}/opj_dump + add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-dump + COMMAND opj_dump -i ${OUTPUT_FILENAME} -o ${OUTPUT_FILENAME}-ENC-${IT_TEST_ENC}.txt ) @@ -249,8 +283,8 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST}) NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode) # Compare the dump file with the baseline - add_test(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dump2base - ${EXECUTABLE_OUTPUT_PATH}/compare_dump_files + add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dump2base + COMMAND compare_dump_files -b ${BASELINE_NR}/opj_v2_${OUTPUT_FILENAME_NAME_WE}-ENC-${IT_TEST_ENC}.txt -t ${OUTPUT_FILENAME}-ENC-${IT_TEST_ENC}.txt ) @@ -261,8 +295,8 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST}) # Decode the encoding file with kakadu expand command if (KDU_EXPAND_EXECUTABLE) - add_test(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref - ${KDU_EXPAND_EXECUTABLE} + add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-decode-ref + COMMAND ${KDU_EXPAND_EXECUTABLE} -i ${OUTPUT_FILENAME} -o ${OUTPUT_FILENAME}.raw ) @@ -272,8 +306,8 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST}) NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-encode) # Compare the decoding file with baseline generated from the kdu_expand and baseline.j2k - add_test(NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base - ${EXECUTABLE_OUTPUT_PATH}/compareRAWimages + add_test(NAME NR-ENC-${INPUT_FILENAME_NAME}-${IT_TEST_ENC}-compare_dec-ref-out2base + COMMAND compare_raw_files -b ${BASELINE_NR}/opj_${OUTPUT_FILENAME_NAME_WE}-ENC-${IT_TEST_ENC}.raw -t ${OUTPUT_FILENAME}.raw ) @@ -287,11 +321,15 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST}) # DECODER TEST SUITE else() + string(FIND ${INPUT_FILENAME} "nonregression" nr_pos) + if(${nr_pos} GREATER 0) + list(APPEND nonregression_filenames_used ${INPUT_FILENAME_NAME}) + endif() math(EXPR IT_TEST_DEC "${IT_TEST_DEC}+1" ) # Decode the input image - add_test(NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode - ${EXECUTABLE_OUTPUT_PATH}/opj_decompress + add_test(NAME NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode + COMMAND opj_decompress ${CMD_ARG_LIST_2} ) @@ -300,11 +338,20 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST}) set_tests_properties(NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode PROPERTIES WILL_FAIL TRUE) else() + # if not failed, check against registered md5: + add_test(NAME NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode-md5 COMMAND ${CMAKE_COMMAND} + -DREFFILE:STRING=${CMAKE_CURRENT_SOURCE_DIR}/md5refs.txt + -DOUTFILENAME:STRING=${OUTPUT_FILENAME} + -P ${CMAKE_CURRENT_SOURCE_DIR}/checkmd5refs.cmake) + + set_tests_properties(NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode-md5 + PROPERTIES DEPENDS NR-DEC-${INPUT_FILENAME_NAME}-${IT_TEST_DEC}-decode + ) # FIXME: add a compare2base function base on raw which # can output png diff files if necesary # add_test(NR-${filename}-compare2base -# ${EXECUTABLE_OUTPUT_PATH}/comparePGXimages +# ${EXECUTABLE_OUTPUT_PATH}/compare_images # -b ${BASELINE_NR}/opj_${filenameRef} # -t ${TEMP}/${filename}.pgx # -n ${nbComponents} @@ -323,3 +370,18 @@ foreach(OPJ_TEST_CMD_LINE ${OPJ_TEST_CMD_LINE_LIST}) endif() endforeach() + +set(existing_filenames) +foreach(f ${OPJ_DATA_NR_LIST}) + get_filename_component(ff ${f} NAME) + list(APPEND existing_filenames ${ff}) +endforeach() +list(REMOVE_ITEM existing_filenames ${nonregression_filenames_used}) + +# keep track of new addition: +# if we reach here, then a J2K files was added but no test is present in +# test_suite.ctest.in: +foreach(found_but_no_test ${existing_filenames}) + add_test(NAME Found-But-No-Test-${found_but_no_test} COMMAND ${CMAKE_COMMAND} -E echo "${found_but_no_test}") + set_tests_properties(Found-But-No-Test-${found_but_no_test} PROPERTIES WILL_FAIL TRUE) +endforeach() diff --git a/tests/nonregression/checkmd5refs.cmake b/tests/nonregression/checkmd5refs.cmake new file mode 100644 index 00000000..d6198af0 --- /dev/null +++ b/tests/nonregression/checkmd5refs.cmake @@ -0,0 +1,66 @@ +# Copyright (c) 2014 Mathieu Malaterre +# +# Redistribution and use is allowed according to the terms of the New +# BSD license. +# For details see the accompanying COPYING-CMAKE-SCRIPTS file. + +# check md5 refs +# +# This script will be used to make sure we never introduce a regression on any +# of the nonregression file. +# +# The approach is relatively simple, we compute a md5sum for each of the decode +# file. Anytime the md5sum is different from the reference one, we assume +# something went wrong and simply fails. of course if could happen during the +# course of openjpeg development that the internals are changed that impact the +# decoding process that the output would be bitwise different (while PSNR would +# be kept identical). + +# Another more conventional approach is to store the generated output from +# openjpeg however storing the full generated output is generally useless since +# we do not really care about the exact pixel value, we simply need to known +# when a code change impact output generation. furthermore storing the +# complete generated output file, tends to make the svn:/openjpeg-data really +# big. + +# This script expect two inputs +# REFFILE: Path to the md5sum.txt file +# OUTFILENAME: The name of the generated file we want to check The script will +# check whether a PGX or a PNG file was generated in the test suite (computed +# from OUTFILENAME) + +get_filename_component(OUTFILENAME_NAME ${OUTFILENAME} NAME) +string(FIND ${OUTFILENAME_NAME} "." SHORTEST_EXT_POS REVERSE) +string(SUBSTRING ${OUTFILENAME_NAME} 0 ${SHORTEST_EXT_POS} OUTFILENAME_NAME_WE) +file(GLOB globfiles "Temporary/${OUTFILENAME_NAME_WE}*.pgx" "Temporary/${OUTFILENAME_NAME_WE}*.png") +if(NOT globfiles) + message(SEND_ERROR "Could not find output PGX files: ${OUTFILENAME_NAME_WE}") +endif() + +# REFFILE follow what `md5sum -c` would expect as input: +file(READ ${REFFILE} variable) + +foreach(pgxfullpath ${globfiles}) + get_filename_component(pgxfile ${pgxfullpath} NAME) + execute_process( + COMMAND ${CMAKE_COMMAND} -E md5sum ${pgxfile} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/Temporary + RESULT_VARIABLE res + OUTPUT_VARIABLE output + ERROR_VARIABLE error_output + OUTPUT_STRIP_TRAILING_WHITESPACE # important + ) + + # Pass the output back to ctest + if(res) + message(SEND_ERROR "md5 could not be computed, it failed with value ${res}. Output was: ${error_output}") + endif() + + string(REGEX MATCH "[0-9a-f]+ ${pgxfile}" output_var "${variable}") + + if("${output_var}" STREQUAL "${output}") + message(STATUS "equal: [${output_var}] vs [${output}]") + else() + message(SEND_ERROR "not equal: [${output_var}] vs [${output}]") + endif() +endforeach() diff --git a/tests/nonregression/md5refs.txt b/tests/nonregression/md5refs.txt new file mode 100644 index 00000000..f52bed61 --- /dev/null +++ b/tests/nonregression/md5refs.txt @@ -0,0 +1,153 @@ +6f22c9a9bd474202ac6cd3a066e15200 _00042.j2k_0.pgx +a3a0606dfa0779d657c6a923b90e4678 _00042.j2k_1.pgx +106954dc468dfe0884d02268e91f9f5b _00042.j2k_2.pgx +8889def55f1e18dae6002b9b3a6dd152 123.j2c_0.pgx +4a0daf7a9065101379eaebc28e436b1e Bretagne2.j2k_0.pgx +07578fc7bf81d3da694de8ae27308b82 Bretagne2.j2k_1.pgx +3690c42f83bad42f4abea48525d45e0e Bretagne2.j2k_2.pgx +8889def55f1e18dae6002b9b3a6dd152 bug.j2c_0.pgx +22c8d33a956ba83079d1102457bc77a1 buxI.j2k_0.pgx +b8f473c07ba5ebfc195bdd53c3b3b97f buxR.j2k_0.pgx +05c062aca83d13b8095460f38a690a08 Cannotreaddatawithnosizeknown.j2k_0.pgx +6276da0ec5fac44d683d3468b290331d cthead1.j2k_0.pgx +8afcac9a696cc8d753b0eb9f4ae692ff CT_Phillips_JPEG2K_Decompr_Problem.j2k_0.pgx +04d35ab6160c9029549f72358df984da file409752.jp2_0.pgx +2813bd6fdc2c306b91b3da3688b8bf49 file409752.jp2_1.pgx +e273e2aaea4a4fc1b2cf7c09c53c3cc6 file409752.jp2_2.pgx +05c062aca83d13b8095460f38a690a08 illegalcolortransform.j2k_0.pgx +cccccccccccccccccccccccccccccccc issue104_jpxstream.jp2_0.pgx +cccccccccccccccccccccccccccccccc issue104_jpxstream.jp2_1.pgx +cccccccccccccccccccccccccccccccc issue104_jpxstream.jp2_2.pgx +c74edbb49e132b2cfc1eaf7908197b17 issue134.jp2_0.pgx +16fe8ed450da10a6aaae4cf6f467fc21 issue134.jp2_1.pgx +c6091c07bf0ff221008dfb60d893cdff issue134.jp2_2.pgx +cccccccccccccccccccccccccccccccc issue135.j2k_0.pgx +cccccccccccccccccccccccccccccccc issue135.j2k_1.pgx +cccccccccccccccccccccccccccccccc issue135.j2k_2.pgx +619694e5674992b3286244bf13058f7c issue142.j2k_0.pgx +c675c4b77dc3cc2a0d6542a32b438a48 issue142.j2k_1.pgx +663ebdd12dd6a36915ea1152c43cb69a issue142.j2k_2.pgx +c44662b1f7fe01caa2ebf3ad62948e3e issue171.jp2_0.pgx +f70e8a4e5dbefeb44d50edd79b6c4cf6 issue171.jp2_1.pgx +18bc167a1c851db2fd9f8c7af3289134 issue171.jp2_2.pgx +adda4f5e46845b96dd3df14a76aa7229 issue188_beach_64bitsbox.jp2_0.pgx +90a9709c166019d1e101e7b96d257ed9 issue188_beach_64bitsbox.jp2_1.pgx +37e23d2df06ee60bf0f9f5e1c16054d8 issue188_beach_64bitsbox.jp2_2.pgx +cb89739232898a823355861d834b5734 issue205.jp2_0.pgx +a09d34928fd86e6f2d7e6edc1764d2b7 issue205.jp2_1.pgx +6f712d0685f2c5522f01b238365f4284 issue205.jp2_2.pgx +de992d54d59032eb07d21983dbe8155b issue205.jp2_3.pgx +8fae7a39e459409f64e4529d2214087a issue206_image-000.jp2_0.pgx +555a504a93c9a14f61c894da3b393e87 issue206_image-000.jp2_1.pgx +5f06b7c45446ae20c22cada46478a9dc issue206_image-000.jp2_2.pgx +8c0025fe9ffbff839e7735c18f56f596 issue208.jp2_0.pgx +285fedd7e5e92624177d00eaa543e551 issue208.jp2_1.pgx +bc5178a807be5901938d7f555275933f issue208.jp2_2.pgx +37546d44ecf7f2ea40a4f25d177910f3 issue208.jp2_3.pgx +a0823d21d9de699353a3bd1adb23bd1c issue211.jp2_0.pgx +1820161df26c360a62d11800d6cf173f issue211.jp2_1.pgx +e1807db57b5f5192c4b77b83e8b5c477 issue228.j2k_0.pgx +cccccccccccccccccccccccccccccccc issue254.jp2_0.pgx +cccccccccccccccccccccccccccccccc issue254.jp2_1.pgx +cccccccccccccccccccccccccccccccc issue254.jp2_2.pgx +4093cc34d838780b35a8be410247fa7f j2k32.j2k_0.pgx +ce4e556aaa0844b92a92c35c200fc43e j2k32.j2k_1.pgx +ea926520f990640862f3fe6616097613 j2k32.j2k_2.pgx +66b60e866991e03f9a2de18e80d3102b kakadu_v4-4_openjpegv2_broken.j2k_0.pgx +12a8a4668315d9ae27969991251ce85f kodak_2layers_lrcp.j2c_0.pgx +56d0b0c547d6d5bb12f0c36e88722b11 kodak_2layers_lrcp.j2c_1.pgx +48ba092fb40090c160bbd08bdf7bdbf2 kodak_2layers_lrcp.j2c_2.pgx +05c062aca83d13b8095460f38a690a08 MarkerIsNotCompliant.j2k_0.pgx +ff73d2bd32951d9e55b02186aac24aff Marrin.jp2_0.pgx +55ce884dd2346af6a5172a434ee578fa Marrin.jp2_1.pgx +41ec1a0228c703b10f95388c1160753b mem-b2b86b74-2753.jp2_0.pgx +41ec1a0228c703b10f95388c1160753b mem-b2b86b74-2753.jp2_1.pgx +41ec1a0228c703b10f95388c1160753b mem-b2b86b74-2753.jp2_2.pgx +97557ab9e38a7aff621e583fbb66b099 merged.jp2_0.pgx +386fbdcd294429733e3272d62ed5a15a merged.jp2_1.pgx +d3907bbd67be1dae31b4377fa4dc0373 merged.jp2_2.pgx +de8bba9ac366eeb2f170f0cf3605cf12 movie_00000.j2k_0.pgx +334bac3285f7138e9dd29d59bdcb22ff movie_00000.j2k_1.pgx +5511d2c96d1d1f2062491e00d5234506 movie_00000.j2k_2.pgx +de8bba9ac366eeb2f170f0cf3605cf12 movie_00001.j2k_0.pgx +334bac3285f7138e9dd29d59bdcb22ff movie_00001.j2k_1.pgx +5511d2c96d1d1f2062491e00d5234506 movie_00001.j2k_2.pgx +de8bba9ac366eeb2f170f0cf3605cf12 movie_00002.j2k_0.pgx +334bac3285f7138e9dd29d59bdcb22ff movie_00002.j2k_1.pgx +5511d2c96d1d1f2062491e00d5234506 movie_00002.j2k_2.pgx +951a55623a92e97a064a350f11c2637d orb-blue10-lin-j2k.j2k_0.pgx +5033aaf699dfa3dfe041af33c9ad688d orb-blue10-lin-j2k.j2k_1.pgx +dbe33d72484caedf9c2cc18fd670884c orb-blue10-lin-j2k.j2k_2.pgx +0fec67d9546171699958c6682e725b79 orb-blue10-lin-j2k.j2k_3.pgx +84462261381b6732ec4f2addb0070d24 orb-blue10-lin-jp2.jp2_0.pgx +6129edf57e5db2344fcde5ce99ae8732 orb-blue10-lin-jp2.jp2_1.pgx +fdad26b1e078aa32bd4b77a5f44da43c orb-blue10-lin-jp2.jp2_2.pgx +0fec67d9546171699958c6682e725b79 orb-blue10-lin-jp2.jp2_3.pgx +671feee525e2485060536edbf21380f1 orb-blue10-win-j2k.j2k_0.pgx +912cdee24dd360b7999f7ee4a51083b4 orb-blue10-win-j2k.j2k_1.pgx +64833b4b7557936b9233087e92f8ae28 orb-blue10-win-j2k.j2k_2.pgx +789a299a1523b2d9d3f561d12a2da817 orb-blue10-win-j2k.j2k_3.pgx +671feee525e2485060536edbf21380f1 orb-blue10-win-jp2.jp2_0.pgx +7442756e83571c0e87493e03f12b2d34 orb-blue10-win-jp2.jp2_1.pgx +5f99ff2aeb17e167fe7049bcf339d0b3 orb-blue10-win-jp2.jp2_2.pgx +fe028d56d6c7aaee87239a115093412a orb-blue10-win-jp2.jp2_3.pgx +dc78dd4b7739c92cd5291b043cc232ed p0_04_1.j2k.png +e157ce3ec092931d48cdaf275180ed34 p0_04_2.j2k.png +0f0a9b3b8b41f2afaf5d80bf2f36f68c p0_04_3.j2k.png +f78b09250d08365b836654f717ec798c p0_04_4.j2k.png +d7243f4004a30d8856ef4dfa0b9f4bc8 p0_04_5.j2k.png +344233bbe643ad651f82d4e8aaa3be54 p0_04_6_1.j2k.png +d105747d8fb755ef18b37ef83832f7d3 p0_04_6_2.j2k.png +89000c4cb8a83fcb4166624055905258 p0_04_6_3.j2k.png +af2a3ce7be9c8fb2db66ddbceff1dd53 p0_04_6_4.j2k.png +757340902e8dc6d5baa4f8f4628e2bc4 p0_04_6_5.j2k.png +4ec7002317a835f71630a7787cbff30a p0_04_6.j2k.png +d7ed089096806af2f1bf687e1adb427f p0_04.j2k.png +4fecc6d5ebdc2db3bf3ef6bbbbb5b031 p1_04_10.j2k.png +ab969b1d17341d062a6f4d6966a1f221 p1_04_11.j2k.png +70fd9d6f155585258b13cb4b6c469e3f p1_04_12.j2k.png +38f9113129eed30445266dd67ac8ad7d p1_04_13.j2k.png +92945201639e6d8718dc474058f63e45 p1_04_14.j2k.png +bf7b8807d1617b8baa1cbd11af727061 p1_04_15.j2k.png +22afbf50bda7cd1ad562e6c0601c759a p1_04_16.j2k.png +d41f829c40140ec9972edf86681ee53a p1_04_17_t63.j2k.png +70fd9d6f155585258b13cb4b6c469e3f p1_04_17_t63_r2.j2k.png +80bde56ea4d1a5c2b81f3c4227ef754c p1_04_18.t12.j2k.png +5bb3e76ec9d742ec742959f3bb865018 p1_04_19_t12_r1.j2k.png +ef287e72806290a81f61e3d271bdb1dc p1_04_1.j2k.png +d41f829c40140ec9972edf86681ee53a p1_04_2.j2k.png +4dd2a41c60bcf71b8c410833b12706cf p1_04_3.j2k.png +75b9b427ddded86219e361206669482a p1_04_4.j2k.png +de2e66f82b9da9bc2dabda183a455b2f p1_04_5.j2k.png +d12b3c90d4b1cf78f0ad23eedcabe0ea p1_04_6.j2k.png +b3fccf3cbb7186841ba7b86e34cac0c2 p1_04.j2k.png +071597783b2141a12db1765b85943c1d p1_06_10_1.j2k.png +6778de9e9236144747fe4542d03bf6e5 p1_06_10_2.j2k.png +af083204299bbdd993286892b4c9cd29 p1_06_10.j2k.png +af083204299bbdd993286892b4c9cd29 p1_06_11.j2k.png +72a7f65be34450c9ec126fbc58399354 p1_06_1.j2k.png +85b4f3b8f7b987f83972a820d34372a7 p1_06_2.j2k.png +d4fc3ff73e8b5eafbcc2a111b97d362b p1_06_3.j2k.png +a954722553fb25692556cfa87a26bc1a p1_06_4.j2k.png +a62bb79d066e230ea7b34e24681de189 p1_06_5.j2k.png +13d78a5091b06239c2b2012f7927dce8 p1_06_6.j2k.png +da21d175c4dcb03ce1f0a227f49ed7b8 p1_06_7_1.j2k.png +5c434a489375fc9624bab49679cdec76 p1_06_7_2.j2k.png +ce2de61ad83a71c9b13ca5df0a987a69 p1_06_7_3.j2k.png +18f9fbfb0d29e83f697fa93523c53a2b p1_06_7_4.j2k.png +66ede889502134412872b9d8b1e40887 p1_06_7_5.j2k.png +071597783b2141a12db1765b85943c1d p1_06_7_6.j2k.png +85a2b9a1324d72a8cec7041f80529242 p1_06_7.j2k.png +7045c8722e92fb2d447a6dc235a3c619 p1_06_9_1.j2k.png +d41856648d936229f1e3e2cf7d7c7a4d p1_06_9_2.j2k.png +85b4f3b8f7b987f83972a820d34372a7 p1_06_9_3.j2k.png +5fa6e85d6cfa0ed51e5933b2e35f4854 p1_06_9.j2k.png +2e80dbe4a6af432b7f1b54dfa4e164ae p1_06.j2k.png +371aa0a7ff40a73b45f1fa41e210d1db pacs.ge.j2k_0.pgx +6ae110e1fb5a869af3dbc5fbc735b0bd relax.jp2_0.pgx +518a8f28dacc034982507f43763b88dd relax.jp2_1.pgx +c678b04f4d3e59b9d66a8bce37c553c0 relax.jp2_2.pgx +cdb1d69eb48ffd8545751326b86d9d7e test_lossless.j2k_0.pgx +a37e7e5811d7c0c7adb61582790ccd33 text_GBR.jp2_0.pgx +fc2173be54954a146b4e2887ee14be06 text_GBR.jp2_1.pgx +14108b4fb8d9126750db0424417ed17d text_GBR.jp2_2.pgx diff --git a/tests/nonregression/test_suite.ctest.in b/tests/nonregression/test_suite.ctest.in index b442050d..5c5c5091 100644 --- a/tests/nonregression/test_suite.ctest.in +++ b/tests/nonregression/test_suite.ctest.in @@ -32,9 +32,18 @@ opj_compress -i @INPUT_NR_PATH@/random-issue-0005.tif -o @TEMP_PATH@/random-issu # related to issue 62 opj_compress -i @INPUT_NR_PATH@/tmp-issue-0062.raw -o @TEMP_PATH@/tmp-issue-0062-u.raw.j2k -F 512,512,1,16,u opj_compress -i @INPUT_NR_PATH@/tmp-issue-0062.raw -o @TEMP_PATH@/tmp-issue-0062-s.raw.j2k -F 512,512,1,16,s -opj_compress -i @INPUT_NR_PATH@/X_4_2K_24_185_CBR_WB_000.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000.j2k -cinema2K 24 -opj_compress -i @INPUT_NR_PATH@/X_5_2K_24_235_CBR_STEM24_000.tif -o @TEMP_PATH@/X_5_2K_24_235_CBR_STEM24_000.j2k -cinema2K 24 -opj_compress -i @INPUT_NR_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000.tif -o @TEMP_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000.j2k -cinema2K 24 +opj_compress -i @INPUT_NR_PATH@/X_4_2K_24_185_CBR_WB_000.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_C2K_24.j2k -cinema2K 24 +opj_compress -i @INPUT_NR_PATH@/X_5_2K_24_235_CBR_STEM24_000.tif -o @TEMP_PATH@/X_5_2K_24_235_CBR_STEM24_000_C2K_24.j2k -cinema2K 24 +opj_compress -i @INPUT_NR_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000.tif -o @TEMP_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000_C2K_24.j2k -cinema2K 24 +opj_compress -i @INPUT_NR_PATH@/X_4_2K_24_185_CBR_WB_000.tif -o @TEMP_PATH@/X_4_2K_24_185_CBR_WB_000_C2K_48.j2k -cinema2K 48 +opj_compress -i @INPUT_NR_PATH@/X_5_2K_24_235_CBR_STEM24_000.tif -o @TEMP_PATH@/X_5_2K_24_235_CBR_STEM24_000_C2K_48.j2k -cinema2K 48 +opj_compress -i @INPUT_NR_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000.tif -o @TEMP_PATH@/X_6_2K_24_FULL_CBR_CIRCLE_000_C2K_48.j2k -cinema2K 48 +opj_compress -i @INPUT_NR_PATH@/ElephantDream_4K.tif -o @TEMP_PATH@/ElephantDream_4K_C4K.j2k -cinema4K +# issue 141 +opj_compress -i @INPUT_NR_PATH@/issue141.rawl -o @TEMP_PATH@/issue141.rawl.j2k -F 2048,2816,1,16,u +opj_compress -i @INPUT_NR_PATH@/issue141.rawl -o @TEMP_PATH@/issue141.rawl.j2k -F 2048,2816,1,16,u -I +# issue 46: +opj_compress -i @INPUT_NR_PATH@/Bretagne2.ppm -o @TEMP_PATH@/Bretagne2_0.j2k -c [64,64] # DECODER TEST SUITE opj_decompress -i @INPUT_NR_PATH@/Bretagne2.j2k -o @TEMP_PATH@/Bretagne2.j2k.pgx @@ -51,7 +60,7 @@ opj_decompress -i @INPUT_NR_PATH@/buxR.j2k -o @TEMP_PATH@/buxR.j2k.pgx opj_decompress -i @INPUT_NR_PATH@/Cannotreaddatawithnosizeknown.j2k -o @TEMP_PATH@/Cannotreaddatawithnosizeknown.j2k.pgx opj_decompress -i @INPUT_NR_PATH@/cthead1.j2k -o @TEMP_PATH@/cthead1.j2k.pgx opj_decompress -i @INPUT_NR_PATH@/CT_Phillips_JPEG2K_Decompr_Problem.j2k -o @TEMP_PATH@/CT_Phillips_JPEG2K_Decompr_Problem.j2k.pgx -!opj_decompress -i @INPUT_NR_PATH@/illegalcolortransform.j2k -o @TEMP_PATH@/illegalcolortransform.j2k.pgx +opj_decompress -i @INPUT_NR_PATH@/illegalcolortransform.j2k -o @TEMP_PATH@/illegalcolortransform.j2k.pgx opj_decompress -i @INPUT_NR_PATH@/j2k32.j2k -o @TEMP_PATH@/j2k32.j2k.pgx opj_decompress -i @INPUT_NR_PATH@/kakadu_v4-4_openjpegv2_broken.j2k -o @TEMP_PATH@/kakadu_v4-4_openjpegv2_broken.j2k.pgx opj_decompress -i @INPUT_NR_PATH@/MarkerIsNotCompliant.j2k -o @TEMP_PATH@/MarkerIsNotCompliant.j2k.pgx @@ -66,18 +75,18 @@ opj_decompress -i @INPUT_NR_PATH@/orb-blue10-win-j2k.j2k -o @TEMP_PATH@/orb-blu opj_decompress -i @INPUT_NR_PATH@/orb-blue10-win-jp2.jp2 -o @TEMP_PATH@/orb-blue10-win-jp2.jp2.pgx opj_decompress -i @INPUT_NR_PATH@/relax.jp2 -o @TEMP_PATH@/relax.jp2.pgx opj_decompress -i @INPUT_NR_PATH@/test_lossless.j2k -o @TEMP_PATH@/test_lossless.j2k.pgx -# text_GBR.jp2 file exhibt a error about a tile part with a index > of the number of tile-part in this tile. -!opj_decompress -i @INPUT_NR_PATH@/text_GBR.jp2 -o @TEMP_PATH@/text_GBR.jp2.pgx +# text_GBR.jp2 file exhibt a error about a tile part with a index > of the number of tile-part in this tile (related to issue 202, 206, 208) +opj_decompress -i @INPUT_NR_PATH@/text_GBR.jp2 -o @TEMP_PATH@/text_GBR.jp2.pgx # pacs.ge file should throw an error but finally it seems work with v2 opj_decompress -i @INPUT_NR_PATH@/pacs.ge.j2k -o @TEMP_PATH@/pacs.ge.j2k.pgx # related to issue 135 opj_decompress -i @INPUT_NR_PATH@/kodak_2layers_lrcp.j2c -o @TEMP_PATH@/kodak_2layers_lrcp.j2c.pgx opj_decompress -i @INPUT_NR_PATH@/kodak_2layers_lrcp.j2c -o @TEMP_PATH@/kodak_2layers_lrcp.j2c.pgx -l 2 -# related to issue 104 which is closed +# related to issue 104 and 110 opj_decompress -i @INPUT_NR_PATH@/issue104_jpxstream.jp2 -o @TEMP_PATH@/issue104_jpxstream.jp2.pgx # File not supported by kakadu (Malformed PCLR box) and not supoprter by openjpeg (problem with value of TPSot) -opj_decompress -i @INPUT_NR_PATH@/mem-b2ace68c-1381.jp2 -o @TEMP_PATH@/mem-b2ace68c-1381.jp2.pgx -# File which produced weird output with kakadu and not supoprter by openjpeg (problem with value of TPSot) +!opj_decompress -i @INPUT_NR_PATH@/mem-b2ace68c-1381.jp2 -o @TEMP_PATH@/mem-b2ace68c-1381.jp2.pgx +# File which produced weird output with kakadu and not supoprter by openjpeg (problem with value of TPSot, issue 202, 206, 208) opj_decompress -i @INPUT_NR_PATH@/mem-b2b86b74-2753.jp2 -o @TEMP_PATH@/mem-b2b86b74-2753.jp2.pgx # issue 191 raised by the gdal fuzzer test (should properly failed) !opj_decompress -i @INPUT_NR_PATH@/gdal_fuzzer_unchecked_numresolutions.jp2 -o @TEMP_PATH@/gdal_fuzzer_unchecked_numresolutions.pgx @@ -87,6 +96,75 @@ opj_decompress -i @INPUT_NR_PATH@/mem-b2b86b74-2753.jp2 -o @TEMP_PATH@/mem-b2b8 !opj_decompress -i @INPUT_NR_PATH@/gdal_fuzzer_check_number_of_tiles.jp2 -o @TEMP_PATH@/gdal_fuzzer_check_number_of_tiles.pgx # issue 194 raised by the gdal fuzzer test (should nicely failed) ! opj_decompress -i @INPUT_NR_PATH@/gdal_fuzzer_check_comp_dx_dy.jp2 -o @TEMP_PATH@/gdal_fuzzer_check_comp_dx_dy.pgx +# issue 202 +opj_decompress -i @INPUT_NR_PATH@/file409752.jp2 -o @TEMP_PATH@/file409752.jp2.pgx +# issue 188 +opj_decompress -i @INPUT_NR_PATH@/issue188_beach_64bitsbox.jp2 -o @TEMP_PATH@/issue188_beach_64bitsbox.jp2.pgx +# issue 206 +opj_decompress -i @INPUT_NR_PATH@/issue206_image-000.jp2 -o @TEMP_PATH@/issue206_image-000.jp2.pgx +# issue 205 +opj_decompress -i @INPUT_NR_PATH@/issue205.jp2 -o @TEMP_PATH@/issue205.jp2.pgx +# issue 225 (sumatrapdf) +!opj_decompress -i @INPUT_NR_PATH@/451.pdf.SIGSEGV.5b5.3723.jp2 -o @TEMP_PATH@/451.pdf.SIGSEGV.5b5.3723.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/1888.pdf.asan.35.988.jp2 -o @TEMP_PATH@/1888.pdf.asan.35.988.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/2539.pdf.SIGFPE.706.1712.jp2 -o @TEMP_PATH@/2539.pdf.SIGFPE.706.1712.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/2236.pdf.SIGSEGV.398.1376.jp2 -o @TEMP_PATH@/2236.pdf.SIGSEGV.398.1376.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/1336.pdf.asan.47.376.jp2 -o @TEMP_PATH@/1336.pdf.asan.47.376.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/1851.pdf.SIGSEGV.ce9.948.jp2 -o @TEMP_PATH@/1851.pdf.SIGSEGV.ce9.948.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/4149.pdf.SIGSEGV.cf7.3501.jp2 -o @TEMP_PATH@/4149.pdf.SIGSEGV.cf7.3501.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/4035.pdf.SIGSEGV.d8b.3375.jp2 -o @TEMP_PATH@/4035.pdf.SIGSEGV.d8b.3375.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/2977.pdf.asan.67.2198.jp2 -o @TEMP_PATH@/2977.pdf.asan.67.2198.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/451.pdf.SIGSEGV.ce9.3723.jp2 -o @TEMP_PATH@/451.pdf.SIGSEGV.ce9.3723.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/3635.pdf.asan.77.2930.jp2 -o @TEMP_PATH@/3635.pdf.asan.77.2930.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/1802.pdf.SIGSEGV.36e.894.jp2 -o @TEMP_PATH@/1802.pdf.SIGSEGV.36e.894.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/451.pdf.SIGSEGV.f4c.3723.jp2 -o @TEMP_PATH@/451.pdf.SIGSEGV.f4c.3723.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/2.pdf.SIGFPE.706.1112.jp2 -o @TEMP_PATH@/2.pdf.SIGFPE.706.1112.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/147af3f1083de4393666b7d99b01b58b_signal_sigsegv_130c531_6155_5136.jp2 -o @TEMP_PATH@/147af3f1083de4393666b7d99b01b58b_signal_sigsegv_130c531_6155_5136.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/4241ac039aba57e6a9c948d519d94216_asan_heap-oob_14650f2_7469_602.jp2 -o @TEMP_PATH@/4241ac039aba57e6a9c948d519d94216_asan_heap-oob_14650f2_7469_602.jp2 +# issue 228 (16bits/lossy) +opj_decompress -i @INPUT_NR_PATH@/issue228.j2k -o @TEMP_PATH@/issue228.j2k.pgx +# issue 229 +!opj_decompress -i @INPUT_NR_PATH@/27ac957758a35d00d6765a0c86350d9c.SIGFPE.d25.537.jpc -o @TEMP_PATH@27ac957758a35d00d6765a0c86350d9c.SIGFPE.d25.537.jpc.pgx +!opj_decompress -i @INPUT_NR_PATH@/26ccf3651020967f7778238ef5af08af.SIGFPE.d25.527.jp2 -o @TEMP_PATH@26ccf3651020967f7778238ef5af08af.SIGFPE.d25.527.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/0290cb77c5df21828fa74cf2ab2c84d8.SIGFPE.d25.31.jp2 -o @TEMP_PATH@0290cb77c5df21828fa74cf2ab2c84d8.SIGFPE.d25.31.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/3672da2f1f67bbecad27d7181b4e9d7c.SIGFPE.d25.805.jpc -o @TEMP_PATH@3672da2f1f67bbecad27d7181b4e9d7c.SIGFPE.d25.805.jpc.pgx +# issue 254 (loss in quality) +opj_decompress -i @INPUT_NR_PATH@/issue254.jp2 -o @TEMP_PATH@/issue254.jp2.pgx +# issue 142 +opj_decompress -i @INPUT_NR_PATH@/issue142.j2k -o @TEMP_PATH@/issue142.j2k.pgx +# issue 134 +opj_decompress -i @INPUT_NR_PATH@/issue134.jp2 -o @TEMP_PATH@/issue134.jp2.pgx +# issue 135 +opj_decompress -i @INPUT_NR_PATH@/issue135.j2k -o @TEMP_PATH@/issue135.j2k.pgx +# issue 208 +opj_decompress -i @INPUT_NR_PATH@/issue208.jp2 -o @TEMP_PATH@/issue208.jp2.pgx +# issue 211 +opj_decompress -i @INPUT_NR_PATH@/issue211.jp2 -o @TEMP_PATH@/issue211.jp2.pgx +# issue 171 +opj_decompress -i @INPUT_NR_PATH@/issue171.jp2 -o @TEMP_PATH@/issue171.jp2.pgx +# issue 171 +!opj_decompress -i @INPUT_NR_PATH@/issue165.jp2 -o @TEMP_PATH@/issue165.jp2.pgx +# +!opj_decompress -i @INPUT_NR_PATH@/broken.jpc -o @TEMP_PATH@/broken.jpc.pgx +# issue 226 +opj_decompress -i @INPUT_NR_PATH@/issue226.j2k -o @TEMP_PATH@/issue226.j2k.pgx +# issue 297 +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1103421.jp2 -o @TEMP_PATH@/edf_c2_1103421.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1178956.jp2 -o @TEMP_PATH@/edf_c2_1178956.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1000290.jp2 -o @TEMP_PATH@/edf_c2_1000290.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1000691.jp2 -o @TEMP_PATH@/edf_c2_1000691.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_20.jp2 -o @TEMP_PATH@/edf_c2_20.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1377017.jp2 -o @TEMP_PATH@/edf_c2_1377017.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1002767.jp2 -o @TEMP_PATH@/edf_c2_1002767.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_10025.jp2 -o @TEMP_PATH@/edf_c2_10025.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1000234.jp2 -o @TEMP_PATH@/edf_c2_1000234.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_225881.jp2 -o @TEMP_PATH@/edf_c2_225881.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1000671.jp2 -o @TEMP_PATH@/edf_c2_1000671.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1013627.jp2 -o @TEMP_PATH@/edf_c2_1013627.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1015644.jp2 -o @TEMP_PATH@/edf_c2_1015644.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_101463.jp2 -o @TEMP_PATH@/edf_c2_101463.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1674177.jp2 -o @TEMP_PATH@/edf_c2_1674177.jp2.pgx +!opj_decompress -i @INPUT_NR_PATH@/edf_c2_1673169.jp2 -o @TEMP_PATH@/edf_c2_1673169.jp2.pgx # decode with specific area # prec=12; nb_c=1 @@ -118,27 +196,27 @@ opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_3.j2k.png -d opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_4.j2k.png -d 3,3,9,9 opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_5.j2k.png -d 4,4,7,7 opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_6.j2k.png -d 4,4,5,5 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06.j2k.png -d 0,0,12,12 -r 1 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_1.j2k.png -d 1,8,8,11 -r 1 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_2.j2k.png -d 9,9,12,12 -r 1 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_3.j2k.png -d 10,4,12,10 -r 1 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_4.j2k.png -d 3,3,9,9 -r 1 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_5.j2k.png -d 4,4,7,7 -r 1 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_6.j2k.png -d 4,4,5,5 -r 1 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7.j2k.png -d 0,0,12,12 -r 1 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_1.j2k.png -d 1,8,8,11 -r 1 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_2.j2k.png -d 9,9,12,12 -r 1 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_3.j2k.png -d 10,4,12,10 -r 1 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_4.j2k.png -d 3,3,9,9 -r 1 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_5.j2k.png -d 4,4,7,7 -r 1 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_7_6.j2k.png -d 4,4,5,5 -r 1 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_6.j2k.png -d 9,9,12,12 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_8_6.j2k.png -d 9,9,12,12 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06.j2k_t0.png -t 0 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_1.j2k_t5.png -t 5 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_2.j2k_t9.png -t 9 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_3.j2k_t15.png -t 15 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_9.j2k.png -t 0 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_9_1.j2k.png -t 5 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_9_2.j2k.png -t 9 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_9_3.j2k.png -t 15 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06.j2k_t0.png -t 0 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_1.j2k_t5.png -t 5 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_2.j2k_t9.png -t 9 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_3.j2k_t15.png -t 15 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_10.j2k.png -t 0 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_10_1.j2k.png -t 5 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_10_2.j2k.png -t 9 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_10_3.j2k.png -t 15 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06.j2k_r4.png -r 4 +opj_decompress -i @INPUT_CONF_PATH@/p1_06.j2k -o @TEMP_PATH@/p1_06_11.j2k.png -r 4 # prec=4; nb_c=3 ; signd=yes opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04.j2k.png -d 0,0,256,256 @@ -147,12 +225,12 @@ opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_2.j2k.png -d opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_3.j2k.png -d 10,150,190,210 opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_4.j2k.png -d 100,80,200,150 opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_5.j2k.png -d 150,20,200,50 -opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04.j2k.png -d 0,0,256,256 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_1.j2k.png -d 128,0,256,128 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_2.j2k.png -d 50,10,120,200 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_3.j2k.png -d 10,150,190,210 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_4.j2k.png -d 100,80,200,150 -r 2 -opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_5.j2k.png -d 150,20,200,50 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6.j2k.png -d 0,0,256,256 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_1.j2k.png -d 128,0,256,128 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_2.j2k.png -d 50,10,120,200 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_3.j2k.png -d 10,150,190,210 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_4.j2k.png -d 100,80,200,150 -r 2 +opj_decompress -i @INPUT_CONF_PATH@/p0_04.j2k -o @TEMP_PATH@/p0_04_6_5.j2k.png -d 150,20,200,50 -r 2 # prec=8; nb_c=1 ; non standard origin (image offset and tile offset); sample sep: 2x1 #opj_decompress -i @INPUT_CONF_PATH@/p1_01.j2k -o @TEMP_PATH@/p1_01.j2k.png -d 5,128,127,226 diff --git a/tests/ppm2rgb3.c b/tests/ppm2rgb3.c new file mode 100644 index 00000000..58e7102c --- /dev/null +++ b/tests/ppm2rgb3.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2014, 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. + */ + +/* + * Technically on UNIX, one can simply call `ppmtorgb3`, but on my system it + * did not work. So I had to write my own. + */ + +#include /* fprintf */ +#include /* strcmp */ +#include /* malloc */ + +static const char magic[] = "P6"; + +static int readheader( FILE *ppm, int *X, int *Y, int *bpp ) +{ + char buffer[256]; + char strbuffer[256]; + char *line; + int n; + + *X = *Y = *bpp = 0; + + line = fgets(buffer, sizeof(buffer), ppm); + if( !line ) return 0; + n = sscanf(buffer, "%255[^\r\n]", strbuffer); + if( n != 1 ) return 0; + if( strcmp(strbuffer, magic ) != 0 ) return 0; + + /* skip comments */ + while( fgets(buffer, sizeof(buffer), ppm) && *buffer == '#' ) + { + } + n = sscanf(buffer, "%d %d", X,Y); + if( n != 2 ) return 0; + line = fgets(buffer, sizeof(buffer), ppm); + if( !line ) return 0; + n = sscanf(buffer, "%d", bpp); + if( n != 1 ) return 0; + if( *bpp != 255 ) return 0; + + return 1; +} + +static int writeoutput( const char *fn, FILE *ppm, int X, int Y, int bpp ) +{ + FILE *outf[] = {NULL, NULL, NULL}; + int i, x, y = 0; + char outfn[256]; + static const char *exts[3] = { + "red", + "grn", + "blu" + }; + char *image_line = NULL; + int ok = 0; + + /* write single comp as PGM: P5 */ + for( i = 0; i < 3; ++i ) + { +#ifdef _MSC_VER +#define snprintf _snprintf /* Visual Studio */ +#endif + snprintf( outfn, sizeof(outfn), "%s.%s.pgm", fn, exts[i] ); + outf[i] = fopen( outfn, "wb" ); + if( !outf[i] ) goto cleanup; + /* write header */ + fprintf( outf[i], "P5\n" ); + fprintf( outf[i], "%d %d\n", X, Y ); + fprintf( outf[i], "%d\n", bpp ); + } + + /* write pixel data */ + image_line = (char*)malloc( (size_t)X * 3 * sizeof(char) ); + if( !image_line ) goto cleanup; + while( fread(image_line, sizeof(char), (size_t)X * 3, ppm) == (size_t)X * 3 ) + { + for( x = 0; x < X; ++x ) + for( i = 0; i < 3; ++i ) + if( fputc( image_line[3*x+i], outf[i] ) == EOF ) goto cleanup; + ++y; + } + if( y == Y ) + ok = 1; +cleanup: + free(image_line); + for( i = 0; i < 3; ++i ) + if( outf[i] ) fclose( outf[i] ); + + return ok; +} + +int main(int argc, char *argv[]) +{ + const char *fn; + FILE *ppm = NULL; + int X, Y, bpp; + int ok = 0; + + if( argc < 2 ) + { + fprintf( stderr, "%s input.ppm\n", argv[0] ); + goto cleanup; + } + fn = argv[1]; + ppm = fopen( fn, "rb" ); + + if( !readheader( ppm, &X, &Y, &bpp ) ) goto cleanup; + + if( !writeoutput(fn, ppm, X, Y, bpp ) ) goto cleanup; + + ok = 1; +cleanup: + if(ppm) fclose(ppm); + return ok ? EXIT_SUCCESS : EXIT_FAILURE; +} diff --git a/tests/test_tile_decoder.c b/tests/test_tile_decoder.c index 81f791cb..9779eb2e 100644 --- a/tests/test_tile_decoder.c +++ b/tests/test_tile_decoder.c @@ -99,7 +99,7 @@ static int infile_format(const char *fname) return -1; memset(buf, 0, 12); - l_nb_read = fread(buf, 1, 12, reader); + l_nb_read = (unsigned int)fread(buf, 1, 12, reader); fclose(reader); if (l_nb_read != 12) return -1; @@ -136,20 +136,6 @@ static int infile_format(const char *fname) /* -------------------------------------------------------------------------- */ -/** - sample error callback expecting a FILE* client object - */ -static void error_callback_file(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** - sample warning callback expecting a FILE* client object - */ -static void warning_callback_file(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[WARNING] %s", msg); -} /** sample error debug callback expecting no client object */ @@ -186,8 +172,7 @@ int main (int argc, char *argv[]) OPJ_UINT32 l_tile_index; OPJ_BYTE * l_data = (OPJ_BYTE *) malloc(1000); OPJ_BOOL l_go_on = OPJ_TRUE; - OPJ_INT32 l_tile_x0=0, l_tile_y0=0 ; - OPJ_UINT32 l_tile_width=0, l_tile_height=0, l_nb_tiles_x=0, l_nb_tiles_y=0, l_nb_comps=0 ; + OPJ_UINT32 l_nb_comps=0 ; OPJ_INT32 l_current_tile_x0,l_current_tile_y0,l_current_tile_x1,l_current_tile_y1; int da_x0=0; diff --git a/tests/test_tile_encoder.c b/tests/test_tile_encoder.c index 22ecb348..350890c4 100644 --- a/tests/test_tile_encoder.c +++ b/tests/test_tile_encoder.c @@ -35,20 +35,6 @@ /* -------------------------------------------------------------------------- */ -/** -sample error callback expecting a FILE* client object -*/ -static void error_callback_file(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** -sample warning callback expecting a FILE* client object -*/ -static void warning_callback_file(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[WARNING] %s", msg); -} /** sample error debug callback expecting no client object */ @@ -116,7 +102,7 @@ int main (int argc, char *argv[]) /* should be test_tile_encoder 3 2000 2000 1000 1000 8 tte1.j2k */ if( argc == 9 ) { - num_comps = atoi( argv[1] ); + num_comps = (OPJ_UINT32)atoi( argv[1] ); image_width = atoi( argv[2] ); image_height = atoi( argv[3] ); tile_width = atoi( argv[4] ); @@ -140,14 +126,14 @@ int main (int argc, char *argv[]) { return 1; } - l_nb_tiles = (image_width/tile_width) * (image_height/tile_height); - l_data_size = tile_width * tile_height * num_comps * (comp_prec/8); + l_nb_tiles = (OPJ_UINT32)(image_width/tile_width) * (OPJ_UINT32)(image_height/tile_height); + l_data_size = (OPJ_UINT32)tile_width * (OPJ_UINT32)tile_height * (OPJ_UINT32)num_comps * (OPJ_UINT32)(comp_prec/8); - l_data = (OPJ_BYTE*) malloc(tile_width * tile_height * num_comps * (comp_prec/8) * sizeof(OPJ_BYTE)); + l_data = (OPJ_BYTE*) malloc(l_data_size * sizeof(OPJ_BYTE)); fprintf(stdout, "Encoding random values -> keep in mind that this is very hard to compress\n"); for (i=0;idx = 1; l_current_param_ptr->dy = 1; - l_current_param_ptr->h = image_height; - l_current_param_ptr->w = image_width; + l_current_param_ptr->h = (OPJ_UINT32)image_height; + l_current_param_ptr->w = (OPJ_UINT32)image_width; l_current_param_ptr->sgnd = 0; - l_current_param_ptr->prec = comp_prec; + l_current_param_ptr->prec = (OPJ_UINT32)comp_prec; l_current_param_ptr->x0 = 0; l_current_param_ptr->y0 = 0; @@ -241,7 +227,7 @@ int main (int argc, char *argv[]) } /* should we do j2k or jp2 ?*/ - len = strlen( output_file ); + len = (unsigned char)strlen( output_file ); if( strcmp( output_file + len - 4, ".jp2" ) == 0 ) { l_codec = opj_create_compress(OPJ_CODEC_JP2); @@ -267,8 +253,8 @@ int main (int argc, char *argv[]) l_image->x0 = 0; l_image->y0 = 0; - l_image->x1 = image_width; - l_image->y1 = image_height; + l_image->x1 = (OPJ_UINT32)image_width; + l_image->y1 = (OPJ_UINT32)image_height; l_image->color_space = OPJ_CLRSPC_SRGB; if (! opj_setup_encoder(l_codec,&l_param,l_image)) { @@ -287,6 +273,13 @@ int main (int argc, char *argv[]) } l_stream = opj_stream_create_default_file_stream(l_file, OPJ_FALSE); + if (! l_stream) { + fprintf(stderr, "ERROR -> test_tile_encoder: failed to create the stream from the output file %s !\n",output_file ); + fclose(l_file); + opj_destroy_codec(l_codec); + opj_image_destroy(l_image); + return 1; + } if (! opj_start_compress(l_codec,l_image,l_stream)) { fprintf(stderr, "ERROR -> test_tile_encoder: failed to start compress!\n"); diff --git a/tests/unit/CMakeLists.txt b/tests/unit/CMakeLists.txt index d6bca7ad..ae47b88e 100644 --- a/tests/unit/CMakeLists.txt +++ b/tests/unit/CMakeLists.txt @@ -5,14 +5,13 @@ include_directories( ${OPENJPEG_SOURCE_DIR}/src/lib/openjp2 ) -add_executable(testempty0 testempty0.c) -add_executable(testempty1 testempty1.c) -add_executable(testempty2 testempty2.c) - -target_link_libraries(testempty0 openjp2) -target_link_libraries(testempty1 openjp2) -target_link_libraries(testempty2 openjp2) - -add_test(testempty0 ${EXECUTABLE_OUTPUT_PATH}/testempty0) -add_test(testempty1 ${EXECUTABLE_OUTPUT_PATH}/testempty1) -add_test(testempty2 ${EXECUTABLE_OUTPUT_PATH}/testempty2) +set(unit_test + testempty0 + testempty1 + testempty2 +) +foreach(ut ${unit_test}) + add_executable(${ut} ${ut}.c) + target_link_libraries(${ut} openjp2) + add_test(NAME ${ut} COMMAND ${ut}) +endforeach() diff --git a/tests/unit/testempty0.c b/tests/unit/testempty0.c index 32d6f266..09850604 100644 --- a/tests/unit/testempty0.c +++ b/tests/unit/testempty0.c @@ -1,3 +1,7 @@ -#include +#include "openjpeg.h" -int main(int argc, char **argv) { return 0; } +int main(int argc, char **argv) { + (void)argc; + (void)argv; + return 0; +} diff --git a/tests/unit/testempty1.c b/tests/unit/testempty1.c index add522a6..8e30a5f4 100644 --- a/tests/unit/testempty1.c +++ b/tests/unit/testempty1.c @@ -39,7 +39,7 @@ void info_callback(const char *msg, void *v); void error_callback(const char *msg, void *v) { (void)msg; (void)v; -assert(0); +puts(msg); } void warning_callback(const char *msg, void *v) { (void)msg; @@ -57,15 +57,15 @@ int main(int argc, char *argv[]) const char * v = opj_version(); const OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_GRAY; - int numcomps = 1; - int i; - int image_width = 256; - int image_height = 256; + unsigned int numcomps = 1; + unsigned int i; + unsigned int image_width = 256; + unsigned int image_height = 256; opj_cparameters_t parameters; - int subsampling_dx = 0; - int subsampling_dy = 0; + unsigned int subsampling_dx = 0; + unsigned int subsampling_dy = 0; opj_image_cmptparm_t cmptparm; opj_image_t *image; @@ -92,17 +92,17 @@ int main(int argc, char *argv[]) for (i = 0; i < image_width * image_height; i++) { - int compno; + unsigned int compno; for(compno = 0; compno < numcomps; compno++) { image->comps[compno].data[i] = 0; } } - /* catch events using our callbacks and give a local context */ - opj_set_info_handler(l_codec, info_callback,00); - opj_set_warning_handler(l_codec, warning_callback,00); - opj_set_error_handler(l_codec, error_callback,00); + /* catch events using our callbacks and give a local context */ + opj_set_info_handler(l_codec, info_callback,00); + opj_set_warning_handler(l_codec, warning_callback,00); + opj_set_error_handler(l_codec, error_callback,00); l_codec = opj_create_compress(OPJ_CODEC_J2K); opj_set_info_handler(l_codec, info_callback,00); @@ -118,6 +118,13 @@ int main(int argc, char *argv[]) l_stream = opj_stream_create_default_file_stream(f,OPJ_FALSE); assert(l_stream); bSuccess = opj_start_compress(l_codec,image,l_stream); + if( !bSuccess ) + { + opj_stream_destroy(l_stream); + opj_destroy_codec(l_codec); + opj_image_destroy(image); + return 0; + } assert( bSuccess ); bSuccess = opj_encode(l_codec, l_stream); diff --git a/tests/unit/testempty2.c b/tests/unit/testempty2.c index 47ef4cc2..8a5fe221 100644 --- a/tests/unit/testempty2.c +++ b/tests/unit/testempty2.c @@ -40,7 +40,7 @@ void info_callback(const char *msg, void *v); void error_callback(const char *msg, void *v) { (void)msg; (void)v; -assert(0); +puts(msg); } void warning_callback(const char *msg, void *v) { (void)msg; @@ -58,15 +58,15 @@ int main(int argc, char *argv[]) const char * v = opj_version(); const OPJ_COLOR_SPACE color_space = OPJ_CLRSPC_GRAY; - int numcomps = 1; - int i; - int image_width = 256; - int image_height = 256; + unsigned int numcomps = 1; + unsigned int i; + unsigned int image_width = 256; + unsigned int image_height = 256; opj_cparameters_t parameters; - int subsampling_dx = parameters.subsampling_dx; - int subsampling_dy = parameters.subsampling_dy; + unsigned int subsampling_dx; + unsigned int subsampling_dy; const char outputfile[] = "testempty2.j2k"; opj_image_cmptparm_t cmptparm; @@ -74,13 +74,15 @@ int main(int argc, char *argv[]) opj_codec_t* l_codec = 00; OPJ_BOOL bSuccess; FILE *f; - opj_stream_t *l_stream = 00; + opj_stream_t *l_stream = 00; (void)argc; (void)argv; opj_set_default_encoder_parameters(¶meters); parameters.cod_format = J2K_CFMT; puts(v); + subsampling_dx = (unsigned int)parameters.subsampling_dx; + subsampling_dy = (unsigned int)parameters.subsampling_dy; cmptparm.prec = 8; cmptparm.bpp = 8; cmptparm.sgnd = 0; @@ -94,17 +96,17 @@ int main(int argc, char *argv[]) for (i = 0; i < image_width * image_height; i++) { - int compno; + unsigned int compno; for(compno = 0; compno < numcomps; compno++) { image->comps[compno].data[i] = 0; } } - /* catch events using our callbacks and give a local context */ - opj_set_info_handler(l_codec, info_callback,00); - opj_set_warning_handler(l_codec, warning_callback,00); - opj_set_error_handler(l_codec, error_callback,00); + /* catch events using our callbacks and give a local context */ + opj_set_info_handler(l_codec, info_callback,00); + opj_set_warning_handler(l_codec, warning_callback,00); + opj_set_error_handler(l_codec, error_callback,00); l_codec = opj_create_compress(OPJ_CODEC_J2K); opj_set_info_handler(l_codec, info_callback,00); @@ -118,8 +120,25 @@ int main(int argc, char *argv[]) assert( f ); l_stream = opj_stream_create_default_file_stream(f,OPJ_FALSE); + if( !l_stream ) + { + fprintf( stderr, "Something went wrong during creation of stream\n" ); + fclose(f); + opj_destroy_codec(l_codec); + opj_image_destroy(image); + opj_stream_destroy(l_stream); + return 1; + } assert(l_stream); bSuccess = opj_start_compress(l_codec,image,l_stream); + if( !bSuccess ) + { + fclose(f); + opj_stream_destroy(l_stream); + opj_destroy_codec(l_codec); + opj_image_destroy(image); + return 0; + } assert( bSuccess ); bSuccess = opj_encode(l_codec, l_stream); @@ -138,7 +157,7 @@ int main(int argc, char *argv[]) { FILE *fsrc = fopen(outputfile, "rb"); opj_codec_t* d_codec = 00; - opj_dparameters_t dparameters; + opj_dparameters_t dparameters; assert( fsrc ); d_codec = opj_create_decompress(OPJ_CODEC_J2K); @@ -158,7 +177,7 @@ int main(int argc, char *argv[]) bSuccess = opj_decode(l_codec, l_stream, image); assert( bSuccess ); - bSuccess = opj_end_decompress(l_codec, l_stream); + bSuccess = opj_end_decompress(l_codec, l_stream); assert( bSuccess ); opj_stream_destroy(l_stream); diff --git a/thirdparty/CMakeLists.txt b/thirdparty/CMakeLists.txt index 844d1831..089ce149 100644 --- a/thirdparty/CMakeLists.txt +++ b/thirdparty/CMakeLists.txt @@ -29,8 +29,8 @@ IF(BUILD_THIRDPARTY) # Try to build it message(STATUS "We will build PNG lib from thirdparty") ADD_SUBDIRECTORY(libpng) - SET(HAVE_PNG_H 1 PARENT_SCOPE) - SET(HAVE_LIBPNG 1 PARENT_SCOPE) + SET(OPJ_HAVE_PNG_H 1 PARENT_SCOPE) + SET(OPJ_HAVE_LIBPNG 1 PARENT_SCOPE) SET(PNG_LIBNAME png PARENT_SCOPE) SET(PNG_INCLUDE_DIRNAME ${OPENJPEG_SOURCE_DIR}/thirdparty/libpng PARENT_SCOPE) ELSE (BUILD_THIRDPARTY) @@ -38,13 +38,13 @@ ELSE (BUILD_THIRDPARTY) FIND_PACKAGE(PNG) IF(PNG_FOUND) message(STATUS "Your system seems to have a PNG lib available, we will use it") - SET(HAVE_PNG_H 1 PARENT_SCOPE) - SET(HAVE_LIBPNG 1 PARENT_SCOPE) + SET(OPJ_HAVE_PNG_H 1 PARENT_SCOPE) + SET(OPJ_HAVE_LIBPNG 1 PARENT_SCOPE) SET(PNG_LIBNAME ${PNG_LIBRARIES} PARENT_SCOPE) SET(PNG_INCLUDE_DIRNAME ${PNG_PNG_INCLUDE_DIR} PARENT_SCOPE) ELSE(PNG_FOUND) # not found - SET(HAVE_PNG_H 0 PARENT_SCOPE) - SET(HAVE_LIBPNG 0 PARENT_SCOPE) + SET(OPJ_HAVE_PNG_H 0 PARENT_SCOPE) + SET(OPJ_HAVE_LIBPNG 0 PARENT_SCOPE) message(STATUS "PNG lib not found, activate BUILD_THIRDPARTY if you want build it") ENDIF(PNG_FOUND) ENDIF (ZLIB_FOUND) @@ -62,27 +62,27 @@ IF(BUILD_THIRDPARTY) ${OPENJPEG_SOURCE_DIR}/thirdparty/libtiff ${OPENJPEG_BINARY_DIR}/thirdparty/libtiff PARENT_SCOPE) - SET(HAVE_TIFF_H 1 PARENT_SCOPE) - SET(HAVE_LIBTIFF 1 PARENT_SCOPE) + SET(OPJ_HAVE_TIFF_H 1 PARENT_SCOPE) + SET(OPJ_HAVE_LIBTIFF 1 PARENT_SCOPE) ELSE (BUILD_THIRDPARTY) FIND_PACKAGE(TIFF) IF(TIFF_FOUND) message(STATUS "Your system seems to have a TIFF lib available, we will use it") - SET(HAVE_TIFF_H 1 PARENT_SCOPE) - SET(HAVE_LIBTIFF 1 PARENT_SCOPE) + SET(OPJ_HAVE_TIFF_H 1 PARENT_SCOPE) + SET(OPJ_HAVE_LIBTIFF 1 PARENT_SCOPE) SET(TIFF_LIBNAME ${TIFF_LIBRARIES} PARENT_SCOPE) SET(TIFF_INCLUDE_DIRNAME ${TIFF_INCLUDE_DIR} PARENT_SCOPE) ELSE (TIFF_FOUND) # not found - SET(HAVE_TIFF_H 0 PARENT_SCOPE) - SET(HAVE_LIBTIFF 0 PARENT_SCOPE) + SET(OPJ_HAVE_TIFF_H 0 PARENT_SCOPE) + SET(OPJ_HAVE_LIBTIFF 0 PARENT_SCOPE) message(STATUS "TIFF lib not found, activate BUILD_THIRDPARTY if you want build it") ENDIF(TIFF_FOUND) ENDIF(BUILD_THIRDPARTY) #------------ # Try to find lib LCMS2 (or by default LCMS) -SET(HAVE_LCMS_H 0 PARENT_SCOPE) -SET(HAVE_LIBLCMS 0 PARENT_SCOPE) +SET(OPJ_HAVE_LCMS_H 0 PARENT_SCOPE) +SET(OPJ_HAVE_LIBLCMS 0 PARENT_SCOPE) IF( BUILD_THIRDPARTY) # Try to build lcms2 @@ -90,14 +90,14 @@ IF( BUILD_THIRDPARTY) ADD_SUBDIRECTORY(liblcms2) SET(LCMS_LIBNAME lcms2 PARENT_SCOPE) SET(LCMS_INCLUDE_DIRNAME ${OPENJPEG_SOURCE_DIR}/thirdparty/liblcms2/include PARENT_SCOPE) # - SET(HAVE_LCMS2_H 1 PARENT_SCOPE) - SET(HAVE_LIBLCMS2 1 PARENT_SCOPE) + SET(OPJ_HAVE_LCMS2_H 1 PARENT_SCOPE) + SET(OPJ_HAVE_LIBLCMS2 1 PARENT_SCOPE) ELSE (BUILD_THIRDPARTY) FIND_PACKAGE(LCMS2) IF(LCMS2_FOUND) message(STATUS "Your system seems to have a LCMS2 lib available, we will use it") - SET(HAVE_LCMS2_H 1 PARENT_SCOPE) - SET(HAVE_LIBLCMS2 1 PARENT_SCOPE) + SET(OPJ_HAVE_LCMS2_H 1 PARENT_SCOPE) + SET(OPJ_HAVE_LIBLCMS2 1 PARENT_SCOPE) SET(LCMS_LIBNAME ${LCMS2_LIBRARIES} PARENT_SCOPE) SET(LCMS_INCLUDE_DIRNAME ${LCMS2_INCLUDE_DIRS} PARENT_SCOPE) ELSE (LCMS2_FOUND) # not found lcms2 @@ -105,13 +105,13 @@ ELSE (BUILD_THIRDPARTY) FIND_PACKAGE(LCMS) IF(LCMS_FOUND) message(STATUS "Your system seems to have a LCMS lib available, we will use it") - SET(HAVE_LCMS_H 1 PARENT_SCOPE) - SET(HAVE_LIBLCMS 1 PARENT_SCOPE) + SET(OPJ_HAVE_LCMS_H 1 PARENT_SCOPE) + SET(OPJ_HAVE_LIBLCMS 1 PARENT_SCOPE) SET(LCMS_LIBNAME ${LCMS_LIBRARIES} PARENT_SCOPE) SET(LCMS_INCLUDE_DIRNAME ${LCMS_INCLUDE_DIRS} PARENT_SCOPE) ELSE (LCMS_FOUND) # not found lcms - SET(HAVE_LCMS2_H 0 PARENT_SCOPE) - SET(HAVE_LIBLCMS2 0 PARENT_SCOPE) + SET(OPJ_HAVE_LCMS2_H 0 PARENT_SCOPE) + SET(OPJ_HAVE_LIBLCMS2 0 PARENT_SCOPE) message(STATUS "LCMS2 or LCMS lib not found, activate BUILD_THIRDPARTY if you want build it") ENDIF (LCMS_FOUND) ENDIF(LCMS2_FOUND) diff --git a/thirdparty/libtiff/test_inline.c b/thirdparty/libtiff/test_inline.c index ad25a9c6..db0d056c 100644 --- a/thirdparty/libtiff/test_inline.c +++ b/thirdparty/libtiff/test_inline.c @@ -3,8 +3,3 @@ typedef int foo_t; static inline foo_t static_foo(){return 0;} foo_t foo(){return 0;} int main(int argc, char *argv[]){return 0;} -/* Test source lifted from /usr/share/autoconf/autoconf/c.m4 */ -typedef int foo_t; -static inline foo_t static_foo(){return 0;} -foo_t foo(){return 0;} -int main(int argc, char *argv[]){return 0;}