From 7caaea18b728ead4e45226aafc09dba01e514a2d Mon Sep 17 00:00:00 2001 From: Antonin Descampe Date: Thu, 31 Jul 2008 18:47:41 +0000 Subject: [PATCH] Deleting obsolete files and directories, adding v2-specific files and directories, updating existing files to v2. See README.v2 for more info --- CMakeLists.txt | 55 +- ChangeLog | 9 +- Free_CMakeImport.cmake | 14 + README.v2 | 26 + codec/compat/getopt.c | 8 +- codec/convert.c | 5 +- codec/image_to_j2k.c | 268 +- codec/j2k_to_image.c | 233 +- indexer_JPIP/CMakeLists.txt | 5 - indexer_JPIP/Makefile | 23 - indexer_JPIP/bio.c | 125 - indexer_JPIP/bio.h | 38 - indexer_JPIP/cio.c | 129 - indexer_JPIP/cio.h | 44 - indexer_JPIP/fix.h | 34 - indexer_JPIP/index_create.c | 1218 -- indexer_JPIP/int.c | 89 - indexer_JPIP/int.h | 41 - indexer_JPIP/j2k.h | 288 - indexer_JPIP/jp2.c | 301 - indexer_JPIP/jp2.h | 44 - indexer_JPIP/jpip.c | 768 -- indexer_JPIP/jpip.h | 42 - indexer_JPIP/pi.c | 465 - indexer_JPIP/pi.h | 72 - indexer_JPIP/t2.c | 389 - indexer_JPIP/t2.h | 46 - indexer_JPIP/tcd.c | 285 - indexer_JPIP/tcd.h | 137 - indexer_JPIP/tgt.c | 170 - indexer_JPIP/tgt.h | 80 - jp3d/CMakeLists.txt | 11 - jp3d/DllJp3dVM.dsp | 273 - jp3d/DllJp3dVM.sln | 21 - jp3d/DllJp3dVM.vcproj | 278 - jp3d/LICENSE.txt | 30 - jp3d/LibJp3dVM.sln | 21 - jp3d/LibJp3dVM.vcproj | 249 - jp3d/Makefile | 72 - jp3d/README.txt | 285 - jp3d/codec/CMakeLists.txt | 53 - jp3d/codec/convert.c | 997 -- jp3d/codec/convert.h | 51 - jp3d/codec/dirent.h | 676 -- jp3d/codec/getopt.c | 109 - jp3d/codec/getopt.h | 14 - jp3d/codec/jp3d_to_volume.c | 535 - jp3d/codec/jp3d_vm_dec.ncb | Bin 470016 -> 0 bytes jp3d/codec/jp3d_vm_dec.sln | 30 - jp3d/codec/jp3d_vm_dec.suo | Bin 13312 -> 0 bytes jp3d/codec/jp3d_vm_dec.vcproj | 157 - jp3d/codec/jp3d_vm_enc.ncb | Bin 568320 -> 0 bytes jp3d/codec/jp3d_vm_enc.sln | 35 - jp3d/codec/jp3d_vm_enc.suo | Bin 21504 -> 0 bytes jp3d/codec/jp3d_vm_enc.vcproj | 157 - jp3d/codec/volume_to_jp3d.c | 903 -- jp3d/libjp3dvm/CMakeLists.txt | 24 - jp3d/libjp3dvm/bio.c | 189 - jp3d/libjp3dvm/bio.h | 132 - jp3d/libjp3dvm/cio.c | 217 - jp3d/libjp3dvm/cio.h | 100 - jp3d/libjp3dvm/dwt.c | 1016 -- jp3d/libjp3dvm/dwt.h | 100 - jp3d/libjp3dvm/event.c | 181 - jp3d/libjp3dvm/event.h | 58 - jp3d/libjp3dvm/fix.h | 62 - jp3d/libjp3dvm/int.h | 122 - jp3d/libjp3dvm/jp3d.c | 2328 ---- jp3d/libjp3dvm/jp3d.h | 518 - jp3d/libjp3dvm/jp3d_lib.c | 76 - jp3d/libjp3dvm/jp3d_lib.h | 75 - jp3d/libjp3dvm/mct.c | 131 - jp3d/libjp3dvm/mct.h | 97 - jp3d/libjp3dvm/mqc.c | 548 - jp3d/libjp3dvm/mqc.h | 201 - jp3d/libjp3dvm/openjpeg.c | 207 - jp3d/libjp3dvm/openjpeg.h | 715 -- jp3d/libjp3dvm/opj_includes.h | 82 - jp3d/libjp3dvm/pi.c | 630 - jp3d/libjp3dvm/pi.h | 145 - jp3d/libjp3dvm/raw.c | 86 - jp3d/libjp3dvm/raw.h | 99 - jp3d/libjp3dvm/t1.c | 1181 -- jp3d/libjp3dvm/t1.h | 173 - jp3d/libjp3dvm/t1_3d.c | 1230 -- jp3d/libjp3dvm/t1_3d.h | 173 - jp3d/libjp3dvm/t2.c | 675 -- jp3d/libjp3dvm/t2.h | 101 - jp3d/libjp3dvm/tcd.c | 1738 --- jp3d/libjp3dvm/tcd.h | 334 - jp3d/libjp3dvm/tgt.c | 256 - jp3d/libjp3dvm/tgt.h | 124 - jp3d/libjp3dvm/volume.c | 89 - jp3d/libjp3dvm/volume.h | 43 - jp3d/tcltk/LPI_JP3D_VM.tcl | 114 - jp3d/tcltk/Thumbs.db | Bin 18944 -> 0 bytes jp3d/tcltk/decoder.tcl | 272 - jp3d/tcltk/encoder.tcl | 470 - jp3d/tcltk/logoLPI.gif | Bin 5212 -> 0 bytes libopenjpeg/CMakeLists.txt | 33 +- libopenjpeg/bio.c | 60 +- libopenjpeg/bio.h | 27 +- libopenjpeg/cio.c | 885 +- libopenjpeg/cio.h | 323 +- libopenjpeg/dwt.c | 510 +- libopenjpeg/dwt.h | 23 +- libopenjpeg/event.c | 69 +- libopenjpeg/event.h | 40 +- libopenjpeg/fix.h | 10 +- libopenjpeg/function_list.c | 147 + libopenjpeg/function_list.h | 131 + libopenjpeg/image.c | 124 +- libopenjpeg/image.h | 14 +- libopenjpeg/int.h | 60 +- libopenjpeg/invert.c | 291 + indexer_JPIP/fix.c => libopenjpeg/invert.h | 28 +- libopenjpeg/j2k.c | 10102 +++++++++++++--- libopenjpeg/j2k.h | 660 +- libopenjpeg/j2k_lib.c | 12 +- libopenjpeg/j2k_lib.h | 4 +- libopenjpeg/jp2.c | 2580 +++- libopenjpeg/jp2.h | 273 +- libopenjpeg/jpt.c | 158 +- libopenjpeg/jpt.h | 36 +- libopenjpeg/mct.c | 254 +- libopenjpeg/mct.h | 46 +- libopenjpeg/mqc.c | 64 +- libopenjpeg/mqc.h | 41 +- libopenjpeg/openjpeg.c | 848 +- libopenjpeg/openjpeg.h | 602 +- libopenjpeg/opj_configure.h | 16 + libopenjpeg/opj_includes.h | 32 +- libopenjpeg/opj_malloc.h | 285 +- libopenjpeg/pi.c | 2004 ++- libopenjpeg/pi.h | 107 +- libopenjpeg/profile.c | 177 + libopenjpeg/profile.h | 83 + libopenjpeg/raw.c | 12 +- libopenjpeg/raw.h | 21 +- libopenjpeg/t1.c | 630 +- libopenjpeg/t1.h | 55 +- libopenjpeg/t2.c | 1245 +- libopenjpeg/t2.h | 49 +- libopenjpeg/tcd.c | 2847 +++-- libopenjpeg/tcd.h | 291 +- libopenjpeg/tgt.c | 213 +- libopenjpeg/tgt.h | 42 +- libs/FreeImage/FreeImage.h | 1046 ++ libs/FreeImage/freeimage.s.lib | Bin 0 -> 1960314 bytes libs/FreeImage/libfreeimage.a | Bin 0 -> 10041296 bytes libs/FreeImage/libfreeimage.s.a | Bin 0 -> 4099612 bytes opj_configure.h.in | 16 + .../CMakeLists.txt | 29 + .../test2_decoder.c | 367 + .../test2_encoder.c | 492 + test_V2_tile_handling/CMakeLists.txt | 27 + test_V2_tile_handling/test_decoder.c | 244 + test_V2_tile_handling/test_encoder.c | 299 + 158 files changed, 23230 insertions(+), 31374 deletions(-) create mode 100644 Free_CMakeImport.cmake create mode 100644 README.v2 delete mode 100644 indexer_JPIP/CMakeLists.txt delete mode 100644 indexer_JPIP/Makefile delete mode 100644 indexer_JPIP/bio.c delete mode 100644 indexer_JPIP/bio.h delete mode 100644 indexer_JPIP/cio.c delete mode 100644 indexer_JPIP/cio.h delete mode 100644 indexer_JPIP/fix.h delete mode 100644 indexer_JPIP/index_create.c delete mode 100644 indexer_JPIP/int.c delete mode 100644 indexer_JPIP/int.h delete mode 100644 indexer_JPIP/j2k.h delete mode 100644 indexer_JPIP/jp2.c delete mode 100644 indexer_JPIP/jp2.h delete mode 100644 indexer_JPIP/jpip.c delete mode 100644 indexer_JPIP/jpip.h delete mode 100644 indexer_JPIP/pi.c delete mode 100644 indexer_JPIP/pi.h delete mode 100644 indexer_JPIP/t2.c delete mode 100644 indexer_JPIP/t2.h delete mode 100644 indexer_JPIP/tcd.c delete mode 100644 indexer_JPIP/tcd.h delete mode 100644 indexer_JPIP/tgt.c delete mode 100644 indexer_JPIP/tgt.h delete mode 100644 jp3d/CMakeLists.txt delete mode 100755 jp3d/DllJp3dVM.dsp delete mode 100755 jp3d/DllJp3dVM.sln delete mode 100755 jp3d/DllJp3dVM.vcproj delete mode 100755 jp3d/LICENSE.txt delete mode 100755 jp3d/LibJp3dVM.sln delete mode 100755 jp3d/LibJp3dVM.vcproj delete mode 100755 jp3d/Makefile delete mode 100755 jp3d/README.txt delete mode 100644 jp3d/codec/CMakeLists.txt delete mode 100755 jp3d/codec/convert.c delete mode 100755 jp3d/codec/convert.h delete mode 100755 jp3d/codec/dirent.h delete mode 100755 jp3d/codec/getopt.c delete mode 100755 jp3d/codec/getopt.h delete mode 100755 jp3d/codec/jp3d_to_volume.c delete mode 100755 jp3d/codec/jp3d_vm_dec.ncb delete mode 100755 jp3d/codec/jp3d_vm_dec.sln delete mode 100755 jp3d/codec/jp3d_vm_dec.suo delete mode 100755 jp3d/codec/jp3d_vm_dec.vcproj delete mode 100755 jp3d/codec/jp3d_vm_enc.ncb delete mode 100755 jp3d/codec/jp3d_vm_enc.sln delete mode 100755 jp3d/codec/jp3d_vm_enc.suo delete mode 100755 jp3d/codec/jp3d_vm_enc.vcproj delete mode 100755 jp3d/codec/volume_to_jp3d.c delete mode 100644 jp3d/libjp3dvm/CMakeLists.txt delete mode 100755 jp3d/libjp3dvm/bio.c delete mode 100755 jp3d/libjp3dvm/bio.h delete mode 100755 jp3d/libjp3dvm/cio.c delete mode 100755 jp3d/libjp3dvm/cio.h delete mode 100755 jp3d/libjp3dvm/dwt.c delete mode 100755 jp3d/libjp3dvm/dwt.h delete mode 100755 jp3d/libjp3dvm/event.c delete mode 100755 jp3d/libjp3dvm/event.h delete mode 100755 jp3d/libjp3dvm/fix.h delete mode 100755 jp3d/libjp3dvm/int.h delete mode 100755 jp3d/libjp3dvm/jp3d.c delete mode 100755 jp3d/libjp3dvm/jp3d.h delete mode 100755 jp3d/libjp3dvm/jp3d_lib.c delete mode 100755 jp3d/libjp3dvm/jp3d_lib.h delete mode 100755 jp3d/libjp3dvm/mct.c delete mode 100755 jp3d/libjp3dvm/mct.h delete mode 100755 jp3d/libjp3dvm/mqc.c delete mode 100755 jp3d/libjp3dvm/mqc.h delete mode 100755 jp3d/libjp3dvm/openjpeg.c delete mode 100755 jp3d/libjp3dvm/openjpeg.h delete mode 100755 jp3d/libjp3dvm/opj_includes.h delete mode 100755 jp3d/libjp3dvm/pi.c delete mode 100755 jp3d/libjp3dvm/pi.h delete mode 100755 jp3d/libjp3dvm/raw.c delete mode 100755 jp3d/libjp3dvm/raw.h delete mode 100755 jp3d/libjp3dvm/t1.c delete mode 100755 jp3d/libjp3dvm/t1.h delete mode 100755 jp3d/libjp3dvm/t1_3d.c delete mode 100755 jp3d/libjp3dvm/t1_3d.h delete mode 100755 jp3d/libjp3dvm/t2.c delete mode 100755 jp3d/libjp3dvm/t2.h delete mode 100755 jp3d/libjp3dvm/tcd.c delete mode 100755 jp3d/libjp3dvm/tcd.h delete mode 100755 jp3d/libjp3dvm/tgt.c delete mode 100755 jp3d/libjp3dvm/tgt.h delete mode 100755 jp3d/libjp3dvm/volume.c delete mode 100755 jp3d/libjp3dvm/volume.h delete mode 100755 jp3d/tcltk/LPI_JP3D_VM.tcl delete mode 100755 jp3d/tcltk/Thumbs.db delete mode 100755 jp3d/tcltk/decoder.tcl delete mode 100755 jp3d/tcltk/encoder.tcl delete mode 100755 jp3d/tcltk/logoLPI.gif create mode 100644 libopenjpeg/function_list.c create mode 100644 libopenjpeg/function_list.h create mode 100644 libopenjpeg/invert.c rename indexer_JPIP/fix.c => libopenjpeg/invert.h (67%) create mode 100644 libopenjpeg/opj_configure.h create mode 100644 libopenjpeg/profile.c create mode 100644 libopenjpeg/profile.h create mode 100644 libs/FreeImage/FreeImage.h create mode 100755 libs/FreeImage/freeimage.s.lib create mode 100644 libs/FreeImage/libfreeimage.a create mode 100755 libs/FreeImage/libfreeimage.s.a create mode 100644 opj_configure.h.in create mode 100644 test_Free_image_V2_tile_handling/CMakeLists.txt create mode 100644 test_Free_image_V2_tile_handling/test2_decoder.c create mode 100644 test_Free_image_V2_tile_handling/test2_encoder.c create mode 100644 test_V2_tile_handling/CMakeLists.txt create mode 100644 test_V2_tile_handling/test_decoder.c create mode 100644 test_V2_tile_handling/test_encoder.c diff --git a/CMakeLists.txt b/CMakeLists.txt index df1230e7..b7a50295 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -24,7 +24,7 @@ INCLUDE_REGULAR_EXPRESSION("^.*$") #----------------------------------------------------------------------------- # OPENJPEG version number, useful for packaging and doxygen doc: SET(OPENJPEG_VERSION_MAJOR 1) -SET(OPENJPEG_VERSION_MINOR 3) +SET(OPENJPEG_VERSION_MINOR 2) SET(OPENJPEG_VERSION_BUILD 0) SET(OPENJPEG_VERSION "${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}.${OPENJPEG_VERSION_BUILD}") @@ -36,10 +36,14 @@ SET(OPENJPEG_LIBRARY_PROPERTIES SOVERSION "${OPENJPEG_VERSION_MAJOR}.${OPENJPEG_VERSION_MINOR}" ) +#----------------------------------------------------------------------------- +# Test for some required system information. +INCLUDE (${CMAKE_ROOT}/Modules/CMakeBackwardCompatibilityC.cmake) #----------------------------------------------------------------------------- # OpenJPEG build configuration options. OPTION(BUILD_SHARED_LIBS "Build OpenJPEG with shared libraries." OFF) +OPTION(ENABLE_PROFILING "Enable profiling for the library" OFF) #----------------------------------------------------------------------------- SET (EXECUTABLE_OUTPUT_PATH ${OPENJPEG_BINARY_DIR}/bin CACHE PATH "Single output directory for building all executables.") @@ -61,29 +65,38 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/openjpeg_mangle.h.in @ONLY IMMEDIATE) ENDIF(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/openjpeg_mangle.h.in) +#----------------------------------------------------------------------------- +# Configure files with settings for use by the build. +CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/opj_configure.h.in + ${CMAKE_CURRENT_BINARY_DIR}/opj_configure.h) + + #----------------------------------------------------------------------------- # Always build the library INCLUDE_DIRECTORIES(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) SUBDIRS( libopenjpeg - mj2 + codec + test_V2_tile_handling + test_Free_image_V2_tile_handling + # mj2 # cmake 2.4.5 has poor java support #j2kviewer/src ) -IF(NOT UNIX) -SUBDIRS( - jpwl - jp3d - indexer_JPIP - ) -ENDIF(NOT UNIX) +#IF(NOT UNIX) +#SUBDIRS( +# jpwl +# jp3d +# indexer_JPIP +# ) +#ENDIF(NOT UNIX) #----------------------------------------------------------------------------- # Build example only if requested -IF(BUILD_EXAMPLES) - SUBDIRS(codec) -ENDIF(BUILD_EXAMPLES) +#IF(BUILD_EXAMPLES) +# SUBDIRS(codec) +#ENDIF(BUILD_EXAMPLES) #----------------------------------------------------------------------------- # For the documentation @@ -94,15 +107,15 @@ ENDIF(BUILD_DOCUMENTATION) #----------------------------------------------------------------------------- # For openjpeg team if they ever want Dart+CMake -IF(OPENJPEG_STANDALONE) - INCLUDE(Dart) - MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH) - IF(BUILD_TESTING) - ENABLE_TESTING() - SET(BUILDNAME "OpenJPEG-${CMAKE_SYSTEM}-${CMAKE_C_COMPILER}" CACHE STRING "Name of build on the dashboard") - MARK_AS_ADVANCED(BUILDNAME) - ENDIF(BUILD_TESTING) -ENDIF(OPENJPEG_STANDALONE) +#IF(OPENJPEG_STANDALONE) +# INCLUDE(Dart) +# MARK_AS_ADVANCED(BUILD_TESTING DART_ROOT TCL_TCLSH) +# IF(BUILD_TESTING) +# ENABLE_TESTING() +# SET(BUILDNAME "OpenJPEG-${CMAKE_SYSTEM}-${CMAKE_C_COMPILER}" CACHE STRING "Name of build on the dashboard") +# MARK_AS_ADVANCED(BUILDNAME) +# ENDIF(BUILD_TESTING) +#ENDIF(OPENJPEG_STANDALONE) # Adding test with dataset from: # http://www.crc.ricoh.com/~gormish/jpeg2000conformance/ diff --git a/ChangeLog b/ChangeLog index 3565e425..773b71de 100644 --- a/ChangeLog +++ b/ChangeLog @@ -5,6 +5,9 @@ What's New for OpenJPEG ! : changed + : added +July 31, 2008 ++ [antonin] created a branch for openjpeg version 2. Modifications that have been applied to the trunk after revision 483 should be re-applied on the branch (version 2 has been developed based on revision 483). + July 9, 2008 + [Parvatha] Added the default lossless parameter to opj_set_default_encoder_parameters in openjpeg.c. @@ -42,7 +45,7 @@ February 11, 2008 February 5, 2008 ! [Parvatha] In convert.c, corrected imagetobmp() conversion for grayscale. In tcd.c, corrected Rate modification in - tcd_init_encode(). Thanks to Jeremy Furtek and Jérôme Fimes. + tcd_init_encode(). Thanks to Jeremy Furtek and Jérôme Fimes. January 31, 2008 ! [GB] In opjviewer, unification of JPEG 2000 family handlers (*.jp2, *.mj2, *.j2k) in a single file @@ -352,7 +355,7 @@ March 30, 2007 * [GB] OPJViewer should now work under Linux, at least with not big j2k files. Tested under Suse 10.1 64 bit. March 29, 2007 -* [Parvatha] Enable accepting file names with `-´ symbol .Modification getopt.c +* [Parvatha] Enable accepting file names with `-´ symbol .Modification getopt.c * [Parvatha] Rsiz profile name generation to be STD_RSIZ for profiles which are not DCI compliant.Modification in image_to_j2k.c ! [Parvatha] renamed convert_progression_order to j2k_convert_progression_order. Modification j2k.c * [Parvatha] Calculation of number of tile part in each tile in j2k_calculate_tp. Modification j2k.c @@ -369,7 +372,7 @@ March 28, 2007 March 27, 2007 + [GB] Improved parsing in OPJViewer, as well some minor aesthetic modifications; support for image rendering with bit depths lower than 8 bits; can display an arbitrary frame of an MJ2 file (only in B/W, though); can reload a file; better resizing capabilities -* [GB] Following to Hervé's suggestions, all the exit() calls, added by JPWL strict checking in t2.c and j2k.c, +* [GB] Following to Hervé's suggestions, all the exit() calls, added by JPWL strict checking in t2.c and j2k.c, have been substituted with (object free'ing + opj_evt_message(EVT_ERROR) + return) + [GB] Added linking to TIFF library in the JPWL VC6 workspaces diff --git a/Free_CMakeImport.cmake b/Free_CMakeImport.cmake new file mode 100644 index 00000000..9b8aaf24 --- /dev/null +++ b/Free_CMakeImport.cmake @@ -0,0 +1,14 @@ +# Import library +#________________ + + # MESSAGE(STATUS "IMPORT : FreeImagelibrary") + + # Include directories + INCLUDE_DIRECTORIES(${OPENJPEG_SOURCE_DIR}/libs/FreeImage) + + # Link libraries + LINK_DIRECTORIES(${OPENJPEG_SOURCE_DIR}/libs/FreeImage) + + LINK_LIBRARIES(freeimage.s) + ADD_DEFINITIONS ( -DFREEIMAGE_LIB ) + diff --git a/README.v2 b/README.v2 new file mode 100644 index 00000000..be57240e --- /dev/null +++ b/README.v2 @@ -0,0 +1,26 @@ +Preliminary notes +----------------- + +The Version 2 of openjpeg has been currently added as a branch on the repository. + +All the trunk has been copied and files that needed to change have been patched. In comparison with the trunk, the 'jp3d' directory has been removed because it's based on a modified version of libopenjpeg version 1 and there is no plan to make it reach the version 2 status. Idem with the 'indexer_JPIP', which is obsolete and should be rewritten from scratch. + +At the time of the branch creation, the following files and directories have been updated (or added) for version 2 : +* libopenjpeg/ +* codec/ +* test_Free_image_V2_tile_handling/ : a test program that uses libopenjpeg v2 and libfreeimage (see libs) to implement a basic codec. +* test_V2_tile_handling/ : a test program that generates a random image and (de)compresses it with libopenjpeg v2. +* CMakeLists.txt +* Free_CMakeImport.cmake +* opj_configure.h.in + +Other files and directories from the trunk (project files, jpwl/, OPJViewer/, ...) have also been copied in the branch and should be modified progressively to comply with v2. Check the Changelog for updates on this topic. + +Enjoy v2 and feel free to contribute ! + + +Instructions to compile v2 +-------------------------- + +to be added. + diff --git a/codec/compat/getopt.c b/codec/compat/getopt.c index f434924b..23270e6a 100644 --- a/codec/compat/getopt.c +++ b/codec/compat/getopt.c @@ -59,11 +59,7 @@ typedef struct option #define BADARG (int)':' #define EMSG "" -/* As this class remembers its values from one Java call to the other, reset the values before each use */ -void reset_options_reading() { - opterr = 1; - optind = 1; -} + /* * getopt -- @@ -136,7 +132,7 @@ struct option *longopts, int totlen) { char param = 1; again: - if (optind >= argc || !argv[optind] || *argv[optind]!='-') + if (optind>argc || !argv[optind] || *argv[optind]!='-') return -1; if (argv[optind][0]=='-' && argv[optind][1]==0) { diff --git a/codec/convert.c b/codec/convert.c index e56d1311..4572d7e5 100644 --- a/codec/convert.c +++ b/codec/convert.c @@ -914,8 +914,7 @@ int imagetobmp(opj_image_t * image, const char *outfile) { 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; + } for (i = 0; i < 256; i++) { fprintf(fdest, "%c%c%c%c", i, i, i, 0); @@ -1087,7 +1086,7 @@ opj_image_t* pgxtoimage(const char *filename, opj_cparameters_t *parameters) { comp->data[i] = v; } fclose(f); - comp->bpp = int_floorlog2(max) + 1; + //comp->bpp = int_floorlog2(max) + 1; return image; } diff --git a/codec/image_to_j2k.c b/codec/image_to_j2k.c index 7e9436e1..15621489 100644 --- a/codec/image_to_j2k.c +++ b/codec/image_to_j2k.c @@ -6,6 +6,7 @@ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2006-2007, Parvatha Elangovan + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,10 +31,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include +#define __USE_BSD #include #include #include - +#define USE_OPJ_DEPRECATED #include "openjpeg.h" #include "compat/getopt.h" #include "convert.h" @@ -208,9 +210,8 @@ void encode_help_display() { 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,"-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,"\n"); /* UniPG>> */ #ifdef USE_JPWL @@ -522,6 +523,8 @@ void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_ } parameters->numpocs = initialise_4K_poc(parameters->POC,parameters->numresolution); break; + default : + break; } switch (parameters->cp_cinema){ @@ -565,6 +568,8 @@ void cinema_setup_encoder(opj_cparameters_t *parameters,opj_image_t *image, img_ } parameters->max_comp_size = COMP_48_CS; break; + default: + break; } parameters->cp_disto_alloc = 1; } @@ -587,7 +592,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters, }; /* parse the command line */ - const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:" + const char optlist[] = "i:o:hr:q:n:b:c:t:p:s:SEM:x:R:d:T:If:P:C:F:m:" #ifdef USE_JPWL "W:" #endif /* USE_JPWL */ @@ -908,7 +913,7 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters, 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].compno1, POC[numpocs].progorder) == 7) { POC[numpocs].prg1 = give_progression(POC[numpocs].progorder); numpocs++; while (*s && *s != '/') { @@ -1044,6 +1049,76 @@ int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters, fprintf(stdout,"CINEMA 4K compliant codestream\n"); parameters->cp_rsiz = CINEMA4K; } + break; + + case 'm': /* output file */ + { + char *lFilename = optarg; + char * lMatrix; + char *lCurrentPtr ; + int lNbComp = 0; + int lTotalComp; + int lMctComp; + float * lCurrentDoublePtr; + float * lSpace; + int * l_int_ptr; + int i; + int lStrLen; + + FILE * lFile = fopen(lFilename,"r"); + if + (lFile == NULL) + { + return 1; + } + 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;ibuffer, 1, codestream_length, f); - fclose(f); - - fprintf(stderr,"Generated outfile %s\n",parameters.outfile); - /* close and free the byte stream */ - opj_cio_close(cio); - - /* Write the index to disk */ - if (*indexfilename) { - bSuccess = write_index_file(&cstr_info, indexfilename); - if (bSuccess) { - fprintf(stderr, "Failed to output index file into [%s]\n", indexfilename); - } - } - - /* free remaining compression structures */ - opj_destroy_compress(cinfo); - if (*indexfilename) - opj_destroy_cstr_info(&cstr_info); - } else { /* JP2 format output */ - int codestream_length; - opj_cio_t *cio = NULL; - FILE *f = NULL; - - /* get a JP2 compressor handle */ - opj_cinfo_t* cinfo = opj_create_compress(CODEC_JP2); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stderr); - - /* setup the encoder parameters using the current image and using user parameters */ - opj_setup_encoder(cinfo, ¶meters, image); - - /* open a byte stream for writing */ - /* allocate memory for all tiles */ - cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); - - /* encode the image */ - if (*indexfilename) // If need to extract codestream information - bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info); - else - bSuccess = opj_encode(cinfo, cio, image, NULL); - if (!bSuccess) { - opj_cio_close(cio); - fprintf(stderr, "failed to encode image\n"); - return 1; - } - codestream_length = cio_tell(cio); - - /* write the buffer to disk */ - f = fopen(parameters.outfile, "wb"); - if (!f) { - fprintf(stderr, "failed to open %s for writing\n", parameters.outfile); - return 1; - } - fwrite(cio->buffer, 1, codestream_length, f); - fclose(f); - fprintf(stderr,"Generated outfile %s\n",parameters.outfile); - /* close and free the byte stream */ - opj_cio_close(cio); - - /* Write the index to disk */ - if (*indexfilename) { - bSuccess = write_index_file(&cstr_info, indexfilename); - if (bSuccess) { - fprintf(stderr, "Failed to output index file\n"); - } - } - - /* free remaining compression structures */ - opj_destroy_compress(cinfo); - if (*indexfilename) - opj_destroy_cstr_info(&cstr_info); + cinfo = parameters.cod_format == J2K_CFMT ? opj_create_compress(CODEC_J2K) : opj_create_compress(CODEC_JP2); + opj_setup_encoder(cinfo, ¶meters, image); + f = fopen(parameters.outfile, "wb"); + if + (! f) + { + fprintf(stderr, "failed to encode image\n"); + return 1; } - + /* open a byte stream for writing */ + /* allocate memory for all tiles */ + cio = opj_stream_create_default_file_stream(f,false); + if + (! cio) + { + return 1; + } + /* encode the image */ + /*if (*indexfilename) // If need to extract codestream information + bSuccess = opj_encode_with_info(cinfo, cio, image, &cstr_info); + else*/ + bSuccess = opj_start_compress(cinfo,image,cio); + bSuccess = bSuccess && opj_encode(cinfo, cio); + bSuccess = bSuccess && opj_end_compress(cinfo, cio); + + if + (!bSuccess) + { + opj_stream_destroy(cio); + fclose(f); + 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(cio); + fclose(f); + + /* Write the index to disk */ + if (*indexfilename) { + bSuccess = write_index_file(&cstr_info, indexfilename); + if (bSuccess) { + fprintf(stderr, "Failed to output index file\n"); + } + } + + /* free remaining compression structures */ + opj_destroy_codec(cinfo); + if (*indexfilename) + opj_destroy_cstr_info(&cstr_info); + /* free image data */ opj_image_destroy(image); } diff --git a/codec/j2k_to_image.c b/codec/j2k_to_image.c index feee30a0..523cb5c4 100644 --- a/codec/j2k_to_image.c +++ b/codec/j2k_to_image.c @@ -6,6 +6,7 @@ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2006-2007, Parvatha Elangovan + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,10 +31,11 @@ * POSSIBILITY OF SUCH DAMAGE. */ #include +#define __USE_BSD #include #include #include - +#define USE_OPJ_DEPRECATED #include "openjpeg.h" #include "compat/getopt.h" #include "convert.h" @@ -504,27 +506,24 @@ void info_callback(const char *msg, void *client_data) { /* -------------------------------------------------------------------------- */ -int main(int argc, char **argv) { +int main(int argc, char **argv) +{ opj_dparameters_t parameters; /* decompression parameters */ img_fol_t img_fol; - opj_event_mgr_t event_mgr; /* event manager */ opj_image_t *image = NULL; FILE *fsrc = NULL; - unsigned char *src = NULL; - int file_length; + bool bResult; int num_images; int i,imageno; dircnt_t *dirptr; - opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ - opj_cio_t *cio = NULL; + opj_codec_t* dinfo = NULL; /* handle to a decompressor */ + opj_stream_t *cio = NULL; opj_codestream_info_t cstr_info; /* Codestream information structure */ char indexfilename[OPJ_PATH_LEN]; /* index file name */ + OPJ_INT32 l_tile_x0,l_tile_y0; + OPJ_UINT32 l_tile_width,l_tile_height,l_nb_tiles_x,l_nb_tiles_y; /* configure the event callbacks (not required) */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; /* set decoding parameters to default values */ opj_set_default_decoder_parameters(¶meters); @@ -566,7 +565,8 @@ int main(int argc, char **argv) { } /*Encoding image one by one*/ - for(imageno = 0; imageno < num_images ; imageno++) { + for(imageno = 0; imageno < num_images ; imageno++) + { image = NULL; fprintf(stderr,"\n"); @@ -580,155 +580,90 @@ int main(int argc, char **argv) { /* read the input file and put it in memory */ /* ---------------------------------------- */ fsrc = fopen(parameters.infile, "rb"); - if (!fsrc) { + if + (!fsrc) + { fprintf(stderr, "ERROR -> failed to open %s for reading\n", parameters.infile); return 1; } - fseek(fsrc, 0, SEEK_END); - file_length = ftell(fsrc); - fseek(fsrc, 0, SEEK_SET); - src = (unsigned char *) malloc(file_length); - fread(src, 1, file_length, fsrc); - fclose(fsrc); - + cio = opj_stream_create_default_file_stream(fsrc,true); /* decode the code-stream */ /* ---------------------- */ - switch(parameters.decod_format) { - case J2K_CFMT: + switch + (parameters.decod_format) { - /* JPEG-2000 codestream */ + case J2K_CFMT: + { + /* JPEG-2000 codestream */ - /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_J2K); + /* get a decoder handle */ + dinfo = opj_create_decompress(CODEC_J2K); + break; + } + case JP2_CFMT: + { + /* JPEG 2000 compressed image data */ + /* get a decoder handle */ + dinfo = opj_create_decompress(CODEC_JP2); + break; + } + case JPT_CFMT: + { + /* JPEG 2000, JPIP */ + /* get a decoder handle */ + dinfo = opj_create_decompress(CODEC_JPT); + break; + } + default: + fprintf(stderr, "skipping file..\n"); + opj_stream_destroy(cio); + continue; + } + /* catch events using our callbacks and give a local context */ + + /* setup the decoder decoding parameters using user parameters */ + opj_setup_decoder(dinfo, ¶meters); - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); - - /* decode the stream and fill the image structure */ - if (*indexfilename) // If need to extract codestream information + /* decode the stream and fill the image structure */ + /* if (*indexfilename) // If need to extract codestream information image = opj_decode_with_info(dinfo, cio, &cstr_info); else - image = opj_decode(dinfo, cio); - if(!image) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - return 1; - } - - /* close the byte stream */ - opj_cio_close(cio); - - /* Write the index to disk */ - if (*indexfilename) { - char bSuccess; - bSuccess = write_index_file(&cstr_info, indexfilename); - if (bSuccess) { - fprintf(stderr, "Failed to output index file\n"); - } - } - } - break; - - case JP2_CFMT: + */ + bResult = opj_read_header( + dinfo, + &image, + &l_tile_x0, + &l_tile_y0, + &l_tile_width, + &l_tile_height, + &l_nb_tiles_x, + &l_nb_tiles_y, + cio); + image = opj_decode(dinfo, cio); + bResult = bResult && (image != 00); + bResult = bResult && opj_end_decompress(dinfo,cio); + if + (!image) { - /* JPEG 2000 compressed image data */ + fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); + opj_destroy_codec(dinfo); + opj_stream_destroy(cio); + fclose(fsrc); + return 1; + } - /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_JP2); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using the current image and user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); - - /* decode the stream and fill the image structure */ - if (*indexfilename) // If need to extract codestream information - image = opj_decode_with_info(dinfo, cio, &cstr_info); - else - image = opj_decode(dinfo, cio); - if(!image) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - return 1; - } - - /* close the byte stream */ - opj_cio_close(cio); - - /* Write the index to disk */ - if (*indexfilename) { - char bSuccess; - bSuccess = write_index_file(&cstr_info, indexfilename); - if (bSuccess) { - fprintf(stderr, "Failed to output index file\n"); - } + /* close the byte stream */ + opj_stream_destroy(cio); + fclose(fsrc); + /* Write the index to disk */ + if (*indexfilename) { + char bSuccess; + bSuccess = write_index_file(&cstr_info, indexfilename); + if (bSuccess) { + fprintf(stderr, "Failed to output index file\n"); } } - break; - - case JPT_CFMT: - { - /* JPEG 2000, JPIP */ - - /* get a decoder handle */ - dinfo = opj_create_decompress(CODEC_JPT); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); - - /* decode the stream and fill the image structure */ - if (*indexfilename) // If need to extract codestream information - image = opj_decode_with_info(dinfo, cio, &cstr_info); - else - image = opj_decode(dinfo, cio); - if(!image) { - fprintf(stderr, "ERROR -> j2k_to_image: failed to decode image!\n"); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - return 1; - } - - /* close the byte stream */ - opj_cio_close(cio); - - /* Write the index to disk */ - if (*indexfilename) { - char bSuccess; - bSuccess = write_index_file(&cstr_info, indexfilename); - if (bSuccess) { - fprintf(stderr, "Failed to output index file\n"); - } - } - } - break; - - default: - fprintf(stderr, "skipping file..\n"); - continue; - } - - /* free the memory containing the code-stream */ - free(src); - src = NULL; /* create output image */ /* ------------------- */ @@ -789,8 +724,10 @@ int main(int argc, char **argv) { } /* free remaining structures */ - if(dinfo) { - opj_destroy_decompress(dinfo); + if + (dinfo) + { + opj_destroy_codec(dinfo); } /* free codestream information structure */ if (*indexfilename) diff --git a/indexer_JPIP/CMakeLists.txt b/indexer_JPIP/CMakeLists.txt deleted file mode 100644 index 4dbb95b0..00000000 --- a/indexer_JPIP/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# index_create - -ADD_EXECUTABLE(index_create -bio.c cio.c int.c pi.c t2.c tgt.c tcd.c index_create.c jpip.c jp2.c -) diff --git a/indexer_JPIP/Makefile b/indexer_JPIP/Makefile deleted file mode 100644 index 40c049ea..00000000 --- a/indexer_JPIP/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -CC = gcc - -LDFLAGS = -lm -CFLAGS = -Wall - -all: index_create - - -bio.o : bio.c bio.h -cio.o : cio.c cio.h -int.o : int.c -pi.o : pi.c pi.h int.h -index_create.o : index_create.c j2k.h cio.h tcd.h int.h -t2.o : t2.c t2.h tcd.h bio.h j2k.h pi.h tgt.h int.h cio.h -tgt.o : tgt.c bio.h tgt.h -tcd.o : tcd.c tcd.h t2.h int.h -jpip.o : jpip.c j2k.h cio.h tcd.h int.h -jp2.o : jp2.c j2k.h cio.h tcd.h int.h - -index_create : bio.o cio.o int.o pi.o t2.o tgt.o tcd.o index_create.o jpip.o jp2.o - -clean: - rm -rf *.o *.*~ *~ core.* diff --git a/indexer_JPIP/bio.c b/indexer_JPIP/bio.c deleted file mode 100644 index 2c989e56..00000000 --- a/indexer_JPIP/bio.c +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 "bio.h" -#include - -static unsigned char *bio_start, *bio_end, *bio_bp; -static unsigned int bio_buf; -static int bio_ct; - -extern jmp_buf j2k_error; - -/// -/// Number of bytes written. -/// -int bio_numbytes() { - return bio_bp-bio_start; -} - -/// -/// Init decoder. -/// -/// Input buffer -/// Input buffer length -void bio_init_dec(unsigned char *bp, int len) { - bio_start=bp; - bio_end=bp+len; - bio_bp=bp; - bio_buf=0; - bio_ct=0; -} - -int bio_byteout() -{ - 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; -} - -/// -/// Read byte. -/// -int bio_bytein() { - bio_buf=(bio_buf<<8)&0xffff; - bio_ct=bio_buf==0xff00?7:8; - if (bio_bp>=bio_end) return 1; //longjmp(j2k_error, 1); - bio_buf|=*bio_bp++; - return 0; -} - -/// -/// Read bit. -/// -int bio_getbit() { - if (bio_ct==0) { - bio_bytein(); - } - bio_ct--; - return (bio_buf>>bio_ct)&1; -} - -/// -/// Read bits. -/// -/// Number of bits to read -int bio_read(int n) { - int i, v; - v=0; - for (i=n-1; i>=0; i--) { - v+=bio_getbit()< -/// Flush bits. -/// -int bio_flush() { - bio_ct=0; - bio_byteout(); - if (bio_ct==7) { - bio_ct=0; - if ( bio_byteout()) return 1;; - } - return 0; -} - -/// -/// -int bio_inalign() { - bio_ct=0; - if ((bio_buf&0xff)==0xff) { - if( bio_bytein()) return 1; - bio_ct=0; - } - return 0; -} diff --git a/indexer_JPIP/bio.h b/indexer_JPIP/bio.h deleted file mode 100644 index eea6cff0..00000000 --- a/indexer_JPIP/bio.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003-2004, Yannick Verschueren - * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __BIO_H -#define __BIO_H - -int bio_numbytes(); -void bio_init_dec(unsigned char *bp, int len); -int bio_read(int n); -int bio_flush(); -int bio_inalign(); - -#endif diff --git a/indexer_JPIP/cio.c b/indexer_JPIP/cio.c deleted file mode 100644 index 29f160ee..00000000 --- a/indexer_JPIP/cio.c +++ /dev/null @@ -1,129 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 "cio.h" -#include - -static unsigned char *cio_start, *cio_end, *cio_bp; - -extern jmp_buf j2k_error; - -/// -/// Number of bytes written. -/// -int cio_numbytes() { - return cio_bp-cio_start; -} - -/// -/// Get position in byte stream. -/// -int cio_tell() { - return cio_bp-cio_start; -} - -/// -/// Set position in byte stream. -/// -void cio_seek(int pos) { - cio_bp=cio_start+pos; -} - -/// -/// Number of bytes left before the end of the stream. -/// -int cio_numbytesleft() { - return cio_end-cio_bp; -} - -/// -/// Get pointer to the current position in the stream. -/// -unsigned char *cio_getbp() { - return cio_bp; -} - -/// -/// Initialize byte IO. -/// -void cio_init(unsigned char *bp, int len) { - cio_start=bp; - cio_end=bp+len; - cio_bp=bp; -} - -/// -/// Write a byte. -/// -void cio_byteout(unsigned char v) { - if (cio_bp>=cio_end) longjmp(j2k_error, 1); - *cio_bp++=v; - -} - -/// -/// Read a byte. -/// -unsigned char cio_bytein() { - if (cio_bp>=cio_end) longjmp(j2k_error, 1); - return *cio_bp++; -} - -/// -/// Write a byte. -/// -//void cio_write(unsigned int v, int n) { -void cio_write(long long v, int n) { - int i; - for (i=n-1; i>=0; i--) - { - cio_byteout((unsigned char)((v>>(i<<3))&0xff)); - } -} - -/// -/// Read some bytes. -/// -/* unsigned int cio_read(int n) { */ -long long cio_read(int n) { - int i; - /*unsigned int v;*/ - long long v; - v=0; - for (i=n-1; i>=0; i--) { - v+=cio_bytein()<<(i<<3); - } - return v; -} - -/// -/// Write some bytes. -/// -void cio_skip(int n) { - cio_bp+=n; -} diff --git a/indexer_JPIP/cio.h b/indexer_JPIP/cio.h deleted file mode 100644 index 3e297897..00000000 --- a/indexer_JPIP/cio.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003-2004, Yannick Verschueren - * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef __CIO_H -#define __CIO_H - -int cio_tell(); -void cio_seek(int pos); -int cio_numbytes(); -int cio_numbytesleft(); -unsigned char *cio_getbp(); -void cio_init(unsigned char *bp, int len); -/* void cio_write(unsigned int v, int n); */ -void cio_write(long long v, int n); -/* unsigned int cio_read(int n); */ -long long cio_read(int n); -void cio_skip(int n); - -#endif diff --git a/indexer_JPIP/fix.h b/indexer_JPIP/fix.h deleted file mode 100644 index 4b6e1b54..00000000 --- a/indexer_JPIP/fix.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 __FIX_H -#define __FIX_H - -int fix_mul(int a, int b); - -#endif diff --git a/indexer_JPIP/index_create.c b/indexer_JPIP/index_create.c deleted file mode 100644 index 759f86bb..00000000 --- a/indexer_JPIP/index_create.c +++ /dev/null @@ -1,1218 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003-2004, Yannick Verschueren - * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - -#include -#include -#include -#include -#include - -#include "j2k.h" -#include "cio.h" -#include "tcd.h" -#include "int.h" -#include "jpip.h" -#include "jp2.h" - -#define J2K_MS_SOC 0xff4f -#define J2K_MS_SOT 0xff90 -#define J2K_MS_SOD 0xff93 -#define J2K_MS_EOC 0xffd9 -#define J2K_MS_SIZ 0xff51 -#define J2K_MS_COD 0xff52 -#define J2K_MS_COC 0xff53 -#define J2K_MS_RGN 0xff5e -#define J2K_MS_QCD 0xff5c -#define J2K_MS_QCC 0xff5d -#define J2K_MS_POC 0xff5f -#define J2K_MS_TLM 0xff55 -#define J2K_MS_PLM 0xff57 -#define J2K_MS_PLT 0xff58 -#define J2K_MS_PPM 0xff60 -#define J2K_MS_PPT 0xff61 -#define J2K_MS_SOP 0xff91 -#define J2K_MS_EPH 0xff92 -#define J2K_MS_CRG 0xff63 -#define J2K_MS_COM 0xff64 - -#define J2K_STATE_MHSOC 0x0001 -#define J2K_STATE_MHSIZ 0x0002 -#define J2K_STATE_MH 0x0004 -#define J2K_STATE_TPHSOT 0x0008 -#define J2K_STATE_TPH 0x0010 -#define J2K_STATE_MT 0x0020 - -#define START_NB 5 -#define INCREMENT 5 - -jmp_buf j2k_error; - -static int j2k_state; -static int j2k_curtileno; -static j2k_tcp_t j2k_default_tcp; -static unsigned char *j2k_eot; - -static j2k_image_t *j2k_img; -static j2k_cp_t *j2k_cp; - -static unsigned char **j2k_tile_data; -static int *j2k_tile_len; - -static info_image_t img; - - -void j2k_clean() { - int tileno = 0; - int compno=0, resno=0, precno=0; - - tcd_free(j2k_img, j2k_cp); - for (tileno = 0; tileno < j2k_cp->tw * j2k_cp->th; tileno++) { - info_tile_t *tile_Idx = &img.tile[tileno]; - - for (compno = 0; compno < img.Comp; compno++) - { - info_compo_t *compo_Idx = &tile_Idx->compo[compno]; - for(resno = 0; resno < img.Decomposition + 1; resno++) - { - info_reso_t *reso_Idx = &compo_Idx->reso[resno]; - for (precno = 0; precno < img.tile[tileno].pw * img.tile[tileno].ph; precno++) - { - info_prec_t *prec_Idx = &reso_Idx->prec[precno]; - free(prec_Idx->layer); - } - free(reso_Idx->prec); - } - free(compo_Idx->reso); - } - free(tile_Idx->compo); - free(tile_Idx->marker); - free(tile_Idx->tile_parts); - free(tile_Idx->marker_mul.COC); - free(tile_Idx->marker_mul.RGN); - free(tile_Idx->marker_mul.QCC); - free(tile_Idx->marker_mul.PLT); - free(tile_Idx->marker_mul.PPT); - free(tile_Idx->marker_mul.COM); -} - free(img.tile); - free(img.marker); - free(img.marker_mul.COC); - free(img.marker_mul.RGN); - free(img.marker_mul.QCC); - free(img.marker_mul.PLM); - free(img.marker_mul.PPM); - free(img.marker_mul.COM); -} - - - -void j2k_read_soc() { - j2k_state=J2K_STATE_MHSIZ; -} - - - -void j2k_read_siz() { - int len, i; - info_tile_t *tile; - - len = cio_read(2); - - /* [MHIX BOX] */ - img.marker[img.num_marker].type = J2K_MS_SIZ; - img.marker[img.num_marker].start_pos = cio_tell()-2; - img.marker[img.num_marker].len = len; - img.num_marker++; - /* [MHIX BOX] */ - - cio_read(2); /* Rsiz (capabilities) */ - j2k_img->x1 = cio_read(4); /* Xsiz */ - j2k_img->y1 = cio_read(4); /* Ysiz */ - j2k_img->x0 = cio_read(4); /* X0siz */ - j2k_img->y0 = cio_read(4); /* Y0siz */ - j2k_cp->tdx = cio_read(4); /* XTsiz */ - j2k_cp->tdy = cio_read(4); /* YTsiz */ - j2k_cp->tx0 = cio_read(4); /* XT0siz */ - j2k_cp->ty0 = cio_read(4); /* YTOsiz */ - - j2k_img->numcomps = cio_read(2); /* Csiz */ - j2k_img->comps = (j2k_comp_t*)malloc(j2k_img->numcomps * sizeof(j2k_comp_t)); - for (i = 0; i < j2k_img->numcomps; i++) { - int tmp, w, h; - tmp = cio_read(1); - j2k_img->comps[i].prec = (tmp & 0x7f) + 1; - j2k_img->comps[i].sgnd = tmp >> 7; - j2k_img->comps[i].dx = cio_read(1); - j2k_img->comps[i].dy = cio_read(1); - w = int_ceildiv(j2k_img->x1-j2k_img->x0, j2k_img->comps[i].dx); - h = int_ceildiv(j2k_img->y1-j2k_img->y0, j2k_img->comps[i].dy); - j2k_img->comps[i].data = (int*)malloc(sizeof(int) * w * h); - } - j2k_cp->tw = int_ceildiv(j2k_img->x1 - j2k_cp->tx0, j2k_cp->tdx); - j2k_cp->th = int_ceildiv(j2k_img->y1 - j2k_cp->ty0, j2k_cp->tdy); - - j2k_cp->tcps = (j2k_tcp_t*)calloc((j2k_cp->tw * j2k_cp->th), sizeof(j2k_tcp_t)); - - for (i = 0; i < j2k_cp->tw * j2k_cp->th; i++) - { - j2k_cp->tcps[i].POC = 0; - j2k_cp->tcps[i].numpocs = 0; - // j2k_cp->tcps[i].first=1; - } - - /* Initialization for PPM marker */ - j2k_cp->ppm = 0; - j2k_cp->ppm_data = NULL; - j2k_cp->ppm_previous = 0; - j2k_cp->ppm_store = 0; - - j2k_default_tcp.tccps = (j2k_tccp_t*)malloc(j2k_img->numcomps * sizeof(j2k_tccp_t)); - for (i = 0; i < j2k_cp->tw * j2k_cp->th; i++) { - j2k_cp->tcps[i].tccps = (j2k_tccp_t*)malloc(j2k_img->numcomps * sizeof(j2k_tccp_t)); - } - j2k_tile_data = (unsigned char**)calloc(j2k_cp->tw * j2k_cp->th, sizeof(char*)); - j2k_tile_len = (int*)calloc(j2k_cp->tw * j2k_cp->th, sizeof(int)); - j2k_state = J2K_STATE_MH; - - /* */ - img.Im_w = j2k_img->x1 - j2k_img->x0; - img.Im_h = j2k_img->y1 - j2k_img->y0; - img.Tile_x = j2k_cp->tdx; - img.Tile_y = j2k_cp->tdy; - img.Comp = j2k_img->numcomps; - img.tw = j2k_cp->tw; - img.th = j2k_cp->th; - img.tile = (info_tile_t*)malloc(img.tw * img.th * sizeof(info_tile_t)); - - for (i = 0; i < img.tw * img.th; i++) - { - tile = &img.tile[i]; - tile->marker = (info_marker_t*)malloc(32 * sizeof(info_marker_t)); - tile->num_marker = 0; - tile->marker_mul.num_COC = 0; - tile->marker_mul.CzCOC = START_NB; - tile->marker_mul.num_RGN = 0; - tile->marker_mul.CzRGN = START_NB; - tile->marker_mul.num_QCC = 0; - tile->marker_mul.CzQCC = START_NB; - tile->marker_mul.num_PLT = 0; - tile->marker_mul.CzPLT = START_NB; - tile->marker_mul.num_PPT = 0; - tile->marker_mul.CzPPT = START_NB; - tile->marker_mul.num_COM = 0; - tile->marker_mul.CzCOM = START_NB; - } - /* */ - - - } - -void j2k_read_com() { - int len; - info_tile_t *tile; - info_marker_t *tmp; - - len = cio_read(2); - - /* [MHIX BOX] */ - if (j2k_state == J2K_STATE_MH) - { - if (!img.marker_mul.num_COM) - img.marker_mul.COM = (info_marker_t*)malloc(img.marker_mul.CzCOM * sizeof(info_marker_t)); - if (img.marker_mul.num_COM >= img.marker_mul.CzCOM) - { - tmp = (info_marker_t*)malloc(2 * img.marker_mul.CzCOM * sizeof(info_marker_t)); - memcpy(tmp,img.marker_mul.COM,img.marker_mul.CzCOM); - img.marker_mul.CzCOM *= 2; - free(img.marker_mul.COM); - img.marker_mul.COM = tmp; - } - - img.marker_mul.COM[img.marker_mul.num_COM].type = J2K_MS_COM; - img.marker_mul.COM[img.marker_mul.num_COM].start_pos = cio_tell()-2; - img.marker_mul.COM[img.marker_mul.num_COM].len = len; - img.marker_mul.num_COM++; - } else - { - tile = &img.tile[j2k_curtileno]; - if (!tile->marker_mul.num_COM) - tile->marker_mul.COM = (info_marker_t*)calloc(START_NB, sizeof(info_marker_t)); - if (tile->marker_mul.num_COM >= tile->marker_mul.CzCOM) - { - tmp = (info_marker_t*)malloc(2 * tile->marker_mul.CzCOM * sizeof(info_marker_t)); - memcpy(tmp,tile->marker_mul.COM,tile->marker_mul.CzCOM); - tile->marker_mul.CzCOM *= 2; - free(tile->marker_mul.COM); - tile->marker_mul.COM = tmp; - } - tile->marker_mul.COM[tile->marker_mul.num_COM].type = J2K_MS_COM; - tile->marker_mul.COM[tile->marker_mul.num_COM].start_pos = cio_tell()-2; - tile->marker_mul.COM[tile->marker_mul.num_COM].len = len; - tile->marker_mul.num_COM++; - } - /* [MHIX BOX] */ - - cio_skip(len - 2); -} - - - - -void j2k_read_cox(int compno) { - int i; - j2k_tcp_t *tcp; - j2k_tccp_t *tccp; - - tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; - tccp = &tcp->tccps[compno]; - tccp->numresolutions = cio_read(1) + 1; - - img.Decomposition = tccp->numresolutions - 1; /* */ - - tccp->cblkw = cio_read(1) + 2; - tccp->cblkh = cio_read(1) + 2; - tccp->cblksty = cio_read(1); - tccp->qmfbid = cio_read(1); - if (tccp->csty&J2K_CP_CSTY_PRT) { - for (i = 0; i < tccp->numresolutions; i++) { - int tmp = cio_read(1); - tccp->prcw[i] = tmp&0xf; - tccp->prch[i] = tmp>>4; - } - } -} - - - - -void j2k_read_cod() { - int len, i, pos; - j2k_tcp_t *tcp; - info_tile_t *tile; - - tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; - len = cio_read(2); - - /* [MHIX BOX] */ - if (j2k_state == J2K_STATE_MH) - { - img.marker[img.num_marker].type = J2K_MS_SIZ; - img.marker[img.num_marker].start_pos = cio_tell()-2; - img.marker[img.num_marker].len = len; - img.num_marker++; - } - else - { - tile = &img.tile[j2k_curtileno]; - tile->marker[tile->num_marker].type = J2K_MS_SIZ; - tile->marker[tile->num_marker].start_pos = cio_tell()-2; - tile->marker[tile->num_marker].len = len; - tile->num_marker++; - } - /* [MHIX BOX] */ - - tcp->csty = cio_read(1); - tcp->prg = cio_read(1); - tcp->numlayers = cio_read(2); - tcp->mct = cio_read(1); - - pos = cio_tell(); - for (i = 0; i < j2k_img->numcomps; i++) { - tcp->tccps[i].csty = tcp->csty&J2K_CP_CSTY_PRT; - cio_seek(pos); - j2k_read_cox(i); - } - - /* */ - img.Prog = tcp->prg; - img.Layer = tcp->numlayers; - /* */ -} - - - - -void j2k_read_coc() { - int len, compno; - j2k_tcp_t *tcp; - info_tile_t *tile; - info_marker_t *tmp; - - tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; - len = cio_read(2); - - /* [MHIX BOX] */ - if (j2k_state == J2K_STATE_MH) - { - if (!img.marker_mul.num_COC) - img.marker_mul.COC = (info_marker_t*)malloc(img.marker_mul.CzCOC * sizeof(info_marker_t)); - if (img.marker_mul.num_COC >= img.marker_mul.CzCOC) - { - tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzCOC) * sizeof(info_marker_t)); - memcpy(tmp,img.marker_mul.COC,img.marker_mul.CzCOC); - img.marker_mul.CzCOC += INCREMENT; - free(img.marker_mul.COC); - img.marker_mul.COC = tmp; - } - img.marker_mul.COC[img.marker_mul.num_COC].type = J2K_MS_COC; - img.marker_mul.COC[img.marker_mul.num_COC].start_pos = cio_tell()-2; - img.marker_mul.COC[img.marker_mul.num_COC].len = len; - img.marker_mul.num_COC++; - } else - { - tile = &img.tile[j2k_curtileno]; - if (!tile->marker_mul.num_COC) - tile->marker_mul.COC = (info_marker_t*)malloc(tile->marker_mul.CzCOC * sizeof(info_marker_t)); - if (tile->marker_mul.num_COC >= tile->marker_mul.CzCOC) - { - tmp = (info_marker_t*)malloc((INCREMENT + tile->marker_mul.CzCOC) * sizeof(info_marker_t)); - memcpy(tmp,tile->marker_mul.COC,tile->marker_mul.CzCOC); - tile->marker_mul.CzCOC += INCREMENT; - free(tile->marker_mul.COC); - tile->marker_mul.COC = tmp; - } - tile->marker_mul.COC[tile->marker_mul.num_COC].type = J2K_MS_COC; - tile->marker_mul.COC[tile->marker_mul.num_COC].start_pos = cio_tell() - 2; - tile->marker_mul.COC[tile->marker_mul.num_COC].len = len; - tile->marker_mul.num_COC++; - } - /* [MHIX BOX] */ - - compno =cio_read(j2k_img->numcomps <= 256 ? 1 : 2); - - tcp->tccps[compno].csty = cio_read(1); - j2k_read_cox(compno); -} - - - - -void j2k_read_qcx(int compno, int len) { - int tmp; - j2k_tcp_t *tcp; - j2k_tccp_t *tccp; - int bandno, numbands; - - tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; - tccp = &tcp->tccps[compno]; - tmp = cio_read(1); - tccp->qntsty = tmp & 0x1f; - tccp->numgbits = tmp >> 5; - numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT ? len - 1 : (len - 1) / 2); - for (bandno = 0; bandno < numbands; bandno++) { - int expn, mant; - if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { /* WHY STEPSIZES WHEN NOQNT ? */ - expn = cio_read(1) >> 3; - mant = 0; - } else { - tmp = cio_read(2); - expn = tmp >> 11; - mant = tmp & 0x7ff; - } - tccp->stepsizes[bandno].expn = expn; - tccp->stepsizes[bandno].mant = mant; - } -} - - - - -void j2k_read_qcd() { - int len, i, pos; - info_tile_t *tile; - - len = cio_read(2); - - /* [MHIX BOX] */ - if (j2k_state == J2K_STATE_MH) - { - img.marker[img.num_marker].type = J2K_MS_QCD; - img.marker[img.num_marker].start_pos = cio_tell()-2; - img.marker[img.num_marker].len = len; - img.num_marker++; - } else - { - tile = &img.tile[j2k_curtileno]; - tile->marker[tile->num_marker].type = J2K_MS_QCD; - tile->marker[tile->num_marker].start_pos = cio_tell()-2; - tile->marker[tile->num_marker].len = len; - tile->num_marker++; - } - /* [MHIX BOX] */ - - - pos=cio_tell(); - for (i = 0; i < j2k_img->numcomps; i++) { - cio_seek(pos); - j2k_read_qcx(i, len - 2); - } -} - - - - -void j2k_read_qcc() { - int len, compno; - info_tile_t *tile; - info_marker_t *tmp; - - len = cio_read(2); - /* [MHIX BOX] */ - if (j2k_state == J2K_STATE_MH) - { - if (!img.marker_mul.num_QCC) - img.marker_mul.QCC = (info_marker_t*)malloc(img.marker_mul.CzQCC * sizeof(info_marker_t)); - if (img.marker_mul.num_QCC >= img.marker_mul.CzQCC) - { - tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzQCC) * sizeof(info_marker_t)); - memcpy(tmp,img.marker_mul.QCC,img.marker_mul.CzQCC); - img.marker_mul.CzQCC += INCREMENT; - free(img.marker_mul.QCC); - img.marker_mul.QCC = tmp; - } - img.marker_mul.QCC[img.marker_mul.num_QCC].type = J2K_MS_QCC; - img.marker_mul.QCC[img.marker_mul.num_QCC].start_pos = cio_tell() - 2; - img.marker_mul.QCC[img.marker_mul.num_QCC].len = len; - img.marker_mul.num_QCC++; - } else - { - tile = &img.tile[j2k_curtileno]; - if (!tile->marker_mul.num_QCC) - tile->marker_mul.QCC = (info_marker_t*)malloc(tile->marker_mul.CzQCC * sizeof(info_marker_t)); - if (tile->marker_mul.num_QCC >= tile->marker_mul.CzQCC) - { - tmp = (info_marker_t*)malloc((INCREMENT + tile->marker_mul.CzQCC) * sizeof(info_marker_t)); - memcpy(tmp,tile->marker_mul.QCC,tile->marker_mul.CzQCC); - tile->marker_mul.CzQCC += INCREMENT; - free(tile->marker_mul.QCC); - tile->marker_mul.QCC = tmp; - } - tile->marker_mul.QCC[tile->marker_mul.num_QCC].type = J2K_MS_QCC; - tile->marker_mul.QCC[tile->marker_mul.num_QCC].start_pos = cio_tell()-2; - tile->marker_mul.QCC[tile->marker_mul.num_QCC].len = len; - tile->marker_mul.num_QCC++; - } - /* [MHIX BOX] */ - - compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); - j2k_read_qcx(compno, len - 2 - (j2k_img->numcomps <= 256 ? 1 : 2)); -} - - - - -void j2k_read_poc() { - int len, numpchgs, i, old_poc; - j2k_tcp_t *tcp; - j2k_tccp_t *tccp; - info_tile_t *tile; - - tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; - old_poc = tcp->POC ? tcp->numpocs+1 : 0; - tcp->POC = 1; - tccp = &tcp->tccps[0]; - len = cio_read(2); - - /* [MHIX BOX] */ - if (j2k_state == J2K_STATE_MH) - { - img.marker[img.num_marker].type = J2K_MS_POC; - img.marker[img.num_marker].start_pos = cio_tell()-2; - img.marker[img.num_marker].len = len; - img.num_marker++; - } else - { - tile = &img.tile[j2k_curtileno]; - tile->marker[tile->num_marker].type = J2K_MS_POC; - tile->marker[tile->num_marker].start_pos = cio_tell()-2; - tile->marker[tile->num_marker].len = len; - tile->num_marker++; - } - /* [MHIX BOX] */ - - numpchgs = (len - 2) / (5 + 2 * (j2k_img->numcomps <= 256 ? 1 : 2)); - for (i = 0; i < numpchgs; i++) { - j2k_poc_t *poc; - poc = &tcp->pocs[i]; - poc->resno0 = cio_read(1); - poc->compno0 = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); - poc->layno1 = int_min(cio_read(2), tcp->numlayers); - poc->resno1 = int_min(cio_read(1), tccp->numresolutions); - poc->compno1 = int_min(cio_read(j2k_img->numcomps <= 256 ? 1 : 2), j2k_img->numcomps); - poc->prg = cio_read(1); - } - - tcp->numpocs = numpchgs + old_poc - 1; -} - - - - -void j2k_read_crg() { - int len, i, Xcrg_i, Ycrg_i; - - len = cio_read(2); - - /* [MHIX BOX] */ - img.marker[img.num_marker].type = J2K_MS_CRG; - img.marker[img.num_marker].start_pos = cio_tell()-2; - img.marker[img.num_marker].len = len; - img.num_marker++; - /* [MHIX BOX] */ - - for (i = 0; i < j2k_img->numcomps; i++) - { - Xcrg_i = cio_read(2); - Ycrg_i = cio_read(2); - } -} - - - - -void j2k_read_tlm() { - int len, Ztlm, Stlm, ST, SP, tile_tlm, i; - long int Ttlm_i, Ptlm_i; - info_marker_t *tmp; - - len = cio_read(2); - - /* [MHIX BOX] */ - if (!img.marker_mul.num_TLM) - img.marker_mul.TLM = (info_marker_t*)malloc(img.marker_mul.CzTLM * sizeof(info_marker_t)); - if (img.marker_mul.num_TLM >= img.marker_mul.CzTLM) - { - tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzTLM) * sizeof(info_marker_t)); - memcpy(tmp,img.marker_mul.TLM,img.marker_mul.CzTLM); - img.marker_mul.CzTLM += INCREMENT; - free(img.marker_mul.TLM); - img.marker_mul.TLM = tmp; - } - img.marker_mul.TLM[img.marker_mul.num_TLM].type = J2K_MS_TLM; - img.marker_mul.TLM[img.marker_mul.num_TLM].start_pos = cio_tell()-2; - img.marker_mul.TLM[img.marker_mul.num_TLM].len = len; - img.marker_mul.num_TLM++; - /* [MHIX BOX] */ - - Ztlm = cio_read(1); - Stlm = cio_read(1); - 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(ST); - Ptlm_i = cio_read(SP ? 4 : 2); - } -} - - - - -void j2k_read_plm() { - int len, i, Z_plm, N_plm, add, packet_len=0; - info_marker_t *tmp; - - len=cio_read(2); - - /* [MHIX BOX] */ - if (!img.marker_mul.num_PLM) - img.marker_mul.PLM = (info_marker_t*)malloc(img.marker_mul.CzPLM * sizeof(info_marker_t)); - if (img.marker_mul.num_PLM >= img.marker_mul.CzPLM) - { - tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzPLM) * sizeof(info_marker_t)); - memcpy(tmp,img.marker_mul.PLM,img.marker_mul.CzPLM); - img.marker_mul.CzPLM += INCREMENT; - free(img.marker_mul.PLM); - img.marker_mul.PLM = tmp; - } - img.marker_mul.PLM[img.marker_mul.num_PLM].type = J2K_MS_PLM; - img.marker_mul.PLM[img.marker_mul.num_PLM].start_pos = cio_tell()-2; - img.marker_mul.PLM[img.marker_mul.num_PLM].len = len; - img.marker_mul.num_PLM++; - /* [MHIX BOX] */ - - Z_plm = cio_read(1); - len -= 3; - while (len > 0) - { - N_plm = cio_read(4); - len -= 4; - for (i = N_plm ; i > 0 ; i--) - { - add = cio_read(1); - len--; - packet_len = (packet_len << 7) + add; - if ((add & 0x80) == 0) - { - /* New packet */ - packet_len = 0; - } - if (len <= 0) break; - } - } -} - - - - -void j2k_read_plt() { - int len, i, Zplt, packet_len=0, add; - info_tile_t *tile; - info_marker_t *tmp; -; - len = cio_read(2); - - /* [MHIX BOX] */ - tile = &img.tile[j2k_curtileno]; - if (!tile->marker_mul.num_PLT) - tile->marker_mul.PLT = (info_marker_t*)malloc(tile->marker_mul.CzPLT * sizeof(info_marker_t)); - if (tile->marker_mul.num_PLT >= tile->marker_mul.CzPLT) - { - tmp = (info_marker_t*)malloc((INCREMENT + tile->marker_mul.CzPLT) * sizeof(info_marker_t)); - memcpy(tmp,tile->marker_mul.PLT,tile->marker_mul.CzPLT); - tile->marker_mul.CzPLT += INCREMENT; - free(tile->marker_mul.PLT); - tile->marker_mul.PLT = tmp; - } - - tile->marker_mul.PLT[tile->marker_mul.num_PLT].type = J2K_MS_PLT; - tile->marker_mul.PLT[tile->marker_mul.num_PLT].start_pos = cio_tell()-2; - tile->marker_mul.PLT[tile->marker_mul.num_PLT].len = len; - tile->marker_mul.num_PLT++; - /* [MHIX BOX] */ - - Zplt = cio_read(1); - for (i = len-3; i > 0; i--) - { - add = cio_read(1); - packet_len = (packet_len << 7) + add; - if ((add & 0x80) == 0) - { - /* New packet */ - packet_len = 0; - } - } -} - - - - -void j2k_read_ppm() { - int len, Z_ppm, i, j; - int N_ppm; - info_marker_t *tmp; - - len = cio_read(2); - - /* [MHIX BOX] */ - if (!img.marker_mul.num_PPM) - img.marker_mul.PPM = (info_marker_t*)malloc(img.marker_mul.CzPPM * sizeof(info_marker_t)); - if (img.marker_mul.num_PPM >= img.marker_mul.CzPPM) - { - tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzPPM) * sizeof(info_marker_t)); - memcpy(tmp,img.marker_mul.PPM,img.marker_mul.CzPPM); - img.marker_mul.CzPPM += INCREMENT; - free(img.marker_mul.PPM); - img.marker_mul.PPM = tmp; - } - img.marker_mul.PLM[img.marker_mul.num_PPM].type = J2K_MS_PPM; - img.marker_mul.PLM[img.marker_mul.num_PPM].start_pos = cio_tell()-2; - img.marker_mul.PLM[img.marker_mul.num_PPM].len = len; - img.marker_mul.num_PPM++; - /* [MHIX BOX] */ - - j2k_cp->ppm = 1; - - Z_ppm = cio_read(1); /* Z_ppm */ - len -= 3; - while (len > 0) - { - if (j2k_cp->ppm_previous == 0) - { - N_ppm = cio_read(4); /* N_ppm */ - len -= 4; - } else - { - N_ppm = j2k_cp->ppm_previous; - } - - j = j2k_cp->ppm_store; - if (Z_ppm == 0) /* First PPM marker */ - j2k_cp->ppm_data = (unsigned char*)calloc(N_ppm, sizeof(unsigned char)); - else /* NON-first PPM marker */ - j2k_cp->ppm_data = (unsigned char*)realloc(j2k_cp->ppm_data, (N_ppm + j2k_cp->ppm_store) * sizeof(unsigned char)); - - for (i = N_ppm ; i > 0 ; i--) /* Read packet header */ - { - j2k_cp->ppm_data[j] = cio_read(1); - j++; - len--; - if (len == 0) break; /* Case of non-finished packet header in present marker but finished in next one */ - } - - j2k_cp->ppm_previous = i - 1; - j2k_cp->ppm_store = j; - } -} - - - - -void j2k_read_ppt() { - int len, Z_ppt, i, j = 0; - j2k_tcp_t *tcp; - info_tile_t *tile; - len=cio_read(2); - - /* [MHIX BOX] */ - tile = & img.tile[j2k_curtileno]; - tile->marker[tile->num_marker].type = J2K_MS_PPT; - tile->marker[tile->num_marker].start_pos = cio_tell()-2; - tile->marker[tile->num_marker].len = len; - tile->num_marker++; - /* [MHIX BOX] */ - - Z_ppt = cio_read(1); - tcp = &j2k_cp->tcps[j2k_curtileno]; - tcp->ppt = 1; - if (Z_ppt == 0) /* First PPT marker */ - { - tcp->ppt_data = (unsigned char*)calloc(len - 3, sizeof(unsigned char)); - tcp->ppt_store = 0; - } - else /* NON-first PPT marker */ - tcp->ppt_data = (unsigned char*)realloc(tcp->ppt_data, (len - 3 + tcp->ppt_store) * sizeof(unsigned char)); - - j = tcp->ppt_store; - for (i = len - 3 ; i > 0 ; i--) - { - tcp->ppt_data[j] = cio_read(1); - j++; - } - tcp->ppt_store = j; -} - - - - -void j2k_read_sot() { - int len, tileno, totlen, partno, numparts, i; - j2k_tcp_t *tcp; - j2k_tccp_t *tmp; - info_tile_t *tile; - info_tile_part_t *tilepart_tmp; - - - //fprintf(stderr,"SOT\n"); - len = cio_read(2); - tileno = cio_read(2); - /* [MHIX BOX] */ - tile = & img.tile[tileno]; - tile->marker[tile->num_marker].type = J2K_MS_SOT; - tile->marker[tile->num_marker].start_pos = cio_tell() - 4; - tile->marker[tile->num_marker].len = len; - tile->num_marker++; - /* [MHIX BOX] */ - - totlen = cio_read(4); - if (!totlen) totlen = cio_numbytesleft() + 8; - partno = cio_read(1); - numparts = cio_read(1); - - /* */ - if (tileno == 0 && partno == 0 ) - img.Main_head_end = cio_tell() - 7; /* Correction End = First byte of first SOT */ - - img.tile[tileno].num_tile = tileno; - /* */ - - tile->numparts = partno + 1; /* INDEX : Number of tile_parts for the tile */ - img.num_max_tile_parts = int_max(tile->numparts, img.num_max_tile_parts); /* INDEX : Maximum number of tile_part per tile */ - - if (partno == 0) - { - tile->tile_parts = (info_tile_part_t*)malloc(START_NB * sizeof(info_tile_part_t*)); - tile->Cztile_parts = START_NB; - } - if (partno >= tile->Cztile_parts) - { - tilepart_tmp = (info_tile_part_t*)malloc((INCREMENT + tile->Cztile_parts) * sizeof(info_tile_part_t)); - memcpy(tmp, tile->tile_parts, tile->Cztile_parts); - tile->Cztile_parts += INCREMENT; - free(tile->tile_parts); - tile->tile_parts = tilepart_tmp; - } - - tile->tile_parts[partno].start_pos = cio_tell() - 12; /* INDEX : start_pos of the tile_part */ - tile->tile_parts[partno].length = totlen; /* INDEX : length of the tile_part */ - tile->tile_parts[partno].end_pos = totlen + cio_tell() - 12; /* INDEX : end position of the tile_part */ - - - j2k_curtileno = tileno; - j2k_eot = cio_getbp() - 12 + totlen; - j2k_state = J2K_STATE_TPH; - tcp = &j2k_cp->tcps[j2k_curtileno]; - - tile->tile_parts[numparts].num_reso_AUX = tcp->tccps[0].numresolutions; /* INDEX : AUX value for TPIX */ - - if (partno == 0) - // if (tcp->first == 1) - { - tmp = tcp->tccps; - *tcp = j2k_default_tcp; - /* Initialization PPT */ - tcp->ppt = 0; - tcp->ppt_data = NULL; - - tcp->tccps = tmp; - for (i = 0; i < j2k_img->numcomps; i++) { - tcp->tccps[i] = j2k_default_tcp.tccps[i]; - } - //j2k_cp->tcps[j2k_curtileno].first=0; - } -} - - - -void j2k_read_rgn() { - int len, compno, roisty; - j2k_tcp_t *tcp; - info_tile_t *tile; - info_marker_t *tmp; - // fprintf(stderr,"RGN\n"); - tcp = j2k_state == J2K_STATE_TPH ? &j2k_cp->tcps[j2k_curtileno] : &j2k_default_tcp; - len = cio_read(2); - - /* [MHIX BOX]*/ - if (j2k_state == J2K_STATE_MH) - { - if (!img.marker_mul.num_RGN) - img.marker_mul.RGN = (info_marker_t*)malloc(img.marker_mul.CzRGN * sizeof(info_marker_t)); - if (img.marker_mul.num_RGN >= img.marker_mul.CzRGN) - { - tmp = (info_marker_t*)malloc((INCREMENT + img.marker_mul.CzRGN) * sizeof(info_marker_t)); - memcpy(tmp,img.marker_mul.RGN, img.marker_mul.CzRGN); - img.marker_mul.CzRGN += INCREMENT; - free(img.marker_mul.RGN); - img.marker_mul.RGN = tmp; - } - img.marker_mul.RGN[img.marker_mul.num_RGN].type = J2K_MS_RGN; - img.marker_mul.RGN[img.marker_mul.num_RGN].start_pos = cio_tell() - 2; - img.marker_mul.RGN[img.marker_mul.num_RGN].len = len; - img.marker_mul.num_RGN++; - } else - { - tile = &img.tile[j2k_curtileno]; - if (!tile->marker_mul.num_RGN) - tile->marker_mul.RGN = (info_marker_t*)malloc(tile->marker_mul.CzRGN * sizeof(info_marker_t)); - if (tile->marker_mul.num_RGN >= tile->marker_mul.CzRGN) - { - tmp = (info_marker_t*)malloc((INCREMENT + tile->marker_mul.CzRGN) * sizeof(info_marker_t)); - memcpy(tmp,tile->marker_mul.RGN,tile->marker_mul.CzRGN); - tile->marker_mul.CzRGN += INCREMENT; - free(tile->marker_mul.RGN); - tile->marker_mul.RGN = tmp; - } - - tile->marker_mul.RGN[tile->marker_mul.num_RGN].type = J2K_MS_RGN; - tile->marker_mul.RGN[tile->marker_mul.num_RGN].start_pos = cio_tell() - 2; - tile->marker_mul.RGN[tile->marker_mul.num_RGN].len = len; - tile->marker_mul.num_RGN++; - } - /* [MHIX BOX] */ - - compno = cio_read(j2k_img->numcomps <= 256 ? 1 : 2); - roisty = cio_read(1); - tcp->tccps[compno].roishift = cio_read(1); -} - - - - - -void j2k_read_sod() { - int len; - unsigned char *data; - info_tile_t *tile; - info_tile_part_t *tile_part; - // fprintf(stderr,"SOD\n"); - /* [MHIX BOX] */ - tile = &img.tile[j2k_curtileno]; - tile->marker[tile->num_marker].type = J2K_MS_SOD; - tile->marker[tile->num_marker].start_pos = cio_tell(); - tile->marker[tile->num_marker].len = 0; - tile->num_marker++; - /* [MHIX BOX] */ - - tile_part = &tile->tile_parts[tile->numparts - 1]; /* INDEX : Current tilepart of a tile */ - tile_part->length_header = cio_tell() - 1 - tile_part->start_pos; /* INDEX : length of the tile-part header */ - tile_part->end_header = cio_tell() - 1; /* INDEX : end header position of the tile-part header */ - - len = int_min(j2k_eot - cio_getbp(), cio_numbytesleft()); - - j2k_tile_len[j2k_curtileno] += len; - data = (unsigned char*)realloc(j2k_tile_data[j2k_curtileno], j2k_tile_len[j2k_curtileno]); - memcpy(data, cio_getbp(), len); - j2k_tile_data[j2k_curtileno] = data; - cio_skip(len); - j2k_state = J2K_STATE_TPHSOT; -} - -void j2k_read_eoc() { - int tileno; - tcd_init(j2k_img, j2k_cp, &img); - for (tileno = 0; tilenotw * j2k_cp->th; tileno++) { - tcd_decode_tile(j2k_tile_data[tileno], j2k_tile_len[tileno], tileno, &img); - } - - j2k_state = J2K_STATE_MT; - longjmp(j2k_error, 1); -} - - - - -void j2k_read_unk() { - fprintf(stderr, "warning: unknown marker\n"); -} - - - - -int j2k_index_JPIP(char *Idx_file, char *J2K_file, int len, int version){ - FILE *dest; - char *index; - int pos_iptr, end_pos; - int len_cidx, pos_cidx; - int len_jp2c, pos_jp2c; - int len_fidx, pos_fidx; - - dest=fopen(Idx_file, "wb"); - if (!dest) { - fprintf(stderr, "Failed to open %s for reading !!\n", Idx_file); - return 0; - } - - /* INDEX MODE JPIP */ - index = (char*)malloc(len); - cio_init(index, len); - jp2_write_jp(); - jp2_write_ftyp(); - - jp2_write_jp2h(j2k_img); - jp2_write_dbtl(Idx_file); - - pos_iptr=cio_tell(); - cio_skip(24); /* IPTR further ! */ - - pos_jp2c = cio_tell(); - len_jp2c = jp2_write_jp2c(J2K_file); - - pos_cidx = cio_tell(); - len_cidx = jpip_write_cidx(pos_jp2c + 8,img, j2k_cp, version); /* Correction len_jp2C --> pos_jp2c + 8 */ - - - pos_fidx = cio_tell(); - len_fidx = jpip_write_fidx(pos_jp2c, len_jp2c, pos_cidx, len_cidx); - -end_pos = cio_tell(); - - cio_seek(pos_iptr); - jpip_write_iptr(pos_fidx,len_fidx); - cio_seek(end_pos); - - fwrite(index, 1, cio_tell(), dest); - free(index); - - fclose(dest); - return 1; -} - - - -typedef struct { - int id; - int states; - void (*handler)(); -} j2k_dec_mstabent_t; - -j2k_dec_mstabent_t j2k_dec_mstab[]={ - {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc}, - {J2K_MS_SOT, J2K_STATE_MH|J2K_STATE_TPHSOT, j2k_read_sot}, - {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod}, - {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc}, - {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz}, - {J2K_MS_COD, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_cod}, - {J2K_MS_COC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_coc}, - {J2K_MS_RGN, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_rgn}, - {J2K_MS_QCD, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_qcd}, - {J2K_MS_QCC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_qcc}, - {J2K_MS_POC, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_poc}, - {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm}, - {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm}, - {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt}, - {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm}, - {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt}, - {J2K_MS_SOP, 0, 0}, - {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg}, - {J2K_MS_COM, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_com}, - {0, J2K_STATE_MH|J2K_STATE_TPH, j2k_read_unk} -}; - -j2k_dec_mstabent_t *j2k_dec_mstab_lookup(int id) { - j2k_dec_mstabent_t *e; - for (e = j2k_dec_mstab; e->id != 0; e++) { - if (e->id == id) { - break; - } - } - return e; -} - -int j2k_decode(unsigned char *src, int len, j2k_image_t **image, j2k_cp_t **cp) { - if (setjmp(j2k_error)) { - if (j2k_state != J2K_STATE_MT) { - fprintf(stderr, "WARNING: incomplete bitstream\n"); - return 0; - } - return cio_numbytes(); - } - j2k_img = (j2k_image_t*)calloc(1, sizeof(j2k_image_t)); - j2k_cp = (j2k_cp_t*)calloc(1, sizeof(j2k_cp_t)); - *image = j2k_img; - *cp = j2k_cp; - j2k_state = J2K_STATE_MHSOC; - cio_init(src, len); - for (;;) { - j2k_dec_mstabent_t *e; - int id = cio_read(2); - if (id >> 8 != 0xff) { - fprintf(stderr, "%.8x: expected a marker instead of %x\n", cio_tell() - 2, id); - return 0; - } - e = j2k_dec_mstab_lookup(id); - if (!(j2k_state & e->states)) { - fprintf(stderr, "%.8x: unexpected marker %x\n", cio_tell() - 2, id); - return 0; - } - if (e->handler) { - (*e->handler)(); - } - } - -} - - -#ifdef WIN32 -#include - -BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { - switch (ul_reason_for_call) { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} -#endif - -int main(int argc, char **argv) -{ - FILE *src; - int totlen; - char *j2kfile; - j2k_image_t *imgg; - j2k_cp_t *cp; - int version; - - if (argc != 4) - { - fprintf(stderr,"\nUSAGE : ./index_create J2K-file JP2-file version\n\nVersion : 0, 1, 2 or 3\n 0 : [faix] 4-byte and no AUX fields\n 1 : [faix] 8-byte and no AUX fields\n 2 : [faix] 4-byte and AUX fields\n 3 : [faix] 8-byte and AUX fields\n\nReference Document : annex I from JPIP-FCD-version 2 (SC 29 N5727)\n\n"); - return 1; - } - - src=fopen(argv[1], "rb"); - if (!src) { - fprintf(stderr, "Failed to open %s for reading !!\n", argv[1]); - return 1; - } - - /* length of the codestream */ - fseek(src, 0, SEEK_END); - totlen = ftell(src); - fseek(src, 0, SEEK_SET); - - j2kfile = (char*)malloc(totlen); - fread(j2kfile, 1, totlen, src); - fclose(src); - - img.marker = (info_marker_t*)malloc(32 * sizeof(info_marker_t)); - img.num_marker = 0; - img.num_max_tile_parts = 0; - img.marker_mul.num_COC = 0; - img.marker_mul.CzCOC = START_NB; - img.marker_mul.num_RGN = 0; - img.marker_mul.CzRGN = START_NB; - img.marker_mul.num_QCC = 0; - img.marker_mul.CzQCC = START_NB; - img.marker_mul.num_TLM = 0; - img.marker_mul.CzTLM = START_NB; - img.marker_mul.num_PLM = 0; - img.marker_mul.CzPLM = START_NB; - img.marker_mul.num_PPM = 0; - img.marker_mul.CzPPM = START_NB; - img.marker_mul.num_COM = 0; - img.marker_mul.CzCOM = START_NB; - - /* decode */ - - if (!j2k_decode(j2kfile, totlen, &imgg, &cp)) { - fprintf(stderr, "Index_creator: failed to decode image!\n"); - return 1; - } - free(j2kfile); - - // fseek(src, 0, SEEK_SET); - img.codestream_size = totlen; - sscanf(argv[3], "%d", &version); - if (version > 3) - { - fprintf(stderr,"Error : value of version unauthorized !! Value accepted : 0, 1, 2 or 3 !!\n"); - return 0; - } - - j2k_index_JPIP(argv[2], argv[1], totlen * 2 > 60000 ? totlen * 2 : 60000, version); - - j2k_clean(); - return 0; -} - diff --git a/indexer_JPIP/int.c b/indexer_JPIP/int.c deleted file mode 100644 index 29f778c9..00000000 --- a/indexer_JPIP/int.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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. - */ - -/// -/// Get the minimum of two integers. -/// -int int_min(int a, int b) { - return a -/// Get the maximum of two integers. -/// -int int_max(int a, int b) { - return a>b?a:b; -} - -/// -/// Clamp an integer inside an interval. -/// -int int_clamp(int a, int min, int max) { - if (amax) return max; - return a; -} - -/// -/// Get absolute value of integer. -/// -int int_abs(int a) { - return a<0?-a:a; -} - -/// -/// Divide an integer and round upwards. -/// -int int_ceildiv(int a, int b) { - return (a+b-1)/b; -} - -/// -/// Divide an integer by a power of 2 and round upwards. -/// -int int_ceildivpow2(int a, int b) { - return (a+(1<>b; -} - -/// -/// Divide an integer by a power of 2 and round downwards. -/// -int int_floordivpow2(int a, int b) { - return a>>b; -} - -/// -/// Get logarithm of an integer and round downwards. -/// -int int_floorlog2(int a) { - int l; - for (l=0; a>1; l++) { - a>>=1; - } - return l; -} diff --git a/indexer_JPIP/int.h b/indexer_JPIP/int.h deleted file mode 100644 index 4921ff4d..00000000 --- a/indexer_JPIP/int.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 __INT_H -#define __INT_H - -int int_min(int a, int b); -int int_max(int a, int b); -int int_clamp(int a, int min, int max); -int int_abs(int a); -int int_ceildiv(int a, int b); -int int_ceildivpow2(int a, int b); -int int_floordivpow2(int a, int b); -int int_floorlog2(int a); - -#endif diff --git a/indexer_JPIP/j2k.h b/indexer_JPIP/j2k.h deleted file mode 100644 index 5ead3b45..00000000 --- a/indexer_JPIP/j2k.h +++ /dev/null @@ -1,288 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003-2004, Yannick Verschueren - * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#define VERSION "0.0.8" - -#ifdef WIN32 -#ifdef LIBJ2K_EXPORTS -#define LIBJ2K_API __declspec(dllexport) -#else -#define LIBJ2K_API __declspec(dllimport) -#endif -#else -#define LIBJ2K_API -#endif - -#ifndef __J2K_H -#define __J2K_H - -#define J2K_MAXRLVLS 33 -#define J2K_MAXBANDS (3*J2K_MAXRLVLS+1) - -#define J2K_CP_CSTY_PRT 0x01 -#define J2K_CP_CSTY_SOP 0x02 -#define J2K_CP_CSTY_EPH 0x04 -#define J2K_CCP_CSTY_PRT 0x01 -#define J2K_CCP_CBLKSTY_LAZY 0x01 -#define J2K_CCP_CBLKSTY_RESET 0x02 -#define J2K_CCP_CBLKSTY_TERMALL 0x04 -#define J2K_CCP_CBLKSTY_VSC 0x08 -#define J2K_CCP_CBLKSTY_PTERM 0x10 -#define J2K_CCP_CBLKSTY_SEGSYM 0x20 -#define J2K_CCP_QNTSTY_NOQNT 0 -#define J2K_CCP_QNTSTY_SIQNT 1 -#define J2K_CCP_QNTSTY_SEQNT 2 - -typedef struct -{ - int dx, dy; /* XRsiz, YRsiz */ - int prec; /* precision */ - int bpp; /* deapth of image in bits */ - int sgnd; /* signed */ - int *data; /* image-component data */ -} j2k_comp_t; - -typedef struct { - int version; - int x0, y0; /* XOsiz, YOsiz */ - int x1, y1; /* Xsiz, Ysiz */ - int numcomps; /* number of components */ - int index_on; /* 0 = no index || 1 = index */ - j2k_comp_t *comps; /* image-components */ -} j2k_image_t; - -typedef struct { - int expn; /* exponent */ - int mant; /* mantissa */ -} j2k_stepsize_t; - -typedef struct { - int csty; /* coding style */ - int numresolutions; /* number of resolutions */ - int cblkw; /* width of code-blocks */ - int cblkh; /* height of code-blocks */ - int cblksty; /* code-block coding style */ - int qmfbid; /* discrete wavelet transform identifier */ - int qntsty; /* quantisation style */ - j2k_stepsize_t stepsizes[J2K_MAXBANDS]; /* stepsizes used for quantisation */ - int numgbits; /* number of guard bits */ - int roishift; /* Region of Interest shift */ - int prcw[J2K_MAXRLVLS]; /* Precinct width */ - int prch[J2K_MAXRLVLS]; /* Precinct height */ -} j2k_tccp_t; - -typedef struct { - int resno0, compno0; - int layno1, resno1, compno1; - int prg; - int tile; - char progorder[4]; -} j2k_poc_t; - -typedef struct { - int csty; /* coding style */ - int prg; /* progression order */ - int numlayers; /* number of layers */ - int mct; /* multi-component transform identifier */ - int rates[100]; /* rates of layers */ - int numpocs; /* number of progression order changes */ - int POC; /* Precise if a POC marker has been used O:NO, 1:YES */ - j2k_poc_t pocs[32]; /* progression order changes */ - unsigned char *ppt_data; /* packet header store there for futur use in t2_decode_packet */ - int ppt; /* If ppt == 1 --> there was a PPT marker for the present tile */ - int ppt_store; /* Use in case of multiple marker PPT (number of info already store) */ - j2k_tccp_t *tccps; /* tile-component coding parameters */ -} j2k_tcp_t; - -typedef struct { - int tx0, ty0; /* XTOsiz, YTOsiz */ - int tdx, tdy; /* XTsiz, YTsiz */ - int tw, th; - unsigned char *ppm_data; /* packet header store there for futur use in t2_decode_packet */ - int ppm; /* If ppm == 1 --> there was a PPM marker for the present tile */ - int ppm_store; /* Use in case of multiple marker PPM (number of info already store) */ - int ppm_previous; /* Use in case of multiple marker PPM (case on non-finished previous info) */ - j2k_tcp_t *tcps; /* tile coding parameters */ -} j2k_cp_t; - - - - - -/* Packet information : Layer level */ -typedef struct { - int len; /* Length of the body of the packet */ - int len_header; /* Length of the header of the packet */ - int offset; /* Offset of the body of the packet */ - int offset_header; /* Offset of the header of the packet */ -} info_layer_t; - - -/* Access to packet information : precinct level */ -typedef struct { - info_layer_t *layer; -} info_prec_t; - - -/* Access to packet information : resolution level */ -typedef struct { - info_prec_t *prec; -} info_reso_t; - - -/* Access to packet information : component level */ -typedef struct { - info_reso_t *reso; -} info_compo_t; - - -/* Information about the marker */ -typedef struct { - int type; /* type of marker [SIZ, QCD, POC, PPM, CRG, COD] appearing only once */ - int start_pos; /* Start position of the marker */ - int len; /* Length of the marker */ -} info_marker_t; - - -/* Multiple marker in tile header */ -typedef struct{ - info_marker_t *COC; /* COC markers */ - int num_COC; /* Number of COC marker */ - int CzCOC; /* Current size of the vector COC */ - - info_marker_t *RGN; /* RGN markers */ - int num_RGN; /* Number of RGN marker */ - int CzRGN; /* Current size of the vector RGN */ - - info_marker_t *QCC; /* QCC markers */ - int num_QCC; /* Number of QCC marker */ - int CzQCC; /* Current size of the vector QCC */ - - info_marker_t *PLT; /* PLT markers */ - int num_PLT; /* Number of PLT marker */ - int CzPLT; /* Current size of the vector PLT */ - - info_marker_t *PPT; /* PPT markers */ - int num_PPT; /* Number of PPT marker */ - int CzPPT; /* Current size of the vector PPT */ - - info_marker_t *COM; /* COM markers */ - int num_COM; /* Number of COM marker */ - int CzCOM; /* Current size of the vector COC */ -} info_marker_mul_tile_t; - - -/* Information about each tile_part for a particulary tile */ -typedef struct{ - int start_pos; /* Start position of the tile_part */ - int length; /* Length of the tile_part header + body */ - int length_header; /* Length of the header */ - int end_pos; /* End position of the tile part */ - int end_header; /* End position of the tile part header */ - - int num_reso_AUX; /* Number of resolution level completed */ -} info_tile_part_t; - - -/* Information about each tile */ -typedef struct { - int num_tile; /* Number of Tile */ - int pw, ph; /* number of precinct by tile */ - int num_packet; /* number of packet in the tile */ - info_compo_t *compo; /* component [packet] */ - - info_marker_t *marker; /* information concerning markers inside image [only one apparition] */ - info_marker_mul_tile_t marker_mul; /* information concerning markers inside image [multiple apparition] */ - int num_marker; /* number of marker */ - - int numparts; /* number of tile_part for this tile */ - info_tile_part_t *tile_parts; /* Information about each tile_part */ - int Cztile_parts; /* Current size of the tile_parts vector */ -} info_tile_t; /* index struct */ - - -/* Multiple marker in main header */ -typedef struct{ - info_marker_t *COC; /* COC markers */ - int num_COC; /* Number of COC marker */ - int CzCOC; /* Current size of the vector COC */ - - info_marker_t *RGN; /* RGN markers */ - int num_RGN; /* Number of RGN marker */ - int CzRGN; /* Current size of the vector RGN */ - - info_marker_t *QCC; /* QCC markers */ - int num_QCC; /* Number of QCC marker */ - int CzQCC; /* Current size of the vector QCC */ - - info_marker_t *TLM; /* TLM markers */ - int num_TLM; /* Number of TLM marker */ - int CzTLM; /* Current size of the vector TLM */ - - info_marker_t *PLM; /* PLM markers */ - int num_PLM; /* Number of PLM marker */ - int CzPLM; /* Current size of the vector PLM */ - - info_marker_t *PPM; /* PPM markers */ - int num_PPM; /* Number of PPM marker */ - int CzPPM; /* Current size of the vector PPM */ - - info_marker_t *COM; /* COM markers */ - int num_COM; /* Number of COM marker */ - int CzCOM; /* Current size of the vector COM */ -} info_marker_mul_t; /* index struct */ - - -/* Information about image */ -typedef struct { - int Im_w, Im_h; /* Image width and Height */ - int Tile_x, Tile_y; /* Number of Tile in X and Y */ - int tw, th; - int pw, ph; /* nombre precinct in X and Y */ - int pdx, pdy; /* size of precinct in X and Y */ - - int Prog; /* progression order */ - int Comp; /* Component numbers */ - int Layer; /* number of layer */ - int Decomposition; /* number of decomposition */ - - int Main_head_end; /* Main header position */ - int codestream_size; /* codestream's size */ - - info_marker_t *marker; /* information concerning markers inside image [only one apparition] */ - info_marker_mul_t marker_mul; /* information concerning markers inside image [multiple apparition] */ - int num_marker; /* number of marker */ - - int num_packet_max; /* Maximum number of packet */ - - int num_max_tile_parts; /* Maximum number of tile-part */ - info_tile_t *tile; /* information concerning tiles inside image */ -} info_image_t; /* index struct */ - - -#endif diff --git a/indexer_JPIP/jp2.c b/indexer_JPIP/jp2.c deleted file mode 100644 index 1c193ad7..00000000 --- a/indexer_JPIP/jp2.c +++ /dev/null @@ -1,301 +0,0 @@ -/* - * Copyright (c) 2003-2004, Yannick Verschueren - * Copyright (c) 2003-2004, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS `AS IS' - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -#include "j2k.h" -#include "cio.h" -#include "tcd.h" -#include "int.h" - -#define JPIP_JPIP 0x6a706970 - -#define JP2_JP 0x6a502020 -#define JP2_FTYP 0x66747970 -#define JP2_JP2H 0x6a703268 -#define JP2_IHDR 0x69686472 -#define JP2_COLR 0x636f6c72 -#define JP2_JP2C 0x6a703263 -#define JP2_URL 0x75726c20 -#define JP2_DBTL 0x6474626c -#define JP2_BPCC 0x62706363 -#define JP2 0x6a703220 - - -void jp2_write_url(char *Idx_file) -{ - int len, lenp, i; - char str[256]; - - sprintf(str, "%s", Idx_file); - lenp=cio_tell(); - cio_skip(4); - cio_write(JP2_URL, 4); // DBTL - cio_write(0,1); // VERS - cio_write(0,3); // FLAG - - for (i=0; iy1-j2k_img->x0,4); // HEIGHT - cio_write(j2k_img->x1-j2k_img->x0,4); // WIDTH - cio_write(j2k_img->numcomps,2); // NC - - depth_0=j2k_img->comps[0].prec-1; - sign=j2k_img->comps[0].sgnd; - - for(i=1;inumcomps;i++) - { - depth=j2k_img->comps[i].prec-1; - sign=j2k_img->comps[i].sgnd; - if(depth_0!=depth) BPC_ok=0; - } - - if (BPC_ok) - cio_write(depth_0+(sign<<7),1); - else - cio_write(255,1); - - cio_write(7,1); // C : Always 7 - cio_write(1,1); // UnkC, colorspace unknow - cio_write(0,1); // IPR, no intellectual property - - len=cio_tell()-lenp; - cio_seek(lenp); - cio_write(len,4); // L - cio_seek(lenp+len); - - return BPC_ok; -} - -void jp2_write_bpcc(j2k_image_t *j2k_img) -{ - int len, lenp, i; - - lenp=cio_tell(); - cio_skip(4); - cio_write(JP2_BPCC, 4); // BPCC - - for(i=0;inumcomps;i++) - cio_write(j2k_img->comps[i].prec-1+(j2k_img->comps[i].sgnd<<7),1); - - len=cio_tell()-lenp; - cio_seek(lenp); - cio_write(len,4); // L - cio_seek(lenp+len); -} - -void jp2_write_colr(int BPC_ok, j2k_image_t *j2k_img) -{ - int len, lenp, meth; - - lenp=cio_tell(); - cio_skip(4); - cio_write(JP2_COLR, 4); // COLR - - if ((j2k_img->numcomps==1 || j2k_img->numcomps==3) && (BPC_ok && j2k_img->comps[0].prec==8)) - meth=1; - else - meth=2; - - cio_write(meth,1); // METH - cio_write(0,1); // PREC - cio_write(0,1); // APPROX - - if (meth==1) - cio_write(j2k_img->numcomps>1?16:17,4); // EnumCS - - if (meth==2) - cio_write(0,1); // PROFILE (??) - - len=cio_tell()-lenp; - cio_seek(lenp); - cio_write(len,4); // L - cio_seek(lenp+len); -} - -/* - * Write the JP2H box - * - * JP2 Header box - * - */ -void jp2_write_jp2h(j2k_image_t *j2k_img) -{ - int len, lenp, BPC_ok; - - lenp=cio_tell(); - cio_skip(4); - cio_write(JP2_JP2H, 4); /* JP2H */ - - BPC_ok=jp2_write_ihdr(j2k_img); - - if (!BPC_ok) - jp2_write_bpcc(j2k_img); - jp2_write_colr(BPC_ok, j2k_img); - - len=cio_tell()-lenp; - cio_seek(lenp); - cio_write(len,4); /* L */ - cio_seek(lenp+len); -} - -/* - * Write the FTYP box - * - * File type box - * - */ -void jp2_write_ftyp() -{ - int len, lenp; - - lenp=cio_tell(); - cio_skip(4); - cio_write(JP2_FTYP, 4); /* FTYP */ - - cio_write(JP2,4); /* BR */ - cio_write(0,4); /* MinV */ - cio_write(JP2,4); /* CL0 : JP2 */ - cio_write(JPIP_JPIP,4); /* CL1 : JPIP */ - - len=cio_tell()-lenp; - cio_seek(lenp); - cio_write(len,4); /* L */ - cio_seek(lenp+len); -} - -/* - * Read the FTYP box - * - * File type box - * - */ -void jp2_read_ftyp(int length) -{ - int BR, MinV, type, i; - - BR = cio_read(4); /* BR */ - MinV = cio_read(4); /* MinV */ - length-=8; - - for (i=length/4;i>0;i--) - type = cio_read(4); /* CLi : JP2, JPIP */ -} - -int jp2_write_jp2c(char *J2K_file) -{ - int len, lenp, totlen, i; - FILE *src; - char *j2kfile; - - lenp=cio_tell(); - cio_skip(4); - cio_write(JP2_JP2C, 4); // JP2C - - src=fopen(J2K_file, "rb"); - fseek(src, 0, SEEK_END); - totlen=ftell(src); - fseek(src, 0, SEEK_SET); - - j2kfile=(char*)malloc(totlen); - fread(j2kfile, 1, totlen, src); - fclose(src); - - for (i=0;i -#include -#include -#include -#include - -#include "j2k.h" -#include "cio.h" -#include "tcd.h" -#include "int.h" - -#define JPIP_CIDX 0x63696478 /* Codestream index */ -#define JPIP_CPTR 0x63707472 /* Codestream Finder Box */ -#define JPIP_MANF 0x6d616e66 /* Manifest Box */ -#define JPIP_FAIX 0x66616978 /* Fragment array Index box */ -#define JPIP_MHIX 0x6d686978 /* Main Header Index Table */ -#define JPIP_TPIX 0x74706978 /* Tile-part Index Table box */ -#define JPIP_THIX 0x74686978 /* Tile header Index Table box */ -#define JPIP_PPIX 0x70706978 /* Precinct Packet Index Table box */ -#define JPIP_PHIX 0x70686978 /* Packet Header index Table */ -#define JPIP_FIDX 0x66696478 /* File Index */ -#define JPIP_FPTR 0x66707472 /* File Finder */ -#define JPIP_PRXY 0x70727879 /* Proxy boxes */ -#define JPIP_IPTR 0x69707472 /* Index finder box */ -#define JPIP_PHLD 0x70686c64 /* Place holder */ - -#define JP2C 0x6a703263 - -//static info_marker_t marker_jpip[32], marker_local_jpip[32]; /* SIZE to precise ! */ -//static int num_marker_jpip, num_marker_local_jpip; - -/* - * Write the CPTR box - * - * Codestream finder box (box) - * - */ -void jpip_write_cptr(int offset, info_image_t img) -{ - int len, lenp; - - lenp=cio_tell(); - cio_skip(4); /* L [at the end] */ - cio_write(JPIP_CPTR,4); /* T */ - cio_write(0,2); /* DR A PRECISER !! */ - cio_write(0,2); /* CONT */ - cio_write(offset,8); /* COFF A PRECISER !! */ - cio_write(img.codestream_size,8); /* CLEN */ - len=cio_tell()-lenp; - cio_seek(lenp); - cio_write(len, 4); /* L */ - cio_seek(lenp+len); -} - -/* - * Read the CPTR box - * - * Codestream finder box (box) - * - */ -void jpip_read_cptr() -{ - int DR, CONT; - long long Coff, codestream_size; - - DR = cio_read(2); /* DR */ - CONT = cio_read(2); /* CONT */ - Coff = cio_read(8); /* COFF */ - codestream_size = cio_read(8); /* CLEN */ -} - -/* - * Write the MANF box - * - * Manifest box (box) - * - */ -void jpip_write_manf(int second, int v, info_marker_t *marker) -{ - int len, lenp, i; - lenp=cio_tell(); - cio_skip(4); /* L [at the end] */ - cio_write(JPIP_MANF,4); /* T */ - - if (second) /* Write only during the second pass */ - { - for(i=0;i= 0; i--) /* COC */ - { - cio_write(img.marker_mul.COC[i].type, 2); - cio_write(i, 2); - cio_write(img.marker_mul.COC[i].start_pos, 8); - cio_write(img.marker_mul.COC[i].len, 2); - } - - for(i = img.marker_mul.num_RGN - 1; i >= 0; i--) /* RGN */ - { - cio_write(img.marker_mul.RGN[i].type, 2); - cio_write(i, 2); - cio_write(img.marker_mul.RGN[i].start_pos, 8); - cio_write(img.marker_mul.RGN[i].len, 2); - } - - for(i = img.marker_mul.num_QCC - 1; i >= 0; i--) /* QCC */ - { - cio_write(img.marker_mul.QCC[i].type, 2); - cio_write(i, 2); - cio_write(img.marker_mul.QCC[i].start_pos, 8); - cio_write(img.marker_mul.QCC[i].len, 2); - } - - for(i = img.marker_mul.num_TLM - 1; i >= 0; i--) /* TLM */ - { - cio_write(img.marker_mul.TLM[i].type, 2); - cio_write(i, 2); - cio_write(img.marker_mul.TLM[i].start_pos, 8); - cio_write(img.marker_mul.TLM[i].len, 2); - } - - for(i = img.marker_mul.num_PLM - 1; i >= 0; i--) /* PLM */ - { - cio_write(img.marker_mul.PLM[i].type, 2); - cio_write(i, 2); - cio_write(img.marker_mul.PLM[i].start_pos, 8); - cio_write(img.marker_mul.PLM[i].len, 2); - } - - for(i = img.marker_mul.num_PPM - 1; i >= 0; i--) /* PPM */ - { - cio_write(img.marker_mul.PPM[i].type, 2); - cio_write(i, 2); - cio_write(img.marker_mul.PPM[i].start_pos, 8); - cio_write(img.marker_mul.PPM[i].len, 2); - } - - for(i = img.marker_mul.num_COM - 1; i >= 0; i--) /* COM */ - { - cio_write(img.marker_mul.COM[i].type, 2); - cio_write(i, 2); - cio_write(img.marker_mul.COM[i].start_pos, 8); - cio_write(img.marker_mul.COM[i].len, 2); - } - } - else /* TILE HEADER */ - { - tile = &img.tile[tileno]; - cio_write(tile->tile_parts[0].length_header, 8); /* TLEN */ - - for(i = 0; i < tile->num_marker; i++) /* Marker restricted to 1 apparition */ - { - cio_write(tile->marker[i].type, 2); - cio_write(0, 2); - cio_write(tile->marker[i].start_pos, 8); - cio_write(tile->marker[i].len, 2); - } - - /* Marker NOT restricted to 1 apparition */ - for(i = tile->marker_mul.num_COC - 1; i >= 0; i--) /* COC */ - { - cio_write(tile->marker_mul.COC[i].type, 2); - cio_write(i, 2); - cio_write(tile->marker_mul.COC[i].start_pos, 8); - cio_write(tile->marker_mul.COC[i].len, 2); - } - - for(i = tile->marker_mul.num_RGN - 1; i >= 0; i--) /* RGN */ - { - cio_write(tile->marker_mul.RGN[i].type, 2); - cio_write(i, 2); - cio_write(tile->marker_mul.RGN[i].start_pos, 8); - cio_write(tile->marker_mul.RGN[i].len, 2); - } - - for(i = tile->marker_mul.num_QCC - 1; i >= 0; i--) /* QCC */ - { - cio_write(tile->marker_mul.QCC[i].type, 2); - cio_write(i, 2); - cio_write(tile->marker_mul.QCC[i].start_pos, 8); - cio_write(tile->marker_mul.QCC[i].len, 2); - } - - for(i = tile->marker_mul.num_PLT - 1; i >= 0; i--) /* PLT */ - { - cio_write(tile->marker_mul.PLT[i].type,2); - cio_write(i,2); - cio_write(tile->marker_mul.PLT[i].start_pos,8); - cio_write(tile->marker_mul.PLT[i].len,2); - } - - for(i = tile->marker_mul.num_PPT - 1; i >= 0; i--) /* PPT */ - { - cio_write(tile->marker_mul.PPT[i].type, 2); - cio_write(i, 2); - cio_write(tile->marker_mul.PPT[i].start_pos, 8); - cio_write(tile->marker_mul.PPT[i].len, 2); - } - - for(i = tile->marker_mul.num_COM - 1; i >= 0; i--) /* COM */ - { - cio_write(tile->marker_mul.COM[i].type, 2); - cio_write(i, 2); - cio_write(tile->marker_mul.COM[i].start_pos, 8); - cio_write(tile->marker_mul.COM[i].len, 2); - } - } - - len=cio_tell()-lenp; - cio_seek(lenp); - cio_write(len, 4); /* L */ - cio_seek(lenp+len); - - return len; -} - -/* - * Read the MHIX box - * - * Main Header Index Table (box) - * - */ -void jpip_read_mhix(int len) -{ - int i, v, marker_type, marker_start_pos, marker_len, marker_remains; - - v = (len - 8) / 14; - - for (i=0; icompo[compno]; - int correction; - - num_packet=0; - - if(j2k_cp->tcps[tileno].csty&J2K_CP_CSTY_EPH) - correction=3; - else - correction=1; - for(resno=0;resnoreso[resno]; - for (precno=0;precnoprec[precno]; - for(layno=0;laynolayer[layno]; - cio_write(layer_Idx->offset,(version & 0x01)?8:4); /* start position */ - cio_write((layer_Idx->len_header-correction)?0:layer_Idx->len,(version & 0x01)?8:4); /* length */ - if (version & 0x02) - cio_write(0,4); /* Aux_i,j : Auxiliary value */ - num_packet++; - } - } - } - /* PADDING */ - while (num_packet < img.num_packet_max) - { - cio_write(0,(version & 0x01)?8:4); /* start position */ - cio_write(0,(version & 0x01)?8:4); /* length */ - if (version & 0x02) - cio_write(0,4); /* Aux_i,j : Auxiliary value */ - num_packet++; - } - } - - break; - - case 3: /* PHIX NOT FINISHED !! */ - cio_write(img.num_packet_max,(version & 0x01)?8:4); /* NMAX */ - cio_write(img.tw*img.th,(version & 0x01)?8:4); /* M */ - for(tileno=0;tilenocompo[compno]; - int correction; - - num_packet = 0; - if(j2k_cp->tcps[tileno].csty&J2K_CP_CSTY_EPH) - correction=3; - else - correction=1; - for(resno=0;resnoreso[resno]; - for (precno=0;precnoprec[precno]; - for(layno=0;laynolayer[layno]; - cio_write(layer_Idx->offset_header,(version & 0x01)?8:4); /* start position */ - cio_write((layer_Idx->len_header-correction)?0:layer_Idx->len_header,(version & 0x01)?8:4); /* length */ - if (version & 0x02) - cio_write(0,4); /* Aux_i,j : Auxiliary value */ - num_packet++; - } - } - } - /* PADDING */ - while (num_packettw*j2k_cp->th); - - for ( i = 0; i < 2 ; i++ ) - { - if (i) cio_seek(lenp); - - lenp = cio_tell(); - cio_skip(4); /* L [at the end] */ - cio_write(JPIP_THIX, 4); /* THIX */ - jpip_write_manf(i, j2k_cp->tw*j2k_cp->th, marker); - num_marker_local_jpip=img.Comp; - - for (tileno = 0; tileno < j2k_cp->tw*j2k_cp->th; tileno++) - { - marker[tileno].len = jpip_write_mhix(img, 1, tileno); - marker[tileno].type = JPIP_MHIX; - } - - len=cio_tell()-lenp; - cio_seek(lenp); - cio_write(len, 4); /* L */ - cio_seek(lenp+len); - } - - free(marker); - - return len; -} -/* - * Write the PPIX box - * - * Precinct Packet Index table box (superbox) - * - */ -int jpip_write_ppix(info_image_t img,j2k_cp_t *j2k_cp) -{ - int len, lenp, compno, i; - info_marker_t *marker; - int num_marker_local_jpip; - marker = (info_marker_t*)calloc(sizeof(info_marker_t), img.Comp); - - for (i=0;i<2;i++) - { - if (i) cio_seek(lenp); - - lenp=cio_tell(); - cio_skip(4); /* L [at the end] */ - cio_write(JPIP_PPIX, 4); /* PPIX */ - jpip_write_manf(i,img.Comp,marker); - num_marker_local_jpip=img.Comp; - - for (compno=0; compno -#include - - -/* */ -/* Create a packet iterator. */ -/* */ -pi_iterator_t *pi_create(j2k_image_t * img, j2k_cp_t * cp, int tileno) -{ - int p, q; - int compno, resno, pino; - int maxres = 0; - pi_iterator_t *pi; - j2k_tcp_t *tcp; - j2k_tccp_t *tccp; - - tcp = &cp->tcps[tileno]; - pi = (pi_iterator_t *) malloc((tcp->numpocs + 1) * sizeof(pi_iterator_t)); - - for (pino = 0; pino < tcp->numpocs + 1; pino++) { /* change */ - p = tileno % cp->tw; - q = tileno / cp->tw; - - pi[pino].tx0 = int_max(cp->tx0 + p * cp->tdx, img->x0); - pi[pino].ty0 = int_max(cp->ty0 + q * cp->tdy, img->y0); - pi[pino].tx1 = int_min(cp->tx0 + (p + 1) * cp->tdx, img->x1); - pi[pino].ty1 = int_min(cp->ty0 + (q + 1) * cp->tdy, img->y1); - pi[pino].numcomps = img->numcomps; - pi[pino].comps = (pi_comp_t *) malloc(img->numcomps * sizeof(pi_comp_t)); - - for (compno = 0; compno < pi->numcomps; compno++) { - int tcx0, tcy0, tcx1, tcy1; - pi_comp_t *comp = &pi[pino].comps[compno]; - tccp = &tcp->tccps[compno]; - comp->dx = img->comps[compno].dx; - comp->dy = img->comps[compno].dy; - comp->numresolutions = tccp->numresolutions; - comp->resolutions = - (pi_resolution_t *) malloc(comp->numresolutions * - sizeof(pi_resolution_t)); - tcx0 = int_ceildiv(pi->tx0, comp->dx); - tcy0 = int_ceildiv(pi->ty0, comp->dy); - tcx1 = int_ceildiv(pi->tx1, comp->dx); - tcy1 = int_ceildiv(pi->ty1, comp->dy); - if (comp->numresolutions > maxres) { - maxres = comp->numresolutions; - } - for (resno = 0; resno < comp->numresolutions; resno++) { - int levelno; - int rx0, ry0, rx1, ry1; - int px0, py0, px1, py1; - pi_resolution_t *res = &comp->resolutions[resno]; - if (tccp->csty & J2K_CCP_CSTY_PRT) { - res->pdx = tccp->prcw[resno]; - res->pdy = tccp->prch[resno]; - } else { - res->pdx = 15; - res->pdy = 15; - } - levelno = comp->numresolutions - 1 - resno; - rx0 = int_ceildivpow2(tcx0, levelno); - ry0 = int_ceildivpow2(tcy0, levelno); - rx1 = int_ceildivpow2(tcx1, levelno); - ry1 = int_ceildivpow2(tcy1, levelno); - px0 = int_floordivpow2(rx0, res->pdx) << res->pdx; - py0 = int_floordivpow2(ry0, res->pdy) << res->pdy; - px1 = int_ceildivpow2(rx1, res->pdx) << res->pdx; - py1 = int_ceildivpow2(ry1, res->pdy) << res->pdy; - res->pw = (px1 - px0) >> res->pdx; - res->ph = (py1 - py0) >> res->pdy; - } - } - - tccp = &tcp->tccps[0]; - pi[pino].step_p=1; - pi[pino].step_c=100*pi[pino].step_p; - pi[pino].step_r=img->numcomps*pi[pino].step_c; - pi[pino].step_l=maxres*pi[pino].step_r; - - if (pino==0) - pi[pino].include=(short int*)calloc(img->numcomps*maxres*tcp->numlayers*100,sizeof(short int)); - else - pi[pino].include=pi[pino-1].include; - - /*if (pino == tcp->numpocs) {*/ - 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 = img->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; -} - -/* */ -/* Get next packet in layer=resolution-component-precinct order. */ -/* */ -int pi_next_lrcp(pi_iterator_t * pi) -{ - pi_comp_t *comp; - pi_resolution_t *res; - - if (!pi->first) { - comp = &pi->comps[pi->compno]; - res = &comp->resolutions[pi->resno]; - goto 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->numresolutions) { - - continue; - } - res = &comp->resolutions[pi->resno]; - for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) { - if (!pi->include[pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p]){ - pi->include[pi->layno * pi->step_l + pi->resno * pi->step_r + pi->compno * pi->step_c + pi->precno * pi->step_p] = 1; - return 1; - } - skip:; - } - } - } - } - return 0; -} - -/* */ -/* Get next packet in resolution-layer-component-precinct order. */ -/* */ -int pi_next_rlcp(pi_iterator_t * pi) -{ - pi_comp_t *comp; - pi_resolution_t *res; - if (!pi->first) { - comp = &pi->comps[pi->compno]; - res = &comp->resolutions[pi->resno]; - goto 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->numresolutions) { - continue; - } - res = &comp->resolutions[pi->resno]; - for (pi->precno = 0; pi->precno < res->pw * res->ph; pi->precno++) { - if (!pi->include[pi->layno*pi->step_l+pi->resno*pi->step_r+pi->compno*pi->step_c+pi->precno*pi->step_p]){ - pi->include[pi->layno*pi->step_l+pi->resno*pi->step_r+pi->compno*pi->step_c+pi->precno*pi->step_p] = 1; - return 1; - } - skip:; - } - } - } - } - return 0; -} - -/* */ -/* Get next packet in resolution-precinct-component-layer order. */ -/* */ -int pi_next_rpcl(pi_iterator_t * pi) -{ - pi_comp_t *comp; - pi_resolution_t *res; - if (!pi->first) { - goto 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->numresolutions; resno++) { - int 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)); - pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); - pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); - } - } - } - for (pi->resno = pi->poc.resno0; pi->resno < pi->poc.resno1; pi->resno++) { - 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 levelno; - int trx0, try0; - int rpx, rpy; - int prci, prcj; - comp = &pi->comps[pi->compno]; - if (pi->resno >= comp->numresolutions) { - continue; - } - res = &comp->resolutions[pi->resno]; - levelno = comp->numresolutions - 1 - pi->resno; - trx0 = int_ceildiv(pi->tx0, comp->dx << levelno); - try0 = int_ceildiv(pi->ty0, comp->dy << levelno); - rpx = res->pdx + levelno; - rpy = res->pdy + levelno; - if (! - (pi->x % (comp->dx << rpx) == 0 - || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) { - continue; - } - if (! - (pi->y % (comp->dy << rpy) == 0 - || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) { - continue; - } - prci = - int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), - res->pdx) - int_floordivpow2(trx0, res->pdx); - prcj = - int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), - res->pdy) - int_floordivpow2(try0, res->pdy); - pi->precno = prci + prcj * res->pw; - for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - if (!pi->include[pi->layno*pi->step_l+pi->resno*pi->step_r+pi->compno*pi->step_c+pi->precno*pi->step_p]){ - pi->include[pi->layno*pi->step_l+pi->resno*pi->step_r+pi->compno*pi->step_c+pi->precno*pi->step_p] = 1; - return 1; - } - skip:; - } - } - } - } - } - return 0; -} - -/* */ -/* Get next packet in precinct-component-resolution-layer order. */ -/* */ -int pi_next_pcrl(pi_iterator_t * pi) -{ - pi_comp_t *comp; - pi_resolution_t *res; - if (!pi->first) { - comp = &pi->comps[pi->compno]; - goto 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->numresolutions; resno++) { - int 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)); - pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); - pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); - } - } - } - 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->numresolutions); - pi->resno++) { - int levelno; - int trx0, try0; - int rpx, rpy; - int prci, prcj; - res = &comp->resolutions[pi->resno]; - levelno = comp->numresolutions - 1 - pi->resno; - trx0 = int_ceildiv(pi->tx0, comp->dx << levelno); - try0 = int_ceildiv(pi->ty0, comp->dy << levelno); - rpx = res->pdx + levelno; - rpy = res->pdy + levelno; - if (! - (pi->x % (comp->dx << rpx) == 0 - || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) { - continue; - } - if (! - (pi->y % (comp->dy << rpy) == 0 - || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) { - continue; - } - prci = - int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), - res->pdx) - int_floordivpow2(trx0, res->pdx); - prcj = - int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), - res->pdy) - int_floordivpow2(try0, res->pdy); - pi->precno = prci + prcj * res->pw; - for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - if (! pi->include[pi->layno*pi->step_l+pi->resno*pi->step_r+pi->compno*pi->step_c+pi->precno*pi->step_p]){ - pi->include[pi->layno*pi->step_l+pi->resno*pi->step_r+pi->compno*pi->step_c+pi->precno*pi->step_p] = 1; - return 1; - } - skip:; - } - } - } - } - } - return 0; -} - -/* */ -/* Get next packet in component-precinct-resolution-layer order. */ -/* */ -int pi_next_cprl(pi_iterator_t * pi) -{ - pi_comp_t *comp; - pi_resolution_t *res; - if (!pi->first) { - comp = &pi->comps[pi->compno]; - goto 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->numresolutions; resno++) { - int 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)); - pi->dx = !pi->dx ? dx : int_min(pi->dx, dx); - pi->dy = !pi->dy ? dy : int_min(pi->dy, dy); - } - 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->numresolutions); - pi->resno++) { - int levelno; - int trx0, try0; - int rpx, rpy; - int prci, prcj; - res = &comp->resolutions[pi->resno]; - levelno = comp->numresolutions - 1 - pi->resno; - trx0 = int_ceildiv(pi->tx0, comp->dx << levelno); - try0 = int_ceildiv(pi->ty0, comp->dy << levelno); - rpx = res->pdx + levelno; - rpy = res->pdy + levelno; - if (! - (pi->x % (comp->dx << rpx) == 0 - || (pi->x == pi->tx0 && (trx0 << levelno) % (1 << rpx)))) { - continue; - } - if (! - (pi->y % (comp->dy << rpy) == 0 - || (pi->y == pi->ty0 && (try0 << levelno) % (1 << rpx)))) { - continue; - } - prci = - int_floordivpow2(int_ceildiv(pi->x, comp->dx << levelno), - res->pdx) - int_floordivpow2(trx0, res->pdx); - prcj = - int_floordivpow2(int_ceildiv(pi->y, comp->dy << levelno), - res->pdy) - int_floordivpow2(try0, res->pdy); - pi->precno = prci + prcj * res->pw; - for (pi->layno = 0; pi->layno < pi->poc.layno1; pi->layno++) { - if (! pi->include[pi->layno*pi->step_l+pi->resno*pi->step_r+pi->compno*pi->step_c+pi->precno*pi->step_p]){ - pi->include[pi->layno*pi->step_l+pi->resno*pi->step_r+pi->compno*pi->step_c+pi->precno*pi->step_p] = 1; - return 1; - } - skip:; - } - } - } - } - } - return 0; -} - -/* */ -/* Get next packet. */ -/* */ -int pi_next(pi_iterator_t * pi) -{ - switch (pi->poc.prg) { - case 0: - return pi_next_lrcp(pi); - case 1: - return pi_next_rlcp(pi); - case 2: - return pi_next_rpcl(pi); - case 3: - return pi_next_pcrl(pi); - case 4: - return pi_next_cprl(pi); - } - return 0; -} diff --git a/indexer_JPIP/pi.h b/indexer_JPIP/pi.h deleted file mode 100644 index b300b9e3..00000000 --- a/indexer_JPIP/pi.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * 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 - -#include "j2k.h" -#include "tcd.h" - -typedef struct { - int pdx, pdy; - int pw, ph; -} pi_resolution_t; - -typedef struct { - int dx, dy; - int numresolutions; - pi_resolution_t *resolutions; -} pi_comp_t; - -typedef struct { - short int *include; - int step_l, step_r, step_c, step_p; - int compno, resno, precno, layno; /* component, resolution, precinct and layer that indentify the packet */ - int first; - j2k_poc_t poc; - int numcomps; - pi_comp_t *comps; - int tx0, ty0, tx1, ty1; - int x, y, dx, dy; -} pi_iterator_t; /* packet iterator */ - -/* - * Create a packet iterator - * img: raw image for which the packets will be listed - * cp: coding paremeters - * tileno: number that identifies the tile for which to list the packets - * return value: returns a packet iterator that points to the first packet of the tile - */ -pi_iterator_t *pi_create(j2k_image_t * img, j2k_cp_t * cp, int tileno); - -/* - * Modify the packet iterator to point to the next packet - * pi: packet iterator to modify - * return value: returns 0 if pi pointed to the last packet or else returns 1 - */ -int pi_next(pi_iterator_t * pi); - -#endif diff --git a/indexer_JPIP/t2.c b/indexer_JPIP/t2.c deleted file mode 100644 index 14a44bea..00000000 --- a/indexer_JPIP/t2.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 "t2.h" -#include "tcd.h" -#include "bio.h" -#include "j2k.h" -#include "pi.h" -#include "tgt.h" -#include "int.h" -#include "cio.h" -#include -#include -#include -#include - -#define RESTART 0x04 - -extern jmp_buf j2k_error; - -int t2_getcommacode() { - int n; - for (n=0; bio_read(1); n++) {} - return n; -} - -int t2_getnumpasses() -{ - int n; - if (!bio_read(1)) return 1; - if (!bio_read(1)) return 2; - if ((n=bio_read(2))!=3) return 3+n; - if ((n=bio_read(5))!=31) return 6+n; - return 37+bio_read(7); -} - -void t2_init_seg(tcd_seg_t *seg, int cblksty) { - seg->numpasses=0; - seg->len=0; - seg->maxpasses=cblksty&J2K_CCP_CBLKSTY_TERMALL?1:100; -} - -int t2_decode_packet(unsigned char *src, int len, tcd_tile_t *tile, j2k_cp_t * cp, j2k_tcp_t *tcp, int compno, int resno, int precno, int layno, info_layer_t *layer_Idx) { - int bandno, cblkno; - tcd_tilecomp_t *tilec = &tile->comps[compno]; - tcd_resolution_t *res = &tilec->resolutions[resno]; - unsigned char *c = src; - unsigned char *d = c; - int e; - int present; - - if (layno == 0) { - for (bandno = 0; bandno < res->numbands; bandno++) { - tcd_band_t *band = &res->bands[bandno]; - tcd_precinct_t *prc = &band->precincts[precno]; - tgt_reset(prc->incltree); - tgt_reset(prc->imsbtree); - for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { - tcd_cblk_t *cblk = &prc->cblks[cblkno]; - cblk->numsegs = 0; - } - } - } - /* INDEX */ - layer_Idx->len_header = 0; - - /* 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: (futher) return to codestream for decoding */ - if (cp->ppm == 1) /* PPM */ - { - c = cp->ppm_data; - d = c; - bio_init_dec(c, 1000); - } else - { - if (tcp->ppt == 1) /* PPT */ - { - c = tcp->ppt_data; - d = c; - bio_init_dec(c, 1000); - } else /* Normal Case */ - { - if (tcp->csty & J2K_CP_CSTY_SOP) - { - if ((*c) != 255 || (*(c+1) != 145)) {printf("Error : expected SOP marker [1]!!!\n");} - c += 6; - } - bio_init_dec(c, src + len - c); - layer_Idx->len_header = -6; - } - } - - present = bio_read(1); - - if (!present) - { - bio_inalign(); - /* Normal case */ - c += bio_numbytes(); - if (tcp->csty & J2K_CP_CSTY_EPH) - { - if ((*c) != 255 || (*(c+1) != 146)) {printf("Error : expected EPH marker [1]!!!\n");} - c += 2; - } - /* INDEX */ - layer_Idx->len_header += (c-d); - - /* PPT and PPM dealing */ - if (cp->ppm == 1) /* PPM */ - { - cp->ppm_data = c; - return 0; - } - if (tcp->ppt == 1) /* PPT */ - { - tcp->ppt_data = c; - return 0; - } - return c - src; - } - - for (bandno=0; bandnonumbands; bandno++) { - tcd_band_t *band = &res->bands[bandno]; - tcd_precinct_t *prc = &band->precincts[precno]; - for (cblkno = 0; cblkno < prc->cw * prc->ch; cblkno++) { - int included, increment, n; - tcd_cblk_t *cblk = &prc->cblks[cblkno]; - tcd_seg_t *seg; - if (!cblk->numsegs) { - included = tgt_decode(prc->incltree, cblkno, layno+1); - } else { - included = bio_read(1); - } - if (!included) { - cblk->numnewpasses = 0; - continue; - } - if (!cblk->numsegs) { - int i, numimsbs; - for (i = 0; !tgt_decode(prc->imsbtree, cblkno, i); i++) {} - numimsbs = i-1; - cblk->numbps = band->numbps - numimsbs; - cblk->numlenbits = 3; - } - cblk->numnewpasses = t2_getnumpasses(); - increment = t2_getcommacode(); - cblk->numlenbits += increment; - if (!cblk->numsegs) { - seg = &cblk->segs[0]; - t2_init_seg(seg, tcp->tccps[compno].cblksty); - } else { - seg = &cblk->segs[cblk->numsegs - 1]; - if (seg->numpasses == seg->maxpasses) { - t2_init_seg(++seg, tcp->tccps[compno].cblksty); - } - } - n = cblk->numnewpasses; - do { - seg->numnewpasses = int_min(seg->maxpasses-seg->numpasses, n); - seg->newlen = bio_read(cblk->numlenbits + int_floorlog2(seg->numnewpasses)); - n -= seg->numnewpasses; - if (n > 0) { - t2_init_seg(++seg, tcp->tccps[compno].cblksty); - } - } while (n > 0); - } - } - if(bio_inalign()) return -999; - c += bio_numbytes(); - - if (tcp->csty & J2K_CP_CSTY_EPH) { /* EPH marker */ - if ((*c) != 255 || (*(c+1) != 146)) {printf("Error : expected EPH marker [2]!!!\n"); } - c += 2; - } - - /* INDEX */ - layer_Idx->len_header += (c-d); - - /* PPT Step 2 : see above for details */ - if (cp->ppm == 1) - { - cp->ppm_data = c; /* Update pointer */ - - /* INDEX */ - layer_Idx->len_header = c-d; - - c = src; - d = c; - if (tcp->csty & J2K_CP_CSTY_SOP) - { - if ((*c) != 255 || (*(c+1) != 145)) {printf("Error : expected SOP marker [2] !!!\n"); } - c += 6; - } - bio_init_dec(c, src + len - c); - } else - { - if (tcp->ppt == 1) - { - tcp->ppt_data = c; /* Update pointer */ - /* INDEX */ - layer_Idx->len_header = c-d; - - c = src; - d = c; - if (tcp->csty & J2K_CP_CSTY_SOP) /* SOP marker */ - { - if ((*c) != 255 || (*(c+1) != 145)) {printf("Error : expected SOP marker [2] !!!\n"); } - c += 6; - } - bio_init_dec(c, src + len - c); - - } - } - - for (bandno = 0; bandno < res->numbands; bandno++) { - tcd_band_t *band = &res->bands[bandno]; - tcd_precinct_t *prc = &band->precincts[precno]; - for (cblkno = 0; cblkno < prc->cw*prc->ch; cblkno++) { - tcd_cblk_t *cblk = &prc->cblks[cblkno]; - tcd_seg_t *seg; - if (!cblk->numnewpasses) continue; - if (!cblk->numsegs) { - seg = &cblk->segs[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); - } - } - /* */ - e = c-d; - layer_Idx->len = e; - /* */ - - return c-src; -} - -void t2_init_info_packets(info_image_t *img, j2k_cp_t *cp) -{ - int compno, tileno, resno, precno, layno; - - for(compno = 0; compno < img->Comp; compno++) - { - for(tileno = 0; tileno < img->tw*img->th; tileno++) - { - info_tile_t *tile_Idx = &img->tile[tileno]; - info_compo_t *compo_Idx = &tile_Idx->compo[compno]; - for(resno = 0; resno < img->Decomposition + 1 ; resno++) - { - info_reso_t *reso_Idx = &compo_Idx->reso[resno]; - for (precno = 0; precno < img->tile[tileno].pw * img->tile[tileno].ph; precno++) - { - info_prec_t *prec_Idx = &reso_Idx->prec[precno]; - for(layno = 0; layno < img->Layer ; layno++) - { - info_layer_t *layer_Idx = &prec_Idx->layer[layno]; - layer_Idx->offset = 0; /* start position */ - layer_Idx->len_header = 0; /* length */ - } - } - } - } - } -} - -int t2_decode_packets(unsigned char *src, int len, j2k_image_t *img, j2k_cp_t *cp, int tileno, tcd_tile_t *tile, info_image_t *imgg) { - unsigned char *c = src; - pi_iterator_t *pi; - int pino, compno,e; - int partno; - info_tile_part_t *tile_part; - int position; - int length_read; - info_tile_t *tile_Idx; - info_compo_t *compo_Idx; - info_reso_t *reso_Idx; - info_prec_t *prec_Idx; - info_layer_t *layer_Idx; - - t2_init_info_packets(imgg, cp); /* Initialize the packets information : LEN and OFFSET to 0 */ - - tile_Idx = &imgg->tile[tileno]; - tile_Idx->num_packet = 0; - pi = pi_create(img, cp, tileno); - partno = 0; - tile_part = &tile_Idx->tile_parts[partno]; - position = tile_part->end_header + 1; - length_read = 0; - - for (pino = 0; pino <= cp->tcps[tileno].numpocs; pino++) - { - while (pi_next(&pi[pino])) - { - compo_Idx = &tile_Idx->compo[pi[pino].compno]; - reso_Idx = &compo_Idx->reso[pi[pino].resno]; - prec_Idx = &reso_Idx->prec[pi[pino].precno]; - layer_Idx = &prec_Idx->layer[pi[pino].layno]; - - layer_Idx->offset = position; - layer_Idx->offset_header = position; - - e = t2_decode_packet(c, src+len-c, tile, cp, &cp->tcps[tileno], pi[pino].compno, pi[pino].resno, pi[pino].precno, pi[pino].layno,layer_Idx); - if (e == -999) - { - break; - } else - c += e; - position += e; - - /* Update position in case of multiple tile-parts for a tile >> */ - length_read += e; - if (length_read >= (tile_part->end_pos - tile_part->end_header)) - { - partno++; - tile_part = &tile_Idx->tile_parts[partno]; - position = tile_part->end_header + 1; - length_read = 0; - } - /* << end_update */ - - tile_Idx->num_packet++; - } - - // FREE space memory taken by pi - for (compno = 0; compno < pi[pino].numcomps; compno++) - { - free(pi[pino].comps[compno].resolutions); - } - free(pi[pino].comps); - } - - free(pi[0].include); - free(pi); - - if (e==-999) - return e; - else - { - imgg->num_packet_max=int_max(imgg->num_packet_max,tile_Idx->num_packet); - return c-src; - } -} diff --git a/indexer_JPIP/t2.h b/indexer_JPIP/t2.h deleted file mode 100644 index f4951079..00000000 --- a/indexer_JPIP/t2.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 __T2_H -#define __T2_H - -#include "tcd.h" -#include "j2k.h" - -/* - * Decode the packets of a tile from a source buffer - * src: the source buffer - * len: length of the source buffer - * img: destination image - * cp: image coding parameters - * tileno: number that identifies the tile for which to decode the packets - * tile: tile for which to decode the packets - */ -int t2_decode_packets(unsigned char *src, int len, j2k_image_t *img, j2k_cp_t *cp, int tileno, tcd_tile_t *tile, info_image_t *imgg); - -#endif diff --git a/indexer_JPIP/tcd.c b/indexer_JPIP/tcd.c deleted file mode 100644 index c4045c73..00000000 --- a/indexer_JPIP/tcd.c +++ /dev/null @@ -1,285 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 "tcd.h" -#include "int.h" -#include "t2.h" -#include -#include -#include -#include -#include -#include -#include - -static tcd_image_t tcd_image; - -static j2k_image_t *tcd_img; -static j2k_cp_t *tcd_cp; - -extern jmp_buf j2k_error; - -void tcd_init(j2k_image_t *img, j2k_cp_t *cp, info_image_t *imgg) { - int tileno, compno, resno, bandno, precno, cblkno; - tcd_img=img; - tcd_cp=cp; - tcd_image.tw=cp->tw; - tcd_image.th=cp->th; - tcd_image.tiles=(tcd_tile_t*)malloc(cp->tw*cp->th*sizeof(tcd_tile_t)); - for (tileno=0; tilenotw*cp->th; tileno++) { - j2k_tcp_t *tcp=&cp->tcps[tileno]; - tcd_tile_t *tile=&tcd_image.tiles[tileno]; - // cfr p59 ISO/IEC FDIS15444-1 : 2000 (18 august 2000) - int p=tileno%cp->tw; // si numerotation matricielle .. - int q=tileno/cp->tw; // .. coordonnees de la tile (q,p) q pour ligne et p pour colonne - info_tile_t *tile_Idx=&imgg->tile[tileno]; // INDEX - - // 4 borders of the tile rescale on the image if necessary - tile->x0=int_max(cp->tx0+p*cp->tdx, img->x0); - tile->y0=int_max(cp->ty0+q*cp->tdy, img->y0); - tile->x1=int_min(cp->tx0+(p+1)*cp->tdx, img->x1); - tile->y1=int_min(cp->ty0+(q+1)*cp->tdy, img->y1); - - tile->numcomps=img->numcomps; - tile->comps=(tcd_tilecomp_t*)malloc(img->numcomps*sizeof(tcd_tilecomp_t)); - tile_Idx->compo=(info_compo_t*)malloc(img->numcomps*sizeof(info_compo_t)); // INDEX - for (compno=0; compnonumcomps; compno++) { - j2k_tccp_t *tccp=&tcp->tccps[compno]; - tcd_tilecomp_t *tilec=&tile->comps[compno]; - info_compo_t *compo_Idx=&tile_Idx->compo[compno]; // INDEX - - // border of each tile component (global) - tilec->x0=int_ceildiv(tile->x0, img->comps[compno].dx); - tilec->y0=int_ceildiv(tile->y0, img->comps[compno].dy); - tilec->x1=int_ceildiv(tile->x1, img->comps[compno].dx); - tilec->y1=int_ceildiv(tile->y1, img->comps[compno].dy); - - tilec->data=(int*)malloc(sizeof(int)*(tilec->x1-tilec->x0)*(tilec->y1-tilec->y0)); - tilec->numresolutions=tccp->numresolutions; - tilec->resolutions=(tcd_resolution_t*)malloc(tilec->numresolutions*sizeof(tcd_resolution_t)); - compo_Idx->reso=(info_reso_t*)malloc(tilec->numresolutions*sizeof(info_reso_t)); // INDEX - for (resno=0; resnonumresolutions; resno++) { - int pdx, pdy; - int levelno=tilec->numresolutions-1-resno; - int tlprcxstart, tlprcystart, brprcxend, brprcyend; - int tlcbgxstart, tlcbgystart, brcbgxend, brcbgyend; - int cbgwidthexpn, cbgheightexpn; - int cblkwidthexpn, cblkheightexpn; - tcd_resolution_t *res=&tilec->resolutions[resno]; - info_reso_t *res_Idx=&compo_Idx->reso[resno]; // INDEX - int precno_Idx; // INDEX - - // border for each resolution level (global) - res->x0=int_ceildivpow2(tilec->x0, levelno); - res->y0=int_ceildivpow2(tilec->y0, levelno); - res->x1=int_ceildivpow2(tilec->x1, levelno); - res->y1=int_ceildivpow2(tilec->y1, levelno); - - res->numbands=resno==0?1:3; - // p. 35, table A-23, ISO/IEC FDIS154444-1 : 2000 (18 august 2000) - if (tccp->csty&J2K_CCP_CSTY_PRT) { - pdx=tccp->prcw[resno]; - pdy=tccp->prch[resno]; - } else { - pdx=15; - pdy=15; - } - // p. 64, B.6, ISO/IEC FDIS15444-1 : 2000 (18 august 2000) - tlprcxstart=int_floordivpow2(res->x0, pdx)<y0, pdy)<x1, pdx)<y1, pdy)<pw=(brprcxend-tlprcxstart)>>pdx; - res->ph=(brprcyend-tlprcystart)>>pdy; - - // - imgg->tile[tileno].pw=res->pw; - imgg->tile[tileno].ph=res->ph; - - res_Idx->prec=(info_prec_t*)malloc(res->pw*res->ph*sizeof(info_prec_t)); - for (precno_Idx=0;precno_Idxpw*res->ph;precno_Idx++) - { - info_prec_t *prec_Idx = &res_Idx->prec[precno_Idx]; - prec_Idx->layer=(info_layer_t*)malloc(imgg->Layer*sizeof(info_layer_t)); - } - - imgg->pw=res->pw; // old parser version - imgg->ph=res->ph; // old parser version - imgg->pdx=1<pdy=1< - - if (resno==0) { - tlcbgxstart=tlprcxstart; - tlcbgystart=tlprcystart; - brcbgxend=brprcxend; - brcbgyend=brprcyend; - cbgwidthexpn=pdx; - cbgheightexpn=pdy; - } else { - tlcbgxstart=int_ceildivpow2(tlprcxstart, 1); - tlcbgystart=int_ceildivpow2(tlprcystart, 1); - brcbgxend=int_ceildivpow2(brprcxend, 1); - brcbgyend=int_ceildivpow2(brprcyend, 1); - cbgwidthexpn=pdx-1; - cbgheightexpn=pdy-1; - } - - cblkwidthexpn=int_min(tccp->cblkw, cbgwidthexpn); - cblkheightexpn=int_min(tccp->cblkh, cbgheightexpn); - - for (bandno=0; bandnonumbands; bandno++) { - int x0b, y0b; - tcd_band_t *band=&res->bands[bandno]; - band->bandno=resno==0?0:bandno+1; - x0b=(band->bandno==1)||(band->bandno==3)?1:0; - y0b=(band->bandno==2)||(band->bandno==3)?1:0; - - if (band->bandno==0) { - // band border (global) - band->x0=int_ceildivpow2(tilec->x0, levelno); - band->y0=int_ceildivpow2(tilec->y0, levelno); - band->x1=int_ceildivpow2(tilec->x1, levelno); - band->y1=int_ceildivpow2(tilec->y1, levelno); - } else { - // band border (global) - band->x0=int_ceildivpow2(tilec->x0-(1<y0=int_ceildivpow2(tilec->y0-(1<x1=int_ceildivpow2(tilec->x1-(1<y1=int_ceildivpow2(tilec->y1-(1<precincts=(tcd_precinct_t*)malloc(res->pw*res->ph*sizeof(tcd_precinct_t)); - - for (precno=0; precnopw*res->ph; precno++) { - int tlcblkxstart, tlcblkystart, brcblkxend, brcblkyend; - int cbgxstart=tlcbgxstart+(precno%res->pw)*(1<pw)*(1<precincts[precno]; - // precinct size (global) - prc->x0=int_max(cbgxstart, band->x0); - prc->y0=int_max(cbgystart, band->y0); - prc->x1=int_min(cbgxend, band->x1); - prc->y1=int_min(cbgyend, band->y1); - - tlcblkxstart=int_floordivpow2(prc->x0, cblkwidthexpn)<y0, cblkheightexpn)<x1, cblkwidthexpn)<y1, cblkheightexpn)<cw=(brcblkxend-tlcblkxstart)>>cblkwidthexpn; - prc->ch=(brcblkyend-tlcblkystart)>>cblkheightexpn; - - prc->cblks=(tcd_cblk_t*)malloc(prc->cw*prc->ch*sizeof(tcd_cblk_t)); - - prc->incltree=tgt_create(prc->cw, prc->ch); - prc->imsbtree=tgt_create(prc->cw, prc->ch); - - for (cblkno=0; cblknocw*prc->ch; cblkno++) { - int cblkxstart=tlcblkxstart+(cblkno%prc->cw)*(1<cw)*(1<cblks[cblkno]; - // code-block size (global) - cblk->x0=int_max(cblkxstart, prc->x0); - cblk->y0=int_max(cblkystart, prc->y0); - cblk->x1=int_min(cblkxend, prc->x1); - cblk->y1=int_min(cblkyend, prc->y1); - } - } - } - } - } - } -} - - -void tcd_free(j2k_image_t *img, j2k_cp_t *cp) { - int tileno, compno, resno, bandno, precno; - tcd_img=img; - tcd_cp=cp; - tcd_image.tw=cp->tw; - tcd_image.th=cp->th; - for (tileno=0; tilenotcps[curtileno]; - tcd_tile_t *tile=&tcd_image.tiles[tileno]; - for (compno=0; compnonumcomps; compno++) - { - tcd_tilecomp_t *tilec=&tile->comps[compno]; - for (resno=0; resnonumresolutions; resno++) - { - tcd_resolution_t *res=&tilec->resolutions[resno]; - for (bandno=0; bandnonumbands; bandno++) - { - tcd_band_t *band=&res->bands[bandno]; - for (precno=0; precnopw*res->ph; precno++) - { - tcd_precinct_t *prc=&band->precincts[precno]; - - if (prc->incltree!=NULL) - tgt_destroy(prc->incltree); - if (prc->imsbtree!=NULL) - tgt_destroy(prc->imsbtree); - free(prc->cblks); - } // for (precno - free(band->precincts); - } // for (bandno - } // for (resno - free(tilec->resolutions); - } // for (compno - free(tile->comps); - } // for (tileno - free(tcd_image.tiles); -} - - -int tcd_decode_tile(unsigned char *src, int len, int tileno, info_image_t *imgg) { - int l; - int eof=0; - tcd_tile_t *tile; - - tile = &tcd_image.tiles[tileno]; - - l = t2_decode_packets(src, len, tcd_img, tcd_cp, tileno, tile, imgg); - - if (l==-999) - { - eof=1; - fprintf(stderr, "tcd_decode: incomplete bistream\n"); - } - - if (eof) { - longjmp(j2k_error, 1); - } - - l=1; - return l; -} diff --git a/indexer_JPIP/tcd.h b/indexer_JPIP/tcd.h deleted file mode 100644 index 9a31723b..00000000 --- a/indexer_JPIP/tcd.h +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 __TCD_H -#define __TCD_H - -#include "j2k.h" -#include "tgt.h" - -typedef struct { - int numpasses; - int len; - unsigned char *data; - int maxpasses; - int numnewpasses; - int newlen; -} tcd_seg_t; - -typedef struct { - int rate; - double distortiondec; -} tcd_pass_t; - -typedef struct { - int numpasses; - int len; - unsigned char *data; -} tcd_layer_t; - -typedef struct { - int x0, y0, x1, y1; - int numbps; - int numlenbits; - int len; - int numpasses; - int numnewpasses; - int numsegs; - tcd_seg_t segs[100]; - unsigned char data[8192]; - int numpassesinlayers; - tcd_layer_t layers[100]; - int totalpasses; - tcd_pass_t passes[100]; -} tcd_cblk_t; - -typedef struct { - int x0, y0, x1, y1; - int cw, ch; - tcd_cblk_t *cblks; - tgt_tree_t *incltree; - tgt_tree_t *imsbtree; -} tcd_precinct_t; - -typedef struct { - int x0, y0, x1, y1; - int bandno; - tcd_precinct_t *precincts; - int numbps; - int stepsize; -} tcd_band_t; - -typedef struct { - int x0, y0, x1, y1; - int previous_x0, previous_y0, previous_x1, previous_y1; // usefull for the DWT - int cas_col, cas_row; // usefull for the DWT - int pw, ph; - int numbands; - tcd_band_t bands[3]; -} tcd_resolution_t; - -typedef struct { - int x0, y0, x1, y1; - int previous_row, previous_col; // usefull for the DWT - int numresolutions; - tcd_resolution_t *resolutions; - int *data; -} tcd_tilecomp_t; - -typedef struct { - int x0, y0, x1, y1; - int numcomps; - //int PPT; - //int len_ppt; - tcd_tilecomp_t *comps; -} tcd_tile_t; - -typedef struct { - int tw, th; - tcd_tile_t *tiles; -} tcd_image_t; - -/* - * Initialize the tile coder/decoder - * img: raw image - * cp: coding parameters - * imgg: creation of index file - */ - -void tcd_init(j2k_image_t *img, j2k_cp_t *cp, info_image_t *imgg); - -void tcd_free(j2k_image_t *img, j2k_cp_t *cp); - -/* - * Decode a tile from a buffer into a raw image - * src: source buffer - * len: length of the source buffer - * tileno: number that identifies the tile that will be decoded - * imgg : Structure for index file - */ -int tcd_decode_tile(unsigned char *src, int len, int tileno, info_image_t *imgg); - -#endif diff --git a/indexer_JPIP/tgt.c b/indexer_JPIP/tgt.c deleted file mode 100644 index c2b46824..00000000 --- a/indexer_JPIP/tgt.c +++ /dev/null @@ -1,170 +0,0 @@ -/* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, 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 "tgt.h" -#include "bio.h" -#include -#include - -/// -/// Reset tag-tree. -/// -void tgt_reset(tgt_tree_t *tree) -{ - int i; - for (i=0; inumnodes; i++) { - tree->nodes[i].value=999; - tree->nodes[i].low=0; - tree->nodes[i].known=0; - } -} - -/// -/// Create tag-tree. -/// -tgt_tree_t *tgt_create(int numleafsh, int numleafsv) -{ - int nplh[32]; - int nplv[32]; - tgt_node_t *node; - tgt_node_t *parentnode; - tgt_node_t *parentnode0; - tgt_tree_t *tree; - int i, j, k; - int numlvls; - int n; - - tree=(tgt_tree_t*)malloc(sizeof(tgt_tree_t)); - tree->numleafsh=numleafsh; - tree->numleafsv=numleafsv; - - numlvls=0; - nplh[0]=numleafsh; - nplv[0]=numleafsv; - tree->numnodes=0; - do { - n=nplh[numlvls]*nplv[numlvls]; - nplh[numlvls+1]=(nplh[numlvls]+1)/2; - nplv[numlvls+1]=(nplv[numlvls]+1)/2; - tree->numnodes+=n; - ++numlvls; - } while (n>1); - - tree->nodes=(tgt_node_t*)malloc(tree->numnodes*sizeof(tgt_node_t)); - - node=tree->nodes; - parentnode=&tree->nodes[tree->numleafsh*tree->numleafsv]; - parentnode0=parentnode; - - for (i=0; i=0) { - node->parent=parentnode; - ++node; - if (--k >= 0) { - node->parent=parentnode; - ++node; - } - ++parentnode; - } - if ((j&1)||j==nplv[i]-1) { - parentnode0=parentnode; - } else { - parentnode=parentnode0; - parentnode0+=nplh[i]; - } - } - } - node->parent=0; - - tgt_reset(tree); - - return tree; -} - -/// -/// Destroy tag-tree. -/// -void tgt_destroy(tgt_tree_t *t) { - free(t->nodes); - free(t); -} - -/// -/// Set the value of a leaf of the tag-tree. -/// -void tgt_setvalue(tgt_tree_t *tree, int leafno, int value) { - tgt_node_t *node; - node=&tree->nodes[leafno]; - while (node && node->value>value) { - node->value=value; - node=node->parent; - } -} - -/// -/// Decode the value of a leaf of the tag-tree. -/// -int tgt_decode(tgt_tree_t *tree, int leafno, int threshold) -{ - tgt_node_t *stk[31]; - tgt_node_t **stkptr; - 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 (lowvalue) { - if (bio_read(1)) { - node->value=low; - } else { - ++low; - } - } - node->low=low; - if (stkptr==stk) { - break; - } - node=*--stkptr; - } - - return (node->value -# Microsoft Developer Studio Generated Build File, Format Version 6.00 -# ** DO NOT EDIT ** - -# TARGTYPE "Win32 (x86) Dynamic-Link Library" 0x0102 - -CFG=DllOpenJPEG - Win32 Debug -!MESSAGE This is not a valid makefile. To build this project using NMAKE, -!MESSAGE use the Export Makefile command and run -!MESSAGE -!MESSAGE NMAKE /f "DllOpenJPEG.mak". -!MESSAGE -!MESSAGE You can specify a configuration when running NMAKE -!MESSAGE by defining the macro CFG on the command line. For example: -!MESSAGE -!MESSAGE NMAKE /f "DllOpenJPEG.mak" CFG="DllOpenJPEG - Win32 Debug" -!MESSAGE -!MESSAGE Possible choices for configuration are: -!MESSAGE -!MESSAGE "DllOpenJPEG - Win32 Release" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE "DllOpenJPEG - Win32 Debug" (based on "Win32 (x86) Dynamic-Link Library") -!MESSAGE - -# Begin Project -# PROP AllowPerConfigDependencies 0 -# PROP Scc_ProjName "" -# PROP Scc_LocalPath "" -CPP=cl.exe -MTL=midl.exe -RSC=rc.exe - -!IF "$(CFG)" == "DllOpenJPEG - Win32 Release" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 0 -# PROP BASE Output_Dir "Release" -# PROP BASE Intermediate_Dir "Release" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 0 -# PROP Output_Dir "Release" -# PROP Intermediate_Dir "Release" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DLLOPENJPEG_EXPORTS" /Yu"stdafx.h" /FD /c -# ADD CPP /nologo /MT /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OPJ_EXPORTS" /FD /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "NDEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "NDEBUG" -# ADD RSC /l 0x40c /d "NDEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"Release/OpenJPEG.dll" -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=if not exist dist mkdir dist copy libopenjpeg\openjpeg.h dist copy Release\OpenJPEG.dll dist copy Release\OpenJPEG.lib dist -# End Special Build Tool - -!ELSEIF "$(CFG)" == "DllOpenJPEG - Win32 Debug" - -# PROP BASE Use_MFC 0 -# PROP BASE Use_Debug_Libraries 1 -# PROP BASE Output_Dir "Debug" -# PROP BASE Intermediate_Dir "Debug" -# PROP BASE Target_Dir "" -# PROP Use_MFC 0 -# PROP Use_Debug_Libraries 1 -# PROP Output_Dir "Debug" -# PROP Intermediate_Dir "Debug" -# PROP Ignore_Export_Lib 0 -# PROP Target_Dir "" -# ADD BASE CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "DLLOPENJPEG_EXPORTS" /Yu"stdafx.h" /FD /GZ /c -# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "OPJ_EXPORTS" /FD /GZ /c -# SUBTRACT CPP /YX /Yc /Yu -# ADD BASE MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD MTL /nologo /D "_DEBUG" /mktyplib203 /win32 -# ADD BASE RSC /l 0x40c /d "_DEBUG" -# ADD RSC /l 0x40c /d "_DEBUG" -BSC32=bscmake.exe -# ADD BASE BSC32 /nologo -# ADD BSC32 /nologo -LINK32=link.exe -# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /pdbtype:sept -# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /debug /machine:I386 /out:"Debug/OpenJPEGd.dll" /pdbtype:sept -# Begin Special Build Tool -SOURCE="$(InputPath)" -PostBuild_Cmds=if not exist dist mkdir dist copy libopenjpeg\openjpeg.h dist copy Debug\OpenJPEGd.dll dist copy Debug\OpenJPEGd.lib dist -# End Special Build Tool - -!ENDIF - -# Begin Target - -# Name "DllOpenJPEG - Win32 Release" -# Name "DllOpenJPEG - Win32 Debug" -# Begin Group "Source Files" - -# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" -# Begin Source File - -SOURCE=.\libopenjpeg\bio.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\cio.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\dwt.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\event.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\image.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\j2k.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\j2k_lib.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\jp2.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\jpt.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\mct.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\mqc.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\openjpeg.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\pi.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\raw.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\t1.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\t2.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\tcd.c -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\tgt.c -# End Source File -# End Group -# Begin Group "Header Files" - -# PROP Default_Filter "h;hpp;hxx;hm;inl" -# Begin Source File - -SOURCE=.\libopenjpeg\bio.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\cio.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\dwt.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\event.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\fix.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\image.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\int.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\j2k.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\j2k_lib.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\jp2.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\jpt.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\mct.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\mqc.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\openjpeg.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\opj_includes.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\pi.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\raw.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\t1.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\t2.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\tcd.h -# End Source File -# Begin Source File - -SOURCE=.\libopenjpeg\tgt.h -# End Source File -# End Group -# Begin Group "Resource Files" - -# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" -# Begin Source File - -SOURCE=.\OpenJPEG.rc -# End Source File -# End Group -# End Target -# End Project diff --git a/jp3d/DllJp3dVM.sln b/jp3d/DllJp3dVM.sln deleted file mode 100755 index 7b97dad9..00000000 --- a/jp3d/DllJp3dVM.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "DllOpenJPEG", "DllJp3dVM.vcproj", "{790A6CE5-CE92-4A59-ADF7-54A92760BD6C}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {790A6CE5-CE92-4A59-ADF7-54A92760BD6C}.Debug.ActiveCfg = Debug|Win32 - {790A6CE5-CE92-4A59-ADF7-54A92760BD6C}.Debug.Build.0 = Debug|Win32 - {790A6CE5-CE92-4A59-ADF7-54A92760BD6C}.Release.ActiveCfg = Release|Win32 - {790A6CE5-CE92-4A59-ADF7-54A92760BD6C}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/jp3d/DllJp3dVM.vcproj b/jp3d/DllJp3dVM.vcproj deleted file mode 100755 index 27c2108c..00000000 --- a/jp3d/DllJp3dVM.vcproj +++ /dev/null @@ -1,278 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jp3d/LICENSE.txt b/jp3d/LICENSE.txt deleted file mode 100755 index 4716ce35..00000000 --- a/jp3d/LICENSE.txt +++ /dev/null @@ -1,30 +0,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, HervŽ Drolon, FreeImage Team - * Copyright (c) 2002-2005, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium - * Copyright (c) 2006, Mónica Díez, Image Processing Laboratory (LPI) - 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. - */ diff --git a/jp3d/LibJp3dVM.sln b/jp3d/LibJp3dVM.sln deleted file mode 100755 index 7309c7ab..00000000 --- a/jp3d/LibJp3dVM.sln +++ /dev/null @@ -1,21 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJp3dVM", "LibJp3dVM.vcproj", "{6F3FB035-8F4E-4794-B091-0F0A20223BE7}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Debug.ActiveCfg = Debug|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Debug.Build.0 = Debug|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Release.ActiveCfg = Release|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/jp3d/LibJp3dVM.vcproj b/jp3d/LibJp3dVM.vcproj deleted file mode 100755 index 37953075..00000000 --- a/jp3d/LibJp3dVM.vcproj +++ /dev/null @@ -1,249 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jp3d/Makefile b/jp3d/Makefile deleted file mode 100755 index f2b66cf0..00000000 --- a/jp3d/Makefile +++ /dev/null @@ -1,72 +0,0 @@ -# Linux makefile for OpenJPEG - -VER_MAJOR = 1 -VER_MINOR = 0.0 - -SRCS = ./libopenjpeg/bio.c ./libopenjpeg/cio.c ./libopenjpeg/dwt.c ./libopenjpeg/event.c ./libopenjpeg/image.c ./libopenjpeg/j2k.c ./libopenjpeg/j2k_lib.c ./libopenjpeg/jp2.c ./libopenjpeg/jpt.c ./libopenjpeg/mct.c ./libopenjpeg/mqc.c ./libopenjpeg/openjpeg.c ./libopenjpeg/pi.c ./libopenjpeg/raw.c ./libopenjpeg/t1.c ./libopenjpeg/t2.c ./libopenjpeg/tcd.c ./libopenjpeg/tgt.c -INCLS = ./libopenjpeg/bio.h ./libopenjpeg/cio.h ./libopenjpeg/dwt.h ./libopenjpeg/event.h ./libopenjpeg/fix.h ./libopenjpeg/image.h ./libopenjpeg/int.h ./libopenjpeg/j2k.h ./libopenjpeg/j2k_lib.h ./libopenjpeg/jp2.h ./libopenjpeg/jpt.h ./libopenjpeg/mct.h ./libopenjpeg/mqc.h ./libopenjpeg/openjpeg.h ./libopenjpeg/pi.h ./libopenjpeg/raw.h ./libopenjpeg/t1.h ./libopenjpeg/t2.h ./libopenjpeg/tcd.h ./libopenjpeg/tgt.h ./libopenjpeg/opj_includes.h -INCLUDE = -Ilibopenjpeg - -# General configuration variables: -CC = gcc -AR = ar - -INSTALLDIR = /usr/lib - -# Converts cr/lf to just lf -DOS2UNIX = dos2unix - -COMPILERFLAGS = -O3 -LIBRARIES = -lstdc++ - -MODULES = $(SRCS:.c=.o) -CFLAGS = $(COMPILERFLAGS) $(INCLUDE) - -TARGET = openjpeg -STATICLIB = lib$(TARGET).a -SHAREDLIB = lib$(TARGET)-$(VER_MAJOR).$(VER_MINOR).so -LIBNAME = lib$(TARGET).so.$(VER_MAJOR) - - - -default: all - -all: dist - -dist: OpenJPEG - mkdir dist - cp *.a dist/ - cp *.so dist/ - cp libopenjpeg/openjpeg.h dist/ - -dos2unix: - @$(DOS2UNIX) $(SRCS) $(INCLS) - -OpenJPEG: $(STATICLIB) $(SHAREDLIB) - -.c.o: - $(CC) $(CFLAGS) -c $< -o $@ - -$(STATICLIB): $(MODULES) - $(AR) r $@ $(MODULES) - -$(SHAREDLIB): $(MODULES) - $(CC) -s -shared -Wl,-soname,$(LIBNAME) -o $@ $(MODULES) $(LIBRARIES) - -install: - install -m 644 -o root -g root $(STATICLIB) $(INSTALLDIR) - install -m 755 -o root -g root $(SHAREDLIB) $(INSTALLDIR) - ln -sf $(SHAREDLIB) $(INSTALLDIR)/$(LIBNAME) - ldconfig - -clean: - rm -rf core dist/ u2dtmp* $(MODULES) $(STATICLIB) $(SHAREDLIB) $(LIBNAME) - -osx: - make -f Makefile.osx - -osxinstall: - make -f Makefile.osx install - -osxclean: - make -f Makefile.osx clean diff --git a/jp3d/README.txt b/jp3d/README.txt deleted file mode 100755 index ce04072e..00000000 --- a/jp3d/README.txt +++ /dev/null @@ -1,285 +0,0 @@ -=============================================================================== - JPEG2000 Part 10 (ISO/IEC 15444-10 JP3D) Verification Model - - Version 1.1 -=============================================================================== - - -1. Scope -================ - -This document describes the installation and the use of the JP3D VM decoder and encoder under several operating systems (Linux, Unix, Windows, ...). Version 1.1 contains a complete JPEG 2000 Part 10 encoder, as well as a decoder. -The supported functionalities are compliant with the JPEG2000 part 10 algorithm as described in the WD 6.0. -The provided encoder and the decoder are compatible also with the International standard IS 15444-1 (core coding system). -This implementation has been developped from OpenJPEG implementation of JPEG2000 standard, and for this reason it is written in C language. - -If you find some bugs or if you have problems using the encoder/decoder, please send an e-mail to jp3d@lpi.tel.uva.es - -2. Installing the code -====================================================== - -- After decompressing the zip file provided, you should find -at least the following files in the created 'jp3d_vm' directory: - - * libjp3dvm - This directory contains all library related code - * codec - This directory contains all codec related code - * tcltk - This directory contains the API scripts - * README - The file you are reading - * LICENCE - Copyright statement of the JP3D VM software - -2.1. Compiling the source code in Windows -------------------------------------------- - -This version has been compiled with Visual Studio 2003 using -the projects included in the distribution: - - * LibJp3dVM.vcproj - Creates the library with all the JP3D functionalities - * jp3d_vm_enc.vcproj - Test encoder - * jp3d_vm_dec.vcproj - Test decoder - -2.2. Compiling the source code in Unix-like systems -------------------------------------------- - -Library compilation ------------------------- -This version of the library has been tested under the following OS: -- Fedora Core - -The installation process is as simple as this : -1) Enter the 'jp3d_vm' directory -2) Build the distribution : -make -make install -3) Clean all files produced during the build process -make clean - -Codec compilation ------------------------- -Once you've built the library, you should compile the JP3D codec. - -1) Go to the 'codec' directory -2) Build the encoder and decoder programs: - -gcc convert.c volume_to_jp3d.c -o jp3d_vm_enc -I ../libjp3dvm/ -lm -ljp3dvm -gcc convert.c jp3d_to_volume.c -o jp3d_vm_dec -I ../libjp3dvm/ -lm -ljp3dvm - -Note: You should add '-L ../libjp3dvm/' to those lines if you -did not use the 'install' target (and the 'clean' target neither...). - -3. Running the JP3D VM -==================================================== - -3.1. JP3D ENCODER -==================================================== - -Required arguments ------------------------- - - * Input file(s): -i Involume [*.bin, *.pgx] - -Specifies the volume to compress. Accepted formats are *.BIN (raw binary data) or *.PGX files. -Both formats need some particular settings: - - a) BIN format. As it has no header, volume characteristics will be obtained from a .IMG file. Its location will be specified through the following argument: - -m Involumeinfo.IMG - This file shall have the following structure, with the appropiate value in each case (bit per voxel, color map, dimensions in X,Y,Z): - o Bpp %d - o Color Map %d - o Dimensions %d %d %d - - b) PGX format. Program will consider it as a volume slice. In order to denote a volume through a sequence of slices, you can define the input filename with the common pattern of the set of PGX files followed by a dash (as a wildcard character for the sequence numbers). - - * Output file: -o Outfile [*.jp3d, *j2k] - -Specifies the name of the file where the codestream will be saved. -Part 1 compliant codestream will be created when an outfile has .j2k format. - -Options --------- - - * Rate values : -r 20,10,5 - This option offers the possibility to define the compression rate to apply. - Each value is a factor of compression (i.e. 20 : 1) and will generate a different quality layer. A lossless compression will be signified by the value 1. - NOTE : The order used to define the different levels of compression is important and must be from left to right in descending order. - - * Quality values : -q 30,35,40 - This option offers the possibility to define the quality level to achieve. Each value is a psnr, to be given in dB, and represents a quality layer. - NOTE : The order used to define the different psnr-values is important and must be from left to right in ascending order. - - - * Number of resolutions : -n 3,3,2 - This option offers the possibility to define the number of resolution levels computed for each dimension of the volume through the discret wavelet transform (DWT). Resolution in axial dimension can have a different value than in horizontal and vertical cases, but must be lower. - DEFAULT VALUE : 3,3,1 - - - * Switch modes : -M 3 - This option offers the possibility to use a mode switch during the encoding process: - o BYPASS(LAZY) [1] - o RESET [2] - o RESTART(TERMALL) [4] - o VSC [8] - o ERTERM(SEGTERM) [16] - o SEGMARK(SEGSYM) [32] - o 3D_CONTEXT [64] - For several mode switch just sum corresponding values: i.e. -M 38 => RESTART(4) + RESET(2) + SEGMARK(32) - DEFAULT VALUE: 0 - - - * Progression order : -p LRCP - This option offers the possibility to specify the progression order. Possible progression orders are : LRCP, RLCP, RPCL, PCRL and CPRL. - DEFAULT VALUE: LRCP. - - - * Code-block size : -b 32,32,32 - This option offers the possibility to define the size of the code-block. The dimension must respect the constraint defined in the JPEG-2000 standard. The maximum value autorized is 64x64x64. - DEFAULT VALUE: 64,64,64 - - - * Precinct size : -c [128,128,128],[128,128,128],... - This option offers the possibility to define the size of the precincts at each resolution. Multiple records may be supplied, in which case the first record refers to the highest resolution level and subsequent records to lower resolution levels. The last specified record is right-shifted for each remaining lower resolution levels. - NOTE : specified values must be power of 2. - DEFAULT VALUE: 2^15 x 2^15 x 2^15 - - - * Tile size : -t 512,512,512 - This option offers the possibility to divide the volume in several tiles. The three values define the width, the heigth and the depth of the tile respectivily. - DEFAULT VALUE: Volume dimensions (one tile) - - - * Subsampling factor : -s 2,2,2 - This option offers the possibility to apply a subsampling factor for X, Y and Z axis. Value higher than 2 can be a source of error ! - DEFAULT VALUE: 1,1,1 - - - * SOP marker before each packet : -SOP - This option offers the possibility to add a specific marker before each packet. It is the marker SOP (Start of packet). If the option is not used no SOP marker will be added. - - - * EPH marker after each packet header : -EPH - This option offers the possibility to add a specific marker at the head of each packet header. It is the marker EPH (End of packet Header). If the option is not used no EPH marker will be added. - - - * Offset of the volume origin : -d 150,300,10 - This option offers the possibility to move the origine of the volume in X, Y and/or Z axis. The division in tile could be modified as the anchor point for tiling will be different than the volume origin. - NOTE : the offset of the volume can not be higher than the tile dimension if the tile option is used. - DEFAULT VALUE: 0,0,0 - - - * Offset of the tile origin : -T 100,75,5 - This option offers the possibility to move the anchor point of the volume in X, Y and/or Z axis. - NOTE : the tile anchor point can not be on the volume area. - DEFAULT VALUE: 0,0,0 - - - * Display the help menu : -help - This option displays on screen the content of this page - -Additional options ----------------------------------- - - * Encoding information file: -x index_name.idx - This option offers the possibility to create a text file with some structured information generated through the encoding. The name of the file must be specified, with .idx extension. The information structure is the following: - o Volume size: - + VolW + VolH + VolD - o Progression Order: - + Prog - o Tile size: - + TileW + TileH + TileD - o Number of components: - + NumComp - o Number of layers: - + NumLayer - o Number of decompositions (=(number of resolutions - 1)): - + NumDWTx + NumDWTy + NumDWTz - o Precinct size: - + [Precinct_width(NumDWT),Precinct_height(NumDWT),Precinct_depth(NumDWT)] - + [Precinct_width(NumDWT-1),Precinct_height(NumDWT-1),Precinct_depth(NumDWT-1)] - + ... - + [Precinct_width(0),Precinct_height(0),Precinct_depth(0)] - o Main Header end position: - + MH_EndPos - o Codestream size: - + CSSize - o Tile 0 information: - + TileNum (0) - + StartPos - + TileHeader_EndPos - + EndPos - + TotalDisto (this is the sum of the distortion reductions brought by each packet belonging to this tile) - + NumPix (this is the number of pixels in the tile) - + MaxMSE (=TotalDisto/NumPix) - o Tile1 information: - + TileNum (1) - + ... - o ... - o Tile N information: - + TileNum (N) - + ... - o Packet 0 from Tile 0 information: - + PackNum (0) - + TileNum (0) - + LayerNum - + ResNum - + CompNum - + PrecNum - + StartPos - + EndPos - + Disto (distortion reduction brought by this packet) - o Packet 1 from Tile 0 information: - + PackNum (1) - + ... - o ... - o Packet M from Tile 0 information - o Packet 0 from Tile 1 information - o ... - o Packet M from Tile N information - o Maximum distortion reduction on the whole volume: - + MaxDisto - o Total distortion on the whole volume (sum of the distortion reductions from all packets in the volume): - + TotalDisto - -3.2. JP3D DECODER -==================================================== - -Required arguments ------------------------- - - * Infile : -i compressed file - Currently accepts JP3D and J2K-files. The file type is identified based on its suffix (*.jp3d, *.j2k). - - - * Outfile(s) : -o decompressed file(s) - Currently accepts BIN-files and PGX-files. Binary data is written to the file (not ascii). - If a BIN-file is defined, decoder will create automatically the volume characteristic file appending a .IMG extension to the provided output filename. - If a PGX-file is defined, decoder will understand this as a file pattern, appending corresponding indice from 0 to the number of decoded slices. - NOTE : There will be as many output files as there are components: an indice starting from 0 will then be appended to the output filename, just before the extension. - - -Options available ------------------------- - - * Reduce factor : -r 1,1,0 - Set the number of highest resolution levels to be discarded in each dimension. The decoded volume size is effectively divided by 2 to the power of the number of discarded levels. - NOTE : The reduce factor is limited by the smallest total number of decomposition levels among tiles. - - - * Layer number : -l 2 - Set the maximum number of quality layers to decode. If there are less quality layers than the specified number, all the quality layers are decoded. - - - * Performance comparisons : -O original-file - This option offers the possibility to compute some quality results for the decompressed volume, like the PSNR value achieved or the global SSIM value. Needs the original file in order to compare with the new one. - NOTE: Only valid when -r option is 0,0,0 (both original and decompressed volumes have same resolutions) - NOTE: If original file is .BIN file, the volume characteristics file shall be defined with the -m option. - (i.e. -O original-BIN-file -m original-IMG-file) - - - * Byte order (Big-endian / Little-endian) : -BE - This option offers the possibility to save the decompressed volume with a predefined byte order. - DEFAULT VALUE: Little-endian - - - * Display the help menu : -help - This option displays on screen the content of this page - - diff --git a/jp3d/codec/CMakeLists.txt b/jp3d/codec/CMakeLists.txt deleted file mode 100644 index 8d6599c1..00000000 --- a/jp3d/codec/CMakeLists.txt +++ /dev/null @@ -1,53 +0,0 @@ -# Build the demo app, small examples - -# First thing define the common source: -SET(common_SRCS - convert.c - ) -# Then check if getopt is present: -INCLUDE (${CMAKE_ROOT}/Modules/CheckIncludeFile.cmake) -SET(DONT_HAVE_GETOPT 1) -IF(UNIX) #I am pretty sure only *nix sys have this anyway - CHECK_INCLUDE_FILE("getopt.h" CMAKE_HAVE_GETOPT_H) - # Seems like we need the contrary: - IF(CMAKE_HAVE_GETOPT_H) - SET(DONT_HAVE_GETOPT 0) - ENDIF(CMAKE_HAVE_GETOPT_H) -ENDIF(UNIX) - -# If not getopt was found then add it to the lib: -IF(DONT_HAVE_GETOPT) - ADD_DEFINITIONS(-DDONT_HAVE_GETOPT) - SET(common_SRCS - ${common_SRCS} - compat/getopt.c - ) -ENDIF(DONT_HAVE_GETOPT) - - -# Headers file are located here: -INCLUDE_DIRECTORIES( - ${CMAKE_CURRENT_SOURCE_DIR}/../libjp3dvm - ) - -# Do the proper thing when building static...if only there was configured -# headers or def files instead -#IF(NOT BUILD_SHARED_LIBS) -# ADD_DEFINITIONS(-DOPJ_STATIC) -#ENDIF(NOT BUILD_SHARED_LIBS) - -#FIND_PACKAGE(TIFF REQUIRED) - -# Loop over all executables: -FOREACH(exe jp3d_to_volume volume_to_jp3d) - ADD_EXECUTABLE(${exe} ${exe}.c ${common_SRCS}) - TARGET_LINK_LIBRARIES(${exe} ${OPJ_PREFIX}openjp3dvm) # ${TIFF_LIBRARIES}) - # On unix you need to link to the math library: - IF(UNIX) - TARGET_LINK_LIBRARIES(${exe} m) - ENDIF(UNIX) - # Install exe - INSTALL_TARGETS(/bin/ ${exe}) -ENDFOREACH(exe) - - diff --git a/jp3d/codec/convert.c b/jp3d/codec/convert.c deleted file mode 100755 index 07ecd929..00000000 --- a/jp3d/codec/convert.c +++ /dev/null @@ -1,997 +0,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, Hervé 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 -#include -#include -#include "openjpeg.h" -#ifdef WIN32 -#include "dirent.h" -#else -#include -#endif /* WIN32 */ - - - -void 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"); -} - -/* - * Get logarithm of an integer and round downwards. - * - * log2(a) - */ -static int int_floorlog2(int a) { - int l; - for (l = 0; a > 1; l++) { - a >>= 1; - } - return l; -} - -/* - * Divide an integer by a power of 2 and round upwards. - * - * a divided by 2^b - */ -static int int_ceildivpow2(int a, int b) { - return (a + (1 << b) - 1) >> b; -} - -/* - * Divide an integer and round upwards. - * - * a divided by b - */ -static int int_ceildiv(int a, int b) { - return (a + b - 1) / b; -} - - -/* -->> -->> -->> -->> - -PGX IMAGE FORMAT - -<<-- <<-- <<-- <<-- */ - - -unsigned char readuchar(FILE * f) -{ - unsigned char c1; - fread(&c1, 1, 1, f); - return c1; -} - -unsigned short readushort(FILE * f, int bigendian) -{ - unsigned char c1, c2; - fread(&c1, 1, 1, f); - fread(&c2, 1, 1, f); - if (bigendian) - return (c1 << 8) + c2; - else - return (c2 << 8) + c1; -} - -unsigned int readuint(FILE * f, int bigendian) -{ - unsigned char c1, c2, c3, c4; - fread(&c1, 1, 1, f); - fread(&c2, 1, 1, f); - fread(&c3, 1, 1, f); - fread(&c4, 1, 1, f); - if (bigendian) - return (c1 << 24) + (c2 << 16) + (c3 << 8) + c4; - else - return (c4 << 24) + (c3 << 16) + (c2 << 8) + c1; -} -/*****************************************/ -static unsigned short ShortSwap(unsigned short v) -{ - unsigned char c1, c2; - c1 = v & 0xff; - c2 = (v >> 8) & 0xff; - return (c1 << 8) + c2; -} - -static unsigned int LongSwap (unsigned int i) -{ - unsigned char b1, b2, b3, b4; - b1 = i & 255; - b2 = ( i >> 8 ) & 255; - b3 = ( i>>16 ) & 255; - b4 = ( i>>24 ) & 255; - return ((int)b1 << 24) + ((int)b2 << 16) + ((int)b3 << 8) + b4; -} -/*****************************************/ - -opj_volume_t* pgxtovolume(char *relpath, opj_cparameters_t *parameters) { - - FILE *f = NULL; - int w, h, prec; - unsigned long offset; - int i, s, numcomps, maxvalue, sliceno, slicepos, maxslice = 0; - - OPJ_COLOR_SPACE color_space; - opj_volume_cmptparm_t cmptparm; // maximum of 1 component - opj_volume_t * volume = NULL; - - char endian1,endian2,sign; - char signtmp[32]; - char temp[32]; - opj_volume_comp_t *comp = NULL; - - DIR *dirp; - struct dirent *direntp; - - char *tmp = NULL, *tmp2 = NULL, - *point = NULL, *pgx = NULL; - char tmpdirpath[MAX_PATH]; - char dirpath[MAX_PATH]; - char pattern[MAX_PATH]; - char pgxfiles[MAX_SLICES][MAX_PATH]; - int pgxslicepos[MAX_SLICES]; - char tmpno[3]; - - numcomps = 1; - color_space = CLRSPC_GRAY; - sliceno = 0; - maxvalue = 0; - memset(pgxfiles, 0, MAX_SLICES * MAX_PATH * sizeof(char)); - memset(&cmptparm, 0, sizeof(opj_volume_cmptparm_t)); - - /* Separación del caso de un único slice frente al de muchos */ - if ((tmp = strrchr(relpath,'-')) == NULL){ - //fprintf(stdout,"[INFO] A volume of only one slice....\n"); - sliceno = 1; - maxslice = 1; - strcpy(pgxfiles[0],relpath); - - } else { - //Fetch only the path - strcpy(tmpdirpath,relpath); - if ((tmp = strrchr(tmpdirpath,'/')) != NULL){ - tmp++; *tmp='\0'; - strcpy(dirpath,tmpdirpath); - } else { - strcpy(dirpath,"./"); - } - - //Fetch the pattern of the volume slices - if ((tmp = strrchr (relpath,'/')) != NULL) - tmp++; - else - tmp = relpath; - if ((tmp2 = strrchr(tmp,'-')) != NULL) - *tmp2='\0'; - else{ - fprintf(stdout, "[ERROR] tmp2 ha dado null. no ha encontrado el * %s %s",tmp,relpath); - return NULL; - } - strcpy(pattern,tmp); - - dirp = opendir( dirpath ); - if (dirp == NULL){ - fprintf(stdout, "[ERROR] Infile must be a .pgx file or a directory that contain pgx files"); - return NULL; - } - - /*Read all .pgx files of directory */ - while ( (direntp = readdir( dirp )) != NULL ) - { - /* Found a directory, but ignore . and .. */ - if(strcmp(".",direntp->d_name) == 0 || strcmp("..",direntp->d_name) == 0) - continue; - - if( ((pgx = strstr(direntp->d_name,pattern)) != NULL) && ((tmp2 = strstr(direntp->d_name,".pgx")) != NULL) ){ - - strcpy(tmp,dirpath); - tmp = strcat(tmp,direntp->d_name); - - //Obtenemos el index de la secuencia de slices - if ((tmp2 = strpbrk (direntp->d_name, "0123456789")) == NULL) - continue; - i = 0; - while (tmp2 != NULL) { - tmpno[i++] = *tmp2; - point = tmp2; - tmp2 = strpbrk (tmp2+1,"0123456789"); - }tmpno[i]='\0'; - - //Comprobamos que no estamos leyendo algo raro como pattern.jp3d - if ((point = strpbrk (point,".")) == NULL){ - break; - } - //Slicepos --> index de slice; Sliceno --> no de slices hasta el momento - slicepos = atoi(tmpno); - pgxslicepos[sliceno] = slicepos - 1; - sliceno++; - if (slicepos>maxslice) - maxslice = slicepos; - - //Colocamos el slices en su posicion correspondiente - strcpy(pgxfiles[slicepos-1],tmp); - } - } - - }/* else if pattern*.pgx */ - - if (!sliceno) { - fprintf(stdout,"[ERROR] No slices with this pattern founded !! Please check input volume name\n"); - return NULL; - } - /*if ( maxslice != sliceno) { - fprintf(stdout,"[ERROR] Slices are not sequentially numbered !! Please rename them accordingly\n"); - return NULL; - }*/ - - for (s=0;svolume_offset_x0; - cmptparm.y0 = parameters->volume_offset_y0; - cmptparm.z0 = parameters->volume_offset_z0; - 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; - cmptparm.l = !cmptparm.z0 ? (sliceno - 1) * parameters->subsampling_dz + 1 : cmptparm.z0 + (sliceno - 1) * parameters->subsampling_dz + 1; - - if (sign == '-') { - cmptparm.sgnd = 1; - } else { - cmptparm.sgnd = 0; - } - cmptparm.prec = prec; - cmptparm.bpp = prec; - cmptparm.dcoffset = parameters->dcoffset; - cmptparm.dx = parameters->subsampling_dx; - cmptparm.dy = parameters->subsampling_dy; - cmptparm.dz = parameters->subsampling_dz; - - /* create the volume */ - volume = opj_volume_create(numcomps, &cmptparm, color_space); - if(!volume) { - fclose(f); - return NULL; - } - /* set volume offset and reference grid */ - volume->x0 = cmptparm.x0; - volume->y0 = cmptparm.y0; - volume->z0 = cmptparm.z0; - volume->x1 = cmptparm.w; - volume->y1 = cmptparm.h; - volume->z1 = cmptparm.l; - - /* set volume data :only one component, that is a volume*/ - comp = &volume->comps[0]; - - }//if sliceno==1 - - offset = w * h * s; - - for (i = 0; i < w * h; i++) { - int v; - 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, cmptparm.bigendian); - } else { - v = (short) readushort(f, cmptparm.bigendian); - } - } else { - if (!comp->sgnd) { - v = readuint(f, cmptparm.bigendian); - } else { - v = (int) readuint(f, cmptparm.bigendian); - } - } - if (v > maxvalue) - maxvalue = v; - comp->data[i + offset] = v; - - } - fclose(f); - } // for s --> sliceno - comp->bpp = int_floorlog2(maxvalue) + 1; - if (sliceno != 1) - closedir( dirp ); - //dump_volume(stdout, volume); - return volume; -} - - -int volumetopgx(opj_volume_t * volume, char *outfile) { - int w, wr, wrr, h, hr, hrr, l, lr, lrr; - int i, j, compno, offset, sliceno; - FILE *fdest = NULL; - - for (compno = 0; compno < volume->numcomps; compno++) { - opj_volume_comp_t *comp = &volume->comps[compno]; - char name[256]; - int nbytes = 0; - char *tmp = outfile; - while (*tmp) { - tmp++; - } - while (*tmp!='.') { - tmp--; - } - *tmp='\0'; - for(sliceno = 0; sliceno < volume->z1 - volume->z0; sliceno++) { - - if (volume->numcomps > 1) { - sprintf(name, "%s%d-%d.pgx", outfile, sliceno+1, compno); - } else if ((volume->z1 - volume->z0) > 1) { - sprintf(name, "%s%d.pgx", outfile, sliceno+1); - } else { - sprintf(name, "%s.pgx", outfile); - } - - fdest = fopen(name, "wb"); - if (!fdest) { - fprintf(stdout, "[ERROR] Failed to open %s for writing \n", name); - return 1; - } - - fprintf(stdout,"[INFO] Writing in %s (%s)\n",name,volume->comps[0].bigendian ? "Bigendian" : "Little-endian"); - - w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx); - wr = volume->comps[compno].w; - wrr = int_ceildivpow2(volume->comps[compno].w, volume->comps[compno].factor[0]); - - h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy); - hr = volume->comps[compno].h; - hrr = int_ceildivpow2(volume->comps[compno].h, volume->comps[compno].factor[1]); - - l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz); - lr = volume->comps[compno].l; - lrr = int_ceildivpow2(volume->comps[compno].l, volume->comps[compno].factor[2]); - - fprintf(fdest, "PG %c%c %c%d %d %d\n", comp->bigendian ? 'M':'L', comp->bigendian ? 'L':'M',comp->sgnd ? '-' : '+', comp->prec, wr, hr); - if (comp->prec <= 8) { - nbytes = 1; - } else if (comp->prec <= 16) { - nbytes = 2; - } else { - nbytes = 4; - } - - offset = (sliceno / lrr * l) + (sliceno % lrr); - offset = wrr * hrr * offset; - //fprintf(stdout,"%d %d %d %d\n",offset,wrr*hrr,wrr,w); - for (i = 0; i < wrr * hrr; i++) { - int v = volume->comps[0].data[(i / wrr * w) + (i % wrr) + offset]; - if (volume->comps[0].bigendian) { - for (j = nbytes - 1; j >= 0; j--) { - char byte = (char) ((v >> (j * 8)) & 0xff); - fwrite(&byte, 1, 1, fdest); - } - } else { - for (j = 0; j <= nbytes - 1; j++) { - char byte = (char) ((v >> (j * 8)) & 0xff); - fwrite(&byte, 1, 1, fdest); - } - } - } - - fclose(fdest); - }//for sliceno - }//for compno - - return 0; -} - -/* -->> -->> -->> -->> - -BIN IMAGE FORMAT - -<<-- <<-- <<-- <<-- */ - -opj_volume_t* bintovolume(char *filename, char *fileimg, opj_cparameters_t *parameters) { - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; - int subsampling_dz = parameters->subsampling_dz; - - int i, compno, w, h, l, numcomps = 1; - int prec, max = 0; - -// char temp[32]; - char line[100]; - int bigendian; - - FILE *f = NULL; - FILE *fimg = NULL; - OPJ_COLOR_SPACE color_space; - opj_volume_cmptparm_t cmptparm; /* maximum of 1 component */ - opj_volume_t * volume = NULL; - opj_volume_comp_t *comp = NULL; - - bigendian = 0; - color_space = CLRSPC_GRAY; - - fimg = fopen(fileimg,"r"); - if (!fimg) { - fprintf(stdout, "[ERROR] Failed to open %s for reading !!\n", fileimg); - return 0; - } - - fseek(fimg, 0, SEEK_SET); - while (!feof(fimg)) { - fgets(line,100,fimg); - //fprintf(stdout,"%s %d \n",line,feof(fimg)); - if (strncmp(line,"Bpp",3) == 0){ - sscanf(line,"%*s%*[ \t]%d",&prec); - } else if (strncmp(line,"Color",5) == 0){ - sscanf(line, "%*s%*[ \t]%d",&color_space); - } else if (strncmp(line,"Dim",3) == 0){ - sscanf(line, "%*s%*[ \t]%d%*[ \t]%d%*[ \t]%d",&w,&h,&l); - } - } - //fscanf(fimg, "Bpp%[ \t]%d%[ \t\n]",temp,&prec,temp); - //fscanf(fimg, "Color Map%[ \t]%d%[ \n\t]Dimensions%[ \t]%d%[ \t]%d%[ \t]%d%[ \n\t]",temp,&color_space,temp,temp,&w,temp,&h,temp,&l,temp); - //fscanf(fimg, "Resolution(mm)%[ \t]%d%[ \t]%d%[ \t]%d%[ \n\t]",temp,&subsampling_dx,temp,&subsampling_dy,temp,&subsampling_dz,temp); - - #ifdef VERBOSE - fprintf(stdout, "[INFO] %d \t %d %d %d \t %3.2f %2.2f %2.2f \t %d \n",color_space,w,h,l,subsampling_dx,subsampling_dy,subsampling_dz,prec); - #endif - fclose(fimg); - - /* initialize volume components */ - memset(&cmptparm, 0, sizeof(opj_volume_cmptparm_t)); - - cmptparm.prec = prec; - cmptparm.bpp = prec; - cmptparm.sgnd = 0; - cmptparm.bigendian = bigendian; - cmptparm.dcoffset = parameters->dcoffset; - cmptparm.dx = subsampling_dx; - cmptparm.dy = subsampling_dy; - cmptparm.dz = subsampling_dz; - cmptparm.w = w; - cmptparm.h = h; - cmptparm.l = l; - - /* create the volume */ - volume = opj_volume_create(numcomps, &cmptparm, color_space); - if(!volume) { - fprintf(stdout,"[ERROR] Unable to create volume"); - fclose(f); - return NULL; - } - - /* set volume offset and reference grid */ - volume->x0 = parameters->volume_offset_x0; - volume->y0 = parameters->volume_offset_y0; - volume->z0 = parameters->volume_offset_z0; - volume->x1 = parameters->volume_offset_x0 + (w - 1) * subsampling_dx + 1; - volume->y1 = parameters->volume_offset_y0 + (h - 1) * subsampling_dy + 1; - volume->z1 = parameters->volume_offset_z0 + (l - 1) * subsampling_dz + 1; - - /* set volume data */ - f = fopen(filename, "rb"); - if (!f) { - fprintf(stdout, "[ERROR] Failed to open %s for reading !!\n", filename); - return 0; - } - - /* BINARY */ - for (compno = 0; compno < volume->numcomps; compno++) { - int whl = w * h * l; - /* set volume data */ - comp = &volume->comps[compno]; - - /*if (comp->prec <= 8) { - if (!comp->sgnd) { - unsigned char *data = (unsigned char *) malloc(whl * sizeof(unsigned char)); - fread(data, 1, whl, f); - for (i = 0; i < whl; i++) { - comp->data[i] = data[i]; - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } else { - char *data = (char *) malloc(whl); - fread(data, 1, whl, f); - for (i = 0; i < whl; i++) { - comp->data[i] = data[i]; - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } - } else if (comp->prec <= 16) { - if (!comp->sgnd) { - unsigned short *data = (unsigned short *) malloc(whl * sizeof(unsigned short)); - int leido = fread(data, 2, whl, f); - if (!leido) { - free(data); fclose(f); - return NULL; - } - - for (i = 0; i < whl; i++) { - if (bigendian) //(c1 << 8) + c2; - comp->data[i] = data[i]; - else{ //(c2 << 8) + c1; - comp->data[i] = ShortSwap(data[i]); - } - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } else { - short *data = (short *) malloc(whl); - int leido = fread(data, 2, whl, f); - if (!leido) { - free(data); fclose(f); - return NULL; - } - for (i = 0; i < whl; i++) { - if (bigendian){ //(c1 << 8) + c2; - comp->data[i] = data[i]; - }else{ //(c2 << 8) + c1; - comp->data[i] = (short) ShortSwap((unsigned short) data[i]); - } - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } - } else { - if (!comp->sgnd) { - unsigned int *data = (unsigned int *) malloc(whl * sizeof(unsigned int)); - int leido = fread(data, 4, whl, f); - if (!leido) { - free(data); fclose(f); - return NULL; - } for (i = 0; i < whl; i++) { - if (!bigendian) - comp->data[i] = LongSwap(data[i]); - else - comp->data[i] = data[i]; - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } else { - int leido = fread(comp->data, 4, whl, f); - if (!leido) { - fclose(f); - return NULL; - } - for (i = 0; i < whl; i++) { - if (!bigendian) - comp->data[i] = (int) LongSwap((unsigned int) comp->data[i]); - if (comp->data[i] > max) - max = comp->data[i]; - } - } - }*/ - - for (i = 0; i < whl; i++) { - int v; - 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; - } - comp->bpp = int_floorlog2(max) + 1; - } - fclose(f); - return volume; -} - -int volumetobin(opj_volume_t * volume, char *outfile) { - int w, wr, wrr, h, hr, hrr, l, lr, lrr, max; - int i,j, compno, nbytes; - int offset, sliceno; - FILE *fdest = NULL; - FILE *fimgdest = NULL; -// char *imgtemp; - char name[256]; - - for (compno = 0; compno < 1; compno++) { //Only one component - - fdest = fopen(outfile, "wb"); - if (!fdest) { - fprintf(stdout, "[ERROR] Failed to open %s for writing\n", outfile); - return 1; - } - fprintf(stdout,"[INFO] Writing outfile %s (%s) \n",outfile, volume->comps[0].bigendian ? "Bigendian" : "Little-endian"); - - w = int_ceildiv(volume->x1 - volume->x0, volume->comps[compno].dx); - wr = volume->comps[compno].w; - wrr = int_ceildivpow2(volume->comps[compno].w, volume->comps[compno].factor[0]); - - h = int_ceildiv(volume->y1 - volume->y0, volume->comps[compno].dy); - hr = volume->comps[compno].h; - hrr = int_ceildivpow2(volume->comps[compno].h, volume->comps[compno].factor[1]); - - l = int_ceildiv(volume->z1 - volume->z0, volume->comps[compno].dz); - lr = volume->comps[compno].l; - lrr = int_ceildivpow2(volume->comps[compno].l, volume->comps[compno].factor[2]); - - max = (volume->comps[compno].prec <= 8) ? 255 : (1 << volume->comps[compno].prec) - 1; - - volume->comps[compno].x0 = int_ceildivpow2(volume->comps[compno].x0 - int_ceildiv(volume->x0, volume->comps[compno].dx), volume->comps[compno].factor[0]); - volume->comps[compno].y0 = int_ceildivpow2(volume->comps[compno].y0 - int_ceildiv(volume->y0, volume->comps[compno].dy), volume->comps[compno].factor[1]); - volume->comps[compno].z0 = int_ceildivpow2(volume->comps[compno].z0 - int_ceildiv(volume->z0, volume->comps[compno].dz), volume->comps[compno].factor[2]); - - if (volume->comps[0].prec <= 8) { - nbytes = 1; - } else if (volume->comps[0].prec <= 16) { - nbytes = 2; - } else { - nbytes = 4; - } - - //fprintf(stdout,"w %d wr %d wrr %d h %d hr %d hrr %d l %d lr %d lrr %d max %d nbytes %d\n Factor %d %d %d",w,wr,wrr,h,hr,hrr,l,lr,lrr,max,nbytes,volume->comps[compno].factor[0],volume->comps[compno].factor[1],volume->comps[compno].factor[2]); - - for(sliceno = 0; sliceno < lrr; sliceno++) { - offset = (sliceno / lrr * l) + (sliceno % lrr); - offset = wrr * hrr * offset; - for (i = 0; i < wrr * hrr; i++) { - int v = volume->comps[0].data[(i / wrr * w) + (i % wrr) + offset]; - if (volume->comps[0].bigendian) { - for (j = nbytes - 1; j >= 0; j--) { - char byte = (char) ((v >> (j * 8)) & 0xff); - fwrite(&byte, 1, 1, fdest); - } - } else { - for (j = 0; j <= nbytes - 1; j++) { - char byte = (char) ((v >> (j * 8)) & 0xff); - fwrite(&byte, 1, 1, fdest); - } - } - } - } - - } - - fclose(fdest); - - sprintf(name,"%s.img",outfile); - fimgdest = fopen(name, "w"); - if (!fimgdest) { - fprintf(stdout, "[ERROR] Failed to open %s for writing\n", name); - return 1; - } - fprintf(fimgdest, "Bpp\t%d\nColor Map\t2\nDimensions\t%d\t%d\t%d\nResolution(mm)\t%d\t%d\t%d\t\n", - volume->comps[0].prec,wrr,hrr,lrr,volume->comps[0].dx,volume->comps[0].dy,volume->comps[0].dz); - - fclose(fimgdest); - return 0; -} -/* -->> -->> -->> -->> - -IMG IMAGE FORMAT - -<<-- <<-- <<-- <<-- */ -opj_volume_t* imgtovolume(char *fileimg, opj_cparameters_t *parameters) { - int subsampling_dx = parameters->subsampling_dx; - int subsampling_dy = parameters->subsampling_dy; - int subsampling_dz = parameters->subsampling_dz; - - int i, compno, w, h, l, numcomps = 1; - int prec, max = 0, min = 0; - float dx, dy, dz; - char filename[100], tmpdirpath[100], dirpath[100], *tmp; - char line[100], datatype[100]; - int bigendian; - - FILE *f = NULL; - FILE *fimg = NULL; - OPJ_COLOR_SPACE color_space; - opj_volume_cmptparm_t cmptparm; /* maximum of 1 component */ - opj_volume_t * volume = NULL; - opj_volume_comp_t *comp = NULL; - - bigendian = 0; - color_space = CLRSPC_GRAY; - - fimg = fopen(fileimg,"r"); - if (!fimg) { - fprintf(stderr, "[ERROR] Failed to open %s for reading !!\n", fileimg); - return 0; - } - - //Fetch only the path - strcpy(tmpdirpath,fileimg); - if ((tmp = strrchr(tmpdirpath,'/')) != NULL){ - tmp++; *tmp='\0'; - strcpy(dirpath,tmpdirpath); - } else { - strcpy(dirpath,"./"); - } - - fseek(fimg, 0, SEEK_SET); - while (!feof(fimg)) { - fgets(line,100,fimg); - //fprintf(stdout,"%s %d \n",line,feof(fimg)); - if (strncmp(line,"Image",5) == 0){ - sscanf(line,"%*s%*[ \t]%s",datatype); - } else if (strncmp(line,"File",4) == 0){ - sscanf(line,"%*s %*s%*[ \t]%s",filename); - strcat(dirpath, filename); - strcpy(filename,dirpath); - } else if (strncmp(line,"Min",3) == 0){ - sscanf(line,"%*s %*s%*[ \t]%d%*[ \t]%d",&min,&max); - prec = int_floorlog2(max - min + 1); - } else if (strncmp(line,"Bpp",3) == 0){ - sscanf(line,"%*s%*[ \t]%d",&prec); - } else if (strncmp(line,"Color",5) == 0){ - sscanf(line, "%*s %*s%*[ \t]%d",&color_space); - } else if (strncmp(line,"Dim",3) == 0){ - sscanf(line, "%*s%*[ \t]%d%*[ \t]%d%*[ \t]%d",&w,&h,&l); - } else if (strncmp(line,"Res",3) == 0){ - sscanf(line,"%*s%*[ \t]%f%*[ \t]%f%*[ \t]%f",&dx,&dy,&dz); - } - - } - #ifdef VERBOSE - fprintf(stdout, "[INFO] %s %d \t %d %d %d \t %f %f %f \t %d %d %d \n",filename,color_space,w,h,l,dx,dy,dz,max,min,prec); - #endif - fclose(fimg); - - /* error control */ - if ( !prec || !w || !h || !l ){ - fprintf(stderr,"[ERROR] Unable to read IMG file correctly. Found some null values."); - return NULL; - } - - /* initialize volume components */ - memset(&cmptparm, 0, sizeof(opj_volume_cmptparm_t)); - - cmptparm.prec = prec; - cmptparm.bpp = prec; - cmptparm.sgnd = 0; - cmptparm.bigendian = bigendian; - cmptparm.dcoffset = parameters->dcoffset; - cmptparm.dx = subsampling_dx; - cmptparm.dy = subsampling_dy; - cmptparm.dz = subsampling_dz; - cmptparm.w = w; - cmptparm.h = h; - cmptparm.l = l; - - /* create the volume */ - volume = opj_volume_create(numcomps, &cmptparm, color_space); - if(!volume) { - fprintf(stdout,"[ERROR] Unable to create volume"); - return NULL; - } - - /* set volume offset and reference grid */ - volume->x0 = parameters->volume_offset_x0; - volume->y0 = parameters->volume_offset_y0; - volume->z0 = parameters->volume_offset_z0; - volume->x1 = parameters->volume_offset_x0 + (w - 1) * subsampling_dx + 1; - volume->y1 = parameters->volume_offset_y0 + (h - 1) * subsampling_dy + 1; - volume->z1 = parameters->volume_offset_z0 + (l - 1) * subsampling_dz + 1; - - max = 0; - /* set volume data */ - f = fopen(filename, "rb"); - if (!f) { - fprintf(stderr, "[ERROR] Failed to open %s for reading !!\n", filename); - fclose(f); - return 0; - } - - /* BINARY */ - for (compno = 0; compno < volume->numcomps; compno++) { - int whl = w * h * l; - /* set volume data */ - comp = &volume->comps[compno]; - - /*if (comp->prec <= 8) { - if (!comp->sgnd) { - unsigned char *data = (unsigned char *) malloc(whl * sizeof(unsigned char)); - fread(data, 1, whl, f); - for (i = 0; i < whl; i++) { - comp->data[i] = data[i]; - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } else { - char *data = (char *) malloc(whl); - fread(data, 1, whl, f); - for (i = 0; i < whl; i++) { - comp->data[i] = data[i]; - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } - } else if (comp->prec <= 16) { - if (!comp->sgnd) { - unsigned short *data = (unsigned short *) malloc(whl * sizeof(unsigned short)); - int leido = fread(data, 2, whl, f); - if (!leido) { - free(data); fclose(f); - return NULL; - } - - for (i = 0; i < whl; i++) { - if (bigendian) //(c1 << 8) + c2; - comp->data[i] = data[i]; - else{ //(c2 << 8) + c1; - comp->data[i] = ShortSwap(data[i]); - } - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } else { - short *data = (short *) malloc(whl); - int leido = fread(data, 2, whl, f); - if (!leido) { - free(data); fclose(f); - return NULL; - } - for (i = 0; i < whl; i++) { - if (bigendian){ //(c1 << 8) + c2; - comp->data[i] = data[i]; - }else{ //(c2 << 8) + c1; - comp->data[i] = (short) ShortSwap((unsigned short) data[i]); - } - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } - } else { - if (!comp->sgnd) { - unsigned int *data = (unsigned int *) malloc(whl * sizeof(unsigned int)); - int leido = fread(data, 4, whl, f); - if (!leido) { - free(data); fclose(f); - return NULL; - } for (i = 0; i < whl; i++) { - if (!bigendian) - comp->data[i] = LongSwap(data[i]); - else - comp->data[i] = data[i]; - if (comp->data[i] > max) - max = comp->data[i]; - } - free(data); - } else { - int leido = fread(comp->data, 4, whl, f); - if (!leido) { - fclose(f); - return NULL; - } - for (i = 0; i < whl; i++) { - if (!bigendian) - comp->data[i] = (int) LongSwap((unsigned int) comp->data[i]); - if (comp->data[i] > max) - max = comp->data[i]; - } - } - }*/ - - for (i = 0; i < whl; i++) { - int v; - 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; - } - comp->bpp = int_floorlog2(max) + 1; - } - fclose(f); - return volume; -} - diff --git a/jp3d/codec/convert.h b/jp3d/codec/convert.h deleted file mode 100755 index 18ae2127..00000000 --- a/jp3d/codec/convert.h +++ /dev/null @@ -1,51 +0,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, HervŽ 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 __JP3D_CONVERT_H -#define __JP3D_CONVERT_H - -/** -Load a single volume component encoded in PGX file format -@param filename Name of the PGX file to load -@param parameters *List ?* -@return Returns a greyscale volume if successful, returns NULL otherwise -*/ -opj_volume_t* pgxtovolume(char *filename, opj_cparameters_t *parameters); - -int volumetopgx(opj_volume_t *volume, char *outfile); - -opj_volume_t* bintovolume(char *filename,char *fileimg, opj_cparameters_t *parameters); - -int volumetobin(opj_volume_t *volume, char *outfile); - -opj_volume_t* imgtovolume(char *fileimg, opj_cparameters_t *parameters); - -#endif /* __J2K_CONVERT_H */ - diff --git a/jp3d/codec/dirent.h b/jp3d/codec/dirent.h deleted file mode 100755 index a67e5874..00000000 --- a/jp3d/codec/dirent.h +++ /dev/null @@ -1,676 +0,0 @@ -/* - * uce-dirent.h - operating system independent dirent implementation - * - * Copyright (C) 1998-2002 Toni Ronkko - * - * Permission is hereby granted, free of charge, to any person obtaining - * a copy of this software and associated documentation files (the - * ``Software''), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sublicense, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED ``AS IS'', WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. - * IN NO EVENT SHALL TONI RONKKO BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * - * May 28 1998, Toni Ronkko - * - * $Id: uce-dirent.h,v 1.7 2002/05/13 10:48:35 tr Exp $ - * - * $Log: uce-dirent.h,v $ - * Revision 1.7 2002/05/13 10:48:35 tr - * embedded some source code directly to the header so that no source - * modules need to be included in the MS Visual C project using the - * interface, removed all the dependencies to other headers of the `uce' - * library so that the header can be made public - * - * Revision 1.6 2002/04/12 16:22:04 tr - * Unified Compiling Environment (UCE) replaced `std' library - * - * Revision 1.5 2001/07/20 16:33:40 tr - * moved to `std' library and re-named defines accordingly - * - * Revision 1.4 2001/07/10 16:47:18 tronkko - * revised comments - * - * Revision 1.3 2001/01/11 13:16:43 tr - * using ``uce-machine.h'' for finding out defines such as `FREEBSD' - * - * Revision 1.2 2000/10/08 16:00:41 tr - * copy of FreeBSD man page - * - * Revision 1.1 2000/07/10 05:53:16 tr - * Initial revision - * - * Revision 1.2 1998/07/19 18:29:14 tr - * Added error reporting capabilities and some asserts. - * - * Revision 1.1 1998/07/04 16:27:51 tr - * Initial revision - * - * - * MSVC 1.0 scans automatic dependencies incorrectly when your project - * contains this very header. The problem is that MSVC cannot handle - * include directives inside #if..#endif block those are never entered. - * Since this header ought to compile in many different operating systems, - * there had to be several conditional blocks that are compiled only in - * operating systems for what they were designed for. MSVC 1.0 cannot - * handle inclusion of sys/dir.h in a part that is compiled only in Apollo - * operating system. To fix the problem you need to insert DIR.H into - * SYSINCL.DAT located in MSVC\BIN directory and restart visual C++. - * Consult manuals for more informaton about the problem. - * - * Since many UNIX systems have dirent.h we assume to have one also. - * However, if your UNIX system does not have dirent.h you can download one - * for example at: http://ftp.uni-mannheim.de/ftp/GNU/dirent/dirent.tar.gz. - * You can also see if you have one of dirent.h, direct.h, dir.h, ndir.h, - * sys/dir.h and sys/ndir.h somewhere. Try defining HAVE_DIRENT_H, - * HAVE_DIRECT_H, HAVE_DIR_H, HAVE_NDIR_H, HAVE_SYS_DIR_H and - * HAVE_SYS_NDIR_H according to the files found. - */ -#ifndef DIRENT_H -#define DIRENT_H -#define DIRENT_H_INCLUDED - -/* find out platform */ -#if defined(MSDOS) /* MS-DOS */ -#elif defined(__MSDOS__) /* Turbo C/Borland */ -# define MSDOS -#elif defined(__DOS__) /* Watcom */ -# define MSDOS -#endif - -#if defined(WIN32) /* MS-Windows */ -#elif defined(__NT__) /* Watcom */ -# define WIN32 -#elif defined(_WIN32) /* Microsoft */ -# define WIN32 -#elif defined(__WIN32__) /* Borland */ -# define WIN32 -#endif - -/* - * See what kind of dirent interface we have unless autoconf has already - * determinated that. - */ -#if !defined(HAVE_DIRENT_H) && !defined(HAVE_DIRECT_H) && !defined(HAVE_SYS_DIR_H) && !defined(HAVE_NDIR_H) && !defined(HAVE_SYS_NDIR_H) && !defined(HAVE_DIR_H) -# if defined(_MSC_VER) /* Microsoft C/C++ */ - /* no dirent.h */ -# elif defined(__BORLANDC__) /* Borland C/C++ */ -# define HAVE_DIRENT_H -# define VOID_CLOSEDIR -# elif defined(__TURBOC__) /* Borland Turbo C */ - /* no dirent.h */ -# elif defined(__WATCOMC__) /* Watcom C/C++ */ -# define HAVE_DIRECT_H -# elif defined(__apollo) /* Apollo */ -# define HAVE_SYS_DIR_H -# elif defined(__hpux) /* HP-UX */ -# define HAVE_DIRENT_H -# elif defined(__alpha) || defined(__alpha__) /* Alpha OSF1 */ -# error "not implemented" -# elif defined(__sgi) /* Silicon Graphics */ -# define HAVE_DIRENT_H -# elif defined(sun) || defined(_sun) /* Sun Solaris */ -# define HAVE_DIRENT_H -# elif defined(__FreeBSD__) /* FreeBSD */ -# define HAVE_DIRENT_H -# elif defined(__linux__) /* Linux */ -# define HAVE_DIRENT_H -# elif defined(__GNUC__) /* GNU C/C++ */ -# define HAVE_DIRENT_H -# else -# error "not implemented" -# endif -#endif - -/* include proper interface headers */ -#if defined(HAVE_DIRENT_H) -# include -# ifdef FREEBSD -# define NAMLEN(dp) ((int)((dp)->d_namlen)) -# else -# define NAMLEN(dp) ((int)(strlen((dp)->d_name))) -# endif - -#elif defined(HAVE_NDIR_H) -# include -# define NAMLEN(dp) ((int)((dp)->d_namlen)) - -#elif defined(HAVE_SYS_NDIR_H) -# include -# define NAMLEN(dp) ((int)((dp)->d_namlen)) - -#elif defined(HAVE_DIRECT_H) -# include -# define NAMLEN(dp) ((int)((dp)->d_namlen)) - -#elif defined(HAVE_DIR_H) -# include -# define NAMLEN(dp) ((int)((dp)->d_namlen)) - -#elif defined(HAVE_SYS_DIR_H) -# include -# include -# ifndef dirent -# define dirent direct -# endif -# define NAMLEN(dp) ((int)((dp)->d_namlen)) - -#elif defined(MSDOS) || defined(WIN32) - - /* figure out type of underlaying directory interface to be used */ -# if defined(WIN32) -# define DIRENT_WIN32_INTERFACE -# elif defined(MSDOS) -# define DIRENT_MSDOS_INTERFACE -# else -# error "missing native dirent interface" -# endif - - /*** WIN32 specifics ***/ -# if defined(DIRENT_WIN32_INTERFACE) -# include -# if !defined(DIRENT_MAXNAMLEN) -# define DIRENT_MAXNAMLEN (MAX_PATH) -# endif - - - /*** MS-DOS specifics ***/ -# elif defined(DIRENT_MSDOS_INTERFACE) -# include - - /* Borland defines file length macros in dir.h */ -# if defined(__BORLANDC__) -# include -# if !defined(DIRENT_MAXNAMLEN) -# define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT)) -# endif -# if !defined(_find_t) -# define _find_t find_t -# endif - - /* Turbo C defines ffblk structure in dir.h */ -# elif defined(__TURBOC__) -# include -# if !defined(DIRENT_MAXNAMLEN) -# define DIRENT_MAXNAMLEN ((MAXFILE)+(MAXEXT)) -# endif -# define DIRENT_USE_FFBLK - - /* MSVC */ -# elif defined(_MSC_VER) -# if !defined(DIRENT_MAXNAMLEN) -# define DIRENT_MAXNAMLEN (12) -# endif - - /* Watcom */ -# elif defined(__WATCOMC__) -# if !defined(DIRENT_MAXNAMLEN) -# if defined(__OS2__) || defined(__NT__) -# define DIRENT_MAXNAMLEN (255) -# else -# define DIRENT_MAXNAMLEN (12) -# endif -# endif - -# endif -# endif - - /*** generic MS-DOS and MS-Windows stuff ***/ -# if !defined(NAME_MAX) && defined(DIRENT_MAXNAMLEN) -# define NAME_MAX DIRENT_MAXNAMLEN -# endif -# if NAME_MAX < DIRENT_MAXNAMLEN -# error "assertion failed: NAME_MAX >= DIRENT_MAXNAMLEN" -# endif - - - /* - * Substitute for real dirent structure. Note that `d_name' field is a - * true character array although we have it copied in the implementation - * dependent data. We could save some memory if we had declared `d_name' - * as a pointer refering the name within implementation dependent data. - * We have not done that since some code may rely on sizeof(d_name) to be - * something other than four. Besides, directory entries are typically so - * small that it takes virtually no time to copy them from place to place. - */ - typedef struct dirent { - char d_name[NAME_MAX + 1]; - - /*** Operating system specific part ***/ -# if defined(DIRENT_WIN32_INTERFACE) /*WIN32*/ - WIN32_FIND_DATA data; -# elif defined(DIRENT_MSDOS_INTERFACE) /*MSDOS*/ -# if defined(DIRENT_USE_FFBLK) - struct ffblk data; -# else - struct _find_t data; -# endif -# endif - } dirent; - - /* DIR substitute structure containing directory name. The name is - * essential for the operation of ``rewinndir'' function. */ - typedef struct DIR { - char *dirname; /* directory being scanned */ - dirent current; /* current entry */ - int dirent_filled; /* is current un-processed? */ - - /*** Operating system specific part ***/ -# if defined(DIRENT_WIN32_INTERFACE) - HANDLE search_handle; -# elif defined(DIRENT_MSDOS_INTERFACE) -# endif - } DIR; - -# ifdef __cplusplus -extern "C" { -# endif - -/* supply prototypes for dirent functions */ -static DIR *opendir (const char *dirname); -static struct dirent *readdir (DIR *dirp); -static int closedir (DIR *dirp); -static void rewinddir (DIR *dirp); - -/* - * Implement dirent interface as static functions so that the user does not - * need to change his project in any way to use dirent function. With this - * it is sufficient to include this very header from source modules using - * dirent functions and the functions will be pulled in automatically. - */ -#include -#include -#include -#include -#include - -/* use ffblk instead of _find_t if requested */ -#if defined(DIRENT_USE_FFBLK) -# define _A_ARCH (FA_ARCH) -# define _A_HIDDEN (FA_HIDDEN) -# define _A_NORMAL (0) -# define _A_RDONLY (FA_RDONLY) -# define _A_SUBDIR (FA_DIREC) -# define _A_SYSTEM (FA_SYSTEM) -# define _A_VOLID (FA_LABEL) -# define _dos_findnext(dest) findnext(dest) -# define _dos_findfirst(name,flags,dest) findfirst(name,dest,flags) -#endif - -static int _initdir (DIR *p); -static const char *_getdirname (const struct dirent *dp); -static void _setdirname (struct DIR *dirp); - -/* - * - * open directory stream for reading - * DIR *opendir (const char *dirname); - * - * Open named directory stream for read and return pointer to the - * internal working area that is used for retrieving individual directory - * entries. The internal working area has no fields of your interest. - * - * Returns a pointer to the internal working area or NULL in case the - * directory stream could not be opened. Global `errno' variable will set - * in case of error as follows: - * - * - * [EACESS |Permission denied. - * [EMFILE |Too many open files used by the process. - * [ENFILE |Too many open files in system. - * [ENOENT |Directory does not exist. - * [ENOMEM |Insufficient memory. - * [ENOTDIR |dirname does not refer to directory. This value is not - * reliable on MS-DOS and MS-Windows platforms. Many - * implementations return ENOENT even when the name refers to a - * file.] - *
- *
- */ -static DIR *opendir(const char *dirname) -{ - DIR *dirp; - assert (dirname != NULL); - - dirp = (DIR*)malloc (sizeof (struct DIR)); - if (dirp != NULL) { - char *p; - - /* allocate room for directory name */ - dirp->dirname = (char*) malloc (strlen (dirname) + 1 + strlen ("\\*.*")); - if (dirp->dirname == NULL) { - /* failed to duplicate directory name. errno set by malloc() */ - free (dirp); - return NULL; - } - /* Copy directory name while appending directory separator and "*.*". - * Directory separator is not appended if the name already ends with - * drive or directory separator. Directory separator is assumed to be - * '/' or '\' and drive separator is assumed to be ':'. */ - strcpy (dirp->dirname, dirname); - p = strchr (dirp->dirname, '\0'); - if (dirp->dirname < p && - *(p - 1) != '\\' && *(p - 1) != '/' && *(p - 1) != ':') - { - strcpy (p++, "\\"); - } -# ifdef DIRENT_WIN32_INTERFACE - strcpy (p, "*"); /*scan files with and without extension in win32*/ -# else - strcpy (p, "*.*"); /*scan files with and without extension in DOS*/ -# endif - - /* open stream */ - if (_initdir (dirp) == 0) { - /* initialization failed */ - free (dirp->dirname); - free (dirp); - return NULL; - } - } - return dirp; -} - - -/* - * - * read a directory entry - * struct dirent *readdir (DIR *dirp); - * - * Read individual directory entry and return pointer to a structure - * containing the name of the entry. Individual directory entries returned - * include normal files, sub-directories, pseudo-directories "." and ".." - * and also volume labels, hidden files and system files in MS-DOS and - * MS-Windows. You might want to use stat(2) function to determinate which - * one are you dealing with. Many dirent implementations already contain - * equivalent information in dirent structure but you cannot depend on - * this. - * - * The dirent structure contains several system dependent fields that - * generally have no interest to you. The only interesting one is char - * d_name[] that is also portable across different systems. The d_name - * field contains the name of the directory entry without leading path. - * While d_name is portable across different systems the actual storage - * capacity of d_name varies from system to system and there is no portable - * way to find out it at compile time as different systems define the - * capacity of d_name with different macros and some systems do not define - * capacity at all (besides actual declaration of the field). If you really - * need to find out storage capacity of d_name then you might want to try - * NAME_MAX macro. The NAME_MAX is defined in POSIX standard althought - * there are many MS-DOS and MS-Windows implementations those do not define - * it. There are also systems that declare d_name as "char d_name[1]" and - * then allocate suitable amount of memory at run-time. Thanks to Alain - * Decamps (Alain.Decamps@advalvas.be) for pointing it out to me. - * - * This all leads to the fact that it is difficult to allocate space - * for the directory names when the very same program is being compiled on - * number of operating systems. Therefore I suggest that you always - * allocate space for directory names dynamically. - * - * - * Returns a pointer to a structure containing name of the directory entry - * in `d_name' field or NULL if there was an error. In case of an error the - * global `errno' variable will set as follows: - * - * - * [EBADF |dir parameter refers to an invalid directory stream. This value - * is not set reliably on all implementations.] - *
- *
- */ -static struct dirent * -readdir (DIR *dirp) -{ - assert(dirp != NULL); - if (dirp == NULL) { - errno = EBADF; - return NULL; - } - -#if defined(DIRENT_WIN32_INTERFACE) - if (dirp->search_handle == INVALID_HANDLE_VALUE) { - /* directory stream was opened/rewound incorrectly or it ended normally */ - errno = EBADF; - return NULL; - } -#endif - - if (dirp->dirent_filled != 0) { - /* - * Directory entry has already been retrieved and there is no need to - * retrieve a new one. Directory entry will be retrieved in advance - * when the user calls readdir function for the first time. This is so - * because real dirent has separate functions for opening and reading - * the stream whereas Win32 and DOS dirents open the stream - * automatically when we retrieve the first file. Therefore, we have to - * save the first file when opening the stream and later we have to - * return the saved entry when the user tries to read the first entry. - */ - dirp->dirent_filled = 0; - } else { - /* fill in entry and return that */ -#if defined(DIRENT_WIN32_INTERFACE) - if (FindNextFile (dirp->search_handle, &dirp->current.data) == FALSE) { - /* Last file has been processed or an error occured */ - FindClose (dirp->search_handle); - dirp->search_handle = INVALID_HANDLE_VALUE; - errno = ENOENT; - return NULL; - } - -# elif defined(DIRENT_MSDOS_INTERFACE) - if (_dos_findnext (&dirp->current.data) != 0) { - /* _dos_findnext and findnext will set errno to ENOENT when no - * more entries could be retrieved. */ - return NULL; - } -# endif - - _setdirname (dirp); - assert (dirp->dirent_filled == 0); - } - return &dirp->current; -} - - -/* - * - * close directory stream. - * int closedir (DIR *dirp); - * - * Close directory stream opened by the `opendir' function. Close of - * directory stream invalidates the DIR structure as well as previously read - * dirent entry. - * - * The function typically returns 0 on success and -1 on failure but - * the function may be declared to return void on same systems. At least - * Borland C/C++ and some UNIX implementations use void as a return type. - * The dirent wrapper tries to define VOID_CLOSEDIR whenever closedir is - * known to return nothing. The very same definition is made by the GNU - * autoconf if you happen to use it. - * - * The global `errno' variable will set to EBADF in case of error. - * - */ -static int -closedir (DIR *dirp) -{ - int retcode = 0; - - /* make sure that dirp points to legal structure */ - assert (dirp != NULL); - if (dirp == NULL) { - errno = EBADF; - return -1; - } - - /* free directory name and search handles */ - if (dirp->dirname != NULL) free (dirp->dirname); - -#if defined(DIRENT_WIN32_INTERFACE) - if (dirp->search_handle != INVALID_HANDLE_VALUE) { - if (FindClose (dirp->search_handle) == FALSE) { - /* Unknown error */ - retcode = -1; - errno = EBADF; - } - } -#endif - - /* clear dirp structure to make sure that it cannot be used anymore*/ - memset (dirp, 0, sizeof (*dirp)); -# if defined(DIRENT_WIN32_INTERFACE) - dirp->search_handle = INVALID_HANDLE_VALUE; -# endif - - free (dirp); - return retcode; -} - - -/* - * - * rewind directory stream to the beginning - * void rewinddir (DIR *dirp); - * - * Rewind directory stream to the beginning so that the next call of - * readdir() returns the very first directory entry again. However, note - * that next call of readdir() may not return the same directory entry as it - * did in first time. The directory stream may have been affected by newly - * created files. - * - * Almost every dirent implementation ensure that rewinddir will update - * the directory stream to reflect any changes made to the directory entries - * since the previous ``opendir'' or ``rewinddir'' call. Keep an eye on - * this if your program depends on the feature. I know at least one dirent - * implementation where you are required to close and re-open the stream to - * see the changes. - * - * Returns nothing. If something went wrong while rewinding, you will - * notice it later when you try to retrieve the first directory entry. - */ -static void -rewinddir (DIR *dirp) -{ - /* make sure that dirp is legal */ - assert (dirp != NULL); - if (dirp == NULL) { - errno = EBADF; - return; - } - assert (dirp->dirname != NULL); - - /* close previous stream */ -#if defined(DIRENT_WIN32_INTERFACE) - if (dirp->search_handle != INVALID_HANDLE_VALUE) { - if (FindClose (dirp->search_handle) == FALSE) { - /* Unknown error */ - errno = EBADF; - } - } -#endif - - /* re-open previous stream */ - if (_initdir (dirp) == 0) { - /* initialization failed but we cannot deal with error. User will notice - * error later when she tries to retrieve first directory enty. */ - /*EMPTY*/; - } -} - - -/* - * Open native directory stream object and retrieve first file. - * Be sure to close previous stream before opening new one. - */ -static int -_initdir (DIR *dirp) -{ - assert (dirp != NULL); - assert (dirp->dirname != NULL); - dirp->dirent_filled = 0; - -# if defined(DIRENT_WIN32_INTERFACE) - /* Open stream and retrieve first file */ - dirp->search_handle = FindFirstFile (dirp->dirname, &dirp->current.data); - if (dirp->search_handle == INVALID_HANDLE_VALUE) { - /* something went wrong but we don't know what. GetLastError() could - * give us more information about the error, but then we should map - * the error code into errno. */ - errno = ENOENT; - return 0; - } - -# elif defined(DIRENT_MSDOS_INTERFACE) - if (_dos_findfirst (dirp->dirname, - _A_SUBDIR | _A_RDONLY | _A_ARCH | _A_SYSTEM | _A_HIDDEN, - &dirp->current.data) != 0) - { - /* _dos_findfirst and findfirst will set errno to ENOENT when no - * more entries could be retrieved. */ - return 0; - } -# endif - - /* initialize DIR and it's first entry */ - _setdirname (dirp); - dirp->dirent_filled = 1; - return 1; -} - - -/* - * Return implementation dependent name of the current directory entry. - */ -static const char * -_getdirname (const struct dirent *dp) -{ -#if defined(DIRENT_WIN32_INTERFACE) - return dp->data.cFileName; - -#elif defined(DIRENT_USE_FFBLK) - return dp->data.ff_name; - -#else - return dp->data.name; -#endif -} - - -/* - * Copy name of implementation dependent directory entry to the d_name field. - */ -static void -_setdirname (struct DIR *dirp) { - /* make sure that d_name is long enough */ - assert (strlen (_getdirname (&dirp->current)) <= NAME_MAX); - - strncpy (dirp->current.d_name, - _getdirname (&dirp->current), - NAME_MAX); - dirp->current.d_name[NAME_MAX] = '\0'; /*char d_name[NAME_MAX+1]*/ -} - -# ifdef __cplusplus -} -# endif -# define NAMLEN(dp) ((int)(strlen((dp)->d_name))) - -#else -# error "missing dirent interface" -#endif - - -#endif /*DIRENT_H*/ diff --git a/jp3d/codec/getopt.c b/jp3d/codec/getopt.c deleted file mode 100755 index 69addc97..00000000 --- a/jp3d/codec/getopt.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright (c) 1987, 1993, 1994 - * The Regents of the University of California. 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. - * 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 - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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. - */ - -/* last review : october 29th, 2002 */ - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95"; -#endif /* LIBC_SCCS and not lint */ - -#include -#include -#include - -int opterr = 1, /* if error message should be printed */ - optind = 1, /* index into parent argv vector */ - optopt, /* character checked for validity */ - optreset; /* reset getopt */ -char *optarg; /* argument associated with option */ - -#define BADCH (int)'?' -#define BADARG (int)':' -#define EMSG "" - -/* - * getopt -- - * Parse argc/argv argument vector. - */ -int getopt(int nargc, char *const *nargv, const char *ostr) { - - # define __progname nargv[0] /* program name */ - - static char *place = EMSG; /* option letter processing */ - char *oli; /* option letter list index */ - - if (optreset || !*place) { /* update scanning pointer */ - optreset = 0; - if (optind >= nargc || *(place = nargv[optind]) != '-') { - place = EMSG; - return (-1); - } - if (place[1] && *++place == '-') { /* found "--" */ - ++optind; - place = EMSG; - return (-1); - } - } /* option letter okay? */ - - if ((optopt = (int) *place++) == (int) ':' || !(oli = strchr(ostr, optopt))) { - /* if the user didn't specify '-' as an option, assume it means -1. */ - if (optopt == (int) '-') - return (-1); - if (!*place) - ++optind; - if (opterr && *ostr != ':') - (void) fprintf(stdout,"[ERROR] %s: illegal option -- %c\n", __progname, optopt); - return (BADCH); - } - - if (*++oli != ':') { /* don't need argument */ - optarg = NULL; - if (!*place) - ++optind; - } else { /* need an argument */ - if (*place) /* no white space */ - optarg = place; - else if (nargc <= ++optind) { /* no arg */ - place = EMSG; - if (*ostr == ':') - return (BADARG); - if (opterr) - (void) fprintf(stdout, "[ERROR] %s: option requires an argument -- %c\n", __progname, optopt); - return (BADCH); - } else /* white space */ - optarg = nargv[optind]; - place = EMSG; - ++optind; - } - return (optopt); /* dump back option letter */ -} diff --git a/jp3d/codec/getopt.h b/jp3d/codec/getopt.h deleted file mode 100755 index 23299d1b..00000000 --- a/jp3d/codec/getopt.h +++ /dev/null @@ -1,14 +0,0 @@ -/* last review : october 29th, 2002 */ - -#ifndef _GETOPT_H_ -#define _GETOPT_H_ - -extern int opterr; -extern int optind; -extern int optopt; -extern int optreset; -extern char *optarg; - -extern int getopt(int nargc, char *const *nargv, const char *ostr); - -#endif /* _GETOPT_H_ */ diff --git a/jp3d/codec/jp3d_to_volume.c b/jp3d/codec/jp3d_to_volume.c deleted file mode 100755 index 81dc1c78..00000000 --- a/jp3d/codec/jp3d_to_volume.c +++ /dev/null @@ -1,535 +0,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, Hervé 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 -#include -#include -#include - -#include "openjpeg.h" -#include "getopt.h" -#include "convert.h" - -#ifndef WIN32 -#define stricmp strcasecmp -#define strnicmp strncasecmp -#endif - -/* ----------------------------------------------------------------------- */ -static double calc_PSNR(opj_volume_t *original, opj_volume_t *decoded) -{ - int max, i, k, compno = 0, size; - double sum, total = 0; - int global = 1; - - max = (original->comps[compno].prec <= 8) ? 255 : (1 << original->comps[compno].prec) - 1; - if (global) { - size = (original->x1 - original->x0) * (original->y1 - original->y0) * (original->z1 - original->z0); - - for (compno = 0; compno < original->numcomps; compno++) { - for(sum = 0, i = 0; i < size; ++i) { - if ((decoded->comps[compno].data[i] < 0) || (decoded->comps[compno].data[i] > max)) - fprintf(stdout,"[WARNING] Data out of range during PSNR computing...\n"); - else - sum += (original->comps[compno].data[i] - decoded->comps[compno].data[i]) * (original->comps[compno].data[i] - decoded->comps[compno].data[i]); - } - } - sum /= size; - total = ((sum==0.0) ? 0.0 : 10 * log10(max * max / sum)); - } else { - size = (original->x1 - original->x0) * (original->y1 - original->y0); - - for (k = 0; k < original->z1 - original->z0; k++) { - int offset = k * size; - for (sum = 0, compno = 0; compno < original->numcomps; compno++) { - for(i = 0; i < size; ++i) { - if ((decoded->comps[compno].data[i + offset] < 0) || (decoded->comps[compno].data[i + offset] > max)) - fprintf(stdout,"[WARNING] Data out of range during PSNR computing...\n"); - else - sum += (original->comps[compno].data[i + offset] - decoded->comps[compno].data[i + offset]) * (original->comps[compno].data[i + offset] - decoded->comps[compno].data[i + offset]); - } - } - sum /= size; - total = total + ((sum==0.0) ? 0.0 : 10 * log10(max * max / sum)); - } - - } - if(total == 0) /* perfect reconstruction, PSNR should return infinity */ - return -1.0; - - return total; - //return 20 * log10((max - 1) / sqrt(sum)); -} - -static double calc_SSIM(opj_volume_t *original, opj_volume_t *decoded) -{ - int max, i, compno = 0, size, sizeM; - double sum; - double mux = 0.0, muy = 0.0, sigmax = 0.0, sigmay = 0.0, - sigmaxy = 0.0, structx = 0.0, structy = 0.0; - double lcomp,ccomp,scomp; - double C1,C2,C3; - - max = (original->comps[compno].prec <= 8) ? 255 : (1 << original->comps[compno].prec) - 1; - size = (original->x1 - original->x0) * (original->y1 - original->y0) * (original->z1 - original->z0); - - //MSSIM - -// sizeM = size / (original->z1 - original->z0); - - sizeM = size; - for(sum = 0, i = 0; i < sizeM; ++i) { - // First, the luminance of each signal is compared. - mux += original->comps[compno].data[i]; - muy += decoded->comps[compno].data[i]; - } - mux /= sizeM; - muy /= sizeM; - - //We use the standard deviation (the square root of variance) as an estimate of the signal contrast. - for(sum = 0, i = 0; i < sizeM; ++i) { - // First, the luminance of each signal is compared. - sigmax += (original->comps[compno].data[i] - mux) * (original->comps[compno].data[i] - mux); - sigmay += (decoded->comps[compno].data[i] - muy) * (decoded->comps[compno].data[i] - muy); - sigmaxy += (original->comps[compno].data[i] - mux) * (decoded->comps[compno].data[i] - muy); - } - sigmax /= sizeM - 1; - sigmay /= sizeM - 1; - sigmaxy /= sizeM - 1; - - sigmax = sqrt(sigmax); - sigmay = sqrt(sigmay); - sigmaxy = sqrt(sigmaxy); - - //Third, the signal is normalized (divided) by its own standard deviation, - //so that the two signals being compared have unit standard deviation. - - //Luminance comparison - C1 = (0.01 * max) * (0.01 * max); - lcomp = ((2 * mux * muy) + C1)/((mux*mux) + (muy*mux) + C1); - //Constrast comparison - C2 = (0.03 * max) * (0.03 * max); - ccomp = ((2 * sigmax * sigmay) + C2)/((sigmax*sigmax) + (sigmay*sigmay) + C2); - //Structure comparison - C3 = C2 / 2; - scomp = (sigmaxy + C3) / (sigmax * sigmay + C3); - //Similarity measure - - sum = lcomp * ccomp * scomp; - return sum; -} - -void decode_help_display() { - fprintf(stdout,"HELP\n----\n\n"); - fprintf(stdout,"- the -h option displays this help information on screen\n\n"); - - fprintf(stdout,"List of parameters for the JPEG 2000 encoder:\n"); - fprintf(stdout,"\n"); - fprintf(stdout," Required arguments \n"); - fprintf(stdout," ---------------------------- \n"); - fprintf(stdout," -i ( *.jp3d, *.j3d )\n"); - fprintf(stdout," Currently accepts J3D-files. The file type is identified based on its suffix.\n"); - fprintf(stdout," -o ( *.pgx, *.bin )\n"); - fprintf(stdout," Currently accepts PGX-files and BIN-files. Binary data is written to the file (not ascii). \n"); - fprintf(stdout," If a PGX filename is given, there will be as many output files as slices; \n"); - fprintf(stdout," an indice starting from 0 will then be appended to the output filename,\n"); - fprintf(stdout," just before the \"pgx\" extension.\n"); - fprintf(stdout," -m ( *.img ) \n"); - fprintf(stdout," Required only for BIN-files. Ascii data of volume characteristics is written. \n"); - fprintf(stdout,"\n"); - fprintf(stdout," Optional \n"); - fprintf(stdout," ---------------------------- \n"); - fprintf(stdout," -h \n "); - fprintf(stdout," Display the help information\n"); - fprintf(stdout," -r \n"); - fprintf(stdout," Set the number of highest resolution levels to be discarded on each dimension. \n"); - fprintf(stdout," The volume resolution is effectively divided by 2 to the power of the\n"); - fprintf(stdout," number of discarded levels. The reduce factor is limited by the\n"); - fprintf(stdout," smallest total number of decomposition levels among tiles.\n"); - fprintf(stdout," -l \n"); - fprintf(stdout," Set the maximum number of quality layers to decode. If there are\n"); - fprintf(stdout," less quality layers than the specified number, all the quality layers\n"); - fprintf(stdout," are decoded. \n"); - fprintf(stdout," -O original-file \n"); - fprintf(stdout," This option offers the possibility to compute some quality results \n"); - fprintf(stdout," for the decompressed volume, like the PSNR value achieved or the global SSIM value. \n"); - fprintf(stdout," Needs the original file in order to compare with the new one.\n"); - fprintf(stdout," NOTE: Only valid when -r option is 0,0,0 (both original and decompressed volumes have same resolutions) \n"); - fprintf(stdout," NOTE: If original file is .BIN file, the volume characteristics file shall be defined with the -m option. \n"); - fprintf(stdout," (i.e. -O original-BIN-file -m original-IMG-file) \n"); - fprintf(stdout," -BE \n"); - fprintf(stdout," Define that the recovered volume data will be saved with big endian byte order.\n"); - fprintf(stdout," By default, little endian byte order is used.\n"); - fprintf(stdout,"\n"); -} - -/* -------------------------------------------------------------------------- */ - -int get_file_format(char *filename) { - int i; - static const char *extension[] = {"pgx", "bin", "j3d", "jp3d", "j2k", "img"}; - static const int format[] = { PGX_DFMT, BIN_DFMT, J3D_CFMT, J3D_CFMT, J2K_CFMT, IMG_DFMT}; - char * ext = strrchr(filename, '.') + 1; - for(i = 0; i < sizeof(format); i++) { - if(strnicmp(ext, extension[i], 3) == 0) { - return format[i]; - } - } - - return -1; -} - -/* -------------------------------------------------------------------------- */ - -int parse_cmdline_decoder(int argc, char **argv, opj_dparameters_t *parameters) { - /* parse the command line */ - - while (1) { - int c = getopt(argc, argv, "i:o:O:r:l:B:m:h"); - if (c == -1) - break; - switch (c) { - case 'i': /* input file */ - { - char *infile = optarg; - parameters->decod_format = get_file_format(infile); - switch(parameters->decod_format) { - case J3D_CFMT: - case J2K_CFMT: - break; - default: - fprintf(stdout, "[ERROR] Unknown format for infile %s [only *.j3d]!! \n", infile); - return 1; - break; - } - strncpy(parameters->infile, infile, MAX_PATH); - fprintf(stdout, "[INFO] Infile: %s \n", parameters->infile); - - } - break; - - case 'm': /* img file */ - { - char *imgfile = optarg; - int imgformat = get_file_format(imgfile); - switch(imgformat) { - case IMG_DFMT: - break; - default: - fprintf(stdout, "[ERROR] Unrecognized format for imgfile : %s [accept only *.img] !!\n\n", imgfile); - return 1; - break; - } - strncpy(parameters->imgfile, imgfile, MAX_PATH); - fprintf(stdout, "[INFO] Imgfile: %s Format: %d\n", parameters->imgfile, imgformat); - } - break; - - /* ----------------------------------------------------- */ - - case 'o': /* output file */ - { - char *outfile = optarg; - parameters->cod_format = get_file_format(outfile); - switch(parameters->cod_format) { - case PGX_DFMT: - case BIN_DFMT: - break; - default: - fprintf(stdout, "[ERROR] Unrecognized format for outfile : %s [accept only *.pgx or *.bin] !!\n\n", outfile); - return 1; - break; - } - strncpy(parameters->outfile, outfile, MAX_PATH); - fprintf(stdout, "[INFO] Outfile: %s \n", parameters->outfile); - - } - break; - - /* ----------------------------------------------------- */ - - case 'O': /* Original image for PSNR computing */ - { - char *original = optarg; - parameters->orig_format = get_file_format(original); - switch(parameters->orig_format) { - case PGX_DFMT: - case BIN_DFMT: - break; - default: - fprintf(stdout, "[ERROR] Unrecognized format for original file : %s [accept only *.pgx or *.bin] !!\n\n", original); - return 1; - break; - } - strncpy(parameters->original, original, MAX_PATH); - fprintf(stdout, "[INFO] Original file: %s \n", parameters->original); - } - break; - - /* ----------------------------------------------------- */ - - case 'r': /* reduce option */ - { - //sscanf(optarg, "%d, %d, %d", ¶meters->cp_reduce[0], ¶meters->cp_reduce[1], ¶meters->cp_reduce[2]); - int aux; - aux = sscanf(optarg, "%d,%d,%d", ¶meters->cp_reduce[0], ¶meters->cp_reduce[1], ¶meters->cp_reduce[2]); - if (aux == 2) - parameters->cp_reduce[2] = 0; - else if (aux == 1) { - parameters->cp_reduce[1] = parameters->cp_reduce[0]; - parameters->cp_reduce[2] = 0; - }else if (aux == 0){ - parameters->cp_reduce[0] = 0; - parameters->cp_reduce[1] = 0; - parameters->cp_reduce[2] = 0; - } - } - break; - - /* ----------------------------------------------------- */ - - case 'l': /* layering option */ - { - sscanf(optarg, "%d", ¶meters->cp_layer); - } - break; - - /* ----------------------------------------------------- */ - - case 'B': /* BIGENDIAN vs. LITTLEENDIAN */ - { - parameters->bigendian = 1; - } - break; - - /* ----------------------------------------------------- */ - - case 'L': /* BIGENDIAN vs. LITTLEENDIAN */ - { - parameters->decod_format = LSE_CFMT; - } - break; - - /* ----------------------------------------------------- */ - - case 'h': /* display an help description */ - { - decode_help_display(); - return 1; - } - break; - - /* ----------------------------------------------------- */ - - default: - fprintf(stdout,"[WARNING] This option is not valid \"-%c %s\"\n",c, optarg); - break; - } - } - - /* check for possible errors */ - - if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) { - fprintf(stdout,"[ERROR] At least one required argument is missing\n Check jp3d_to_volume -help for usage information\n"); - return 1; - } - - return 0; -} - -/* -------------------------------------------------------------------------- */ - -/** -sample error callback expecting a FILE* client object -*/ -void error_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** -sample warning callback expecting a FILE* client object -*/ -void warning_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[WARNING] %s", msg); -} -/** -sample debug callback expecting no client object -*/ -void info_callback(const char *msg, void *client_data) { - fprintf(stdout, "[INFO] %s", msg); -} - -/* -------------------------------------------------------------------------- */ - -int main(int argc, char **argv) { - - opj_dparameters_t parameters; /* decompression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - opj_volume_t *volume = NULL; - - opj_volume_t *original = NULL; - opj_cparameters_t cparameters; /* original parameters */ - - FILE *fsrc = NULL; - unsigned char *src = NULL; - int file_length; - int decodeok; - double psnr, ssim; - - opj_dinfo_t* dinfo = NULL; /* handle to a decompressor */ - opj_cio_t *cio = NULL; - - /* configure the event callbacks (not required) */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; - - /* set decoding parameters to default values */ - opj_set_default_decoder_parameters(¶meters); - - /* parse input and get user decoding parameters */ - strcpy(parameters.original,"NULL"); - strcpy(parameters.imgfile,"NULL"); - if(parse_cmdline_decoder(argc, argv, ¶meters) == 1) { - return 0; - } - - /* read the input file and put it in memory */ - /* ---------------------------------------- */ - fprintf(stdout, "[INFO] Loading %s file \n",parameters.decod_format==J3D_CFMT ? ".jp3d" : ".j2k"); - fsrc = fopen(parameters.infile, "rb"); - if (!fsrc) { - fprintf(stdout, "[ERROR] Failed to open %s for reading\n", parameters.infile); - return 1; - } - fseek(fsrc, 0, SEEK_END); - file_length = ftell(fsrc); - fseek(fsrc, 0, SEEK_SET); - src = (unsigned char *) malloc(file_length); - fread(src, 1, file_length, fsrc); - fclose(fsrc); - - /* decode the code-stream */ - /* ---------------------- */ - if (parameters.decod_format == J3D_CFMT || parameters.decod_format == J2K_CFMT) { - /* get a JP3D or J2K decoder handle */ - if (parameters.decod_format == J3D_CFMT) - dinfo = opj_create_decompress(CODEC_J3D); - else if (parameters.decod_format == J2K_CFMT) - dinfo = opj_create_decompress(CODEC_J2K); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)dinfo, &event_mgr, stderr); - - /* setup the decoder decoding parameters using user parameters */ - opj_setup_decoder(dinfo, ¶meters); - - /* open a byte stream */ - cio = opj_cio_open((opj_common_ptr)dinfo, src, file_length); - - /* decode the stream and fill the volume structure */ - volume = opj_decode(dinfo, cio); - if(!volume) { - fprintf(stdout, "[ERROR] jp3d_to_volume: failed to decode volume!\n"); - opj_destroy_decompress(dinfo); - opj_cio_close(cio); - return 1; - } - - /* close the byte stream */ - opj_cio_close(cio); - } - - /* free the memory containing the code-stream */ - free(src); - src = NULL; - - /* create output volume */ - /* ------------------- */ - - switch (parameters.cod_format) { - case PGX_DFMT: /* PGX */ - decodeok = volumetopgx(volume, parameters.outfile); - if (decodeok) - fprintf(stdout,"[ERROR] Unable to write decoded volume into pgx files\n"); - break; - - case BIN_DFMT: /* BMP */ - decodeok = volumetobin(volume, parameters.outfile); - if (decodeok) - fprintf(stdout,"[ERROR] Unable to write decoded volume into pgx files\n"); - break; - } - switch (parameters.orig_format) { - case PGX_DFMT: /* PGX */ - if (strcmp("NULL",parameters.original) != 0){ - fprintf(stdout,"Loading original file %s \n",parameters.original); - cparameters.subsampling_dx = 1; cparameters.subsampling_dy = 1; cparameters.subsampling_dz = 1; - cparameters.volume_offset_x0 = 0;cparameters.volume_offset_y0 = 0;cparameters.volume_offset_z0 = 0; - original = pgxtovolume(parameters.original,&cparameters); - } - break; - - case BIN_DFMT: /* BMP */ - if (strcmp("NULL",parameters.original) != 0 && strcmp("NULL",parameters.imgfile) != 0){ - fprintf(stdout,"Loading original file %s %s\n",parameters.original,parameters.imgfile); - cparameters.subsampling_dx = 1; cparameters.subsampling_dy = 1; cparameters.subsampling_dz = 1; - cparameters.volume_offset_x0 = 0;cparameters.volume_offset_y0 = 0;cparameters.volume_offset_z0 = 0; - original = bintovolume(parameters.original,parameters.imgfile,&cparameters); - } - break; - } - - 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); - - if(original){ - psnr = calc_PSNR(original,volume); - ssim = calc_SSIM(original,volume); - if (psnr < 0.0) - fprintf(stdout, " PSNR: Inf , SSMI %f -- Perfect reconstruction!\n",ssim); - else - fprintf(stdout, " PSNR: %f , SSIM %f \n",psnr,ssim); - } - /* free remaining structures */ - if(dinfo) { - opj_destroy_decompress(dinfo); - } - - /* free volume data structure */ - opj_volume_destroy(volume); - - return 0; -} - diff --git a/jp3d/codec/jp3d_vm_dec.ncb b/jp3d/codec/jp3d_vm_dec.ncb deleted file mode 100755 index fc66b661edfbd0af2e2a473a556b48111c086a3f..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 470016 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 _P5&z}u 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 F{2x0#sNDbn diff --git a/jp3d/codec/jp3d_vm_dec.sln b/jp3d/codec/jp3d_vm_dec.sln deleted file mode 100755 index e696c5f7..00000000 --- a/jp3d/codec/jp3d_vm_dec.sln +++ /dev/null @@ -1,30 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jp3d_vm_dec", "jp3d_vm_dec.vcproj", "{E0C1B905-5B10-4C9A-AF55-2D8144D518AB}" - ProjectSection(ProjectDependencies) = postProject - {6F3FB035-8F4E-4794-B091-0F0A20223BE7} = {6F3FB035-8F4E-4794-B091-0F0A20223BE7} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJp3dVM", "..\LibJp3dVM.vcproj", "{6F3FB035-8F4E-4794-B091-0F0A20223BE7}" - ProjectSection(ProjectDependencies) = postProject - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {E0C1B905-5B10-4C9A-AF55-2D8144D518AB}.Debug.ActiveCfg = Debug|Win32 - {E0C1B905-5B10-4C9A-AF55-2D8144D518AB}.Debug.Build.0 = Debug|Win32 - {E0C1B905-5B10-4C9A-AF55-2D8144D518AB}.Release.ActiveCfg = Release|Win32 - {E0C1B905-5B10-4C9A-AF55-2D8144D518AB}.Release.Build.0 = Release|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Debug.ActiveCfg = Debug|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Debug.Build.0 = Debug|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Release.ActiveCfg = Release|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/jp3d/codec/jp3d_vm_dec.suo b/jp3d/codec/jp3d_vm_dec.suo deleted file mode 100755 index 28c2e25584f555673a87eee32fe678e195049c10..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13312 zcmeI2Pi)*r701VRN|U-xXqzU%q-BZYCY0FtZ)!JCx?Zo7v~l9bAt}OAwDzvub=Uh_ zcGpfqoC_Bus1PUMfYcUx0zu0K2@Wj+3DE-zLL3XU2g(JhNc;=X)_lG*``bVE?q^SmdQFUPiI zqmkafGjP^;e6l8B!Y0WxZLYAIwWmEujnAEAq+0sv%ip>5{O^9z)Iy`jcDt72Q1r~4 zISKU{a$$41S{JM8_L%0TJ(S)HG>%mbDilb5mCl)n$(U!%DHG?JHJ{--#+dx_jB8f$ z`yd)ndq8`pR{GMR+Fwd1p`;Z^m?^$5n+Z#Ok(mKwLb-| ziS&SUfM4e80RLUOKsrGCUwS}uSiJw$?mo)=_WrYtvJZp(;C}D`_y`DqkAefB9UKH5 z;6ZQ*90uy+A)Y6}5zq;`z$ZXAP<=1YKF|*az)|op7z9J$5ukRT*_S&0(0zLF$FQ`f^p}vV zMEyxJwJ+o)vuQ68%LJmaKs267d6{@NzUZmjU7_@qOg54ToQy?TVg-h+X1ouct8ahe(3*wcH1aS8zmk~f3Muj^ zokVMnqh&|P%`v(@T3w`_ zRsQ5BzSYDRsWSa5j9Wg@YMtqR>As58^eab2bSy;M}%|6|DRJXGZeU&zgcXQTzo zrz7k?`As`Pt@K6vT&_Fq_bfEi%(~=F^Pk{7lhem@b}wa-Yv}^DEY(PlKwmzYWxhuK zsnORg3De+rHkGzfOwU@4e=5%ThDyeR=sn zb3Rn_@)K>%zdY5}tQ~iU{4LVurmLv2ZWCJRF%--EI5L+(9_2GsvP9i=?7zJXKsHdR z8h!sPHp0%xf^w+~`IkKxU$yQ(#X5ZXm!33kmDKAVB#S*!m<*>PWvy3QnP*FPVk zt3S(Nk-~YYp zPVxRZARVVvT&MHj7&Dcy^CVj-UqTi$mDgZ8bvbsA*)v*B^h^&v<`6FYJAU(0d;9Sp{qfCfho+7j>VXg~9{DRZS zn{oOnKk6=KdOCLwnS%#AE#|vh#z6=@AzhNOr=A$PbZu6M_-B)Bi2S8m?Qik<-`B(P zgHwz}p0~VVr>*7hR!^cYx{5p2O8?`u{eqi#;=M^rHDaYInzvcbE>!aR3u8J^hy5+) zzr2(b`oCFjUmf&&=roaYa95t+-9~(zwa^LwJhr{O#QL6_y3rmjuMJ(yw@|k-2Ib;5 z;;{*x^S3VL6r1>aKKGAYuGQSIxfb(Jp7JJI%)j!j{+-YLC!c#KpL;i#YcrG=2nltlHp}qYf9)J9TDt(P_6p+QQG_Z$G>Ou@82fyU1b9l1JpBIjBbD1g?yz4|r(0)(8}g$CT8sS1FIP0o`7mz&I25iwh_h7Th*#=*E@2Wj z|Cr|-UtM>(oI7&%;0AXCUH435pxhC(_$n+*=|y|pq;R4xV7q9!#OErZjbVN{NZ7)m zlK_COk9s*y_wX433V;j}&`=0WM{IpYZOMQQhm6qr8VlCb+t)w9KOBl;z3tUwy^F+p zH!k3?1Ycdu!s>nh{#>nujV$=bEUo4wD^+^z*_@RsS)+p$)@Utv_4Pz6{99X{os9Yt`#+G)jta7w zTbo2F - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jp3d/codec/jp3d_vm_enc.ncb b/jp3d/codec/jp3d_vm_enc.ncb deleted file mode 100755 index 7f0733b784a9544d0aa7a90ad9b21c4c654df270..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 568320 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 z zl05trV zjLck=xgYa}Wi&>N&kId`2Wtj>q0y!V^P*fUOG+-vZdmPaei^*(3B)?14pxYzh_#bZ zUWwN?sGHJtz%%@vgqYHGgpS>9W}~w%+X-_ixe=yxoe?)_mUp0E4_j^*p`NQ^VcU0; z4T)zH&pC8Ggu1jLru=%zxryr%J^cDwetlpOJXS(X>H0}-qIsgDv+h1XZI&%&`^5xi zUWO#*C+=f?aids%d2%Iwib-(Y2FZ%#1<4_lk1}h!3_;A2pG7gWoV~uoq@K5jw@j~Z zKsQ1@!cVb~-~RG^#%CEXvHdW9xBNyUhIM@fH3mk&Hh){+ z7uTXg`7^$$vXG`BjX?SeiF&$kB2hP&@lC0VPu+X!+Ecfly7bhYr>;D8W?WPX!kB_tt7ndsSFzAe5lsUKe-+uJeE@GR29 zNWD9vybOFNBi}}B8LN=7ZyAfQ9r_gN&mRMPH_%;!l)^XKX4K;r?4OBrEsn3i_Gu*Q z)mQ5R8l-Rc#J3w#1MI(zZL$;QE_N4r4(Sx6&yX%hx)W(CQVQosBlSh1F8(NBt&#d5 zvEODt&3>8vF#BEhv+P&dkFwunKgoWPI{VboZ`&DlL%JUPhGY9Jw(lXmy$7xb(pN~i zz%K%J5B873{!*mFkj_S$0&EV_UPvb(osYB|QUjzraDEL^0{agje*x0TNb7K1hV3Y9 zw;(--efGiZU)i6sUu2)h{)~MU`yuu*>_6By@VVzR&F7WRBA+upLwr7X?;nV5Gvxaj z`?uo!*GNAh9SWKuI9Chj+Tl0{X*k;aR-`FN8zJl4NT*`|G9Dv!N1BI}fz%A?Yn*=t zJg9@UswcKcuOXd`REBgF(j7=Mk*I$~-74x*Q74M}PSj!%iU}ChBZy^iO6-2vnfCrIZN0r~6mRSFm-(|*l{fLEgGTCx~SLhWubU9M&m3t*V#&V$Xs^706mLgV54ly^IY=^E6wEa4Z zVnZh!M7go5CF5YFw1-1iU)TQ>8!~c?rE3U_goDg-hpw@%F@~7(Yl<0*%VnWM*Ia$e zgqYH`#EjFwWDMv6y*%pE@tL9S9QE{g%sFx%SN2xN`ux5|`z0_N8;<|cBKCTAlNS?z zvg7|=ol}-BHvXSoFw4^Qficla%1EF0jZ@{zWwF>jDOql ze^_p8{2z|jD{1_nKU?PsoacY;f@!wCvFD%967H7-zLdi8|AdL-EnV#S53gJ7`48(6 z8~=}^V8PQ!R7bdSsa$Fg;%f*=K{9MPH(fr4y@oxT07{(smm zG5!Cr+?(ZcbA6=iulGSr|3AEL>*YxAD69WJBPh3G{r?*h5BvK6m?KbrasB^b-rxZ# zPn>P_|4RaXG5!BgzDMMHuXaLp{fQ~RnErnuFm0=i(lRl~>i?suEL~jxKcL$r|1x!V zO8@`qjAys4|35n5w^`FcnJ|HpAcT<@YHAHO?uz9LCenv@H1pu ze{fY23bL4q`OiQm`gN^Re`aXUhbBR1v8YN(#Tz(P2AO`Ya&i?FXBT4*blz`kuk`tU z`v2qHVDzkKNFLUVI9C{9Iq>juj2!P^wPEKrK=O!%{Yia%9nF+7hpr*?YY&o39jvi1 z{>rn!lIUY{Qmji8^f7JaMhCO8blGo=1AZvdRHTct?R)pPVgoVvMVqN$dp~$GRrrUp zS7B_%n88)*4|1IanP|^hrT!q-r;usvWmQTl+@x5C$ijLH?wu<22f6NnOk5xPZ~RsC z{I6;df7bC8Ypyii;4jvUOpTBfrOJ@2;G1TOLzg8h&3UFh=}-rLM_~m<=&M?>i5(a7 z`vWTw(i#3KZt(M3I>zDNLqbgHYRg9XK+YmR>jn%b8}L!>@t*Cl4{D zYXl4SALUY?pRGq@Im}EpOPzW&l?>SaeB@xwWiGc0#TNr-7Zy1*w%C-bO7*G>I! zhnUj!kUH>JbGK7&FDWw9%}nN{-i%(OKI)HMFw~Yg^>g_18HR#X`Eh zE1AYME~weg{aoS!g;CgJ&!&-$d8~w)TdijO4IG z^KBa(gc^`Nv<&}rgR_4O8i0$ZJdCYzFx^eNv=aibf2pqvJg|czeuBG zyCl~tqxrVKs@|VsVY%PR^NBAKT+fX7{X<^GPcghpczqI>^}i|O-VCmJno+iYNZ|RV z{-R<>26R8m>E4YV*F_EIq_iGew7*d-EZ3M5ypuexokry*4Q+)L3(L(i1sSJiaDCPE z4)|3w56i>4=BjyBzUrn?M#l`U!AA3jHDRr{pRUWA>4AK;&3f~cIS%}CORb)B0#B~V zG@0Xw;X91F&k1M@{haZ0MzO_IA37m*&6W)Ou*Qs6nTVEK&%hKi)BENa@oF85`Yw@= zaQ-65K|S|i%lm}3^VHox3w6F3=^60;8`?7q-(S@22+s4KiQC!pn6^KUAaOk;e$4fd zARpIH$hV^W>HI3=_;>q%+xEZ4{=a-u_bGeym@;W@!F;?C%8Tch?YVE^w9+|+N9C8y zF7eMoL$qXed8++3sd`M=9)~HDCU(ysJZSW&L#A+SuxKZk`58vUvo4rjRx)FDaZzeV zvamh@gS7n}7M(^P=L4-}Te8o4NL0#{NmC?EJTmf=pDm805%=!igJ+$Mp9`3tm@=tH z?>Cro$u}AOiX6(_M8TEgZD}Yof~*zlb?by6PKws%hlRQdVCOXo~0D9s;OUOvBM+Jf?8DV|+8r>JE1jQsKv1bwmB zue;x%Y}x>#SQR&aypA@1@9tYy!k*D~>*Kes4{c3b*njenIfV$6F}u7hRWQ3KHKDk? z95R+6jz>xHjDq=-$CQ+%ihPneWs~=x+p}mgKB|lI7tWeoS~88h*qc@|rwjb0RuZ?u zO669xsJs$oD_)4UsziQlz)EJ9kLyy2EN2x~W_@SPE38D>5b|mEk#mb@R3gi{C6&l* ze!-$jYZ2KqcVjntjvd^d`4y7!3*bN z5*ea5t~_qGH?BN>(@PdtqI7ueRw6fjQ&e76^(D?XMdh*No8q@~tBmii9ev*gw$v;u zu%+Hno^74~t>1XRHQ%=6_^tTP%CRjv;(szt^&rts- z)Z2>r{|w8G>HnZz{@E?E|Emd_RdSnr(i2$z_@R;#%#*>|2R@wN-7BKQF5(e9Vj9OV zs-6uqW6T*{LC2dU1%DXW+$|5t!!c|Wunq84^g;KCAC`MD({D`YF2KslQp}6XDC5mc z)3i@Sw+z@U*qhQOCUgAIaim*@J8~g@w2{fgd5d}YR$r_(GZB{1n1{5XiLj*3KhmZq z(*$`lFhQ|MZEP|JPMm1@Woirs+T28Wv+Nqf?r|(zy5dKhoQSTP#u%lIPEOj*zD8lNhJ~r)zBCH;wVRTaap$Mz5^Qg29im(P6x0SX+k<8Xt5^aYfx<(qCleR<= zhV>ZyXj>FvO>}L8wnh;@8=sW6N11~UILKb3X0YrVueL}LU2~0#O53E&aia%Xx)$mK zn6^q$87-mhf3VsvMOZ7LjrKjv8{Stb;d&NrnRD^Yq(fHAJD#CVCpU1SNim;9vLzcEx5w^S9eA3n`lhJ%q zd}cbSy*O>JGJAY)EVhUG!lEr!l()0`U#4wVgzc%e@U+#6urBJWi?&;tL&s>pu?)`v z{piw`E28VBF<)uh6=B_V-G;Va5!OTF-qQ9f!g{LiKW)Jxte3{KrEOS*_15()+KNS3 zALtwnRvWGe>kF>|N2*O%g!NN>d)jzK*KIF33P0L>MRfgzacXD-7GVR>XBDeWScL7Z zv2bW37Q}&Fh8CEOA8p2>GWM0Z_|b+e%DbP&Po+&+M3<-j#b{#|VFP6bezZA@@(zO5 z#Z0w9i?G4!n}D`xIpO_01W{H`R@<})8;a;c%hgs5*amxV4Ab=-+O9=(!-esWXv>yk zg8pTMFm@7c+akJ=h+%Y^+PX#9{&FgQw0*1Q%W^8N*L_H+*n#S|b3FJ(*hKX^Nt?!q-@)n|G_)1hyoai9OWHa{bW>!D*iTY1p z;K*`}`bvMDSl9-~YV43(9c-z_C)q%3;JA*q+~d?PJO^WyDDUx-XY$NHNEgbtOkf`=? zN0zgsxoK{mbg;9frD*F7!a4`e0kVB zY@Y2O$1afj&HbjHgRPQl4So)GA=W$ZHXR)7BDo&+4~IF}#d0fr#|$GD%6y63412ep z4&9}4qq)%}9qcmLv#&Gr9PDzeovt^l9Bj4RVeT*wDpt$yORkW6&AsMBhwcyZpn1@2 zM7u=K<&{{oeZ)*=TZQ-d8jZ6u*uk#Sctsr@Y%O#`MwrVTepkyFjQKCdvmfzW2QR4i z%8kS@?zGRxHF7_GO>jN3`lsefiv8cU_%e7v1~`4rb@D8JogD0Xc?Q2~4t9e)iC<#} zyHTFT?B4*bHnmGy;_zE9FX310 zV7JSQ_-!VZ8b8#w!5!+K{0xWRo$%QDip)j1St!G{%U$?7dRva@fxP%Wvw829Z}I!S zJFxJ&-6J34w~BNjcCW_e`P`wq4>~#@N(YDTe)Tb4j~J%QY#9%z4bm8g?m_t)zoQ)N zA)$|xpB(IA_3!bLgFONbjUVJA2ipJ*jUT1C(?>kY7q6-2V2{Zb{4$-qk3-YsQ|U=8 zydF=eU-Y{jY@^1l+T!#PPhwnP%)ZX`eM)`TpN?<8sQsRn!_DF5Y6sgSlc6KFyOZ}B zjkj}{L-$9G%d>@8cwap$)1Wu@0I^W!=b%e=g!#o|Ro zcAS1b{diD=NPmg@qmd>ejf2k9|H&WZKc@+NKQ#S6DSg|8Lax4$>1Mp{qL zVya3>rGxau1PxM%yYS720e1oQojSRqZO4>uhtjna(}|^4s^otFp?h zGQ*vI;x&y!cB<3Iye#hSn^I=V%rg%5mK^B2tx13A^4 zYHo7!{#j#mZX_1A%ZGBBIn9i6@_r=C&2m%d=LDN9)Hr*ft_ z({ys`_L-p}O>bA~Yv_Jte=-Q#8s_7{y=`6>B@GJh#c%~DgwF`GaCbt>MN zmtzjq`v-jdnF&*x(CWGd1$q(bU|9 zvycbA`D?>Re>3PAHd_K(`1WrG|NTvm!uAx8%($0IfXeD+U18L4RAaRz8FL%J0CE)nm$)!1GEpZZq=gWYqrt3bCFyw)J! zmDpd01pof{Cij}%gmew$y-~dU>);1_J@VX&JP+Xf9msP#&OeC#JCSZdx(nss2J9j1 z`*8qj+$~;>`;qQL*-s_3V01kz*TUHJ%N6}%6+7g5e;U@w4< z@c~{%dI|I&Vf$xnKg9Mmoc|NjJE$k(08D-p=`G0nHntz2eHky{J)~!mUPgKz={clV zkp75-I09#n6Yu#0P}XRac_7Lf558k?ZmjyyrXTIVmp1)te}eg?X27~*PWVHlVMtq$ zCLukIM4a@2-*4i?NY@4PWO+z;;{14Qf5P?)q)#w!_X^VYNX>y?1?(~GFU0-|q#~qC zk!Av0f;0qaCDIj0J&;mJ599nzNVTy4B=VOcor826j*r9kU~F@6{?3iqM;#tUIuhv> zV4opffc@)ujFgA845>a+C!}9+p8m{(I-Q4c*NI5CAw7W<=+Xw;xXx^RpJSu=I_vgy zWGh-LeIDca)BQvnCGK-P7Hqkno(eEtB^LMeffAlx-O&ah?FN63=I8T0TukW${0`jqrL3y{}IN0wvKx8E3qHKYD zJQwV9yBXuFuxBDsYZ-d-4BXZ*KjE{S8~j zaqut>VEl(q@T~Ekr=9!G#0!nn2k|3VcjgabX8xM}Ackg;Cw@%dQtv^=fd8*OPM3$* z`H!eS*WuY7ENe65W}C1*=wFTXV|hW|?QH{DNyGi19fNH;AL13o|0EvobAsdentyyh zIG?^vU;pPFv9o_?n= zC=`84MSo2{`)UZ~`rZBy_bMh5>iX+EY%BWz`ePe>HhdrW`tal=IY-72!<;6X7=KyP z4!(Z*trOY$R)g-qrE)pxT7pFBYD#OY$v)s<^<+jy>&zdVG8#y&WS8V#VVXV&s-jycUIy=o3!YdJspR&qMAP`>ukGkJP)BC$}G-Qh>4MzYkAr3=i;7JI?3DbB!QNYoxA7K|W&f;~-yfJ~$?yK;CVYPkHIfP-ASF z0`WRe5pNHS|8J~>@qh6$@ZE{=|0az8|Lu?e&2Je0d$IBV?il}PVEn&3#{bD3jQ_91 z_+K#o$EuxYF#a#X_`m2s82@+NiSd66jQ>}@kMjKS|M34{{9n8i<9`q1e{;ZA&wq1x z`_0DtD|+S(bUeC9D+i;Ow~6w8lQ>-lhB&?CM+d70d)+*pbBp*@N93@6QV;z29DE6S z-kx#@3;8>NBiMBAp!lX z(EmS&sVQPR@c$3_EZq+L|0e>v9r*tb>k;$+xi|8vd@=u@VYxB?|1$!*Jh>7-_5T^t z#r*#hQ+_f3pBz)9Sl^ic&yX(W|8s0W7xVug((S7{~yxD{C|f0cHsX%q>K6g59N#b|11gQ`*r^R z>HlXrzMk+();igN`9c@Gfa)I za_HConRz+KpjdVI=3OeQ{c0phZt#+%63bkV@_D=u z<{g6Akj&E@-%r6DPA$x71o1kzhX->wLH=M{kx#?7Fb<6K+!>m|kZB@PZ-0)2^DXyc zpS@$VcVbIDPPJ2E4fCoI?;J95Ro&CK&^7A1+N^H>}s7ccq?ST>ozc z*5atQ8Q1??0sUa=3C8vRcrQ`cFRuT$Le5rQKh^(3eQg=%sBU9i|8E8Q^ucDZQT@MA zmh)7XPWAu7yywdXv%%{Bjm=k`tQGLjOdYv;{i8M06_~}MUSC}QZw2lg>eqE3UD(bS zsScm7|F^-)cQLN(daM5z%5sV71omX!5W7@$0+UX;m#N-iT>ozc{MA#}FRuT$0{8G; z<}R!Mm$OCnURS_lJ@pvl`hP2+r%Qduxc=V?jMW}Bk2?B)XdZtY6Z8LFXy5$_Jg4X4 zr~bdg@zW0ce~0{ji~sMS++~sf@6myLG5_BzL&sw=|KDM`G5_BoUCjS?SdWhM zU)=w9P;SiscX2=$^Zy-=?_&PH!*XN(zmpgzr8w^0f&cHY9x?ylA-|aa?~pF$|J$F( zO<)WX`TquCisi=qf0qXJz&u#s|2zC1xE?WMeE;9bW!oj@|2r&q2ljth)3f!B+5ce( zX!*tbe}~s&2ljuwMp}=!{hu9sCg7)QBz|jgPek`~%>M7lpxl`K->87!4($KJ`o`@4 zi0SK6g4$F<%|Lq@?yCeI*fNlr&e{55g z?>G4W3a{G^{C|blE$06#Y`;qK{}u9!`Tq*rFXsO%q>K6g3ZLH{`2WJUioO40{=e7; z+I~Cm{}nz*G5=qod@=uDpyPYQ_5T%MztaEL@?(DY|Ao$=qBT&Cz5bVQu003-09mi} z42O625*XNI9{#`RX6Crevsn-fCiqQDW&b)&BA+VxcTqYDc<1F%J)# z%95?No5K$QHhV#t#j3&5u&WFpR-W=@&cTXB7ukbY{r z_3-0Y*Tfgsq4<4sC@{ncwt4HR?PhJ#Ax^Nx>Z=`OOJW19J$6lLAhbd4LM)WIq1w4_ zA-@o7q;{V#I9Ow~m%M-&;`-P!nyB4pkwa(gYbO#zjA2XHOl>I3iG|mwx!UHQL@aEV z7HSLns6*FM-_Mt@t>918@@u8@N~aN{uKUr+)4zP4>;Awh* zY$6ucx2@#i*M{XDG`GmowNo48>q!^N*Iw;Nr#N{#s9p37hi*6ZHG7|fbyQo`fqH$% z4zXqIuC~6T6&vTbX(zSoeV?-Ub6oUrOJA<}pv%o^Tf~08Cgyyn<2Pv%u;S?@7TXhF z%!_0xvHbjlEY=0{V@Jya%!@d|7VE0Es@D)hJZp<}Q`^#$i6IWO#k#8vYA5m=JaD4L zdZ;b@AYv1T4!2lOe5)^zubeV^soi@n>BeGj72Ux5Rz7*!lEG_qd zaTe>V_Nzw|3+vWTZE3Fozbx3R+4kEDJ!8X9M#0NrCsXWX257Kq}YC# zMY~w0k&bc56dQ;y(bHuXu@w3j#fIuP%R|J*=8v)10ctPlJ=z)L-M-Ls?1$7{yyo4Y zPuUgQKH|0L1zpYF;$`=M0!dHkMeZqHP8aEm>mMZQH=cm!?s}wGkPb!)&T)I?BC9V* zok6DEf$fR<{|GwjP%hqAq_e+Y6Wcd&e_Vz%3uy|{QlvAHo<_O~dCxD}6Kk!m)GjJSF#OZsMYp}QCTpzR*=M(sz zpw3i${*K4#_|E7&ouczBg1OY;GH4C11>P-9Fe}6OmfW9!KKs4`yKi9UJNpj1pM@uE zGsf$rse>MjHjvz3hTey^-`w8^`&S%b_b&neO+KFt@Hx)sQw@AHP8{f~;mt(*O6ENt zc>`PDnvg+bmjiE!x5Jb*mZm=Byl|M^p9220&u88)$jg3>`z`S-YfL=sd*HA7F}lB( z#^WT-Ebyn@Dfi2f_gr7LOvqNc#^Nndmd1+*O)g~khhO*VsQch1md1epgMNK4ggori z$+IzJnCJ6p20ru|K)fr;Qopm?61Ai%DXH2ltHjH_;1=9T#9zb`k(&}7mc}dW*WwrVCiuJxlXu1Utk0-X2Z$4Fe)uV|mNU-~?_Uil36Sr)f1A+fw*pZVE`*99KmugcFP zWeen^%)vgl|G&QDr(tZrYOuX$``{a)8m7$HG?{qbuE!c0_dfuBsZY}z`yb7yc>I3} zCIW+b3+Cj!h5aVLjgtZ+@MIi|{V><4F?$uuMDy<@?HnveT1yAH2K-28^VY^3)E)A= zVqm3t>w(({xeD0lNVHiS3O*f?Mj`Q-&k2vaA#t3{@6|g&`#93eNW2e-{fPaBpxI=; zG$T=OEWv9Tr(sjw>*y`PH+W`<89c3cUeP8w@UKBxPD9PN-C^ZC_O zpHsD&*YDrYf$uoRGJXSefh?SF%6 zNE$m>J@vJAC+mwi+`LAsq&}k09V3Td66VkU7Fy;HsS` zwEv5+mT0|O)b=mJTEX7tBq_igPgF)qt~1w}#SYe5ZZJ0(+5<*;+h8U1A-R=p70S{U z+H5Dta;II|>Ac?QpwqaX%|Kj-8H~=6e_9WF&6fHYb^Qm~xSqThlrBT(`mZLP$OemL z>)b8phWOsvR$R~7h10sunp3o(w7Bbk9JnCxLqFL%%kR2tc&qFDUBf%50Nk4IngZ0V z{;pwdo$T)#-s*CHSFyGZ_;(R^y5rwPtkpSxrSsNUpRwn9AIz?5tk1Ad$k8=7jrAG! z3AJ_oPh)+C&p*f4qiw9u#2UZvXoykCU>oZ*Iabhz zm3~bR-Wy|NKAR~!R^Aui1>X=Go3H-0@mOKqqpx%ahM~p=($&CQe=qzrPN@G}*MLm` z$ITiibYgy6jtOcY2jdEAoKU|{sDbe-eZOiP&XHqBSvnghRO4`l{Hm+(zKCStB*N`WukF7Lw=3rLHslh zXJKi9rE8|+NR68r(zQ?@&l=}4ETff<;Wf_X;#7Z|x3ye}pT@a7c;sMX)HS)Mqx7~DXu5m8M4;yIn?hf7NyF}wx4h`D0v#!%>{7S#yrkC&%{&0-~ z|3WpShveb6%)xr!sgvBuGbk^8n_hPMdHU81FzyF__Bh|exmIqO z?nb-3gA|{C?T_};Ik(QR>&Np&t$*6N==>V;SS$-Gh+XX*nK!`4a%4CBzD2vJ{=ep} zsoxHFAs=9$u8!=EU;4aOd@d_E$N4VSwW7JG$gcl4*#C#?lQH{$J~t@}8MFUyi9^L= z_Wz+Tf|&h(i2eUz|6dEw&x!1B(LBxZyl#N*0QaZhiN2+y-A|%dnTk0Y;x+IDUEa#> zcf%9OxfS9y!6%5@Tn&5%&9rzs%*mGcd9#r>2lF4K{}A-lXXpM!DC=jRPd4x%hBN!P z+x)URpsYncpB(Uc+LtXGvSkdhd~QQt>a3Ax0&`j)_;twyf5vmSa(dF%m*FGOb1say z!M*aBUsfZOMIWogZ%5uBK63-e)4(t5M&z~gUi6^TMP~c;?SlH!E`fQ^KwkQE<^FBh zf5qqD4*VbW+q@BYcJO)L44z{Sw)BEow7q>f-vj>CN{d&6%?17JlII`5lRi|r{~-1c z^7DGgd+|JrZ^AkLktT(*KJjHpL54nlx$D7ys-HK3yes^=bVgn1Lza2(1ph_(cAwD- zs4qy|Lp!hY%Su9X7pgU;a11ztrcS3I6(iN8Z|yXP7U;O`!R~m#q(Eqd!~n zzXRn4bBUQ~=O9jW8{|FK=a~VXhxmMM0iW!Y&D#ci=ueh>9s-}%yW4$gy3O-tdmr>c zENfUs$!R`M1D<#I?a&tOP~`K!9rT<0`evZM^shwzyyI5+d9#o=h#Ou9Jp1_NHb=Sh zeLlB>PrH=O+X`~hFE9Dr1)7zw+Z1`}SD5>^ zVt>6)Pb0rIjl9d(+xtE#4?+^N$eA)U@e$2y? zK8fqXcqQED7hz()-Oof>cl-4HL4S?UXAJfa^~mcu=KK(wRvGdPt*)DRg zpLZni=X{#Iv451$rzZH&S2AT-4?eg0@?V4fQ+)n)vERX$%|Ny{d_Duf$4s?(yWrk_ z+AnJ~@VzrEZcxh)efqtC_w@N>gU^Y+3$bWcL{%X1LFXt;HBHl(RnM zdBZPjEO>HWnRqVt>GPQT4})fcpSKS3Ui$}&C-8i6F4^)KE}!~*Mj`JgU$$zHEdd_+ z=!qED`%b^y2H;7(R_3jP=l3jM&Me3|-7hN_W&PdfIRZR6mreS5*ry+8?%xYOkNff@ z!Jl*B#Os0vgGt>_V876pCkOKEJJsS{(azN0C4F_saOZ_~zd87<_2sD!d5-brsR?Kvx4fTgflY_F3@#U!wd9L#BVQLvu@0c{z zK-0(PpNYI*_&l?~lQDfrQx9d)M>hBG!G7KocE1$#Px|s_Lw@SIlBP9ycJbwz37YeK z8L}Y55WlRo!09KO^bde%o7?SvCp?2c`7&ff2I{twrUQ81=(kTTw9gqO7SF=H_hriN zC$XNYF)ctp3U#CoEc5P$BgQ-8er=R>xG(>kkb(ZYiQf;L--X=w_$A=WUjmwo{IU*5 zS+%bWXjV#rUzc^Dc>`^WVV`6#Tc5Gfm$Mq=+Z>t(;tCTNuBjA@zwKTc7myYmdI}+vI;>&h0WTXBu`J}*qoljpI^zZoc)P_8N zgPf$PjrQU9GWX&6P^vYy`$@>tvbEh$pgouQb-Ws7J>r*j5Xz$dGxN4WS^Ng$eiQIv zJSMx3K6$F$uL~K9{p;Hn*OxKgNwX9(EcEMA4F3CEX>oYQ)bBsiGy>1>eEG8>f7jNQ zCI_-n7n(GTGW5_?*j}&Uy*gSp`*I!vITy@Q{4V5vQ}DdpuNQR?Hz6>vL zFVA$~2}}|YuZwc`Yi;*ypqAbQGVp#)#_w~!lMOpj~CQc1_??}6UDC%;IUv6ELJF~UL zv(P3({JevamvMQRcQknNyPNyXz~^CK&H~8ExJktMHGP`TvmSW%^=0E6%v=67$^d;s zUj~5;YQu@Vy;0V5zrLBM?^S-e2ZCoypS~vOxvs>rx`EF{e!07WW}csymJ>(#@-G0- zFZ^;Z1^pd9&+(u?v$f@8P~Ug`x=aJjo_<-hQsA5d%W97LUhmhdA?n3=VZ>X3&vL)q znkaW4KW{DMebO&$3~285^EN`>j00?5>IWD5b;&{dT;0Ow+8aI^6PjJcs|tH(qu!1Pkb2+=s9n~ zyludrw%Oc23HSt`59a_lKQJ5H;h?qC-3yE7mzB(!T{3(6oXVa5=0s)~xx7**Vtvjw ziutbKY$KZQ3eG`v^IgH4%~IKGQhrl&<3~N;6_W3QMO|NT8x4I|$Q&#k?V=X1{N>yu z{~LCY75TL0oaJvRn`?YQ-uQliZEG8+jqh)Zeplh~vg7;d<;BmX?+3m`16$AdaXO#$ z?iWdT%RIH+ z3g>7&vo=vLInXI1!*s+*Q87Hfp61OqXJW1C3YLMqR+j39bJB`I3QJeZoQ7}PpPR<% z>Y5JtGEyw0YiLf!n$&Yx?}_*|HJl3%F)g>HSq+V+8BV!v40VDO3;A_0tFStBfzt-N z8_tD?nDXmv&V{zA+Ny&=E7k7&v9qk+;f|hc#ltqi3qobXpC9$KzIkRRJ z&n^!Tu*jbkKbRdq2+0ac=LR?!g!^TsC56Rh!I}BRWyR$S3rd6IiQU7!9^qckU=IT$ zw3-yoESR5aKdDFWK2s+3>eg*aaC(ky)!=;mRLQIvnsw2f`9+pI)}m5YK7T=Bc}m-6 ztFx(2g|YUIm))Ze%5H>GJ8hZ%iTFz40XQvStW}xz*&c2 z;hd79paJ6<+jrzqd0|n0Ij$M+0G8D`MNxL&Dnn}f|=; z8oHG{L$@k@s8f1T$t;ISH|MCkbL1TKh#xI*vMq43E$AT_rrSG8ctfN*b|O%O>t0lx zUr>J3?j3pE?d8{dApS3`A@7jg^=a-R^?L_J(&s|0!_6Vz*WNCum5#=Lj-Xgq1sDrX6k7s^vi3 zHX`CS5)f_Jbo<}X|9|L9Kj!~GTqBS9{}0D4mE`|FEF4QRJU=WH!Nw+f)Gi|!VVoZ3(7X~#pcS}br| zAb;y#y8G6pblVmCBU9h#N3mj27*wR5sT#5=ojO0MeHV;NG?I-oZD2gMzLVpu(b@)*pp!O)gWOhk9 zR6Ltw!!$ZOU`zv%ISm0>TVh%u^xx@z&Qm%$@ItA|G5j21Q{v?ZzN{eT^rvZ#OV4O=a;()X)_93=y$qZo0J6Bt! zu%NUse^L4DIrC?sVSy@O4})@f@0W&U@W?s9v;t>k6ywSGvAXwVVdEHo#X3*y7DW5x7bG2jqr-QYC z4oF{l(ZO1(|IbH>L0{MMYXz+l_zvs@&qvg0-F!g1hyVEAR{l{TlXWbF}{s6aY(Joo%l=b z1kJA`83M0%_Al^DwdVsOH)Fl4zrqtC>307rv4_iDR)1WbwjJ-fQpR7>B`oyB3vSf- zpvOb56I0Z;;@|k~$(5%hmG&?1r12;3zwU+`dcmS6`n$j14Jy|wkn5|~)Z63VxQJlu zy}Yd<7nz2B#-xDNLBbu&`*(zcC2`01u<<%Vx-4iMK?iUnZ>xX!d2`gSg2v_u>1wJ^ zTlQrp#BwDMKO2Wbv_BE}Za4@(-mmnF$9tDs>LsPe$O!KF01s%OxLaY&4Bq!gKL~%C z?W}zxH7>XLx4kR8%}hIUV%ZaUvGLV$weQsH_$=h2UqyS$K9v=6+huaGw2onscMZH= z4p&WL~a)wZ8_8ghMv z_OcyQC3a6cBZNz{jJ^6zAHJe-ms>t8>hH5Uu46KG-*?8d75qI6x$E-1p0Wu2>23lR z_y2Psyi31C4E|m$orkDi%Z z-Cg=bqA)bhqxYYta+N|Z+R=Opi-;BS*O(-YZ_0}u>FzIEVt>1$LrY4-ns=*Q8z2{b z*!+h3D_!dU{5X}D6Wm{oH^3ir{b2mn_&?|UD>w{XwKXy2qTNy5EkUer>N&Slo2Gc5 z&=y_+)hA%M_C-cuI*b!>x$DL-t}&`UeTdQT(ArR+-}W&{ zsh+5nP&i)qwY^d#tW}h}D8k(4(OZ zk!4NZ&SQsJBD@< zmac`=O*BYw?9Ox=cwB;{V|F}W+`fck`ieRUX)V(2NYu%nh?Jh^HqhSZ=MVO2Pdy3P z9Hcn?MHuJNPa4ah{vgLuj6Hrc(lfatf5U~(!m~rW?BG1}r|W74ehEi`p67$(?fEdS zh)+7-|KvDbPjXk6S5^44-oG{e$L)9zf@Wf@1H@c$WI@ilFInY0+X5R?6|Pb<03ugF$P_Ac#pe!=h$!95*v~4 zT$XK6ZFujiM;iUGXv>y=ZFywNcOV+l&yJ%DA=f?gX~*f|4cTrR*|&mU#8PeL|NYcT zp8kVvue%{vRr)*Zte*PbKKhBOIgWl4a?#IzOEDM$xBAsh_p3&@>D-s$<{<-p#zels zw4AxRT-&R~M4i@w-PCfKJjd=&!c)L8J#X%NoBUvwH0tP|9@f%=R&<6Pd-olJ;7>|-s)QCX#AQG13kYYzBOIF&MiTQIVMZj46_sCL^1I5 zln(xI5vy>q!>=>e;zme_DP1pk;XT>x?$GTcdH5*?VJyF4GS(EDQ&}!CZKnft9z(IP z+(TtI)5jbI-cdaYRDV6hwA>@*dud?uSS}t!%Wtmw1X3(4ccI+s{lhzy{K9wr5;-Ed zIa!Oc2>z7cvGUKv&xzBWdYr62)j~|^&O$88ugxV+`(2{*ogt=lSIenpjZt3|VLRWf zK6gS)>F$Aj)y)i6E0n?3b6fqK}ss$;e!CMUB=2gv5F zXE-KREG(m;>h-I?3}RYFW5aQ(Vxi1U%}LPfS05pvEG-Pju7TeWdk>||GC5KH;KMmARw2RIao>5pd0Ixt$H|2?hr;D_u8p9%9w>Ar{_4JxqI8-6|H=qZjNL&XEmH z+xIo|;hj^lupa%*#fd8ufnOC{?%syJYZap`TJFAPdg8*wcwY0cT?QJ)<_R&S8)E+D z6(w$S${l7F%VJS1EO&&tKk;!w{ceQqx4)r(*AP>Fqs>)`dlS>0at~0u4aIn$D&2T< zmAoQnW1nMCj-M)usZ3p^Krd`(&JRXC;_;vv!+H$TVMsw4J42JMd&PLo+mj>xe7uZv zVOy~pi8R}iV_P)oap{YpMkJn{e_%gKns#x0x*PtSqsY|!L zHm2O^H0d(O_1boH-M2@ZE?>HyUq$y~MKp2w;^l4cUf3R8x?Dkx>7JU;Wg?^Cvy%_kM-xKG#&c}7VJ(0L>R}HBEiEDFQQ>8zmTmOJ-I~e(p z=sTOfvgyNwen99ig#JnB+nTWxHS3hl7nfOI61`p!r~z5}psHxADi zw)BBbpVyq5pr32{7vT31zlZq!!?wC`Bg)AT*#mhw4?)}V^N?tRPk%S`g-xF%wXZ~7 zKz|KV3g6P3Q4jjdIunU82(G}EKC0*^yIL2}AbqFqtx#z%!!dm% zFkaUdB-*bJM}2NZnu4?udEQ1k75kU*7^yqbJfsYyW=LP-Jbfb2zMnSr^ueDeN)kQ6Mak4mn3~h(*GCzbwDsT*^X#~_W|c4UdOwyF?jzC+i&^)$M*)`3#V+1-pRj~K6tONFM72l zt^xY2iuMC6*i!EFefH(6tK(UKOg#5%k6C`eGuVCwrk;S><#<^|0w(hU5h!?6TK6?zz37X?vwT2dN1(9X0eA5%cRr`{DoL- z1LB&T<^{eyEcS%l>)q=GzI`mVQFixs_nP7Uj%0pP{$>7U1{1@0mpT}0tYk>m=1&tYvnV^@G`tdN5`+n=Tgn9=Dq1)UmzYyb&ozAqwDq;spr-6=zB0XInKW~ zzLZ8@Babm$BD$|6%ggep>&M zgFU>5?_>`ioIQM3dzkz3w6veU5|EIkL^up&s)IzcC^dQ$a^d3??Adu zylIc%{G&McILh6CavuZ!1kyuD4JKlF`ykWu?Wo!PpU4Zj&VfwSf2~q~kgG3b z;(AP#`h#2#LZ%Z_RZ1!ypsa>W)PJo~e`v3tA=4RctCUn|ujz9xf=twZtx|txLitUQ ziQ~{J^=HaEl|UxWyHu$^Q(DjrGF2u0S8X3NtN19$#rdl$^=FFPW@65k->p^Z&rBRY z6>@P-xk~+^|9TxVagMu6{h7g~`}lL^RZFf8b6*~edqbwGH@+V__*}@v zIrl2{XF3*s0J#`Ts7n2rAw!o#rnAOXDXB1?7+i1%Wcu@gRZXrThkXl~{&Y}PlWXpR zpCJ=tZB(g0Gco@e$iz4;RqD?S?fK9ok%Nn>lvKFyJEzJZ)6Z2-uA<`XVypjJrCJQ_ zHDaFCf2~?_P3-sR`3iKS7y;)q$Ntk?iSUxmd|MLK-?)UA3ux-YK`99E{%;4pv|7F+Xvz2CAcd zw}UlQz2i+z8I3e{D3;=4ZPi%)b-(M-HBmb1oJVciRO!BR=$a{A4~MR~(hYa87Fanu zN)C6hmWs`CuvUsa2rRk}Qn({$$-f-B)@r9-%ejZz=-P052WzWq$a_0jJJlD@LtCMY z4fbAZk2@TZRxoFbu142H+rWSK68!oRqb&^9PTRn8Z8?4g4qaDR(Vi||mxOr9qV`O&*K`!^RfJi;6DcK#aN%T9}E1~HvkqK({_l*rNv$0k$Q;Z zk$OV9N9r-IN9z64JW}IQG3W?fKv#Bv=795zN{_bfb6z;76t1`{TkOb9_~dCN@D^U# z;VNSMt+%ZCyRZc7scTo3Fr#$Nw1U!ISOxn2D=8?2+pk?%2;;)fDwuziTLj~Y2Jd?I zubmOqiZL#O_iGkS6*@ZY*%u~_}H`UKNq{Mfbf>xbw&7L64Ikw1@R5a zQU$Y%Qk4+`LBkD|Ym|kq6~$eciHGk7q)a5)vgP|9-(Ix1@$367dGXYr3&!qMaOaP> z;rKVPf$H|kDOhC3yICG<24!JvKfp0`*3~Gf54Mx>aP-CYb|mPu$T{TyhI#>-I&oLe(^$k7ETNB!-A6Q*PilJB?c@DOSv;#1tLlqhAkYjU; zL0YA230s9}p6V>}qeihd(kO93g0=$&kj=XrnqZ3B6DX#1o#kS4t-02r>#k#S#W4S4 z%jhH5nP&{`4-C2@%WrS}22zY=D8E7S7x`Lk6ryrRYM-?n*G2Ox-8g9BeXn*55#1sB z4YZbYA-^N!XK3zO-OHr|MDrHN1zv7~whv}%Aj@eJxWHKd4~28W?DcuSM@O! z3+Wcfd~<=J{Y2ExN9#A0Vyv&0yA-;>r+cdNc?vQswoEQfT$@mx&-?&8Np4DPO3(%) zs_&^%=pE~zUea{6QL6zlpwVw=PAKSe5$cyGfGY9wc zQAm8&xV^zYF7UUn`rBpx_9NWud^ZI8sOkEp@85y7UZfg#%2v9k@pI{VtUR6!848h( zM4E@RJer2{y2_+)LM(B8-uIN6JeMT?XFP1LbN5 z%Z8TdP^}Z?x(DZOLweHR@|gP?X=VrG`XJicb=T=iehC?_g(_6;SyB z;{uT<&o5ZC%fv44z6)9BSAIamuu;l;>^i~m^;(!dO!?2giz#;c`=361Xe$*x*BN-H zjaA#J2+P6y`WUsPim=+434vV(^M>#L`k0xUskT-TT|;>FJV@7pBdoE|{+ha4LoaxuSFl9U~VwSQ3^S`LfB$o1x$4=R0(nG8Mmkhb~Kf zf}ZGL+4$5sL@sc!YC6un*1>XgOgqoPs_VD@FbAul^X8vTjn|{5e*eGfV2m_9R@OOK zZP_2cO%7H^{heOoV7WT)u-?JyBAT>~zaF)p^=-VjBVT>BpZahz3d|Hs~Yz-Lut|Nk>LVCcQqhu#rF2f>6MqzOThVhBlqU>Zqi0*VE}f(6Bn zV(;BW*NO!!tFF4PYhPWvyY8yncU}3t&$;Ef6GQWh``z#VzqzlIJJ08ynK?6e?$k49 ze5|$Z?|MVR8W5@ZJoa#Ns zoZ+M`q4P>VbFdC-dwHdkj*dDvl#6fzC5|k;XdnBS`hpp=)6aw6tSIy_#|p;2KOgJE z99(Z5$0gWx`ra9O!c4d{B zr4BZn-C5=4J15=|I&Uz*;X6X-A>McRM(TXU9~^9y&P|9;Nw|hoi*G~La!#duTEidh ze=SP*2Cmr-HV#WJmzv0?kMd2>^&Pcc6Zt*LT)^d>HpqBwMlx$M%6P3u7_ZI|#%nc< z-@~E7&`{OnS?En@8PC7sU5@1Y`lJv0?J0{baDNNU5{%z_pd#EGp)K&f0i6z32-SqLpfmU; zuH@bk8Ufu8t%0u%ln2!({wdHcxCcU$p`Fk&=AUE_`cGDqrW28gdrRI^oNj35&x)tSh*QZJv$73F3Ao=@4Z{=M|J2e@c^i|?eLDBY0W-NT zVNlfc-1Sc^CDb|EnD@!O3PK-~Fy_QjtlFnz6=AV&IUwaI z0)XcndWR=nVa&~>>}N=Qbbt7Vv1^jgq|XX4p7p(&9qG4V4d7NR9Y8nTO>Pp7{AG5+ zdIgb-bpiRy;VqwC;9J6wm9I|tjsMl!6#wPBJFfHZ_m0QfLPqj=em{SeOj?Z>&Pd{q zAom2)^HG{H3yE7!h4|zgCJN6bO&1uGy%|dgTZI2j-bW2MOv1Mr)|(pheXxdL>4cub z*CBKLqW6@VQ}5VtxkSm59ConuxoU`%tI_?gbP*`TYjepc=W&eyn-Ou^sn% zp3kF%Tn{C1zr%dbSf0tB@U$S4&WFTZ!Sl7y{m>&2FUs`hKAC51VKx`xu9M=+KyZ?c ztQKRr8@vb96FMB~2la>2pn=dJXfV_oS_J=MNT!)7eAM8~Q$dAL5mXG7K$4ziP#IJX zRY1!j3OaQ+brZB2;$vV0h}@7A&Xb^%q4m%c&^6H0&|jgyL4SwxMGj~&v;-=EmO?F| zR!|$LEi@i#2epSJ?>ayop-xa&=m=;eGzvNrN{2F_(a;#^W8(S*`V{&M`W*TK`YrT3 z=u7DL&>x_$ps%5Cpg%%?g5HPz4DEqD!b^dwLDiwdpj4;^R1>NN)rRUo4WUL*b4bcZ zXQ&I5ARLN>_OmIPSp3rYHMQTLiF*>%4H^xNfyP4PAZF!gll?Ze7k7#+^P|+k5JgR^ zIf@|G$9ya9J-E+}d1NnsZ=_E4az#{XgqB{?=vq5N&PQhSjU zKQU+uU2E^RVk^b={+rbV^3|VXw^*^AVqx?e2y;!U=ILrrMf`dR!D>^s$6K+lB60Y9 zb?J@tQkyG^DPMiFi}`=C!J>XOyoTDZiZJDC%zXG^R_wGS!}IM4M40k5=biskZMjHz zMzI#=I6KdZZ5Q$DW3AY~-^>$RFG;M8Io>X`A2@l?-mJ1GS=kqw46lQEANvtv8z$+u z6LrB^R&2#2v2NyXHpQ#w@b%=ID6?WqM#A&+rMHd~B1~oO%Qw=~KH>27)BbCODPNjt zU|UIYxX@Wc5{+^6S2SX z7b|vjBs@Q_Ch2%5!c>;Ye5duS*xE_PJB|8wg%#U7$$6?Q)1JmeZ1Ko<>gT~MzM)68 zofrV`_0R_hAZ}?p4#i#iM0*QU;@ew1;Tm%ITz-e)?C&1>3GWAG|NopeHI3$L%>Mu8 z5Ubk$zu2&n_g0^p?bkFW;?AaKdxeTk+;@Wy>*Tvr8F7`+YZ1IHW1AxS4B}4EZ>~iH zCGN?L!^cxOihD6UVs}j3bxbcK>xVR%X6UU~SHFFTkN=wRrDrERwc-CVkRb;dved5{`4c--8*b5{6WvO|YmyJ5D=O|T`28*j zb1{A|Tj1jjc^eCYJQ+xO`vfx7LWV^_x@wWG8v_3N@Mi@1Qyu<2fo$stUu>93TrCNI zSrBGdcvb}I%|*_-{e7N1c#2?_Z}t5l|M2Sp+?|pCy&#RBz>^u|TP^(F61=aryf4wQ zl(?FZ#(Ng{?ncOVVjy!}WR~8$@N`3l8G+1Wajy*GO>g!uJ2{ZK1#vwZgd?*!+IHZ# z9`bw@yd#BZ6nPt=UqJ zES3J|mu9dv{ro)sbiAqXk!*|$v2#2OR`36&?yziyD64yK5LT}ZxIM2cQ=-lC22kWcz*|`pOxQ_jY@cky^=%;it$CTcDH+~iEIOTH zK6kJos^8rP`I3A?u?Dr#SO*)XbBEGaB+Kq_#>VT+1x|P)7$={s^>8x0Bb4t(hi|0v zt#zHP zmht>G=2izAhuyI2%vuKcpu!e*Dbg^KHdn;$YK_=(37U{bZgVt!pR4kU5FXptbym zsgBG^`DU7*am{hCEb|K2Xa}2Re$Lg`!HzL6a{Zp~Em?++HP3Nv5-fV>vl$!jG7k$D zeGA874e=RsnS;$yz84&9uJYX~7zvE_D@y*dW`Bs)B!ZAR75YaC*4aU}l{l)8d9S#;=Cx`L2H z9f=<)#}Bn3)uVQaF z$(PE!@I`8)EQ!^m4xX;|h?7_ydTwjgK5-JOhxNp()n0KDYrvAvTvN)RB#AX;p7{me zMr|ZZbJh-)n(G|Cmb5t!8MQ|n@wK6!R%X;5ZG#QtWU_9TY`NO+~v$J`7OL5CjJE%et9PSp6!e$ zT6!&gTc2dVkNw`X_F6l(KDRT*Xv-X%+WM52+d%yOk#&f%j;+t_j9DgmlN?*0+Zihz z<{jpFOUEz=p3Xk9vBonQ>@6G3UbFG6VUEM5F<#wFo=xW2RGwk`vpzOJH(=A# z!@g(D+5Dcxvtzi=f$uouJ$pLOu<=>50BkAG^0_Y}Ol*JF&%ti%Lilo_Jm^&DG~>-X z#dvuOxMOc~X`%5}oX9wE9^tG&2JC${KOVo!ahKzs4~}h5yB5Fepf$!jX*Kr^P%%`- z?^WEzw&yZP?0udAg*HA-+ki5r`q<_hpjxnBi#o$+?wfPK&FjrX&g_>GOvo3Pv$Z{U^9T#q&pSKgt^OL(s$cdye1F!}l|uGe)K#;kAB= zJGMTt_3U9Q+H3uD?z^F9;dzC;-1WWrfBF7(&*L5ru}(;#sb+p+r+B*OG5Q{Am}y?F zm&4+NjreMre6PYQ5DY$lPPUHr*%gD&)9~tCiVFmQA?~ey&S$K zs;d%V8eTKjmS)-096p(4OH&(!DvR>9V%_RWv%=wPqk1F}rhM&qQ-3|+{fXf|#Y1(M zb#&QBB;UG_xTQ}eb;g;HtZm*3?Sw{6Vx^gRytdPQ9cr-&FJ}gRUYB_vo{L_!oEbPS zgY~!Z#$QaL{*Z7>nLG>Qko)LC?(g`sxLd;CHPI)*#Vz;OcP0JPbyj>n&t#Q6?mzCn zCCz^(cac|QjX%F5gS1h%O8t6UaF=!7uzr<%k@`{Yf=PP!mIpUab;A}JC9cY8k>4xH zPmxE$j@Q*4k76A%psU~sWxew@)&s!9-*T69Z(w38j&(x@kyYw;xl6q+?@He3Ke;!n zmrP5@6R-cJy%C%Lv!HmmRk<@`@>TV2!}M2P|C6>}_t({?yy*8}O)qBRbbnohr7*(I zGP=Kx@73q4PLKnQ?yrmZq^(a^o15|-`h2w+l?^?pJ#zRw_&@UZ)JrH2mma*=AJqqP zO+}`)m;I=*9DLx&wF#MCzWm_5{-{2X>+i^P*Hu4iEC(Mray^JlPHS#OD90i~aH(oBxmaV)OqI7MuT%u-N>6 zgvI9nBP=%mA7Qci|45eq&j07JLnWI3kKS)={y)MF(fofD-aK6=csE!R@XN-0T_CRDrm=(NakAAtW`=|1a{|hJrn`eJQohB4MP+TV@{M%(mMGs^2P;s%Qx?V3yA;iW z$IR8N10~aOf_al`mxC3Wx4G_hup;F<$H9sfdmAj7rzL1AykmaWk$DsHO6KVDn3Jk$ zYuYIewgMg346FJc(w9=cRi+;LZC5&cYtdItu@5`gsb-iRX8-PBr=w>(-iEqYet2h~ zW82A|BYZa7`qb4+rlL4Iun}gq_B-flybd z8`OocdvNa#^@6Vtb7no6hwRL~FY}PSnTPCTyt9TGFJ&lU41rj4JZmKJkH9?&8ICaC zsp&7(G4Zfps&*b?Oi1}4?h`bGR2%EXo zMzf$}3I8~FW*hG*=1grK;V*(OmuLC>UW_{jnhz~7UNQ5Stmu0u7W1qW-ZFn*zbF<{ zp5zV79;Hv2N3jtmWBt+ozW$)xiKW1ST)MAcbb{1x4c!YSduU~DV{iNV8#Ch`p6Oka zaxS|mq}=B-Pb)hw#NC~>>+>i3?zdQv|2oBYr=Yo^y0!2$Bpj(Xgue*>Wy5{j6dpad z8U8fnSsTQgOT7MhY@!dgSkI7@FuNh=)*v6Y!qYa8rzY}L$OL{)=+W`LSf-sLK%ux5a6?v5w$X0-Cj|4JY43FsYNH{&gLwhlGku%hDZj0Z0 zf-rO756^LLj0|$FtN2YthBpHl>LY`k)h77+xL*k3ItRZu2K*NOj|2XC@PxY8vO={p zh-*Ila)zvgQw{zFK|YIh%J6LPe#jta?g~#`!U=Wd#roywAYGkFS3%&{Z|h_2KmNYg z{?nG4gtSZhY5ya?|K|4J`sYFBp`9iD1a1E#Sz_&f#P@%^{U>dHyZHm!e|eYG*Lj?u zx6k%JiX+zkNBxdN)c!}Z?4$kvg7&{&rS_lN-)aB%(EjhC{b$L_+f#?OkoLczQv07% zsr}zW`~P_r?SK7B?f)Ly|2?$-9Axb6q5Y>;@L2s83wR!@RvuO=yx-FP+gSVmTiXAA zLHoai_CLLf_CKdm`%fF|{W{kEHwxPSoJ#Hg7qtJjQu|*(`~O+2{cjYs|I}Gd`@e_w ze-G{dHOcnh>rg^JV;T1D%Hb`9iXhfx+n!*&It9jiZx!(^r=PKsHOCbudVn{r=AM2s_xr( zUUxq{iy6zv+L`o6!Z0S#?~eZ#{0n3>{rohI>&$#E6!KTTcR+SYzu@Ah^7HWb6NDLG z!wYe_FGYqigd=%V4po*X&KtVB7y5C9>o^j(58y&B|tnzj90R@}nR5`U`KlCBLP@st2tD>Jo*i?N*dV~3k{8QM%X5lK3-crJ z;G>b;UtUT`*qao&jR0izY=RG*5|fB*{P&~pr6M=CbolVXf|V7)&%Er4fB$KLQ5?nsiJ%~_k_`S+KO^VP z*E?(_Nhhvkc$EBPkTE<7!cir@%0a(h)MJlh&dQ$|FSPPEHhj4IDJhE!C8b*(3pL2}`XCM7fJpYirqmN;S z;l6$6&Vkwqy|}ii(x&Kv;M?#Uw?i8Dv#)16_Tex7>^t~c(9f5?gtSP2qkVBzZ0}9t>~gxFx(#_ak3bJn=Z=vPoEblWkvo zmE{WaZGW=ujV~@=u>W7@_oSwfb4#A#ZH?_X>b)`#z~`=7S*t=HrGm%WuY2_G}bK9&ONnWqH1Y`NAG^;o5l^~7H(9|5Uf z(G%`xYL61XV*|g3shzMdl&^n)rRo~vw}LHrJn&mXZ7n`?PICRc9(r?Pzw)$m{WTAn z+pfo|nAjA2U-*hil*U`fq;ut75a+AM4v-R4{TkL2gSCNrto(_M(fWenHJ!P(dITz1 zOTn^2tf68rZx_EI)=2j}7YP>mZLGRSYaFbJ?pr?7!J1;JA=Av4I8ws!ni<)b-pRq5 z>ptyU#Ba5buLY~alg$n%yp~vam};JKuvYA;m~KW(cr!!4t#yz0pB=t7y8l{qNK*}+ zf`sHjTS~@4bN|Khyl=8(- z%AwpVq`Y#`|u8ET53JpW_~KEOt65E8j>t0GD%Dq>s`b_utMB<~fO9 zu)R@S$3Nr|Ox&m9w;Evz&D)Q?`QR)3aZERdfggIq%}y&**=%!V{eQ9l-J51y>LNSl;ODtv1Dj6h5fcBwx5%Zd0NLr zn1+{!J-G;;Fg zWVL~)n8cxeH<>N=DSN%cx5dc!8ez(JrOC0Y?RE4elk(l*pA!;d%6BKW@ut|ZPI@2E zIxxbNZzuXV-EEE&@AJAZN--14_ZqtdQ*3BQ$IqAdv@VY@4evAaASbu1cH;e`+O&u; z<@?U0cUk@woXoP9Jz3m0qSqbg@_<1nMo>T3LYW2l$lm|nsoJFEoB+D>6G$lRdXvr(S zaQ}UbuyT%xVv#H(ZT*zNDXoJt>GP$tqPN^A7V(X-&vOS$EBPhc^{=?sukPD5vF`c+Z)UdGZ^_~ZA!*%_u{9j zF;6&7Jdo#G2_qaIjwDU-aiRF%-}B1x$H!V##b5b(82$yMYa0|F`^Dqm+w;ot%UG^* z90$S^$|3$GAND54-kw)A#uxebhR4VL!nd#Y86W#sm8aqOHU8e?>4}e-_w|1F#aB5G zE05=^lB+77P_B4fd&}#6@l=*4%!31Y_xqAd!r526q5S*f3*Wn(ml4i&eM9;Fns@C{ zC&>E`-}%AthUG^3WRmA~2Bj*I1saPmqLi=qq1&h+rLHi=B1e;fs=lktwM@`Tc@g+JB8O_@)2N*S_W7`6XmjmGCtlyClVVZ4vrRWU*q)Gxrz6M6T!dl~ z-%>0BHnpk;9K~Czc^&Eo`|++YcX@yIW=nYZm2xRov5&9zVl_Q0Aj-eB<}WG#N>Lrr zD7_nWT%;J^yC2@U*#7>5y-dqqH@&ozb^bERv;(_Um7B($>s& zLKjc5h_8h`oqqk@4qt2A5$$Ck3-h3zU5}lS-#U5FQO6UCMKX7_mz(Woj3Zx99Zx70 z#oO0z;mnA^P9F5LUD!_$VLTH{?VGU%zEk3j`tXCS%v~uK#XHnqnzB75)baJp#&9cV za4Ht@9bp$SR#%}LoNcQz*ji#zTkMt*`ojZ`{ z@%0R8KP&h5t6B%Dil?$1@jh2oa#VgEm!qnFePucJ##31iNmJ#x4umHzPna(f&T*}i zd3zu{VL$G_>wn)btCjoQmEZB+`rHS@SJk_&D&7O-i@)>A?Z3?b>3JP|mwugG&1~_m z@Y;2t4v>0U+u_>mNSb04qdfV1jm&V{&iftTcG9kT3zO}g>s>2;qwrdpZQeEBk^uAT zicZ>}Q;anOzwYU6*3)7?Dtu{w(>^GtT9}UBeD83_?_g$qx|s+ge%XbBLYuiG@Eg>Z zXl(cOF=X-MID(q&By*(j;mhYsM-zK=fT2sS;f>{-jiL5SC%g&FB6T$prhJpw!8zBw z>+ns{HIN8XzUl0DTDIS_O4jq8$~t<}mi}1cJN$+^yZd?;o@FBSr}&ZaL!3XZM=QLd zuX~_85?&a7<+D;GjNhmFVO4b(d5-Gfj}?#SUe#~$7oO+1Klj_cq+f5e{GDQ2V;gRU zc}_4OgPf;e%SP6&zjXN8YTv72@3`M~ytiY_B|YOO?VIa!n@#7SBK;L(0$3+_K{$AnvR9HQNjhwclf3%c8!BgQ%ufI2*=Ue_;$r_s)HS^ zSpN*Ac@VF7i(_}u&Ubs;hkY2A0#hir{O5QCzh`i6R#*EM2iwT`Vcl(82`@_TCf##Cz=`8b z&K2utCpvs*F>+0_-5tKO)h57~0|;-%_-tR6b4)E;%QkZOHmjY0ha6eXRT~4l9qc^L z{z}+a1)GpL)erA{{kA?ED&H!ZpOE)<0cU=Vv7b=CB;U~%bA!FX))@g7y`u}wPP@~} z-rFR05pyn&*v5iI`M1^FVsEjsC%GXuEB$ycHV@hdZCA(dCFVAJn?26KE~O0KW5+w# zW#%q>mmT0>mzz7VfmuzkT6?t4-o$$0P4*@$``DARTxssJ_gUG~oy4|j9s7u2k$hK~ zhnQ3QP_XD-UTq$;kJ(+ZdUuoAZl17D*m;syLB3S}{$>6zZ8u*%c`NxVm4(;@^livq z5@6Lq#+yBSN6GI$mD>ND+-CQjMi_&`=R!yHZ&m11-yB$luPnubd-#g4pTzB0Q z=eyIq%=MVVcNcm9ZNzE! z3m;<%KmQ)mvq8EFUzC3j>p3Nj9lwvLO|mJ1@&0_jk8)n#*X9I=?=e0196Q{>UNOhmV{9MtDz#Q8T_4#*Nn2`{+N-2Jiv0e1bQCN>K+2cO zjQENEIam=^Q`a8!tf&a9t79WQ<0!%!sxF;yR(f{JyQHll zekDJvGd`5FNI!S5HmXnf7YA#Lt?wb`We01Aosjsa5PB?@GRld{A}%4dwEl zK&Q>3CE1ug>6}dFb*^hxBHuk^p!83|K1}6%_&k2ToA8IfEAz+4$@dVx{FZ&kp&q}u zh3X(<@|}OFecN(v7wQGy!tc#h_A2XL%zkl;4VjwQkg@FjuD=9@F6_v(Ucec~>@RQ4 zzH+gJEjDCAyD}S3hmZZ_HQ6`Lfhb;mu`9EN`-#|~DT8Ehnd~Jy1KJ2}!gkI&Z0MZC z{p7%w_Xccvug9*yQ->bo= zl;4ShNu8irHMOPvrNfu1YsSy*N`C91PT-pkUtOJ#_=|%z)OnSM#cxobh=mt9gHpha2t2bxvBF8a( zjCl-N3cUvQ8FUfuo8>o@4y}ipKs}-Fc>c?7#yk(n8Qoi`dryV#hMtBlA>TxoDZGmf zga`Q4MCQ0#(jjxFw&$ySOV;4sDiT zq5W^M=Utg6v@;OaAMxjgx>SCPjfXfc?$DpO$5#>V*R(w{4JqwvQ?}BPpk}dS#l&~evFy867M^ZlG=@8yf?yBB}JeRoS{yO;=hF#UY zsyyF-Y~THB&z`G@=F8g)$I3^?;;Fgk7}4pr=Ah31#D_@`5cP!2wSLr9=6OP_>is{Q z!Wh_PqCHf<4Ot6bVs7HSTG9VjtT7r2<)Q7Qoj%r#R(P0swtJkfC0UiG`8VKpKQBHe zJ(3r4|LtDf4-&>ss4BjyFbPMjKW%yD3(c=9$**Jb4440mI8wJBR-7+xF(!tNr}?C35|5{pH@L`+s(tgv|7bow*_A(b{}-LHl2glC^-# zw>QVP-az+t zzTpvdX_t{N{2l7;$y|L^`+B7g7Ygg&qltGLBcCJe5q9*%WIuZw8bdNi_U!mLR?1oT zEp2y)4?Ba*uiZW&&R1r7*B%s4yFJ|q}PPp3WGhF-VW^?J*} zR+tHPf?Xl9L~8^qaW}L_IP$GBb!}Zc*TGhs`nJApFfJa)i8|h2>ZD_h8Dt09flj<@ zb-wc$2V1A}qN^P2B%Q;%B7=8W?M;1$+cAOaJvSnn#IGa!YihUQn!_${=mM z=wCf1STxt4f~Hj`b0gnQ_^nGVBI9f64~KnY>CZ|(_*s$AqF*d+z2E0fp?w`@x`8F@gleV(m$Y|bAG;6F5Bd-P)vxvK zq)0!*?`<4(D2K|!dYXQ7`-iWMp#n3%`w6z_4pr~-P)UefNA57@eeX~Oc!&x=LJ^ugx+nRmu z03AnerLK_jPY;Pd|Nr;7(`y{qr;9cF^v-y1xas?092nAY`9HNDI~SRx{QL1%KQPbx z!3OU8-_@icC`e8!J1TqpJK%uQ9qx{D43*yGBAftku$);;!b^(Dr37 zFQ7})hU28(KP8p(6XE=i`a`Yk~)OENK4pvKbeS0}rZPmj)cBS|YHev&W{clYmd3hPQeX2W zjJF9j?=;iS!J4WLYG1`dzs+=>Wv~1HqIiG6{=Z1R*#5s@99S1E5II*#_y0wEgBukiD9nCb{bHb!8ihv(UBp-2yE;l6eg7uR(pm@8y0b*fQ=*AZC3wXEZvZjqLK=tvtn=4ky}u4?{kry#4!|9(;oFCK z_9%DO@asQ9e2?+`0Z7*PS^ICxy8jN=^(|}oHFtAoy}dqb{H<8;Z}SrOpW}yh{I<_? zXWidC1-(E#J0aHg>#+V`7hQnoe`&lF*7>cUj^t?|-xh48Nn4N=%jYdr*0SGxzJoPX-LNhW)`-4lo@wD=joG!8 zt7i;_Y1_hT-5Rbr*GgZ>&*v@Zi-_Ge--cX>`L@!&9U15IZKb{8U@h3T-rjuZU@diy z>x|uTzpYpS?y0)4$#`39|4z;rmv2SN&=&eYS8>U?+)1o0_!d2jJ&Cm=_wLlS{BWPa z7UVdcD~Ix&j3Z&LwpZI#f<^hR{*Rn-mE`Nj%FM}TLM)C;vCkxS z3~rBo3){f%L&6VZWqcd9S+u0&kB6Q!FriTxL$Oy-l{MBgoE|b^8<&FFe~qa zwtgFJ`eJXfcbs674#m<;j+f&VPD=J!w$b0&WH;HX9BiOsI~;6~V#hkzV8u=oELu++ zqS%)X-%!O~aj;>EozMFX-{m$l+?++d`zPw%WOyUY{q}zQpkO3T`dQo9y??vC-R^b& zPsI2C!Tmo`+J40SKg1#5^nUmMM6&#d`+sPE{dc~f{XY@k58MCa$3Z^|ee1r?8gI7h zjgNP*1*%7Vyo2Q!(doW-e7u}4#DWGkG@g!Qx!8|rZvT-P$MQ_3&9vvxQAn2Yd^5xj zv0n%leOrrkA5L5G8>M%#?wd(*!dqfS*-`cmC%gjPo3mmF|` zaqgdOYdbqwk?u=*#fjq(t^ZSB`R`*t>;F;ti>?2+4eN;gtp7)T|3laRk;FK0-XEg%e~vZr!}|g2{~}-F2d@7|-^_un|8Jwmnv4CM6KE=v z-{7St8{3=19qckQ*Uq(F&yMq5u6rI%clfTrK4p%bAy`zNuQc=Re49U=HZSPYNdH&% zT9h`Ax82v8r@g1WvGkRb-}!aAA7;H^so^`iUiZ!92o}Y0gYMTkSK^5B??yeBwFQv&Dt4@c-DbYvDibWq``gX$xT-sRcW4}g9qdjG zFVDg5(mgkANn276=*Va!J_bXo3HFw_6EVC`u-X7JNrBPs>AoJ z`Nn=@?{~20%lVIG$zQ_aq zOB^ugUKumCp8CCKL+kqMX+K*1u8hP~!ice>=@LWsP*5Zva_&TFY>yw%vgUkvI^h1Lvtx zw^xk$>0Do~^~lweV&#|n+A)s3Ium<+@&g|%p?rtBzOsW&Y%-oDSkS+ck$)D~$qrUu z*ZDWX*^Ht5R*3&!1Y(zDo%yxj5ILf6A&PI)@`Y-j-#?q&O-n9NCw-I4JA z1G8f<-qKH>v0>5;x86FiX`G?`I{!VMa2k6nDDM9HHjT{Q|I+vV=zsX+iP87_^#OX# zbNqVsLF78SlXi6peCWO+NZ;4P|M9c+6MHnBQ_Gx`=F4^1>8x*b4r_Wo%)R{ub;sTw z|8RW$)9EQm-wSXr%)s?99`$zhjZf;xam#-U;%j+ur3afie z_Zs1~*X{EqSLN@RBX|$;ttb5VF^ZjiUkS$eMKC@qSp_rw!KkNp`j}OFsayFP!g`_( zy8>h`y&vmJHZfzI)CqO)aWU6?;S1`7I<)T_xh@yJ?2xafu4%7x!mF)&_djy5x~eI$jb8hx|kceo^s;o zrt|f`6Taz_Gkm@tI=}gq6JBp!r|l|Out%c~YnigvTEIIB_e#`3iy@tBy@L%<+h)f* z*g&;uTj5}XbT7xv4mMcV`d@UgA-WIz3I`jiwn)!$uwmK`G-l2{>>Jl%&NGc`l7o#< zU6Za3c7*Dcd?(?Nr_xWaLmMT!7staFj`iwbrAGFAjD#;7H`O6!6S%ySS?jXRjYl6& z*S~7CW6i8B?$%Hn;~mkF=k0NKfD*c&Q`)Bi@a!NcP3bo<+F}?I2&?h2r}dhm(Io^1PV)1fCzdziQ^aCVqY2 zdZXXJucm?jkpBIllgcF0YdwBvH?8lBkxTj})NA}P82&f@Wo-R^WT9M-AeWTwE|f+o z!w3F%{o7~%Mr)n}_p%Sp&n_9PPY2h{)cmToi8a&RtidAHc5M90U&{LGCS6^Tpb7tH z@ZXxRzJ7cUf8WW!_Rh1t{cw}8UfFh5V(vHIZa&FxALk?2JIgr}NLlbq9dYRY{-#yU ze#1@B2fg4{&9D1Ku33gP!xVPa9KK(#!m#~-xDJYG`@Z)7Mkl1xmdMF`May#0fXW>{ zZ)`~}s(8f}LvI9ISDLi)lkOsLlyP!C?aCu&S`5_FJ zqty;wvdeN-9>UNn`XAE3vIpcH%J9+-Wnj67RJ6qvhfp>-Nxmqb0Og$UywaSqoTB^+ z&H*1jyrisParPn(X3wcGN!*M%=x=EHfU(h8nUf0^PA|*PE6A18>-( zVSY||{@P;;im`e0BSbJZf8p}QLGb_MI-oR?pYuLRM&Df1adBbE!kogsOW0=UW4LgX zEGk@HzQk0NEk}SwdR%?!@`~(|;{0-RVt!f4x2S{$fssFDc721gsAim8vK4l3%7r!WWmQECs~{6&jm5 zIICXSIa)r^bCoI1UmQh}=rVWotno85=Zxz$aK2eovb;Dizhsd_knKmBTb7?wksl>s z`Jw_1@=)e%UVd&#UVfS6?b6cx#YH(~CrIv29G5Y6+>Gog8M7y6P90}*Rxi)XF@?)3 zigH$&B?XI@6y=nkU~C+S z1$h-qN`3c|e8Q;+eh}`8oWfGFXH^C7A>ZUK$tg?pRA=y#N=^C7oYLHq;);MrUP>~u zL8f$Zk@1r=VDijyrm#Gp#wqzhC3+^^W_l1#D1A?}u(Y)QV3Si?T3C>qBOgtW3X_{% zvb=)gkzdRg8_3mVE;*AuX4;hL)25D_nl%$^(S;@DQuZhdR@ zFOu)Q3Yko4sWRsj7KRaOswleIn))Dn)h%U+P|JgCEhrYTOj*gwa#N&*ek@0>ND&EB zSG2saqQFd#QY$Zv8MW|n)96UZQnPc|{q$ z7jaG=H*+R0erndZ*;zA9aY-33U^zl8F3!(O6qXb(rhYG{gR#QkhcdIcf^LD7ojLkC3%X1dz$FmE;j4zy)??aj9pjyo} z%lHgTVL?$rMK-nX^4xrqSemoEJm2IMl;;-a6cq8Yv(ij?&Z2w@M`1~>kr$9%ksxjP zl+5CiLi%@wCcmt#q%3%0MdgeAFiA~NbPeT)r}?=jWJ}rLgIicoSWvOLiZ3Mg`RJz@ zgz)`OkZAOKSdm}0kdKiMm*}W|vzJ#Ow#gb`q>NT9p{y<`Da@0iSdpNx<*1`)R{x+b z%1R3z1E_OIsGm;BnXLZ*^R8{IS(8uI{}!l!m*o|#=*PT?NY!O-*0ijsn9XO_WrZ|h z{-Xi&=ce`KCsk1Y!Sk6JAw;USe4ug-#Vq5y@2CH%mvYL>i*o!Fb(tHM-2U^i>MhY{ zmsjNIS4mbZJmlX})TD&9NLseEu3-fxg}|>}{K|T7mE_XWpsbYT6zexpk8nmE!4xHur`6pxtZoe+0n27J5MJJR7zKR1ewJLUg1RnK4T_-BZGKrrfnNYmj0y?u zd07tq!m#j_)2wSZap4K&3nMhBUJHuzR)yF?+Cm24x%3c1zvyxYMYt!?@|hpnwB#2` zqb{G*xXEK?W@TiJn@P1njQkcKUFWGdpXv5-c(gX_|Wrwz1o%to& zd!g~mWpqGQ4}T28AXo;C13eHN9@9|HacT6nLl~lcv}4#m@_vsGAB$7-ISn=p{9GF*9>aHXWM4krp}zn6&;9%#2x635It$ zZkmn(r%nqTV`hw-kU4GYOw)Z>4-<7LO!pA)`8`LHjm(UE^y=T^@H7d2M%2?W@oo@lW)+7L4(b1JSr{nLh;%&D1K`dmTzl`&e_^#RVw z8Dox8_vp+F#V2P@$;>io10=gLW=+mwp-~361R0KUW&2^&l{8ai5O1dH|1o2-W@nk{ z{(t`_qvr12rL2q^DMh=-k>Vb%PFD98%0M7sIO6*Z&Z7SO3% zl<3Zvk?5KT2jz(#i8YA=DVK>O68(C}!;y)8BNFt@^Zg%~N9dF2KO(VC`i(L{WY#47 zMja_ujR@U2t8h#B@Q>23Z%slN^iv!m)s8wn0`ddrae!GK2b}s?LrIa3T{uL*>EhRq zF7O@j9O1)B9u*_tQC}peS3=WZQzQ{I+A|iK8GgMSRL@=JlH1)Wo;?HV;g_{uX+7p^ zT_rWCOwsuBL5H%wjC#COnX|@cPMuD-eRSr8Z2!HPnbR^&zg6SMj~z<651cG+GLhiJ zL*N*nJ$a`78b9Qa)+|ANVwfBmFqYb6%;affj+&W0oq3*_M#TQ^)u6EWl7iBbS!zxzGeT;5>vRgy3M?4p0&@~wDdUkmU+p( zWXC($+va8avYq2#@0eHZtF|m7xh}g6d&D2IKkpp&?Ih!P&$RQ}dB-}~uT2ZDg*WHv zIN$rGjn~FIp1plZzaN-t7@#=VQI@rgio>$L1 z!ja_@)68q;EpxC>O)IaJcZ=iqGgHf}<$dj7pPL3=1Fx3j_Y2d=Yvgqj3_S>0!`_CL zZxgSH*QiTUS6~~K>qmGaJUv$-(!u@OWOx}~is&%QvQI+%e#3bR|FYgYqgl5;l6{_I zSSd_re`p5#L&veUJ=S=qWwHlyGW$L!^6V&{P2t%jp0OVOk7JBiZ6^MXHD2{Bp3UOf zaq!JH-sz{}Z!yo7@T`Dmc|6O<-y-&xF5sTSeIfT;mTtCu3(i8(PYK+Y`92 z;y#z~*#C>Rg2yRW9{U76cA|NljOCdVp*7HI<2}04ct@UQyirBQ8^`|Nu`7%>n*G0% z*#Dc!{@)4g|DC+ScvIM|Id!e^rmw@_NyeL5XuMhMTUp8eU%MH3EA9Vf|DEpt{p%&9 zXDd8c`1^lfz8riTzb`Xhw~I;3mHfWOc)z;N-~W3W`+rkz-249DT|Xtfhl%e|!g#3a z{lBet@N6&pe>r=?OR)dfvj4Xg`+w~d&{KrT{$JE^|F_!f#PutF zzr(u-_Wz2FZ~Gqd|C%t~;$5)+_x-ma_W!1_|My$=|E2`{e|J~0|JQ3qd@YSvuQ~F! zGT!b%{2oY}2M|v`unvUTlyHU-&Jn~vg0e82_=oC#^U&_K>}S7y4Eh5-{XOX7mVNK? zyE2db4*AmXCpNP~z9#%mg+4(+;7_c3%Ux&{;r$dn_~WThp64!m;brf80l361``#r^ zxl8zy!NNG?xnS~KbSYY(3y}_qK83jNMp;kxaf;35&+DSQ7htl-@=D?e^(16Zy|~4n zkhsI}#E!MtH@p?v35{Z(-%Z5ZcKW`C?P4|0FUpT*rG z|E`HX2`=vVa|vIt`OtOn#-GLAq3vtAOI}Dm#Gl`R%xzJT=mp&t+{HHcyXaj>eoCIK z!7X>e_LaXk^Dg6Ihj~yr9rAl6c`5Qp*b+}@7hU#rgme`=1Na>eQ_{L&tc!IcUXd@f zrG6&z%e$9%_)qT5>Luk5c_d!plX$WW1@W1HG(A9IK(Wh+cHCnrdU{3+WYh6HN386UMAJ zwN=mUN{3H0`}&*v1qZ?B7WWj>-Q`e(ZDCgV{QNDUX z{x#GyAC7XuYh>hH?+y;u*vNi(#-y=0n&^J`PQBw;Q?=VP$ibS?vzTpeapY^RI))P* zz7|GoLx1h?wN$;sUkeuHK`YfU)bl?@_fqpOcK)a6PbwBW|C8e4W3lr;BP@3QXN1Mh z|BT}O{`sHlP3-*7h%a{jXB1v1)q9Vh|GA!h`19rBBTJU6@1OsG5r3MdD=^LCGT_IM{jKUWt(dptPiKZ9B)#bc>Agz=)=xC zI$U*4a~!On?l0Kjyx;yPjvZ-kknjS#QtK(-V)v@t;TwR4=O}ZO@J0DNka@F7W{+T^ zTbq#YXprg%zv%cKtoo-DoNs!FS;}>nV4_Q`eut{=?|i|cIEJasqFqiN3|Bi9Z#&os z&h*VU8^v!bnXlm;p|&ut5KQ!t6&tCxFm?$Bn~#lB`$_#B>`2w=U8Y$0t)^r3rqEP( z_%h65uGS7VTF*rKgUA=9V+xzk$mH^DshV0 z;9wKf{z1rFgerQ=kQHZ9q=V!HG?=d@*Yp-yq?n~pqeBQTL!v7>e0-VDM^`pwdD=e1;A((f_4H?YtNZ?=wY+d9~M zv&ZhSud$IS>34zorTwMd?Sz-7dmMMtmWAWfjg*1AxUO@sMXKAq)xj34EtUliwgek1 z*O_|+BjWUak_QE9pQTtZ((7YO)jrEw!O*q$u@lq=OkKxsq1u!=S}?N8=PP2gbB#$j zSh4D|e@A>tz7lo@Ut&f(e5K}UF6I|we9IV3Z8OKx#!Im`36Z%>_3v*U80RZDt!yjn z(XUOWtwPVBZ0GPTH+2~M9_C;x^c=}F!J>RwY3kW}cD%#4$~3SI>=_Q~fJM%9k~ImZqNn8DVSHc7UG$8DZ_g8TnnW zHVZx!zfAZ0@8cA;Z4f{IbE7%cKkL&;$7!aKZRDK)xe*&Ka>jt3|4CoZ4{w9%XgfOR ze{RImk(>z{KmSwqV91%Edj4mWr<;Jr z&y9Q=a!zP){^w3V?=RJ}KK1-hrks83GCk`ve*P!BU-axyJ^wS3`3gO=RL}p6;=Pjb z%015cpBwqs)I+-@GH-yT2zQ}_Sb5n7KP zvi*P6rUl{s@9qDqMhjTH#IL{mauSW41xr>_O4sR`nc}`1_iOEayfe1Jo?u^x;LT}c zW#7NJZ=>Cta*Xdbd~Y&ODEPbJ&z$4CYjVDvoNX%j)r2W$REql%+_M6|9)2%f=HrYg zjqV46CqZ1F1TrL$LF@yF-@6EZLEtw9zng-z^d>EGMyK%HPxvddeRo&Bak0@VxJR3Q zLl9Rr;(9-jvo>PWXjE_=gd`?x_N=k38c88E%E=?}2QCkxkAE6~FfpZ)jtn zI{B=7mcTpWcWn@6b;1-o3BrFn;nYa@?v8{b=XDDHDB;K$L)@)#%Y3W2--BQGRpD+& zm}drITEe_9$cIkkLtYU6-S9sbq_;Zh6&uJBj-i*fHSn8?U)>`H+JG=+93wn!h*xYk zi2Dx0>74N0?U7T?Jr(>X@W}kNxPJ-HyFpwj#C3fTel@}$9Qf^xUl~sce=GdTxvk>9 z3%8uRCGHyV{~-v+BOI~0C%7g2F$v$@lW^pmRl#@Q_q2O_cW?T8VgpL>iSUcvEpZPP z`GfvR3hzb6h=Mo6Z%Uc(K8(1;{+8fF;os~2zs#}SP2vac|I3(>Dg82M|6foiIQ#!* zO&{y?{eb;{<%w+HZ*2eHn9%_i+y6H;BiJXnpZ$Le3k&@4_Ot(QdUrY*lD63XzY(=M z`B-fKAM0d37Tf=~ZbU5~+t2>LMCo#$FSh^h((lxEM;*rHVy9L2|3!KFe`x<-_S7-b zW;y%+&{OuY*#5ub{DhCi_WzCT-owXY`~RjS*7)T#w*OD^Mayom|L+Utx>K0zmi>Pg z`%;$Ubsw*f{YR;P#IKCp z!?T_&GPLX9<0*_K#P*NyTub-v;bqwn^P26xyAg3M>EOFlNxRHj2>)dK%D!ZAx5n>dfjrsBBlAjv4}<5-Ae_d8 zGbE6q4l;->TH&bz3qg7BLYzU-|Q{x+oRmhHZ~8S=}#so?Di z=d>WtYZ2GTz;8YL${ddHOo3-d;I}z`k|f!?hiJd?RxKa?aWq#t9AK zllpZdU)m%)$#!?J>&!$u(O&6{C$2YBnDf7sv47I<4Ol^b(A*|iG(Ne}Jj5k^m!HnZnZmhq7&Xd=2fnIhwolaX@1$fA{goQWxh}C zlb!AG-H+Yl*Gwt#rUrBL8|iJn%_V)tWd7|iUvvGfe>|@qFduVm6}~869@KOBK6m(j zYChzWzI!sCA5t4*GLC52Hq6t9)fSobd6RsPppozg?Sm$Gymdx)xjQD zTah0**iN+-*@m*3l=%rMh_@y_9u?t zcdjib)=jLpCwzW=pUzn5ZNw&3v{nng}P4-Wn@P233*>$#D>TI!%qUGgFb0ur2-nZ!Z zq@deV6TKdbo=<)BeOjaEV-`T@_b_($wxiR-T91d0qi5$E?_cQRY(O`sCb~Kn-JJU9 z=(Jt~oroR^x;?GY-)W8hPiu5_3O5=rdlUL7>(B=}2|5`Jot=5;@)XkMv&!JnCV9+t zdS)#o`a#Q~6_Dr+twuKpJ)$F564zPKg~W@VPnYwE7u}xL==-!r_ovlG+_ysKLKhSE zImCMj@t%#JE1=8qcNw}g+t8)Ciu?84ZvwlPIMDg2e+~Y&{ z+-$t7?jf)4!q3C}z7Ie5^869p_d|C=KjHV?(4)lv0P#NvwgY+y`l<2Wc@{ZD$4B&f zcH;jD;@E|IH-w&$==w~1+<4Eu58ung^9s*@4j=kKt$zu<%I}Z3{|5RHdYyRQA)a?h z=X>Poo6uWeZ*%{E`>zP|*O2HG{Q^Sg$h-)>28n(VdPHYVN1kcs?4zZh>DMK48_kt1 z81_=6yvW}OuFLtZ;@D7nkM~#dE4EfCY|rgm08x@AF1S5)FX--$vHQ-R>H=!>iJY9OwL8V zq7pWi)#?i?VPY3;v0$-$7TarL$0Cl&n)|3qd_7DLlcvD3FVbMT&jJRir*O6u2CCz?@|-=Z0!hr=XcLdJrI zorXo`=4pL$s)MDd?#31etETz`cQ{ye)lm@p zDdGA>M@p1@U*92LL*(=0O;x>$O*7+I4PEPAkIW6Hjv4Lq)nwMU&|D-~r@VY0tEJe@ zg0b7c$7(A!&k3&%E#gA6&WX3K+AJIA@YSRBTwv~Uu=>o4EHUK{)_@UMp6TOY4OOqA znS(V#TXvp#$%(hIo|Sf$gEe7{Im3M7U`sJ%bvO2fEso0 zXkFQn`c&GQF)jUZvdqVJq~1M|Yp7s>?X`|*UdeeZIS$|9dM=e$oTc5h1th<(=H1CXP8X98;cu}+ z9lC$W{UzQ}+@HjsMfg+5FVRIjsuAZMLigZq3Ksqrolp6_-#`2{cnZ6X%l6Cp?`1%) zT;!7Z)BmVHkk~T5S?b)jC<$OH&EYBqY2VIu@yc&15SWd6G)qDgEpA4pv*+&G-E} zd8f};SNjhC6fCH_Q)xYp;Sw9n$?zJh?xFXMM;%K2U4wdC>TmMFBQ}pT$sT}VDeN`y z{QUr-jYYv9M&8DRCw1QMh)e3V_&u}%89tZuwARq^s=uAHn7eb<8k8X1SMYZy?#<9m z{Jx6&vyhy%CHl{z?=1SwqR%Y)%c8F=`pKe?Ec(ZyZ!G%7qE9UP!?G4E>o>A4A?qV@ zK9{Uf%lf;lg^S*u=-I8SkKO`}>bum*qGKoebD}SIB$46}{IINc37okM%;R8zg$^qKA47BzmTz zS1M~3GQTf+qOy)4dZ42BDSDpYAmb3^-c`YzJ@UN>r6Ftg#_S&fAN&8&_v;)_UWUI0`6WPO z+F1hqDWDU4U&A+vJdJWcf#1#XzXLx4GvFD6@_Mfu% z+y%&Nd6b#GtS=|z_&m%=+{Gg3Vb>ES|As=8dw1BRA3lz5wIEP1^9u-IerIF z8~ho{7XX(6zv1`kwaN6)Vun>3y+84k^@LTj7$OOuO20$lZAIIg-6!2xz zy6_s{H^9@tmGq^2M*_M0Egs_B%1T3q9YeuutWh2q)W?XiGgk^F>0j|(4ijHPMZ5`-StdzyadJD$*EfpVg0O)T`7 z@V(4)%5O^kQM>z<%Q>(P@t)0b$y0xQ3;qh_)W(3!yZ9ZzJFtE<8oi`jKtCM|;L2a? zR?e?uTcE9SeWBk0Kc|39<)`$rWe)6z8)%#OcLB)<=oKj65ZS6TQ13+W0bCoQZ4hrj z=ZemQj;k)^Z_#%F*%jp#_4hgGmPtEnQAr{H&Y8)$n=z}v(t3K|N}W!Eh8mXE%kza9 z0?nKMb8B)OE}#FyUc&fA37P*3p#|sv_?8av1?T@l_^Ler7g9Dj{})0F&i~2A$nUA= z`2cwHe<6IC#?AkQ(1P=S&K6&#gY$nOe8KrY1!{101n2*jESnpk1?T@{W90aP^M5IA zas#yB{9j1D!TGtg z-27r9=MYonNT{8=;z&u(TV9dY-n_m}q+fsR`Sj+^L(aSAjJ^3`G5GaI-$E_y{IGub z^~dmK)Y8rmyEzom{QT4Vh7UZ(FG>v73YVJi!)S4)47-s@j%MX0nOA(LeBF7M7oYL#PZL(V z=9wqM_|jONI^Cp)@wH%9kNt!xSYEc3xgqA8mVp zpy#}v`40k502=o{1^!wIuCiaca{3N=9$fO3zYeI504`a2$EXKA6juy;eWx6${l7os zeM@$!9|N*C-3@3z*Czqlv8vzHPq94r3bqkvpU=4lyf2LA4AlSh!yVrb-alv0=`~{q z-f&Bo`o;YczTNTBp!A(%cD`7vD`(ro3|JHI_;)2L_vu=>K;E&q|&eb4@Z-!D1+ zo`2N-A@%QHK7Dav%HRGn=wBl)*w}3U+%sBy^Y(dX{&8gY(cMn}X8)IU8?U%}Y|fz1 zU-WH$?fKb%9r^9r?%&+HYROL@?D*#WK_{JY&g#r>W7kff*m?CW&z}Ef%6D(3eYEq_ zzTIY|oN?#OE!}-yKcy$t^D!k}&y>~mXPQat*ZMO3Cb@3r#0F(edh{65B(s6fceH6$ z7I#_df_h1O6U5EQq>H)#xJJq-W!9$enp-}vp8|aW^P9iTE?>Jz;p#q#e?NxN6wzU} z=|)*jpLgG+m{@QAIy;OOhxcHXc`mGMy!UOsA&f7<%;8^F7+<32$G0YomgM=CZVaO( zd-L2khtX0zKhmXPv>M*G{s_^CVs8BMZ>#Cen}0DUv>mm)@BcT$Xtfzl#(Or5~np##a~nt8t!fWI11|H}7zd_}rM9!YR{w=VM`I>oaDJHT}bMZh#HiB=hks$}$&W zb#Ca*mGn3{ROd!U?>lY6XpKF;$|q)rmTltApQMEGHD%3bp!rI)U>(-Kc2pQ&8mpp% z&2GsvB)|Hvnd#5Jyc~mgq2PAe6L4@@wN5lv*b6CaM^c0+m3dgkMSj8eC@sY{{~^S4&K~V z*DzW~&ky|OFj^;X-m54~m(HvdbTxHEGiHaaw+kx@9nA@r=K8d&k?*xn*9IY3EuZzT z9Vi;_9hTPJ^VhvDtd1U@|9N}Sg4bG4o|&D@pfJ8(p5ONUVYCds9(s6lgb92**gB5J z)^v(_g?lyd?T|uiwKjBaPAIK6mK&I?=Z4byV8L;U*%`*y*T}biLKy8>EFz1|!Z2Dt zp0_1tUs%1znI-(o2;=L|6L_iF6UH~dTfh5z7;T{UT{Ip2G{t!l@4C94 z2V?Dej+qfg8;&jKRi<`}P`;7g`cA-aNArs*+|TRz7qjvh6Vq$}Z#e^*PdSd*IsLKS zIF{f2fZjk~=zYAolA7o^09Xp_&St)gTyrOiU9z3u!Zp{Rm?!_3!}A+hH-nfJz-hp< zz}tZ0qI}J{9Kijhd778F7Mp zI1acUSOs4*AQz}Z{o{aJ!H)*U0y}`EC)n@(2Ts9G{8V%zZ_0TJg~0p9T+YEIemifX zcb;Y~m~+8)?{XmUJCFzHzi8`;>i7QxKD8=-|DWOQXRty6(uu9??_{wPE2Pf!VpQg? zSW!y+Plc;g=vEKO&Rw{y#0K5W&eaA91^FvHams(;Mg?Qo4q^JZte)L^bjz5f=$|=( z%@MK);~B{<5e~1W(7h3cRyjha_I3!XhYcRa@C`hD+!1TZ&uR#5!7uyFmd48$hn*7w z|0=jFp;;p?@|SMNQh}Dl2PMvKB$ad$BdDX@VI-@xD2r#eLPtlSL&IlUA}mrvY=lK> z`Xj<3?YI|Vp-18jNhSm5+(>u8;+%;0sdkBqaE}JJii)sYHg<}zMD6YrVUcX{6mf~# z=PA-cdqrF#J3d8PNw$58ut>M}Q-r13x$lS$^7f@Sq9TK{-I0~*O>;+7WZ?ZaqC)58 zujGR}q9S>5j}?g#U| z>0eO3CWsXf5!K0y zSb?0pxSTc&+7^5-FU*I=W?-sg476^nR;|i|#{DGPG-x~VwU1d+UUm+&yUpX~w4!nv z!+`lC@zVcA+laI0`TFECj{Tc|z0ogqR8|{}ZMn?Gf6G6`cu1W%#f#UL%LpZZdBs*p zZL`vE`Qkj^^9CwAK5Lkz#e06{uX%iJR$5wu=YM~iXoDw?wzNdgM}4bk*bZ4*lIK@H zU9_wz<1H=O^T{7A+OVvNmX_lAJ z3_H4*AuNxjvT2^}m!rIOpDpvDm6W*ik>>ewEfsC#G)HS@=J4-a(T?uo`nfrFAlc?Q z(WYj(Yoi60A@j^VqGgSCWm}?8u4%1$hfa06_`Nl#PsBHV>SU`+E6)#1aokdePxfL$ zP|92T`reZ_+?}^J-uhah_$H6+Wy_{}YhN|Qmy_rDMdjk3B;T-sqKz2r>S*V!!8a3a zbe7Yvy~j5}H0~`cuY#}OIy3^PBB*5Bj1DU3G2<69j@8|d*p5=I;3@zrKL zE$_cfM%cBceHhZ*Xe37##%m7)<-&hkw(J@_{(?3$e9*-jjb z&gK0)nWyFVCLWyw@5{Md^)K*mW*BWMQ952TL&9j&%q#rs7Dk(nm;OuUZ`^O?@=h?% z@o%kYJO{0QGt4gjJrc%uBD;qC-fRlvo9Xer7{+&!$9G#8-z<;s{V=}S9$!=LxAOL$ z?8Ul~uU+}|l0_WH$4qP(Z4OZnert{jqh)*Xe%ABsE-yQm$O#XaPs38)}TiO~gKJj;=X^i#coy~p? zBYek($vfAy@wM??BtG}el}p6b7QPm~l3p>hIv2gYFG0lyp7 ztv(MNKQP~jT+ssOMEIA~`xf_?{FUT?G#fm0PDJw|qA8ahvhWXF9}Cy~Na(ysD1V@w z^1!^y=}wktjk(ub0o{Q>InhFY2g(JG2YyRVK;Me$&o0dMPsuxsS(-5wPxO|03s49D zM*cP8y~U^_CO)_@^^0pzOzI>**E0}D){QZ&T`{y|enI0>VFVlL#VSsPruUCzo+9!I zRvhGVnnuo}y|~k9+O0K&)#HW zGswR2bFNu#4bPuAndgq?F|Q0Oo92D@T^~kk?#*MCh0$8^jL$V)!f5H9y<|*D9Ah*7 z#%-A2)W4D>eiI*}4Y45F@QiDn7`*R)N5AUcu1A}00)&UcGte}iO$Ty;VnE0L#>>Yy zw52}3TL8M}^jrDCjs?oBb7eG6h{l~YtCHKxE_VImtFyGI#FJc^cur6*t4T*xzGsqg z1nY>@Y;GlI;1E-~p3e>MD!TSH0(9ozo*1t4F5i0bruC*OU$DKL>%jdWYggGa2mM^U zvb8*0Wo)B7RLRcBAV2qQY5$O^h$6 z&QE|OV9O=@j(_Fb{m*^6|A|)5?%zLd=&0jcj>$Ts&JExGM6?r|M)REE)!Wo+Y0Mn* zmI;cdO^gH>YLP$P$`I9?{VAIpyp^zxho9GMlh;MDPmH-2r~%yE86SRf*~zaZ$9$gA zjOTuL?G3_yA930*fi;d!#19}>f@C^lhkph6vGs|CLH-rOU@>)i5x0Uo4IypGha>+? z@|x(yr-vDXeLE)iW;8!IWLofDtvX+4VP!0NyLx)RBBnQunL_?0@&}WTMi`HGGl9w* zlGmY;sBGS;P3!~m;eg)F9;Y5i<__w~B0sl@;rkR^K!H70|vNQL_XA^qCYWCK_XOVnCygV-POQ18)Apa|Raf-b-&g;lK z_b}#S^2g98UG#Q_H!=1Fr5{fuAKnfB2=eb6@C`@a5`7Tu&95MuZ({i^6IUXQ?@ICu z+f$Z&40`#==OK^K8Ro8@_(hPf%U}(ed?D>vO+FmCL&z^f=+WeV;5;M3^z$3Ovia6U z?sW1M&=Fa=lC?KZoB%F_xUhDC?ZZ7n2(CA6NdS)cb>0KnM68GEX=yiHrRB7dXm|Tob+WRJ| z68-f#I$g%~8C40r&Sb2)nQ4hzV%&_Xl=7 z*Dnp7F4xP`uSgG5wk2bZVqip7s($`g?R0PstDpZ>=ra1N`uSg#{;GcdSE09fAFqD? zSFOLQpZ`_sugEm=yazhX(9W61Zg4rfB0g2(j{#F5A?J3hV1_l zq=oGN;cUTMGg}_q|6}~Hv9@f;{vY%53oR{V|Bs-&ko`Y`w2=Kjg0ztRKZ3N7{Xc@V zko`Y`w2=Kjg0ztRKZ3N7{Xc@Vko`Y`w2=Kjg0ztRKZ3N7{XZs*_3Yfk_Wua-h3x;a zvdby9uR`|!2=ayO|1o8F7t0s2|A({VZO!V#BK~>%e`HN`^@i;KF?ob%i`$yj0P%VI ze{gNs>mX$RkKpwZvj0br7P9|GkQTE4N04@i{XgK-;z!v2ADTDxXd(N51o_q!k#j5yC_gJgh6fetA1SMYieyK~SgUmVf4K2HZ2ylSEoA?XAkEtP-N<5SYD@+De+2nL_WuadLiYa%(n9wC zK%UhvWd9G*7=Od|{|M3!vHyoG0lcyy`+o$>y8S;+$M%kRm`8g54+X&vL?}AI@M2h) zdBNi(YgjBnL+HBh=$OCn9|+x#j;i$v36+ z4!%ivMTxHDEA5nzPBHDGOD*Fo$WBA2|JJ(jVYlA5IByYpeG+y3mDeT#L!BP14M$b- zO`SXky*}am-|vv~A$pxGBgkkq3X zrg{%&R>JdX@#6pc>N;9T{C{74M+=Gn@53V2D;pC3-`CL5LgN3scl{LJ?5FW>O*Zzc zzBtDh693#iBsP%f4HTE#Q!hI&#|* z57Lfc{Quzf7ZU&9*UXDG6Bhp;|7^|grr--0jQ_uNpQDAu|M&HDw2=7!z7CES693=V z+0jDc|NGiFT1fnVUpq$&iT{s}y458l{=cu4qeUqGzpt_96P1G3;064vF#i9e#Q&H7 zcN)ImwW{O)2lfE?HSzx!MS6C3$1 zByU-6(NvF;l@);*nlavtPbI#2^H!mpb4Dc(j@CEwHz??jtU z>LB0vsS9v`jYfa82hpq7Gf{OG=`U{&OLN7p=+kR*S#9zE@>=(I;)gkI5TkNz-v zMV~!7>n~?lZjb&ydz$k;F%`X{@jYiddPSc-3NcR5>$xa={~CNwG}@!^+(xf$_x;bV z@QN$uy5ECd(P)p-lF^FE#Hy=%`KlF;a#B;kg0RpquMVV&kwE&$;FO5FE zPDQ7j_0gwSAv%4e;Fi&pIFFyA({DCJlTzq{UeBP@UpGddUO%GK<}0F4uRo&G;wz(1 zuQlk@RY6#zDRF&`N2k@BqDd)qL9eyw^y<~or`LDrbob`y)9Yb$8onj^^qPWBOSeUz zUh&u4dAT@GHT(B}q-7Z%z~+vR-x#Xv{>ulVG5#TIX%8|t7xO>rp~|YIzb-?sXpDdS z33^3i{NvsaMQ8luOVKMD?M*&Lujuo0HKsSgQlrt{|NZ&H9>(P(e71HGcrp1jG9=(IOk zgkI5TZ}K>LN+TQM@RqMT^sMzs$t>^k`n>mh*cVdL1&&xH!Yp>t*!Px|Q83u(AyU zGm}DVtXz1EFEulr!>Ma4=Q;S1)MY<->yNFTv+Gv2-uQzTI;^Aqa;^}xoOp2T;*_gA zy-Lwb`*yM|AE|jIg))~-JiFsi9COOmhku$atInP=N;_~7L)9B=h%^St#R(*DDCH(;_S|5pJ>Cz|ISJ@C*Ky{k%*CBvV#DHiR+BOm^q-1=nAR-cfs%>HN+)oSQmC zVr0-vv*2{wU#(uS>sF_uOspZ6p-b*sc=dz*`}hC1&gyFFe*Oci*K+jIcP+Ohi5sBG zDcF=Mm;70Q4w)%yI=||T6R)6`)~%8~rlWqwS}DO_>5;=eF!=H{KjZCN%Z^`dUbO30 z9XyUId>HwECh`{%GRvk;nzViR#D;Az_sTcDyTE%6tw1mNN!xLvm6h#I4Y%Z=UsTyI zF0{k^qu5?wucDXMt?ZMr#ok9K!r`j@7HpOLpDLUiURZI4VW`l^*%U z2ZqrzHU+M)73d{D>3$x0(xGmy!+DehsyIZRTGn7<-8LN_*lH$k>K5dEbf@jF=h178 z-|iRB&hrP;D>GO)B1q=hlg}Bm{kGeVZWt;qpqKw;yKZGi`iY?|2jZCr5+e5d$szaK z@xYjUGgH0yi4ydZpR|1(_B~itM@}!*S~jX24)_v)PXK&!Ct5q-{^RTchm1^#*ZZYwDT@Z@k?*k4L>4o!{F_ z(Mx{PH8_uPrctl~UF-`+@b`ZS>AU$UdwuOfFRfeI>%L0wU;ZPYYvL1kwYT@?fz{+UR|jlE^jxn48uO#5E@GoAmJ1p2Ew{!bN70R2@R|EFsGRUQAQYW-Cm z|EFsGRUQAQYW-Cm|EFsGRUQAQYW-Cm|EFsGRUQAQYW-Cm|EFsGRUQAQYW-Cm|EFsG zRUQAQYW-Cm|EFsGRUQAQYW-Cm|EFsGRUQAQYW-Cm|EFsGRUQAQYW-Cm|EFsGRUQAQ zYW-Cm|EFsGRUQB5ko{F1|L2fhR0)IDAFJd4RMI&Wkm;}L_&*i&OJyYbt2+KqWt~$2 zo&Kth|5HJ~R7Rq|s^kAu);Sf>>96YeKNa*#WhDBmI{r^(ol^mw{;H1uQ$fE}Mxwu} zJm5{!e9{Qvsd+s*e9tLBCW+qQ9!+|5VmF70~Ig>i9nu z^h;$V`l~wrPi37`0iFI@w4*xyPX#?wF^T@Fj{j3}*HlQQzpCT^RM;~W6X~z&_&*hQ zO@&nYt2+Kqg*{U-k^ZWV|5I_-giyoQhoU+D&(gO7@mboN9sdbw!G9n1HMpvc=TEKp zKhn!avcapm_kUlRkQ#l}@qa>k<1o+z zxjOz&Sa%%qM|J$4Lv~RpLv{S0(B7yJ|NjyHr$W`MOxzJt;`|pId2tDfh)bY-(rwrV z;+Gt3PsJk|kptxjj_~B~&iC}%iC#^QGv+fiJI{O-qIrdAJ(HPqRv-#Xg&Y+Vx4yq{ z)t~-z+MiauTe#(zH@|=9ntgxz;ktMJy8qul744nLuZAR3+S~Ay%e{)Eho2TmBMD- z`0j-t@gWqU^u?9-1-Eyt(cbmd^bdBQ^pA;Pa-I2yS4(VJJg+!j3dHyF+n?^Q&wRc2 z2?ERQ-={wuDgk=*_B!1=tOTFu><(oEcbuxOzn!_Kz z>NayqMljROv0%GBkHzTKYbo|3j1#%$#>1;+$NrFrT!&Yr60RM8`s#_s->ulc|3CYm z*#8YoBl_Oz_181#rMT4%7*~@`dL_kwMt-&C&qxs<{MgbwyT$g`QOqesQ##Sb6@G_X zFmIwUOByrp!9%h)zc1$ZO@#PTyv~m%u@~O4#_R%K=lAsf#(WLv*)@Q?HMdF=j$I2( zXB^a6xOlQLk4|NeY#@?`_0w4A?W`AE}uHqVx<$7ud=(_6C z4V#|~uD1mG0o^YgLW~~z>rQkn9&F6$v36gi{akuS@n|ifUt;N_ockCofIjP)Bafp$ zfE7SGFbDX{7Gr({-e=#j=VL{2U`ub)--xfcTKi7`?3Q$bd z?LN*Obw5@EJxh4SsYPG@27aJ9_*u|z0KNe(gtiHIttQt1a14-lFMUnE16T;O=C_Z& z**k&x%!%C3x{Cy$n)S)EbTr(I(>W* zeY*;JovpM3{+j?lef=8x-vz!7xS8LZ$)5$L!k^p?9$;@*&IiyC{9W?6PMp_{#=Hca z3w!}w3)~OP0sI^v3-keIBjJJjbofj*4iW&D1f z*;>(p8;HR zH*>#fPlK7)8?zJqcCN)glGot;{>XD_K?BAj;0z!WC;{{hs5sBJ1D7}C-fBc2khdkj zjr?NrrQ}zWpGN)(@FBSN4oxFp%kSFc_W(}<5AwSw&%XuWYk*SVM_?cH*T{F0e@VWZ z{A-{cFr43;YT3AzyV3Jw;M`{zM|v1@LU+!4TN?wk7qoF>jJb3W=X{tkFC-hY8aNu- z`}AqoAv|;Fi_2;6zm8?>J|0~LGsbcbzTlZH^27+ zbHG;u=fe8}umV~Z@B{b=@)cR!d*ls(uE5Pe5y$EPCjdU`8VFnm-X0hP+z-ra$^D29 z15UNyxvR;$G~@S)j1jyS?(PXl&vY%RY>o?y&zKxg2D6+DxGV}KSw z(-VN1j92LP^$g0Bw*a~U`}zF}uo1`wrUIqF*}#*)Cd!@xX}z`5wVhvVy7Q3vp)pJxgA0^l*AJ8&m32+)49?*lKiW?Tdm@A_KuM}Y5uWBGj% zc{2GtU@B0+?^DS?BJY>ZyC?8Dzpo@$Tapvus{74ZgJM4GyS=Ps%7*t6<44BqJMTW_` zocC?hCqLXdZ%^mt_4c2*chLTXf4}+ll<6PWzGD6t3H=AveqwL?W}6F4+vlD6$C2GfcU%6=PhZw;yyEJyIfFib(YN`v=V$+Qi5aigyCfq%lv3~|0LDS zb!P51dkZX{W*+d~14JKT?lO-$o|^FJeNptL<_hnfP53Bto4Iq8r7wm5yxtan1^P}` zwk~Dg=N=S)Z*#AC-qDkx>z!Hj8pwRz(G#HS`&slc=%a64;mMNU)#AgDuWuvKlgtKh zoD!bKEb?Zj!}IXG<7CDo^DC#r(deLg2JyFmUY2h01hdV1hZTJ=`n=}awVZk%b2>Z? zuCY=)b*W3=YQp2up>D3l`$h3-o4zHjoDJR>Bs?CO&pUlyr>x%j zMQ=sfPn{0WAYbq1qK|;5lhdIWI>e5)^d<0UenUJ7)TQ@r;U^(S&kx}Z=^wpE3a?EY zzjN|mqU`5Rhfk2NcX9D7qHLa%IUbqsIvr}mGsNkTfexBC75^amxw+G)2$?lAE&W+= zz1NGU2$^~o2|osXe0?nb5i&JbBzk-E8}B<&cn#>QoemSxLC-kRJ5aV|rp2E_{?V@9 zv%ybtx^+c2eQS!pCUW%6B)mI1q`7)OhQ7hcpNxEcr-~;TdM_vcWn}8xM)Yx%)$>_+ z9dytAV_T^M~SRv^9Tsb&aDgeRqqVhMWgoy-lchm8I

m(EpXjxbe}~iI9m=+M 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 diff --git a/jp3d/codec/jp3d_vm_enc.sln b/jp3d/codec/jp3d_vm_enc.sln deleted file mode 100755 index a0e6a748..00000000 --- a/jp3d/codec/jp3d_vm_enc.sln +++ /dev/null @@ -1,35 +0,0 @@ -Microsoft Visual Studio Solution File, Format Version 8.00 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jp3d_vm_enc", "jp3d_vm_enc.vcproj", "{A9704A2E-3B93-4BAA-9229-02FC93D27201}" - ProjectSection(ProjectDependencies) = postProject - {6F3FB035-8F4E-4794-B091-0F0A20223BE7} = {6F3FB035-8F4E-4794-B091-0F0A20223BE7} - {6F3FB035-8F4E-4794-B091-0F0A20223BE7} = {6F3FB035-8F4E-4794-B091-0F0A20223BE7} - {6F3FB035-8F4E-4794-B091-0F0A20223BE7} = {6F3FB035-8F4E-4794-B091-0F0A20223BE7} - {6F3FB035-8F4E-4794-B091-0F0A20223BE7} = {6F3FB035-8F4E-4794-B091-0F0A20223BE7} - {6F3FB035-8F4E-4794-B091-0F0A20223BE7} = {6F3FB035-8F4E-4794-B091-0F0A20223BE7} - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LibJp3dVM", "..\LibJp3dVM.vcproj", "{6F3FB035-8F4E-4794-B091-0F0A20223BE7}" - ProjectSection(ProjectDependencies) = postProject - {6F3FB035-8F4E-4794-B091-0F0A20223BE7} = {6F3FB035-8F4E-4794-B091-0F0A20223BE7} - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfiguration) = preSolution - Debug = Debug - Release = Release - EndGlobalSection - GlobalSection(ProjectConfiguration) = postSolution - {A9704A2E-3B93-4BAA-9229-02FC93D27201}.Debug.ActiveCfg = Debug|Win32 - {A9704A2E-3B93-4BAA-9229-02FC93D27201}.Debug.Build.0 = Debug|Win32 - {A9704A2E-3B93-4BAA-9229-02FC93D27201}.Release.ActiveCfg = Release|Win32 - {A9704A2E-3B93-4BAA-9229-02FC93D27201}.Release.Build.0 = Release|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Debug.ActiveCfg = Debug|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Debug.Build.0 = Debug|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Release.ActiveCfg = Release|Win32 - {6F3FB035-8F4E-4794-B091-0F0A20223BE7}.Release.Build.0 = Release|Win32 - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - EndGlobalSection - GlobalSection(ExtensibilityAddIns) = postSolution - EndGlobalSection -EndGlobal diff --git a/jp3d/codec/jp3d_vm_enc.suo b/jp3d/codec/jp3d_vm_enc.suo deleted file mode 100755 index 702d0dd81ee6aa926631769e00fd21bde422b579..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 21504 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 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/jp3d/codec/volume_to_jp3d.c b/jp3d/codec/volume_to_jp3d.c deleted file mode 100755 index 84f01e83..00000000 --- a/jp3d/codec/volume_to_jp3d.c +++ /dev/null @@ -1,903 +0,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, Hervé 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 -#include -#include - -#include "openjpeg.h" -#include "getopt.h" -#include "convert.h" - -#ifndef WIN32 -#define stricmp strcasecmp -#define strnicmp strncasecmp -#endif - -/* ----------------------------------------------------------------------- */ - -void encode_help_display() { - fprintf(stdout,"List of parameters for the JPEG2000 Part 10 encoder:\n"); - fprintf(stdout,"------------\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"Required Parameters (except with -h):\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-i : source file (-i source.bin or source*.pgx) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-m : source characteristics file (-m imgfile.img) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-o : destination file (-o dest.jp3d) \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,"-n : number of resolutions (-n 3,3,3) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-I : use the irreversible transforms: ICT + DWT 9-7 (-I) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-C : coding algorithm (-C 2EB) [2EB, 3EB] \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 compression factor.\n"); - fprintf(stdout," - Rate 1 means lossless compression\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,"-b : size of code block (-b 32,32,32) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-c : size of precinct (-c 128,128,128) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-t : size of tile (-t 512,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,2) [-s X,Y,Z] \n"); - fprintf(stdout," - Remark: subsampling bigger than 2 can produce error\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 : code-block style (-M 0) [1=BYPASS(LAZY) 2=RESET 4=RESTART(TERMALL)\n"); - fprintf(stdout," 8=VSC 16=PTERM 32=SEGSYM 64=3DCTXT] \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,"-D : define DC offset (-D 12) \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 volume (-d 150,300,100) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"-l : offset of the origin of the tiles (-l 100,75,25) \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"DEFAULT CODING:\n"); - fprintf(stdout,"------------\n"); - fprintf(stdout,"\n"); - fprintf(stdout," * Lossless\n"); - fprintf(stdout," * 1 tile\n"); - fprintf(stdout," * Size of precinct : 2^15 x 2^15 x 2^15 (means 1 precinct)\n"); - fprintf(stdout," * Size of code-block : 64 x 64 x 64\n"); - fprintf(stdout," * Number of resolutions in x, y and z axis: 3\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, y or z 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 volume\n"); - fprintf(stdout," * No offset of the origin of the tiles\n"); - fprintf(stdout," * Reversible DWT 5-3 on each 2D slice\n"); - fprintf(stdout," * Coding algorithm: 2D-EBCOT \n"); - fprintf(stdout,"\n"); - fprintf(stdout,"REMARKS:\n"); - fprintf(stdout,"---------\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"- The markers written to the main_header are : SOC SIZ COD QCD COM.\n"); - fprintf(stdout,"- COD and QCD markers will never appear in the tile_header.\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"- You need enough disk space memory (twice the original) to encode \n"); - fprintf(stdout,"the volume,i.e. for a 1.5 GB volume you need a minimum of 3GB of disk memory)\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"- When loading *.pgx files, a relative path to directory is needed for input argument \n"); - fprintf(stdout," followed by the common prefix of the slices and a '*' character representing sequential numeration.\n"); - fprintf(stdout,"( -i relativepath/slices*.pgx )\n"); - fprintf(stdout,"\n"); - fprintf(stdout," - The index file has the structure below:\n"); - fprintf(stdout,"\n"); - fprintf(stdout,"\t Image_height Image_width Image_depth\n"); - fprintf(stdout,"\t Progression order: 0 (LRCP)\n"); - fprintf(stdout,"\t Tiles_size_X Tiles_size_Y Tiles_size_Z\n"); - fprintf(stdout,"\t Components_nb\n"); - fprintf(stdout,"\t Layers_nb\n"); - fprintf(stdout,"\t Decomposition_levels\n"); - fprintf(stdout,"\t [Precincts_size_X_res_Nr Precincts_size_Y_res_Nr Precincts_size_Z_res_Nr]\n\t ...\n"); - fprintf(stdout,"\t [Precincts_size_X_res_0 Precincts_size_Y_res_0 Precincts_size_Z_res_0]\n"); - fprintf(stdout,"\t Main_header_end_position\n"); - fprintf(stdout,"\t Codestream_size\n"); - fprintf(stdout,"\t Tile_0 [start_pos end_header end_pos TotalDisto NumPix MaxMSE]\n"); - fprintf(stdout,"\t ...\n"); - fprintf(stdout,"\t Tile_Nt [ '' '' '' '' '' '' ]\n"); - fprintf(stdout,"\t Tpacket_0 [Tile layer res. comp. prec. start_pos end_pos disto]\n"); - fprintf(stdout,"\t ...\n"); - fprintf(stdout,"\t Tpacket_Np ['' '' '' '' '' '' '' '' ]\n"); - fprintf(stdout,"\t MaxDisto\n"); - fprintf(stdout,"\t TotalDisto\n\n"); - fprintf(stdout,"\n"); - -} - -OPJ_PROG_ORDER give_progression(char progression[4]) { - if(strncmp(progression, "LRCP", 4) == 0) { - return LRCP; - } - if(strncmp(progression, "RLCP", 4) == 0) { - return RLCP; - } - if(strncmp(progression, "RPCL", 4) == 0) { - return RPCL; - } - if(strncmp(progression, "PCRL", 4) == 0) { - return PCRL; - } - if(strncmp(progression, "CPRL", 4) == 0) { - return CPRL; - } - - return PROG_UNKNOWN; -} - -OPJ_TRANSFORM give_transform(char transform[4]) { - if(strncmp(transform, "2DWT", 4) == 0) { - return TRF_2D_DWT; - } - if(strncmp(transform, "3DWT", 4) == 0) { - return TRF_3D_DWT; - } - return TRF_UNKNOWN; -} - -OPJ_ENTROPY_CODING give_coding(char coding[3]) { - - if(strncmp(coding, "2EB", 3) == 0) { - return ENCOD_2EB; - } - if(strncmp(coding, "3EB", 3) == 0) { - return ENCOD_3EB; - } - /*if(strncmp(coding, "2GR", 3) == 0) { - return ENCOD_2GR; - } - if(strncmp(coding, "3GR", 3) == 0) { - return ENCOD_3GR; - }*/ - - return ENCOD_UNKNOWN; -} - -int get_file_format(char *filename) { - int i; - static const char *extension[] = {"pgx", "bin", "img", "j3d", "jp3d", "j2k"}; - static const int format[] = { PGX_DFMT, BIN_DFMT, IMG_DFMT, J3D_CFMT, J3D_CFMT, J2K_CFMT}; - char * ext = strrchr(filename, '.') + 1; - if (ext) { - for(i = 0; i < sizeof(format)/sizeof(*format); i++) { - if(strnicmp(ext, extension[i], 3) == 0) { - return format[i]; - } - } - } - - return -1; -} - -/* ------------------------------------------------------------------------------------ */ - -int parse_cmdline_encoder(int argc, char **argv, opj_cparameters_t *parameters) { - int i, value; - - /* parse the command line */ - - while (1) { - int c = getopt(argc, argv, "i:m:o:r:q:f:t:n:c:b:x:p:s:d:hP:S:E:M:D:R:l:T:C:A:I"); - if (c == -1) - break; - switch (c) { - case 'i': /* input file */ - { - char *infile = optarg; - parameters->decod_format = get_file_format(infile); - switch(parameters->decod_format) { - case PGX_DFMT: - case BIN_DFMT: - case IMG_DFMT: - break; - default: - fprintf(stdout, "[ERROR] Unrecognized format for infile : %s [accept only *.pgx or *.bin] !!\n\n", infile); - return 1; - break; - } - strncpy(parameters->infile, infile, MAX_PATH); - fprintf(stdout, "[INFO] Infile: %s \n", parameters->infile); - - } - break; - - /* ----------------------------------------------------- */ - case 'm': /* input IMG file */ - { - char *imgfile = optarg; - int imgformat = get_file_format(imgfile); - switch(imgformat) { - case IMG_DFMT: - break; - default: - fprintf(stdout, "[ERROR] Unrecognized format for imgfile : %s [accept only *.img] !!\n\n", imgfile); - return 1; - break; - } - strncpy(parameters->imgfile, imgfile, MAX_PATH); - fprintf(stdout, "[INFO] Imgfile: %s Format: %d\n", parameters->imgfile, imgformat); - } - break; - - /* ----------------------------------------------------- */ - case 'o': /* output file */ - { - char *outfile = optarg; - parameters->cod_format = get_file_format(outfile); - switch(parameters->cod_format) { - case J3D_CFMT: - case J2K_CFMT: - case LSE_CFMT: - break; - default: - fprintf(stdout, "[ERROR] Unknown output format volume %s [only *.j2k, *.lse3d or *.jp3d]!! \n", outfile); - return 1; - break; - } - strncpy(parameters->outfile, outfile, MAX_PATH); - fprintf(stdout, "[INFO] Outfile: %s \n", parameters->outfile); - } - break; - - /* ----------------------------------------------------- */ - - case 'r': /* define compression rates for each layer */ - { - char *s = optarg; - 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 'q': /* define distorsion (PSNR) for each layer */ - { - char *s = 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; - - /* ----------------------------------------------------- */ - - case 'f': - { - fprintf(stdout, "/---------------------------------------------------\\\n"); - fprintf(stdout, "| Fixed layer allocation option not implemented !! |\n"); - fprintf(stdout, "\\---------------------------------------------------/\n"); - /*int *row = NULL, *col = NULL; - int numlayers = 0, matrix_width = 0; - - char *s = optarg; - sscanf(s, "%d", &numlayers); - s++; - if (numlayers > 9) - s++; - - parameters->tcp_numlayers = numlayers; - matrix_width = parameters->numresolution[0] + parameters->numresolution[1] + parameters->numresolution[2]; - 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 < matrix_width; j++) { - col += 3; j+=2; - 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 */ - { - if (sscanf(optarg, "%d,%d,%d", ¶meters->cp_tdx, ¶meters->cp_tdy, ¶meters->cp_tdz) !=3) { - fprintf(stdout, "[ERROR] '-t' 'dimensions of tiles' argument error ! [-t tdx,tdy,tdz]\n"); - return 1; - } - parameters->tile_size_on = true; - } - break; - - /* ----------------------------------------------------- */ - - case 'n': /* resolution */ - { - int aux; - aux = sscanf(optarg, "%d,%d,%d", ¶meters->numresolution[0], ¶meters->numresolution[1], ¶meters->numresolution[2]); - if (aux == 2) - parameters->numresolution[2] = 1; - else if (aux == 1) { - parameters->numresolution[1] = parameters->numresolution[0]; - parameters->numresolution[2] = 1; - }else if (aux == 0){ - parameters->numresolution[0] = 1; - parameters->numresolution[1] = 1; - parameters->numresolution[2] = 1; - } - } - break; - - /* ----------------------------------------------------- */ - case 'c': /* precinct dimension */ - { - char sep; - int res_spec = 0; - int aux; - char *s = optarg; - do { - sep = 0; - aux = sscanf(s, "[%d,%d,%d]%c", ¶meters->prct_init[0][res_spec], ¶meters->prct_init[1][res_spec], ¶meters->prct_init[2][res_spec], &sep); - if (sep == ',' && aux != 4) { - fprintf(stdout, "[ERROR] '-c' 'dimensions of precincts' argument error ! [-c [prcx_res0,prcy_res0,prcz_res0],...,[prcx_resN,prcy_resN,prcz_resN]]\n"); - return 1; - } - parameters->csty |= 0x01; - res_spec++; - s = strpbrk(s, "]") + 2; - } - while (sep == ','); - parameters->res_spec = res_spec; /* number of precinct size specifications */ - } - break; - - /* ----------------------------------------------------- */ - - case 'b': /* code-block dimension */ - { - int cblockw_init = 0, cblockh_init = 0, cblockl_init = 0; - if (sscanf(optarg, "%d,%d,%d", &cblockw_init, &cblockh_init, &cblockl_init) != 3) { - fprintf(stdout, "[ERROR] '-b' 'dimensions of codeblocks' argument error ! [-b cblkx,cblky,cblkz]\n"); - return 1; - } - if (cblockw_init * cblockh_init * cblockl_init > (1<<18) || cblockw_init > 1024 || cblockw_init < 4 || cblockh_init > 1024 || cblockh_init < 4 || cblockl_init > 1024 || cblockl_init < 4) { - fprintf(stdout,"[ERROR] Size of code_block error (option -b) !!\n\nRestriction :\n * width*height*length<=4096\n * 4<=width,height,length<= 1024\n\n"); - return 1; - } - parameters->cblock_init[0] = cblockw_init; - parameters->cblock_init[1] = cblockh_init; - parameters->cblock_init[2] = cblockl_init; - } - break; - - /* ----------------------------------------------------- */ - - case 'x': /* creation of index file */ - { - char *index = optarg; - strncpy(parameters->index, index, MAX_PATH); - parameters->index_on = 1; - } - break; - - /* ----------------------------------------------------- */ - - case 'p': /* progression order */ - { - char progression[4]; - - strncpy(progression, optarg, 4); - parameters->prog_order = give_progression(progression); - if (parameters->prog_order == -1) { - fprintf(stdout, "[ERROR] Unrecognized progression order [LRCP, RLCP, RPCL, PCRL, CPRL] !!\n"); - return 1; - } - } - break; - - /* ----------------------------------------------------- */ - - case 's': /* subsampling factor */ - { - if (sscanf(optarg, "%d,%d,%d", ¶meters->subsampling_dx, ¶meters->subsampling_dy, ¶meters->subsampling_dz) != 2) { - fprintf(stdout, "[ERROR] '-s' sub-sampling argument error ! [-s dx,dy,dz]\n"); - return 1; - } - } - break; - - /* ----------------------------------------------------- */ - - case 'd': /* coordonnate of the reference grid */ - { - if (sscanf(optarg, "%d,%d,%d", ¶meters->volume_offset_x0, ¶meters->volume_offset_y0, ¶meters->volume_offset_z0) != 3) { - fprintf(stdout, "[ERROR] -d 'coordonnate of the reference grid' argument error !! [-d x0,y0,z0]\n"); - return 1; - } - } - break; - - /* ----------------------------------------------------- */ - - case 'h': /* display an help description */ - { - encode_help_display(); - return 1; - } - break; - - /* ----------------------------------------------------- */ - - case 'P': /* POC */ - { - int numpocs = 0; /* number of progression order change (POC) default 0 */ - opj_poc_t *POC = NULL; /* POC : used in case of Progression order change */ - - char *s = optarg; - POC = parameters->POC; - - fprintf(stdout, "/----------------------------------\\\n"); - fprintf(stdout, "| POC option not fully tested !! |\n"); - fprintf(stdout, "\\----------------------------------/\n"); - - while (sscanf(s, "T%d=%d,%d,%d,%d,%d,%s", &POC[numpocs].tile, - &POC[numpocs].resno0, &POC[numpocs].compno0, - &POC[numpocs].layno1, &POC[numpocs].resno1, - &POC[numpocs].compno1, POC[numpocs].progorder) == 7) { - POC[numpocs].prg = give_progression(POC[numpocs].progorder); - /* POC[numpocs].tile; */ - 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': /* Codification mode switch */ - { - fprintf(stdout, "[INFO] Mode switch option not fully tested !!\n"); - value = 0; - if (sscanf(optarg, "%d", &value) == 1) { - for (i = 0; i <= 6; i++) { - int cache = value & (1 << i); - if (cache) - parameters->mode |= (1 << i); - } - } - } - break; - - /* ------------------------------------------------------ */ - - case 'D': /* DCO */ - { - if (sscanf(optarg, "%d", ¶meters->dcoffset) != 1) { - fprintf(stdout, "[ERROR] DC offset error !! [-D %d]\n",parameters->dcoffset); - return 1; - } - } - break; - - /* ------------------------------------------------------ */ - - case 'R': /* ROI */ - { - if (sscanf(optarg, "OI:c=%d,U=%d", ¶meters->roi_compno, ¶meters->roi_shift) != 2) { - fprintf(stdout, "[ERROR] ROI error !! [-ROI:c='compno',U='shift']\n"); - return 1; - } - } - break; - - /* ------------------------------------------------------ */ - - case 'l': /* Tile offset */ - { - if (sscanf(optarg, "%d,%d,%d", ¶meters->cp_tx0, ¶meters->cp_ty0, ¶meters->cp_tz0) != 3) { - fprintf(stdout, "[ERROR] -l 'tile offset' argument error !! [-l X0,Y0,Z0]"); - return 1; - } - } - break; - - /* ------------------------------------------------------ - - case 'T': // Tranformation of original data (2D-DWT/3D-DWT/3D-RLS/2D-DWT+1D-RLS) - { - char transform[4]; - - strncpy(transform, optarg, 4); - parameters->transform_format = give_transform(transform); - if (parameters->transform_format == -1) { - fprintf(stdout, "[ERROR] -T 'Transform domain' argument error !! [-T 2DWT, 3DWT, 3RLS or 3LSE only]"); - return 1; - } - } - break; - - ------------------------------------------------------ */ - - case 'C': /* Coding of transformed data */ - { - char coding[3]; - - strncpy(coding, optarg, 3); - parameters->encoding_format = give_coding(coding); - if (parameters->encoding_format == -1) { - fprintf(stdout, "[ERROR] -C 'Coding algorithm' argument error !! [-C 2EB, 3EB, 2GR, 3GR or GRI only]"); - return 1; - } - } - break; - - /* ------------------------------------------------------ */ - - case 'I': /* reversible or not */ - { - parameters->irreversible = 1; - } - break; - - default: - fprintf(stdout, "[ERROR] This option is not valid \"-%c %s\"\n", c, optarg); - return 1; - } - } - - /* check for possible errors */ - - if((parameters->infile[0] == 0) || (parameters->outfile[0] == 0)) { - fprintf(stdout, "usage: jp3d_vm_enc -i volume-file -o jp3d-file (+ options)\n"); - return 1; - } - - if((parameters->decod_format == BIN_DFMT) && (parameters->imgfile[0] == 0)) { - fprintf(stdout, "usage: jp3d_vm_enc -i bin-volume-file -m img-file -o jp3d-file (+ options)\n"); - return 1; - } - - if((parameters->decod_format != BIN_DFMT) && (parameters->decod_format != PGX_DFMT) && (parameters->decod_format != IMG_DFMT)) { - fprintf(stdout, "usage: jp3d_vm_enc -i input-volume-file [*.bin,*.pgx,*.img] -o jp3d-file [*.jp3d,*.j2k] (+ options)\n"); - return 1; - } - if((parameters->cod_format != J3D_CFMT) && (parameters->cod_format != J2K_CFMT)) { - fprintf(stdout, "usage: jp3d_vm_enc -i input-volume-file [*.bin,*.pgx,*.img] -o jp3d-file [*.jp3d,*.j2k] (+ options)\n"); - return 1; - } - - if((parameters->encoding_format == ENCOD_2GR || parameters->encoding_format == ENCOD_3GR) && parameters->transform_format != TRF_3D_LSE && parameters->transform_format != TRF_3D_RLS) { - fprintf(stdout, "[ERROR] Entropy coding options -C [2GR,3GR] are only compatible with predictive-based transform algorithms: -T [3RLS,3LSE].\n"); - return 1; - } - if (parameters->encoding_format == ENCOD_3EB) - parameters->mode |= (1 << 6); - - if ((parameters->mode >> 6) & 1) { - parameters->encoding_format = ENCOD_3EB; - } - - if((parameters->numresolution[2] == 0 || (parameters->numresolution[1] == 0) || (parameters->numresolution[0] == 0))) { - fprintf(stdout, "[ERROR] -n 'resolution levels' argument error ! Resolutions must be greater than 1 in order to perform DWT.\n"); - return 1; - } - if (parameters->numresolution[1] != parameters->numresolution[0]) { - fprintf(stdout, "[ERROR] -n 'resolution levels' argument error ! Resolutions in X and Y axis must be the same in this implementation.\n"); - return 1; - } - - if (parameters->numresolution[2] > parameters->numresolution[0]) { - fprintf(stdout, "[ERROR] -n 'resolution levels' argument error ! Resolutions in Z axis must be lower than in X-Y axis.\n"); - return 1; - } - - if (parameters->dcoffset >= 128 && parameters->dcoffset <= -128) { - fprintf(stdout, "[ERROR] -D 'DC offset' argument error ! Value must be -128<=DCO<=128.\n"); - return 1; - } - - if(parameters->numresolution[2] != 1) { - parameters->transform_format = TRF_3D_DWT; - //fprintf(stdout, "[Warning] Resolution level in axial dim > 1 : 3D-DWT will be performed... \n"); - } else if (parameters->numresolution[2] == 1) { - parameters->transform_format = TRF_2D_DWT; - //fprintf(stdout, "[Warning] Resolution level in axial dim == 1 : 2D-DWT will be performed... \n"); - } - - if ((parameters->cod_format == J2K_CFMT) && (parameters->transform_format != TRF_2D_DWT || parameters->encoding_format != ENCOD_2EB)) { - fprintf(stdout, "[WARNING] Incompatible options -o *.j2k and defined transform or encoding algorithm. Latter will be ignored\n"); - parameters->transform_format = TRF_2D_DWT; - parameters->encoding_format = ENCOD_2EB; - } - - if ((parameters->cp_disto_alloc || parameters->cp_fixed_alloc || parameters->cp_fixed_quality) && (!(parameters->cp_disto_alloc ^ parameters->cp_fixed_quality))) { - fprintf(stdout, "[ERROR] Options -r and -q 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.0; /* MOD antonin : losslessbug */ - parameters->tcp_numlayers++; - parameters->cp_disto_alloc = 1; - } - - if((parameters->cp_tx0 > parameters->volume_offset_x0) || (parameters->cp_ty0 > parameters->volume_offset_y0) || (parameters->cp_tz0 > parameters->volume_offset_z0)) { - fprintf(stdout, "[ERROR] Tile offset dimension is unnappropriate --> TX0(%d)<=IMG_X0(%d) TYO(%d)<=IMG_Y0(%d) TZO(%d)<=IMG_Z0(%d)\n", - parameters->cp_tx0, parameters->volume_offset_x0, parameters->cp_ty0, parameters->volume_offset_y0, - parameters->cp_tz0, parameters->volume_offset_z0); - return 1; - } - - for (i = 0; i < parameters->numpocs; i++) { - if (parameters->POC[i].prg == -1) { - fprintf(stdout,"[ERROR] 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 -*/ -void error_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[ERROR] %s", msg); -} -/** -sample warning callback expecting a FILE* client object -*/ -void warning_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[WARNING] %s", msg); -} -/** -sample debug callback expecting a FILE* client object -*/ -void info_callback(const char *msg, void *client_data) { - FILE *stream = (FILE*)client_data; - fprintf(stream, "[INFO] %s", msg); -} - -/* -------------------------------------------------------------------------- */ - -int main(int argc, char **argv) { - bool bSuccess; - bool delete_comment = true; - opj_cparameters_t parameters; /* compression parameters */ - opj_event_mgr_t event_mgr; /* event manager */ - opj_volume_t *volume = NULL; - - /* - configure the event callbacks (not required) - setting of each callback is optionnal - */ - memset(&event_mgr, 0, sizeof(opj_event_mgr_t)); - event_mgr.error_handler = error_callback; - event_mgr.warning_handler = warning_callback; - event_mgr.info_handler = info_callback; - - /* set encoding parameters to default values */ - opj_set_default_encoder_parameters(¶meters); - - /* parse input and get user encoding parameters */ - if(parse_cmdline_encoder(argc, argv, ¶meters) == 1) { - return 0; - } - - if(parameters.cp_comment == NULL) { - parameters.cp_comment = "Created by OpenJPEG version JP3D"; - /* no need to delete parameters.cp_comment on exit */ - delete_comment = false; - } - - /* encode the destination volume */ - /* ---------------------------- */ - if (parameters.cod_format == J3D_CFMT || parameters.cod_format == J2K_CFMT) { - int codestream_length, pixels, bitsin; - opj_cio_t *cio = NULL; - FILE *f = NULL; - opj_cinfo_t* cinfo = NULL; - - /* decode the source volume */ - /* ----------------------- */ - switch (parameters.decod_format) { - case PGX_DFMT: - fprintf(stdout, "[INFO] Loading pgx file(s)\n"); - volume = pgxtovolume(parameters.infile, ¶meters); - if (!volume) { - fprintf(stdout, "[ERROR] Unable to load pgx files\n"); - return 1; - } - break; - - case BIN_DFMT: - fprintf(stdout, "[INFO] Loading bin file\n"); - volume = bintovolume(parameters.infile, parameters.imgfile, ¶meters); - if (!volume) { - fprintf(stdout, "[ERROR] Unable to load bin file\n"); - return 1; - } - break; - - case IMG_DFMT: - fprintf(stdout, "[INFO] Loading img file\n"); - volume = imgtovolume(parameters.infile, ¶meters); - if (!volume) { - fprintf(stderr, "[ERROR] Unable to load img file\n"); - return 1; - } - break; - } - - /* get a JP3D or J2K compressor handle */ - if (parameters.cod_format == J3D_CFMT) - cinfo = opj_create_compress(CODEC_J3D); - else if (parameters.cod_format == J2K_CFMT) - cinfo = opj_create_compress(CODEC_J2K); - - /* catch events using our callbacks and give a local context */ - opj_set_event_mgr((opj_common_ptr)cinfo, &event_mgr, stdout); - - /* setup the encoder parameters using the current volume and using user parameters */ - opj_setup_encoder(cinfo, ¶meters, volume); - - /* open a byte stream for writing */ - /* allocate memory for all tiles */ - cio = opj_cio_open((opj_common_ptr)cinfo, NULL, 0); - - /* encode the volume */ - //fprintf(stdout, "[INFO] Encode the volume\n"); - bSuccess = opj_encode(cinfo, cio, volume, parameters.index); - if (!bSuccess) { - opj_cio_close(cio); - fprintf(stdout, "[ERROR] Failed to encode volume\n"); - return 1; - } - codestream_length = cio_tell(cio); - pixels =(volume->x1 - volume->x0) * (volume->y1 - volume->y0) * (volume->z1 - volume->z0); - bitsin = pixels * volume->comps[0].prec; - fprintf(stdout, "[RESULT] Volume: %d x %d x %d (x %d bpv)\n Codestream: %d B, Ratio: %5.3f bpv, (%5.3f : 1) \n", - (volume->x1 - volume->x0),(volume->y1 - volume->y0),(volume->z1 - volume->z0),volume->comps[0].prec, - codestream_length, ((double)codestream_length * 8.0/(double)pixels), ((double)bitsin/(8.0*(double)codestream_length))); - - /* write the buffer to disk */ - f = fopen(parameters.outfile, "wb"); - if (!f) { - fprintf(stdout, "[ERROR] Failed to open %s for writing\n", parameters.outfile); - return 1; - } - fwrite(cio->buffer, 1, codestream_length, f); - fclose(f); - - /* close and free the byte stream */ - opj_cio_close(cio); - - /* free remaining compression structures */ - opj_destroy_compress(cinfo); - } else { - fprintf(stdout, "[ERROR] Cod_format != JP3d !!! \n"); - return 1; - } - - /* free user parameters structure */ - if(delete_comment) { - if(parameters.cp_comment) free(parameters.cp_comment); - } - if(parameters.cp_matrice) free(parameters.cp_matrice); - - /* free volume data */ - opj_volume_destroy(volume); - - return 0; -} diff --git a/jp3d/libjp3dvm/CMakeLists.txt b/jp3d/libjp3dvm/CMakeLists.txt deleted file mode 100644 index 17a094af..00000000 --- a/jp3d/libjp3dvm/CMakeLists.txt +++ /dev/null @@ -1,24 +0,0 @@ -INCLUDE_REGULAR_EXPRESSION("^.*$") -# Defines the source code for the library -SET(JP3DVM_SRCS -bio.c cio.c dwt.c event.c jp3d.c jp3d_lib.c mct.c mqc.c openjpeg.c pi.c raw.c t1.c t1_3d.c t2.c tcd.c tgt.c volume.c -) - -# Pass proper definition to preprocessor to generate shared lib -IF(WIN32) - IF(BUILD_SHARED_LIBS) - ADD_DEFINITIONS(-DOPJ_EXPORTS) - ELSE(BUILD_SHARED_LIBS) - ADD_DEFINITIONS(-DOPJ_STATIC) - ENDIF(BUILD_SHARED_LIBS) -ENDIF(WIN32) - -# Create the library -#ADD_LIBRARY(${OPENJPEG_LIBRARY_NAME} ${OPENJPEG_SRCS}) -ADD_LIBRARY(${OPJ_PREFIX}openjp3dvm ${JP3DVM_SRCS}) - -# Install library -INSTALL_TARGETS(/lib/ ${OPJ_PREFIX}openjp3dvm) - -# Install includes files -INSTALL_FILES(/include .h) diff --git a/jp3d/libjp3dvm/bio.c b/jp3d/libjp3dvm/bio.c deleted file mode 100755 index 3ac93158..00000000 --- a/jp3d/libjp3dvm/bio.c +++ /dev/null @@ -1,189 +0,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, Hervé 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/jp3d/libjp3dvm/bio.h b/jp3d/libjp3dvm/bio.h deleted file mode 100755 index c65103bd..00000000 --- a/jp3d/libjp3dvm/bio.h +++ /dev/null @@ -1,132 +0,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, Hervé 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(); -/** -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/jp3d/libjp3dvm/cio.c b/jp3d/libjp3dvm/cio.c deleted file mode 100755 index 8814a33b..00000000 --- a/jp3d/libjp3dvm/cio.c +++ /dev/null @@ -1,217 +0,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, Hervé 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. - */ -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. - */ -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/jp3d/libjp3dvm/cio.h b/jp3d/libjp3dvm/cio.h deleted file mode 100755 index c6ad109f..00000000 --- a/jp3d/libjp3dvm/cio.h +++ /dev/null @@ -1,100 +0,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, Hervé 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 openjpeg.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/jp3d/libjp3dvm/dwt.c b/jp3d/libjp3dvm/dwt.c deleted file mode 100755 index 39ee15c2..00000000 --- a/jp3d/libjp3dvm/dwt.c +++ /dev/null @@ -1,1016 +0,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, Hervé 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. - */ - -/* - * NOTE: - * This is a modified version of the openjpeg dwt.c file. - * Average speed improvement compared to the original file (measured on - * my own machine, a P4 running at 3.0 GHz): - * 5x3 wavelets about 2 times faster - * 9x7 wavelets about 3 times faster - * for both, encoding and decoding. - * - * The better performance is caused by doing the 1-dimensional DWT - * within a temporary buffer where the data can be accessed sequential - * for both directions, horizontal and vertical. The 2d vertical DWT was - * the major bottleneck in the former version. - * - * I have also removed the "Add Patrick" part because it is not longer - * needed. - * - * 6/6/2005 - * -Ive (aka Reiner Wahler) - * mail: ive@lilysoft.com - */ - -#include "opj_includes.h" - -/** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ -/*@{*/ - -/** @name Local static functions */ -/*@{*/ -unsigned int ops; -/** -Forward lazy transform (horizontal) -*/ -static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas); -/** -Forward lazy transform (vertical) -*/ -static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas); -/** -Forward lazy transform (axial) -*/ -static void dwt_deinterleave_z(int *a, int *b, int dn, int sn, int xy, int cas); -/** -Inverse lazy transform (horizontal) -*/ -static void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas); -/** -Inverse lazy transform (vertical) -*/ -static void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas); -/** -Inverse lazy transform (axial) -*/ -static void dwt_interleave_z(int *a, int *b, int dn, int sn, int xy, int cas); -/** -Forward 5-3 wavelet tranform in 1-D -*/ -static void dwt_encode_53(int *a, int dn, int sn, int cas); -static void dwt_encode_97(int *a, int dn, int sn, int cas); -/** -Inverse 5-3 wavelet tranform in 1-D -*/ -static void dwt_decode_53(int *a, int dn, int sn, int cas); -static void dwt_decode_97(int *a, int dn, int sn, int cas); -/** -Computing of wavelet transform L2 norms for arbitrary transforms -*/ -static double dwt_calc_wtnorms(int orient, int level[3], int dwtid[3], opj_wtfilt_t *wtfiltx, opj_wtfilt_t *wtfilty, opj_wtfilt_t *wtfiltz); -/** -Encoding of quantification stepsize -*/ -static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize); -/*@}*/ - -/*@}*/ - -#define S(i) a[(i)*2] -#define D(i) a[(1+(i)*2)] -#define S_(i) ((i)<0?S(0):((i)>=sn?S(sn-1):S(i))) -#define D_(i) ((i)<0?D(0):((i)>=dn?D(dn-1):D(i))) -/* new */ -#define SS_(i) ((i)<0?S(0):((i)>=dn?S(dn-1):S(i))) -#define DD_(i) ((i)<0?D(0):((i)>=sn?D(sn-1):D(i))) - -/*

*/ -/* This table contains the norms of the 5-3 wavelets for different bands. */ -/* */ -static double dwt_norm[10][10][10][8]; -static int flagnorm[10][10][10][8]; - -/*static const double dwt_norms[5][8][10] = { - {//ResZ=1 - {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, - {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, - {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, - {.7186, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93} - },{//ResZ=2 - {1.000, 1.8371, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, - {1.2717, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, - {1.2717, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, - {.8803, .9218, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}, - {1.2717}, - {.8803}, - {.8803}, - {.6093}, - },{ //ResZ=3 - {1.000, 1.8371, 4.5604, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, - {1.2717, 2.6403, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, - {1.2717, 2.6403, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, - {.8803, 1.5286, 1.586, 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}, - {1.2717, 2.6403}, - {.8803, 1.5286}, - {.8803, 1.5286}, - {.6093, 0.8850}, - },{ //ResZ=4 - {1.000, 1.8371, 4.5604, 12.4614, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, - {1.2717, 2.6403, 6.7691 , 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, - {1.2717, 2.6403, 6.7691 , 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, - {.8803, 1.5286, 3.6770 , 3.043, 6.019, 12.01, 24.00, 47.97, 95.93}, - {1.2717, 2.6403, 6.7691 }, - {.8803, 1.5286, 3.6770 }, - {.8803, 1.5286, 3.6770 }, - {.6093, 0.8850, 1.9974 }, - },{ //ResZ=5 - {1.000, 1.8371, 4.5604, 12.4614, 34.9025, 21.34, 42.67, 85.33, 170.7, 341.3}, - {1.2717, 2.6403, 6.7691 , 18.6304 , 11.33, 22.64, 45.25, 90.48, 180.9}, - {1.2717, 2.6403, 6.7691 , 18.6304, 11.33, 22.64, 45.25, 90.48, 180.9}, - {.8803, 1.5286, 3.6770 , 9.9446, 6.019, 12.01, 24.00, 47.97, 95.93}, - {1.2717, 2.6403, 6.7691, 18.6304}, - {.8803, 1.5286, 3.6770, 9.9446 }, - {.8803, 1.5286, 3.6770, 9.9446 }, - {.6093, 0.8850, 1.9974, 5.3083 }, - } -};*/ - -/* */ -/* This table contains the norms of the 9-7 wavelets for different bands. */ -/* */ -/*static const double dwt_norms_real[5][8][10] = { - {//ResZ==1 - {1.000, 1.9659, 4.1224, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, - {1.0113, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {1.0113, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {0.5202, 0.9672, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722} - }, { //ResZ==2 - {1.000, 2.7564, 4.1224, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, - {1.4179, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {1.4179, 1.9968, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {0.7294, 0.9672, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}, - {1.4179}, - {0.7294}, - {0.7294}, - {0.3752} //HHH - },{ //ResZ==3 - {1.000, 2.7564, 8.3700, 8.4167, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, - {1.4179, 4.0543, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {1.4179, 4.0543, 4.1834, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {0.7294, 1.9638, 2.0793, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}, - {1.4179, 4.0543}, - {0.7294, 1.9638}, - {0.7294, 1.9638}, - {0.3752, 0.9512} //HHH - },{ //ResZ==4 - {1.000, 2.7564, 8.3700, 24.4183, 16.9356, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, - {1.4179, 4.0543, 12.1366, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {1.4179, 4.0543, 12.1366, 8.5341, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {0.7294, 1.9638, 6.0323, 4.3005, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}, - {1.4179, 4.0543, 12.1366}, - {0.7294, 1.9638, 6.0323}, - {0.7294, 1.9638, 6.0323}, - {0.3752, 0.9512, 2.9982} //HHH - },{ //ResZ==5 - {1.000, 2.7564, 8.3700, 24.4183, 69.6947, 33.9249, 67.8772, 135.7680, 271.5430, 543.0894}, - {1.4179, 4.0543, 12.1366, 35.1203, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {1.4179, 4.0543, 12.1366, 35.1203, 17.1667, 34.3852, 68.7967, 137.6065, 275.2196}, - {0.7294, 1.9638, 6.0323, 17.6977, 8.6867, 17.4188, 34.8608, 69.7332, 139.4722}, - {1.4179, 4.0543, 12.1366, 35.1203}, - {0.7294, 1.9638, 6.0323, 17.6977}, - {0.7294, 1.9638, 6.0323, 17.6977}, - {0.3752, 0.9512, 2.9982, 8.9182} //HHH - } -};*/ - -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,1}},/* 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},{1}}}, /* 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},{1},{1,0,-1}}}, /* 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,22,0,-22,3}}}, /* 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*/ -}; -/* -========================================================== - local functions -========================================================== -*/ - -/* */ -/* Forward lazy transform (horizontal). */ -/* */ -static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) { - int i; - for (i=0; i */ -/* Forward lazy transform (vertical). */ -/* */ -static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) { - int i; - for (i=0; i */ -/* Forward lazy transform (axial). */ -/* */ -static void dwt_deinterleave_z(int *a, int *b, int dn, int sn, int xy, int cas) { - int i; - for (i=0; i */ -/* Inverse lazy transform (horizontal). */ -/* */ -static void dwt_interleave_h(int *a, int *b, int dn, int sn, int cas) { - int i; - int *ai = NULL; - int *bi = NULL; - ai = a; - bi = b + cas; - for (i = 0; i < sn; i++) { - *bi = *ai; - bi += 2; - ai++; - } - ai = a + sn; - bi = b + 1 - cas; - for (i = 0; i < dn; i++) { - *bi = *ai; - bi += 2; - ai++; - } -} - -/* */ -/* Inverse lazy transform (vertical). */ -/* */ -static void dwt_interleave_v(int *a, int *b, int dn, int sn, int x, int cas) { - int i; - int *ai = NULL; - int *bi = NULL; - ai = a; - bi = b + cas; - for (i = 0; i < sn; i++) { - *bi = *ai; - bi += 2; - ai += x; - } - ai = a + (sn * x); - bi = b + 1 - cas; - for (i = 0; i < dn; i++) { - *bi = *ai; - bi += 2; - ai += x; - } -} - -/* */ -/* Inverse lazy transform (axial). */ -/* */ -static void dwt_interleave_z(int *a, int *b, int dn, int sn, int xy, int cas) { - int i; - int *ai = NULL; - int *bi = NULL; - ai = a; - bi = b + cas; - for (i = 0; i < sn; i++) { - *bi = *ai; - bi += 2; - ai += xy; - } - ai = a + (sn * xy); - bi = b + 1 - cas; - for (i = 0; i < dn; i++) { - *bi = *ai; - bi += 2; - ai += xy; - } -} - - -/* */ -/* Forward 5-3 or 9-7 wavelet tranform in 1-D. */ -/* */ -static void dwt_encode_53(int *a, int dn, int sn, int cas) { - int i; - - if (!cas) { - if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ - //for (i = 0; i < dn; i++) D(i) -= (S_(i) + S_(i + 1)) >> 1; - //for (i = 0; i < sn; i++) S(i) += (D_(i - 1) + D_(i) + 2) >> 2; - for (i = 0; i < dn; i++){ - D(i) -= (S_(i) + S_(i + 1)) >> 1; - //ops += 2; - } - for (i = 0; i < sn; i++){ - S(i) += (D_(i - 1) + D_(i) + 2) >> 2; - //ops += 3; - } - } - } else { - /*if (!sn && dn == 1) - S(0) *= 2; - else { - for (i = 0; i < dn; i++) S(i) -= (DD_(i) + DD_(i - 1)) >> 1; - for (i = 0; i < sn; i++) D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2; - }*/ - if (!sn && dn == 1){ - S(0) *= 2; - //ops++; - } else { - for (i = 0; i < dn; i++){ - S(i) -= (DD_(i) + DD_(i - 1)) >> 1; - // ops += 2; - } - for (i = 0; i < sn; i++){ - D(i) += (SS_(i) + SS_(i + 1) + 2) >> 2; - // ops += 3; - } - } - } -} -static void dwt_encode_97(int *a, int dn, int sn, int cas) { - int i; - - if (!cas) { - if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < dn; i++) - D(i) -= fix_mul(S_(i) + S_(i + 1), 12993); - for (i = 0; i < sn; i++) - S(i) -= fix_mul(D_(i - 1) + D_(i), 434); - for (i = 0; i < dn; i++) - D(i) += fix_mul(S_(i) + S_(i + 1), 7233); - for (i = 0; i < sn; i++) - S(i) += fix_mul(D_(i - 1) + D_(i), 3633); - for (i = 0; i < dn; i++) - D(i) = fix_mul(D(i), 5038); /*5038 */ - for (i = 0; i < sn; i++) - S(i) = fix_mul(S(i), 6659); /*6660 */ - } - } else { - if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < dn; i++) - S(i) -= fix_mul(DD_(i) + DD_(i - 1), 12993); - for (i = 0; i < sn; i++) - D(i) -= fix_mul(SS_(i) + SS_(i + 1), 434); - for (i = 0; i < dn; i++) - S(i) += fix_mul(DD_(i) + DD_(i - 1), 7233); - for (i = 0; i < sn; i++) - D(i) += fix_mul(SS_(i) + SS_(i + 1), 3633); - for (i = 0; i < dn; i++) - S(i) = fix_mul(S(i), 5038); /*5038 */ - for (i = 0; i < sn; i++) - D(i) = fix_mul(D(i), 6659); /*6660 */ - } - } -} -/* */ -/* Inverse 5-3 or 9-7 wavelet tranform in 1-D. */ -/* */ -static void dwt_decode_53(int *a, int dn, int sn, int cas) { - int i; - if (!cas) { - if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < sn; i++) S(i) -= (D_(i - 1) + D_(i) + 2) >> 2; - for (i = 0; i < dn; i++) D(i) += (S_(i) + S_(i + 1)) >> 1; - } - } else { - if (!sn && dn == 1) /* NEW : CASE ONE ELEMENT */ - S(0) /= 2; - else { - for (i = 0; i < sn; i++) D(i) -= (SS_(i) + SS_(i + 1) + 2) >> 2; - for (i = 0; i < dn; i++) S(i) += (DD_(i) + DD_(i - 1)) >> 1; - } - } -} -static void dwt_decode_97(int *a, int dn, int sn, int cas) { - int i; - - if (!cas) { - if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < sn; i++) - S(i) = fix_mul(S(i), 10078); /* 10076 */ - for (i = 0; i < dn; i++) - D(i) = fix_mul(D(i), 13318); /* 13320 */ - for (i = 0; i < sn; i++) - S(i) -= fix_mul(D_(i - 1) + D_(i), 3633); - for (i = 0; i < dn; i++) - D(i) -= fix_mul(S_(i) + S_(i + 1), 7233); - for (i = 0; i < sn; i++) - S(i) += fix_mul(D_(i - 1) + D_(i), 434); - for (i = 0; i < dn; i++) - D(i) += fix_mul(S_(i) + S_(i + 1), 12994); /* 12993 */ - } - } else { - if ((sn > 0) || (dn > 1)) { /* NEW : CASE ONE ELEMENT */ - for (i = 0; i < sn; i++) - D(i) = fix_mul(D(i), 10078); /* 10076 */ - for (i = 0; i < dn; i++) - S(i) = fix_mul(S(i), 13318); /* 13320 */ - for (i = 0; i < sn; i++) - D(i) -= fix_mul(SS_(i) + SS_(i + 1), 3633); - for (i = 0; i < dn; i++) - S(i) -= fix_mul(DD_(i) + DD_(i - 1), 7233); - for (i = 0; i < sn; i++) - D(i) += fix_mul(SS_(i) + SS_(i + 1), 434); - for (i = 0; i < dn; i++) - S(i) += fix_mul(DD_(i) + DD_(i - 1), 12994); /* 12993 */ - } - } -} - - -/* */ -/* Get norm of arbitrary wavelet transform. */ -/* */ -static int upandconv(double *nXPS, double *LPS, int lenXPS, int lenLPS) { - /* Perform the convolution of the vectors. */ - int i,j; - double *tmp = (double *)opj_malloc(2*lenXPS * sizeof(double)); - //Upsample - memset(tmp, 0, 2*lenXPS*sizeof(double)); - for (i = 0; i < lenXPS; i++) { - *(tmp + 2*i) = *(nXPS + i); - *(nXPS + i) = 0; - } - //Convolution - for (i = 0; i < 2*lenXPS; i++) { - for (j = 0; j < lenLPS; j++) { - *(nXPS+i+j) = *(nXPS+i+j) + *(tmp + i) * *(LPS + j); - //fprintf(stdout,"*(tmp + %d) * *(LPS + %d) = %f * %f \n",i,j,*(tmp + i),*(LPS + j)); - } - } - free(tmp); - return 2*lenXPS+lenLPS-1; -} - -static double dwt_calc_wtnorms(int orient, int level[3], int dwtid[3], opj_wtfilt_t *wtfiltX, opj_wtfilt_t *wtfiltY, opj_wtfilt_t *wtfiltZ) { - int i, lenLPS, lenHPS; - double Lx = 0, Ly= 0, Hx= 0, Hy= 0, Lz= 0, Hz= 0; - double *nLPSx, *nHPSx,*nLPSy, *nHPSy,*nLPSz, *nHPSz; - int levelx, levely, levelz; - - levelx = (orient == 0) ? level[0]-1 : level[0]; - levely = (orient == 0) ? level[1]-1 : level[1]; - levelz = (orient == 0) ? level[2]-1 : level[2]; - - //X axis - lenLPS = wtfiltX->lenLPS; - lenHPS = wtfiltX->lenHPS; - for (i = 0; i < levelx; i++) { - lenLPS *= 2; - lenHPS *= 2; - lenLPS += wtfiltX->lenLPS - 1; - lenHPS += wtfiltX->lenLPS - 1; - } - nLPSx = (double *)opj_malloc(lenLPS * sizeof(double)); - nHPSx = (double *)opj_malloc(lenHPS * sizeof(double)); - - memcpy(nLPSx, wtfiltX->LPS, wtfiltX->lenLPS * sizeof(double)); - memcpy(nHPSx, wtfiltX->HPS, wtfiltX->lenHPS * sizeof(double)); - lenLPS = wtfiltX->lenLPS; - lenHPS = wtfiltX->lenHPS; - for (i = 0; i < levelx; i++) { - lenLPS = upandconv(nLPSx, wtfiltX->LPS, lenLPS, wtfiltX->lenLPS); - lenHPS = upandconv(nHPSx, wtfiltX->LPS, lenHPS, wtfiltX->lenLPS); - } - for (i = 0; i < lenLPS; i++) - Lx += nLPSx[i] * nLPSx[i]; - for (i = 0; i < lenHPS; i++) - Hx += nHPSx[i] * nHPSx[i]; - Lx = sqrt(Lx); - Hx = sqrt(Hx); - free(nLPSx); - free(nHPSx); - - //Y axis - if (dwtid[0] != dwtid[1] || level[0] != level[1]){ - lenLPS = wtfiltY->lenLPS; - lenHPS = wtfiltY->lenHPS; - for (i = 0; i < levely; i++) { - lenLPS *= 2; - lenHPS *= 2; - lenLPS += wtfiltY->lenLPS - 1; - lenHPS += wtfiltY->lenLPS - 1; - } - nLPSy = (double *)opj_malloc(lenLPS * sizeof(double)); - nHPSy = (double *)opj_malloc(lenHPS * sizeof(double)); - - memcpy(nLPSy, wtfiltY->LPS, wtfiltY->lenLPS * sizeof(double)); - memcpy(nHPSy, wtfiltY->HPS, wtfiltY->lenHPS * sizeof(double)); - lenLPS = wtfiltY->lenLPS; - lenHPS = wtfiltY->lenHPS; - for (i = 0; i < levely; i++) { - lenLPS = upandconv(nLPSy, wtfiltY->LPS, lenLPS, wtfiltY->lenLPS); - lenHPS = upandconv(nHPSy, wtfiltY->LPS, lenHPS, wtfiltY->lenLPS); - } - for (i = 0; i < lenLPS; i++) - Ly += nLPSy[i] * nLPSy[i]; - for (i = 0; i < lenHPS; i++) - Hy += nHPSy[i] * nHPSy[i]; - Ly = sqrt(Ly); - Hy = sqrt(Hy); - free(nLPSy); - free(nHPSy); - } else { - Ly = Lx; - Hy = Hx; - } - //Z axis - if (levelz >= 0) { - lenLPS = wtfiltZ->lenLPS; - lenHPS = wtfiltZ->lenHPS; - for (i = 0; i < levelz; i++) { - lenLPS *= 2; - lenHPS *= 2; - lenLPS += wtfiltZ->lenLPS - 1; - lenHPS += wtfiltZ->lenLPS - 1; - } - nLPSz = (double *)opj_malloc(lenLPS * sizeof(double)); - nHPSz = (double *)opj_malloc(lenHPS * sizeof(double)); - - memcpy(nLPSz, wtfiltZ->LPS, wtfiltZ->lenLPS * sizeof(double)); - memcpy(nHPSz, wtfiltZ->HPS, wtfiltZ->lenHPS * sizeof(double)); - lenLPS = wtfiltZ->lenLPS; - lenHPS = wtfiltZ->lenHPS; - for (i = 0; i < levelz; i++) { - lenLPS = upandconv(nLPSz, wtfiltZ->LPS, lenLPS, wtfiltZ->lenLPS); - lenHPS = upandconv(nHPSz, wtfiltZ->LPS, lenHPS, wtfiltZ->lenLPS); - } - for (i = 0; i < lenLPS; i++) - Lz += nLPSz[i] * nLPSz[i]; - for (i = 0; i < lenHPS; i++) - Hz += nHPSz[i] * nHPSz[i]; - Lz = sqrt(Lz); - Hz = sqrt(Hz); - free(nLPSz); - free(nHPSz); - } else { - Lz = 1.0; Hz = 1.0; - } - switch (orient) { - case 0: - return Lx * Ly * Lz; - case 1: - return Lx * Hy * Lz; - case 2: - return Hx * Ly * Lz; - case 3: - return Hx * Hy * Lz; - case 4: - return Lx * Ly * Hz; - case 5: - return Lx * Hy * Hz; - case 6: - return Hx * Ly * Hz; - case 7: - return Hx * Hy * Hz; - default: - return -1; - } - -} -static void dwt_getwtfilters(opj_wtfilt_t *wtfilt, int dwtid) { - if (dwtid == 0) { //DWT 9-7 - wtfilt->lenLPS = 7; wtfilt->lenHPS = 9; - wtfilt->LPS = (double *)opj_malloc(wtfilt->lenLPS * sizeof(double)); - wtfilt->HPS = (double *)opj_malloc(wtfilt->lenHPS * sizeof(double)); - wtfilt->LPS[0] = -0.091271763114; wtfilt->HPS[0] = 0.026748757411; - wtfilt->LPS[1] = -0.057543526228; wtfilt->HPS[1] = 0.016864118443; - wtfilt->LPS[2] = 0.591271763114; wtfilt->HPS[2] = -0.078223266529; - wtfilt->LPS[3] = 1.115087052457; wtfilt->HPS[3] = -0.266864118443; - wtfilt->LPS[4] = 0.591271763114; wtfilt->HPS[4] = 0.602949018236; - wtfilt->LPS[5] = -0.057543526228; wtfilt->HPS[5] = -0.266864118443; - wtfilt->LPS[6] = -0.091271763114; wtfilt->HPS[6] = -0.078223266529; - wtfilt->HPS[7] = 0.016864118443; - wtfilt->HPS[8] = 0.026748757411; - } else if (dwtid == 1) { //DWT 5-3 - wtfilt->lenLPS = 3; wtfilt->lenHPS = 5; - wtfilt->LPS = (double *)opj_malloc(wtfilt->lenLPS * sizeof(double)); - wtfilt->HPS = (double *)opj_malloc(wtfilt->lenHPS * sizeof(double)); - wtfilt->LPS[0] = 0.5; wtfilt->HPS[0] = -0.125; - wtfilt->LPS[1] = 1; wtfilt->HPS[1] = -0.25; - wtfilt->LPS[2] = 0.5; wtfilt->HPS[2] = 0.75; - wtfilt->HPS[3] = -0.25; - wtfilt->HPS[4] = -0.125; - } else { - fprintf(stdout,"[ERROR] Sorry, this wavelet hasn't been implemented so far ... Try another one :-)\n"); - exit(1); - } -} -/* */ -/* Encoding of quantization stepsize for each subband. */ -/* */ -static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) { - int p, n; - p = int_floorlog2(stepsize) - 13; - n = 11 - int_floorlog2(stepsize); - bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff; - bandno_stepsize->expn = numbps - p; - //if J3D_CCP_QNTSTY_NOQNT --> stepsize = 8192.0 --> p = 0, n = -2 --> mant = 0; expn = (prec+gain) - //else --> bandno_stepsize = (1<<(numbps - expn)) + (1<<(numbps - expn - 11)) * Ub -} - -/* -========================================================== - DWT interface -========================================================== -*/ -/* */ -/* Forward 5-3 wavelet tranform in 3-D. */ -/* */ -void dwt_encode(opj_tcd_tilecomp_t * tilec, int dwtid[3]) { - int i, j, k; - int x, y, z; - int w, h, wh, d; - int level,levelx,levely,levelz,diff; - int *a = NULL; - int *aj = NULL; - int *bj = NULL; - int *cj = NULL; - - ops = 0; - - memset(flagnorm,0,8000*sizeof(int)); - w = tilec->x1-tilec->x0; - h = tilec->y1-tilec->y0; - d = tilec->z1-tilec->z0; - wh = w * h; - levelx = tilec->numresolution[0]-1; - levely = tilec->numresolution[1]-1; - levelz = tilec->numresolution[2]-1; - level = int_max(levelx,int_max(levely,levelz)); - diff = tilec->numresolution[0] - tilec->numresolution[2]; - - a = tilec->data; - - for (x = 0, y = 0, z = 0; x < levelx, y < levely; x++, y++, z++) { - int rw; /* width of the resolution level computed */ - int rh; /* heigth of the resolution level computed */ - int rd; /* depth of the resolution level computed */ - int rw1; /* width of the resolution level once lower than computed one */ - int rh1; /* height of the resolution level once lower than computed one */ - int rd1; /* depth of the resolution level once lower than computed one */ - int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_axl; /* 0 = non inversion on axial filtering 1 = inversion between low-pass and high-pass filtering */ - int dn, sn; - - rw = tilec->resolutions[level - x].x1 - tilec->resolutions[level - x].x0; - rh = tilec->resolutions[level - y].y1 - tilec->resolutions[level - y].y0; - rd = tilec->resolutions[level - z].z1 - tilec->resolutions[level - z].z0; - rw1= tilec->resolutions[level - x - 1].x1 - tilec->resolutions[level - x - 1].x0; - rh1= tilec->resolutions[level - y - 1].y1 - tilec->resolutions[level - y - 1].y0; - rd1= tilec->resolutions[level - z - 1].z1 - tilec->resolutions[level - z - 1].z0; - - cas_col = tilec->resolutions[level - x].x0 % 2; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - cas_row = tilec->resolutions[level - y].y0 % 2; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ - cas_axl = tilec->resolutions[level - z].z0 % 2; - - /*fprintf(stdout," x %d y %d z %d \n",x,y,z); - fprintf(stdout," levelx %d levely %d levelz %d \n",levelx,levely,levelz); - fprintf(stdout," z1 %d z0 %d\n",tilec->resolutions[level - z].z1,tilec->resolutions[level - z].z0); - fprintf(stdout," rw %d rh %d rd %d \n rw1 %d rh1 %d rd1 %d \n",rw,rh,rd,rw1,rh1,rd1);*/ - - for (i = 0; i < rd; i++) { - - cj = a + (i * wh); - - //Horizontal - sn = rw1; - dn = rw - rw1; - bj = (int*)opj_malloc(rw * sizeof(int)); - if (dwtid[0] == 0) { - for (j = 0; j < rh; j++) { - aj = cj + j * w; - for (k = 0; k < rw; k++) bj[k] = aj[k]; - dwt_encode_97(bj, dn, sn, cas_row); - dwt_deinterleave_h(bj, aj, dn, sn, cas_row); - } - } else if (dwtid[0] == 1) { - for (j = 0; j < rh; j++) { - aj = cj + j * w; - for (k = 0; k < rw; k++) bj[k] = aj[k]; - dwt_encode_53(bj, dn, sn, cas_row); - dwt_deinterleave_h(bj, aj, dn, sn, cas_row); - } - } - opj_free(bj); - - //Vertical - sn = rh1; - dn = rh - rh1; - bj = (int*)opj_malloc(rh * sizeof(int)); - if (dwtid[1] == 0) { /*DWT 9-7*/ - for (j = 0; j < rw; j++) { - aj = cj + j; - for (k = 0; k < rh; k++) bj[k] = aj[k*w]; - dwt_encode_97(bj, dn, sn, cas_col); - dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); - } - } else if (dwtid[1] == 1) { /*DWT 5-3*/ - for (j = 0; j < rw; j++) { - aj = cj + j; - for (k = 0; k < rh; k++) bj[k] = aj[k*w]; - dwt_encode_53(bj, dn, sn, cas_col); - dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); - } - } - opj_free(bj); - } - - if (z < levelz){ - //Axial fprintf(stdout,"Axial DWT Transform %d %d %d\n",z,rd,rd1); - sn = rd1; - dn = rd - rd1; - bj = (int*)opj_malloc(rd * sizeof(int)); - if (dwtid[2] == 0) { - for (j = 0; j < (rw*rh); j++) { - aj = a + j; - for (k = 0; k < rd; k++) bj[k] = aj[k*wh]; - dwt_encode_97(bj, dn, sn, cas_axl); - dwt_deinterleave_z(bj, aj, dn, sn, wh, cas_axl); - } - } else if (dwtid[2] == 1) { - for (j = 0; j < (rw*rh); j++) { - aj = a + j; - for (k = 0; k < rd; k++) bj[k] = aj[k*wh]; - dwt_encode_53(bj, dn, sn, cas_axl); - dwt_deinterleave_z(bj, aj, dn, sn, wh, cas_axl); - } - } - opj_free(bj); - } - } - - //fprintf(stdout,"[INFO] Ops: %d \n",ops); -} - - -/* */ -/* Inverse 5-3 wavelet tranform in 3-D. */ -/* */ -void dwt_decode(opj_tcd_tilecomp_t * tilec, int stops[3], int dwtid[3]) { - int i, j, k; - int x, y, z; - int w, h, wh, d; - int level, levelx, levely, levelz, diff; - int *a = NULL; - int *aj = NULL; - int *bj = NULL; - int *cj = NULL; - - a = tilec->data; - - w = tilec->x1-tilec->x0; - h = tilec->y1-tilec->y0; - d = tilec->z1-tilec->z0; - wh = w * h; - levelx = tilec->numresolution[0]-1; - levely = tilec->numresolution[1]-1; - levelz = tilec->numresolution[2]-1; - level = int_max(levelx,int_max(levely,levelz)); - diff = tilec->numresolution[0] - tilec->numresolution[2]; - -/* General lifting framework -- DCCS-LIWT */ - for (x = level - 1, y = level - 1, z = level - 1; x >= stops[0], y >= stops[1]; x--, y--, z--) { - int rw; /* width of the resolution level computed */ - int rh; /* heigth of the resolution level computed */ - int rd; /* depth of the resolution level computed */ - int rw1; /* width of the resolution level once lower than computed one */ - int rh1; /* height of the resolution level once lower than computed one */ - int rd1; /* depth of the resolution level once lower than computed one */ - int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_axl; /* 0 = non inversion on axial filtering 1 = inversion between low-pass and high-pass filtering */ - int dn, sn; - - rw = tilec->resolutions[level - x].x1 - tilec->resolutions[level - x].x0; - rh = tilec->resolutions[level - y].y1 - tilec->resolutions[level - y].y0; - rd = tilec->resolutions[level - z].z1 - tilec->resolutions[level - z].z0; - rw1= tilec->resolutions[level - x - 1].x1 - tilec->resolutions[level - x - 1].x0; - rh1= tilec->resolutions[level - y - 1].y1 - tilec->resolutions[level - y - 1].y0; - rd1= tilec->resolutions[level - z - 1].z1 - tilec->resolutions[level - z - 1].z0; - - cas_col = tilec->resolutions[level - x].x0 % 2; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - cas_row = tilec->resolutions[level - y].y0 % 2; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ - cas_axl = tilec->resolutions[level - z].z0 % 2; - - /*fprintf(stdout," x %d y %d z %d \n",x,y,z); - fprintf(stdout," levelx %d levely %d levelz %d \n",levelx,levely,levelz); - fprintf(stdout," dwtid[0] %d [1] %d [2] %d \n",dwtid[0],dwtid[1],dwtid[2]); - fprintf(stdout," rw %d rh %d rd %d \n rw1 %d rh1 %d rd1 %d \n",rw,rh,rd,rw1,rh1,rd1); - fprintf(stdout,"IDWT Transform %d %d %d %d\n",level, z, rd,rd1);*/ - - if (z >= stops[2] && rd != rd1) { - //fprintf(stdout,"Axial Transform %d %d %d %d\n",levelz, z, rd,rd1); - sn = rd1; - dn = rd - rd1; - bj = (int*)opj_malloc(rd * sizeof(int)); - if (dwtid[2] == 0) { - for (j = 0; j < (rw*rh); j++) { - aj = a + j; - dwt_interleave_z(aj, bj, dn, sn, wh, cas_axl); - dwt_decode_97(bj, dn, sn, cas_axl); - for (k = 0; k < rd; k++) aj[k * wh] = bj[k]; - } - } else if (dwtid[2] == 1) { - for (j = 0; j < (rw*rh); j++) { - aj = a + j; - dwt_interleave_z(aj, bj, dn, sn, wh, cas_axl); - dwt_decode_53(bj, dn, sn, cas_axl); - for (k = 0; k < rd; k++) aj[k * wh] = bj[k]; - } - } - opj_free(bj); - } - - for (i = 0; i < rd; i++) { - //Fetch corresponding slice for doing DWT-2D - cj = tilec->data + (i * wh); - - //Vertical - sn = rh1; - dn = rh - rh1; - bj = (int*)opj_malloc(rh * sizeof(int)); - if (dwtid[1] == 0) { - for (j = 0; j < rw; j++) { - aj = cj + j; - dwt_interleave_v(aj, bj, dn, sn, w, cas_col); - dwt_decode_97(bj, dn, sn, cas_col); - for (k = 0; k < rh; k++) aj[k * w] = bj[k]; - } - } else if (dwtid[1] == 1) { - for (j = 0; j < rw; j++) { - aj = cj + j; - dwt_interleave_v(aj, bj, dn, sn, w, cas_col); - dwt_decode_53(bj, dn, sn, cas_col); - for (k = 0; k < rh; k++) aj[k * w] = bj[k]; - } - } - opj_free(bj); - - //Horizontal - sn = rw1; - dn = rw - rw1; - bj = (int*)opj_malloc(rw * sizeof(int)); - if (dwtid[0]==0) { - for (j = 0; j < rh; j++) { - aj = cj + j*w; - dwt_interleave_h(aj, bj, dn, sn, cas_row); - dwt_decode_97(bj, dn, sn, cas_row); - for (k = 0; k < rw; k++) aj[k] = bj[k]; - } - } else if (dwtid[0]==1) { - for (j = 0; j < rh; j++) { - aj = cj + j*w; - dwt_interleave_h(aj, bj, dn, sn, cas_row); - dwt_decode_53(bj, dn, sn, cas_row); - for (k = 0; k < rw; k++) aj[k] = bj[k]; - } - } - opj_free(bj); - - } - - } - -} - - -/* */ -/* Get gain of wavelet transform. */ -/* */ -int dwt_getgain(int orient, int reversible) { - if (reversible == 1) { - if (orient == 0) - return 0; - else if (orient == 1 || orient == 2 || orient == 4 ) - return 1; - else if (orient == 3 || orient == 5 || orient == 6 ) - return 2; - else - return 3; - } - //else if (reversible == 0){ - return 0; -} - -/* */ -/* Get norm of wavelet transform. */ -/* */ -double dwt_getnorm(int orient, int level[3], int dwtid[3]) { - int levelx = level[0]; - int levely = level[1]; - int levelz = (level[2] < 0) ? 0 : level[2]; - double norm; - - if (flagnorm[levelx][levely][levelz][orient] == 1) { - norm = dwt_norm[levelx][levely][levelz][orient]; - //fprintf(stdout,"[INFO] Level: %d %d %d Orient %d Dwt_norm: %f \n",level[0],level[1],level[2],orient,norm); - } else { - opj_wtfilt_t *wtfiltx =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t)); - opj_wtfilt_t *wtfilty =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t)); - opj_wtfilt_t *wtfiltz =(opj_wtfilt_t *) opj_malloc(sizeof(opj_wtfilt_t)); - //Fetch equivalent filters for each dimension - dwt_getwtfilters(wtfiltx, dwtid[0]); - dwt_getwtfilters(wtfilty, dwtid[1]); - dwt_getwtfilters(wtfiltz, dwtid[2]); - //Calculate the corresponding norm - norm = dwt_calc_wtnorms(orient, level, dwtid, wtfiltx, wtfilty, wtfiltz); - //Save norm in array (no recalculation) - dwt_norm[levelx][levely][levelz][orient] = norm; - flagnorm[levelx][levely][levelz][orient] = 1; - //Free reserved space - opj_free(wtfiltx->LPS); opj_free(wtfilty->LPS); opj_free(wtfiltz->LPS); - opj_free(wtfiltx->HPS); opj_free(wtfilty->HPS); opj_free(wtfiltz->HPS); - opj_free(wtfiltx); opj_free(wtfilty); opj_free(wtfiltz); - //fprintf(stdout,"[INFO] Dwtid: %d %d %d Level: %d %d %d Orient %d Norm: %f \n",dwtid[0],dwtid[1],dwtid[2],level[0],level[1],level[2],orient,norm); - } - return norm; -} -/* */ -/* Calculate explicit stepsizes for DWT. */ -/* */ -void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) { - int totnumbands, bandno, diff; - - assert(tccp->numresolution[0] >= tccp->numresolution[2]); - diff = tccp->numresolution[0] - tccp->numresolution[2]; /*if RESx=RESy != RESz */ - totnumbands = (7 * tccp->numresolution[0] - 6) - 4 * diff; /* 3-D */ - - for (bandno = 0; bandno < totnumbands; bandno++) { - double stepsize; - int resno, level[3], orient, gain; - - /* Bandno: 0 - LLL 1 - LHL - 2 - HLL 3 - HHL - 4 - LLH 5 - LHH - 6 - HLH 7 - HHH */ - - resno = (bandno == 0) ? 0 : ( (bandno <= 3 * diff) ? ((bandno - 1) / 3 + 1) : ((bandno + 4*diff - 1) / 7 + 1)); - orient = (bandno == 0) ? 0 : ( (bandno <= 3 * diff) ? ((bandno - 1) % 3 + 1) : ((bandno + 4*diff - 1) % 7 + 1)); - level[0] = tccp->numresolution[0] - 1 - resno; - level[1] = tccp->numresolution[1] - 1 - resno; - level[2] = tccp->numresolution[2] - 1 - resno; - - /* Gain: 0 - LLL 1 - LHL - 1 - HLL 2 - HHL - 1 - LLH 2 - LHH - 2 - HLH 3 - HHH */ - gain = (tccp->reversible == 0) ? 0 : ( (orient == 0) ? 0 : - ( ((orient == 1) || (orient == 2) || (orient == 4)) ? 1 : - (((orient == 3) || (orient == 5) || (orient == 6)) ? 2 : 3)) ); - - if (tccp->qntsty == J3D_CCP_QNTSTY_NOQNT) { - stepsize = 1.0; - } else { - double norm = dwt_getnorm(orient,level,tccp->dwtid); //Fetch norms if irreversible transform (by the moment only I9.7) - stepsize = (1 << (gain + 1)) / norm; - } - //fprintf(stdout,"[INFO] Bandno: %d Orient: %d Level: %d %d %d Stepsize: %f\n",bandno,orient,level[0],level[1],level[2],stepsize); - dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]); - } -} - - - diff --git a/jp3d/libjp3dvm/dwt.h b/jp3d/libjp3dvm/dwt.h deleted file mode 100755 index afb1ba4f..00000000 --- a/jp3d/libjp3dvm/dwt.h +++ /dev/null @@ -1,100 +0,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, Hervé 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/jp3d/libjp3dvm/event.c b/jp3d/libjp3dvm/event.c deleted file mode 100755 index 6fe8ae2e..00000000 --- a/jp3d/libjp3dvm/event.c +++ /dev/null @@ -1,181 +0,0 @@ -/* - * Copyright (c) 2005, Hervé 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/jp3d/libjp3dvm/event.h b/jp3d/libjp3dvm/event.h deleted file mode 100755 index acc4fc3e..00000000 --- a/jp3d/libjp3dvm/event.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2005, Hervé 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 openjpeg.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/jp3d/libjp3dvm/fix.h b/jp3d/libjp3dvm/fix.h deleted file mode 100755 index f2113b5a..00000000 --- a/jp3d/libjp3dvm/fix.h +++ /dev/null @@ -1,62 +0,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, Hervé 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 __FIX_H -#define __FIX_H - -#if defined(_MSC_VER) || defined(__BORLANDC__) -#define int64 __int64 -#else -#define int64 long long -#endif - -/** -@file fix.h -@brief Implementation of operations of specific multiplication (FIX) - -The functions in FIX.H have for goal to realize specific multiplication. -*/ - -/** @defgroup FIX FIX - Implementation of operations of specific multiplication */ -/*@{*/ - -/** -Multiply two fixed-precision rational numbers. -@param a -@param b -@return Returns a * b -*/ -static int fix_mul(int a, int b) { - int64 temp = (int64) a * (int64) b >> 12; - return (int) ((temp >> 1) + (temp & 1)) ; -} - -/*@}*/ - -#endif /* __FIX_H */ diff --git a/jp3d/libjp3dvm/int.h b/jp3d/libjp3dvm/int.h deleted file mode 100755 index 99ab72bb..00000000 --- a/jp3d/libjp3dvm/int.h +++ /dev/null @@ -1,122 +0,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, Hervé 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 __INT_H -#define __INT_H -/** -@file int.h -@brief Implementation of operations on integers (INT) - -The functions in INT.H have for goal to realize operations on integers. -*/ - -/** @defgroup INT INT - Implementation of operations on integers */ -/*@{*/ - -/** @name Funciones generales (see also openjpeg.h) */ -/*@{*/ -/* ----------------------------------------------------------------------- */ -/** -Get the minimum of two integers -@return Returns a if a < b else b -*/ -static int int_min(int a, int b) { - return a < b ? a : b; -} -/** -Get the maximum of two integers -@return Returns a if a > b else b -*/ -static int int_max(int a, int b) { - return (a > b) ? a : b; -} -/** -Clamp an integer inside an interval -@return -
    -
  • Returns a if (min < a < max) -
  • Returns max if (a > max) -
  • Returns min if (a < min) -
-*/ -static int int_clamp(int a, int min, int max) { - if (a < min) - return min; - if (a > max) - return max; - return a; -} -/** -@return Get absolute value of integer -*/ -static int int_abs(int a) { - return a < 0 ? -a : a; -} - -static double dbl_abs(double a) { - return a < 0 ? -a : a; -} -/** -Divide an integer and round upwards -@return Returns a divided by b -*/ -static int int_ceildiv(int a, int b) { - return (a + b - 1) / b; -} -/** -Divide an integer by a power of 2 and round upwards -@return Returns a divided by 2^b -*/ -static int int_ceildivpow2(int a, int b) { - return (a + (1 << b) - 1) >> b; -} -/** -Divide an integer by a power of 2 and round downwards -@return Returns a divided by 2^b -*/ -static int int_floordivpow2(int a, int b) { - return a >> b; -} -/** -Get logarithm of an integer and round downwards -@return Returns log2(a) -*/ -static int int_floorlog2(int a) { - int l; - for (l = 0; a > 1; l++) { - a >>= 1; - } - return l; -} -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif diff --git a/jp3d/libjp3dvm/jp3d.c b/jp3d/libjp3dvm/jp3d.c deleted file mode 100755 index 4a5527b7..00000000 --- a/jp3d/libjp3dvm/jp3d.c +++ /dev/null @@ -1,2328 +0,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, Hervé 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); -/*@}*/ - -/* ----------------------------------------------------------------------- */ - -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"); -} - -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; -} - diff --git a/jp3d/libjp3dvm/jp3d.h b/jp3d/libjp3dvm/jp3d.h deleted file mode 100755 index d9dcc8e3..00000000 --- a/jp3d/libjp3dvm/jp3d.h +++ /dev/null @@ -1,518 +0,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, Hervé 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 j3d.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 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 */ diff --git a/jp3d/libjp3dvm/jp3d_lib.c b/jp3d/libjp3dvm/jp3d_lib.c deleted file mode 100755 index fe19ab8b..00000000 --- a/jp3d/libjp3dvm/jp3d_lib.c +++ /dev/null @@ -1,76 +0,0 @@ -/* - * Copyright (c) 2005, Hervé 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 -} - -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/jp3d/libjp3dvm/jp3d_lib.h b/jp3d/libjp3dvm/jp3d_lib.h deleted file mode 100755 index 45b28309..00000000 --- a/jp3d/libjp3dvm/jp3d_lib.h +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2005, Hervé 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(); - -/** -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/jp3d/libjp3dvm/mct.c b/jp3d/libjp3dvm/mct.c deleted file mode 100755 index be4b875e..00000000 --- a/jp3d/libjp3dvm/mct.c +++ /dev/null @@ -1,131 +0,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, Hervé 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/jp3d/libjp3dvm/mct.h b/jp3d/libjp3dvm/mct.h deleted file mode 100755 index 81513f7c..00000000 --- a/jp3d/libjp3dvm/mct.h +++ /dev/null @@ -1,97 +0,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, Hervé 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/jp3d/libjp3dvm/mqc.c b/jp3d/libjp3dvm/mqc.c deleted file mode 100755 index 4117bf1f..00000000 --- a/jp3d/libjp3dvm/mqc.c +++ /dev/null @@ -1,548 +0,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, Hervé 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/jp3d/libjp3dvm/mqc.h b/jp3d/libjp3dvm/mqc.h deleted file mode 100755 index 67cfc008..00000000 --- a/jp3d/libjp3dvm/mqc.h +++ /dev/null @@ -1,201 +0,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, Hervé 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(); -/** -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/jp3d/libjp3dvm/openjpeg.c b/jp3d/libjp3dvm/openjpeg.c deleted file mode 100755 index 2a6fe7c6..00000000 --- a/jp3d/libjp3dvm/openjpeg.c +++ /dev/null @@ -1,207 +0,0 @@ -/* - * Copyright (c) 2005, Hervé 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" - -/* ---------------------------------------------------------------------- */ -#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 OPENJPEG_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/jp3d/libjp3dvm/openjpeg.h b/jp3d/libjp3dvm/openjpeg.h deleted file mode 100755 index 36c09aff..00000000 --- a/jp3d/libjp3dvm/openjpeg.h +++ /dev/null @@ -1,715 +0,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, Hervé 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 - -#define OPENJPEG_VERSION "1.0.0" - -/* -========================================================== - Compiler directives -========================================================== -*/ - -#if defined(OPJ_STATIC) || !(defined(WIN32) || defined(__WIN32__)) -#define OPJ_API -#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. -*/ -#ifdef OPJ_EXPORTS -#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(); - -/* -========================================================== - 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/jp3d/libjp3dvm/opj_includes.h b/jp3d/libjp3dvm/opj_includes.h deleted file mode 100755 index ed975733..00000000 --- a/jp3d/libjp3dvm/opj_includes.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright (c) 2005, Hervé 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 OPJ_INCLUDES_H -#define OPJ_INCLUDES_H - -/* - ========================================================== - Standard includes used by the library - ========================================================== -*/ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -/* - ========================================================== - OpenJPEG interface - ========================================================== - */ -#include "openjpeg.h" - -/* - ========================================================== - OpenJPEG modules - ========================================================== -*/ - -#include "dirent.h" -#include "jp3d_lib.h" -#include "event.h" -#include "cio.h" - -#include "volume.h" -#include "jp3d.h" - -#include "mqc.h" -#include "raw.h" -#include "bio.h" -#include "tgt.h" -#include "tcd.h" -#include "t1.h" -#include "t1_3d.h" -#include "dwt.h" -#include "pi.h" -#include "t2.h" -#include "mct.h" -#include "int.h" -#include "fix.h" - -//#include "pred.h" -//#include "golomb.h" - -#endif /* OPJ_INCLUDES_H */ diff --git a/jp3d/libjp3dvm/pi.c b/jp3d/libjp3dvm/pi.c deleted file mode 100755 index 5fd673fd..00000000 --- a/jp3d/libjp3dvm/pi.c +++ /dev/null @@ -1,630 +0,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, Hervé 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; -} - diff --git a/jp3d/libjp3dvm/pi.h b/jp3d/libjp3dvm/pi.h deleted file mode 100755 index 1d3340be..00000000 --- a/jp3d/libjp3dvm/pi.h +++ /dev/null @@ -1,145 +0,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, Hervé 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/jp3d/libjp3dvm/raw.c b/jp3d/libjp3dvm/raw.c deleted file mode 100755 index 59d7d35b..00000000 --- a/jp3d/libjp3dvm/raw.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Hervé 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/jp3d/libjp3dvm/raw.h b/jp3d/libjp3dvm/raw.h deleted file mode 100755 index e17070ab..00000000 --- a/jp3d/libjp3dvm/raw.h +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright (c) 2003-2005, Francois Devaux and Antonin Descampe - * Copyright (c) 2005, Hervé 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(); -/** -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/jp3d/libjp3dvm/t1.c b/jp3d/libjp3dvm/t1.c deleted file mode 100755 index 43a78b6a..00000000 --- a/jp3d/libjp3dvm/t1.c +++ /dev/null @@ -1,1181 +0,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, Hervé 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/jp3d/libjp3dvm/t1.h b/jp3d/libjp3dvm/t1.h deleted file mode 100755 index ec7160c1..00000000 --- a/jp3d/libjp3dvm/t1.h +++ /dev/null @@ -1,173 +0,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, Hervé 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/jp3d/libjp3dvm/t1_3d.c b/jp3d/libjp3dvm/t1_3d.c deleted file mode 100755 index efdf2efc..00000000 --- a/jp3d/libjp3dvm/t1_3d.c +++ /dev/null @@ -1,1230 +0,0 @@ -/* - * 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/jp3d/libjp3dvm/t1_3d.h b/jp3d/libjp3dvm/t1_3d.h deleted file mode 100755 index dd73763d..00000000 --- a/jp3d/libjp3dvm/t1_3d.h +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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/jp3d/libjp3dvm/t2.c b/jp3d/libjp3dvm/t2.c deleted file mode 100755 index 20d8e7d2..00000000 --- a/jp3d/libjp3dvm/t2.c +++ /dev/null @@ -1,675 +0,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, Hervé 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); - } -} - diff --git a/jp3d/libjp3dvm/t2.h b/jp3d/libjp3dvm/t2.h deleted file mode 100755 index 191d0bc4..00000000 --- a/jp3d/libjp3dvm/t2.h +++ /dev/null @@ -1,101 +0,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, Hervé 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/jp3d/libjp3dvm/tcd.c b/jp3d/libjp3dvm/tcd.c deleted file mode 100755 index b0184d58..00000000 --- a/jp3d/libjp3dvm/tcd.c +++ /dev/null @@ -1,1738 +0,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, Hervé 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"); -} - -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/jp3d/libjp3dvm/tcd.h b/jp3d/libjp3dvm/tcd.h deleted file mode 100755 index 0de60b8c..00000000 --- a/jp3d/libjp3dvm/tcd.h +++ /dev/null @@ -1,334 +0,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, Hervé 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 __TCD_H -#define __TCD_H -/** -@file tcd.h -@brief Implementation of a tile coder/decoder (TCD) - -The functions in TCD.C have for goal to encode or decode each tile independently from -each other. The functions in TCD.C are used by some function in JP3D.C. -*/ - -/** @defgroup TCD TCD - Implementation of a tile coder/decoder */ -/*@{*/ - -/** -Tile coder/decoder: segment instance -*/ -typedef struct opj_tcd_seg { -/** Number of passes in the segment */ - int numpasses; -/** Length of information */ - int len; -/** Data */ - unsigned char *data; -/** Number of passes posible for the segment */ - int maxpasses; -/** Number of passes added to the segment */ - int numnewpasses; -/** New length after inclusion of segments */ - int newlen; -} opj_tcd_seg_t; - -/** -Tile coder/decoder: pass instance -*/ -typedef struct opj_tcd_pass { -/** Rate obtained in the pass*/ - int rate; -/** Distorsion obtained in the pass*/ - double distortiondec; - int term; -/** Length of information */ - int len; -} opj_tcd_pass_t; - -/** -Tile coder/decoder: layer instance -*/ -typedef struct opj_tcd_layer { -/** Number of passes in the layer */ - int numpasses; -/** Length of information */ - int len; -/** Distortion within layer */ - double disto; /* add for index (Cfr. Marcela) */ - unsigned char *data; /* data */ -} opj_tcd_layer_t; - -/** -Tile coder/decoder: codeblock instance -*/ -typedef struct opj_tcd_cblk { -/** Dimension of the code-blocks : left upper corner (x0, y0, z0) */ - int x0, y0, z0; -/** Dimension of the code-blocks : right low corner (x1,y1,z1) */ - int x1, y1, z1; -/** Number of bits per simbol in codeblock */ - int numbps; - int numlenbits; - int len; /* length */ -/** Number of pass already done for the code-blocks */ - int numpasses; -/** number of pass added to the code-blocks */ - int numnewpasses; -/** Number of segments */ - int numsegs; -/** Segments informations */ - opj_tcd_seg_t segs[100]; -/** Number of passes in the layer */ - int numpassesinlayers; -/** Layer information */ - opj_tcd_layer_t layers[100]; -/** Total number of passes */ - int totalpasses; -/** Information about the passes */ - opj_tcd_pass_t passes[100]; -/* Data */ - unsigned char data[524288]; - //unsigned char *data; -} opj_tcd_cblk_t; - -/** -Tile coder/decoder: precint instance -*/ -typedef struct opj_tcd_precinct { -/** Dimension of the precint : left upper corner (x0, y0, z0) */ - int x0, y0, z0; -/** Dimension of the precint : right low corner (x1,y1,z1) */ - int x1, y1, z1; -/** Number of codeblocks in precinct in width and heigth and length*/ - int cblkno[3]; -/** Information about the codeblocks */ - opj_tcd_cblk_t *cblks; -/** Inclusion tree */ - opj_tgt_tree_t *incltree; -/** Missing MSBs tree */ - opj_tgt_tree_t *imsbtree; -} opj_tcd_precinct_t; - -/** -Tile coder/decoder: subband instance -*/ -typedef struct opj_tcd_band { -/** Dimension of the subband : left upper corner (x0, y0, z0) */ - int x0, y0, z0; -/** Dimension of the subband : right low corner (x1,y1,z1) */ - int x1, y1, z1; -/** Information about the precints */ - opj_tcd_precinct_t *precincts; /* precinct information */ -/** Number of bits per symbol in band */ - int numbps; -/** Quantization stepsize associated */ - float stepsize; -/** Band orientation (O->LLL,...,7->HHH) */ - int bandno; -} opj_tcd_band_t; - -/** -Tile coder/decoder: resolution instance -*/ -typedef struct opj_tcd_resolution { -/** Dimension of the resolution level : left upper corner (x0, y0, z0) */ - int x0, y0, z0; -/** Dimension of the resolution level : right low corner (x1,y1,z1) */ - int x1, y1, z1; -/** Number of precints in each dimension for the resolution level */ - int prctno[3]; -/** Number of subbands for the resolution level */ - int numbands; -/** Subband information */ - opj_tcd_band_t *bands; -} opj_tcd_resolution_t; - -/** -Tile coder/decoder: component instance -*/ -typedef struct opj_tcd_tilecomp { -/** Dimension of the component : left upper corner (x0, y0, z0) */ - int x0, y0, z0; -/** Dimension of the component : right low corner (x1,y1,z1) */ - int x1, y1, z1; -/** Number of resolutions level if DWT transform*/ - int numresolution[3]; -/** Resolution information */ - opj_tcd_resolution_t *resolutions; -/** Data of the component */ - int *data; -/** Fixed_quality related */ - int nbpix; -/** Number of bits per voxel in component */ - int bpp; -} opj_tcd_tilecomp_t; - -/** -Tile coder/decoder: tile instance -*/ -typedef struct opj_tcd_tile { -/** Dimension of the tile : left upper corner (x0, y0, z0) */ - int x0, y0, z0; -/** Dimension of the tile : right low corner (x1,y1,z1) */ - int x1, y1, z1; -/** Number of components in tile */ - int numcomps; -/** Components information */ - opj_tcd_tilecomp_t *comps; -/** Fixed_quality related : no of bytes of data*/ - int nbpix; -/** Fixed_quality related : distortion achieved in tile */ - double distotile; -/** Fixed_quality related : distortion achieved in each layer */ - double distolayer[100]; -} opj_tcd_tile_t; - -/** -Tile coder/decoder: volume instance -*/ -typedef struct opj_tcd_volume { -/** Number of tiles in width and heigth and length */ - int tw, th, tl; -/** Tiles information */ - opj_tcd_tile_t *tiles; -} opj_tcd_volume_t; - -/** -Tile coder/decoder -*/ -typedef struct opj_tcd { -/** Codec context */ - opj_common_ptr cinfo; -/** Volume information */ - opj_volume_t *volume; -/** Coding parameters */ - opj_cp_t *cp; -/** Coding/decoding parameters common to all tiles */ - opj_tcp_t *tcp; -/** Info on each volume tile */ - opj_tcd_volume_t *tcd_volume; -/** Pointer to the current encoded/decoded tile */ - opj_tcd_tile_t *tcd_tile; -/** Current encoded/decoded tile */ - int tcd_tileno; - - /**@name working variables */ - /*@{*/ - opj_tcd_tile_t *tile; - opj_tcd_tilecomp_t *tilec; - opj_tcd_resolution_t *res; - opj_tcd_band_t *band; - opj_tcd_precinct_t *prc; - opj_tcd_cblk_t *cblk; - /*@}*/ -} opj_tcd_t; - -/** @name Funciones generales */ -/*@{*/ -/* ----------------------------------------------------------------------- */ - -/** -Dump the content of a tcd structure -*/ -void tcd_dump(FILE *fd, opj_tcd_t *tcd, opj_tcd_volume_t *img); -/** -Create a new TCD handle -@param cinfo Codec context info -@return Returns a new TCD handle if successful returns NULL otherwise -*/ -opj_tcd_t* tcd_create(opj_common_ptr cinfo); -/** -Destroy a previously created TCD handle -@param tcd TCD handle to destroy -*/ -void tcd_destroy(opj_tcd_t *tcd); -/** -Initialize the tile coder (allocate the memory) -@param tcd TCD handle -@param volume Raw volume -@param cp Coding parameters -@param curtileno Number that identifies the tile that will be encoded -*/ -void tcd_malloc_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno); -/** -Initialize the tile coder (reuses the memory allocated by tcd_malloc_encode)(for 3D-DWT) -@param tcd TCD handle -@param volume Raw volume -@param cp Coding parameters -@param curtileno Number that identifies the tile that will be encoded -*/ -void tcd_init_encode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp, int curtileno); -/** -Free the memory allocated for encoding -@param tcd TCD handle -*/ -void tcd_free_encode(opj_tcd_t *tcd); -/** -Initialize the tile decoder -@param tcd TCD handle -@param volume Raw volume -@param cp Coding parameters -*/ -void tcd_malloc_decode(opj_tcd_t *tcd, opj_volume_t * volume, opj_cp_t * cp); - -void tcd_makelayer_fixed(opj_tcd_t *tcd, int layno, int final); -void tcd_rateallocate_fixed(opj_tcd_t *tcd); -void tcd_makelayer(opj_tcd_t *tcd, int layno, double thresh, int final); -bool tcd_rateallocate(opj_tcd_t *tcd, unsigned char *dest, int len, opj_volume_info_t * volume_info); -/** -Encode a tile from the raw volume into a buffer -@param tcd TCD handle -@param tileno Number that identifies one of the tiles to be encoded -@param dest Destination buffer -@param len Length of destination buffer -@param volume_info Creation of index file -@return -*/ -int tcd_encode_tile(opj_tcd_t *tcd, int tileno, unsigned char *dest, int len, opj_volume_info_t * volume_info); -/** -Decode a tile from a buffer into a raw volume -@param tcd TCD handle -@param src Source buffer -@param len Length of source buffer -@param tileno Number that identifies one of the tiles to be decoded -*/ -bool tcd_decode_tile(opj_tcd_t *tcd, unsigned char *src, int len, int tileno); -/** -Free the memory allocated for decoding -@param tcd TCD handle -*/ -void tcd_free_decode(opj_tcd_t *tcd); - -/* ----------------------------------------------------------------------- */ -/*@}*/ - -/*@}*/ - -#endif /* __TCD_H */ diff --git a/jp3d/libjp3dvm/tgt.c b/jp3d/libjp3dvm/tgt.c deleted file mode 100755 index 9398ea94..00000000 --- a/jp3d/libjp3dvm/tgt.c +++ /dev/null @@ -1,256 +0,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, Hervé 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; -} diff --git a/jp3d/libjp3dvm/tgt.h b/jp3d/libjp3dvm/tgt.h deleted file mode 100755 index ad27f113..00000000 --- a/jp3d/libjp3dvm/tgt.h +++ /dev/null @@ -1,124 +0,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, Hervé 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/jp3d/libjp3dvm/volume.c b/jp3d/libjp3dvm/volume.c deleted file mode 100755 index 9066e390..00000000 --- a/jp3d/libjp3dvm/volume.c +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright (c) 2005, Hervé 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" - -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/jp3d/libjp3dvm/volume.h b/jp3d/libjp3dvm/volume.h deleted file mode 100755 index 737bde79..00000000 --- a/jp3d/libjp3dvm/volume.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2005, Hervé 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/jp3d/tcltk/LPI_JP3D_VM.tcl b/jp3d/tcltk/LPI_JP3D_VM.tcl deleted file mode 100755 index eb184de7..00000000 --- a/jp3d/tcltk/LPI_JP3D_VM.tcl +++ /dev/null @@ -1,114 +0,0 @@ -#!/bin/sh -# The next line is executed by /bin/sh, but not tcl \ -exec wish "$0" ${1+"$@"} - -namespace eval jp3dVM { - - variable _progress 0 - variable _afterid "" - variable _status "Compute in progress..." - variable notebook - variable mainframe - variable dataout "Process execution information" - variable status - variable prgtext - variable prgindic - - set pwd [pwd] - cd [file dirname [info script]] - variable VMDIR [pwd] - cd $pwd - - foreach script {encoder.tcl decoder.tcl} { - namespace inscope :: source $VMDIR/$script - } -} - - -proc jp3dVM::create { } { - variable notebook - variable mainframe - variable dataout - - bind all { catch {console show} } - - # Menu description - set descmenu { - "&File" {} {} 0 { - {command "E&xit" {} "Exit BWidget jp3dVM" {} -command exit} - } - "&Options" {} {} 0 { - {command "&Encode" {} "Show encoder" {} - -command {$jp3dVM::notebook raise [$jp3dVM::notebook page 0]} - } - {command "&Decode" {} "Show decoder" {} - -command {$jp3dVM::notebook raise [$jp3dVM::notebook page 1]} - } - } - "&Help" {} {} 0 { - {command "&About authors..." {} "Show info about authors" {} - -command {MessageDlg .msgdlg -parent . -title "About authors" -message " Copyright @ LPI-UVA 2006 " -type ok -icon info}} - } - } - - set mainframe [MainFrame .mainframe \ - -menu $descmenu \ - -textvariable jp3dVM::status \ - -progressvar jp3dVM::prgindic] - - $mainframe addindicator -text "JP3D Verification Model 1.0.0" - - # NoteBook creation - set frame [$mainframe getframe] - set notebook [NoteBook $frame.nb] - - set logo [frame $frame.logo] - #creo imagen logo - image create photo LPIimg -file logoLPI.gif - set logoimg [Label $logo.logoimg -image LPIimg] - - set f0 [VMEncoder::create $notebook] - set f1 [VMDecoder::create $notebook] - - set tfinfo [TitleFrame $frame.codinfo -text "Program Execution"] - set codinfo [$tfinfo getframe] - set sw [ScrolledWindow $codinfo.sw -relief sunken -borderwidth 2 -scrollbar both] - set sf [ScrollableFrame $codinfo.sf ] - $sw setwidget $sf - set subf [$sf getframe] - set labinfo [label $subf.labinfo -textvariable jp3dVM::dataout -justify left] - - pack $labinfo -side left - pack $sw - - $notebook compute_size - $notebook raise [$notebook page 0] - - pack $logoimg -side left -fill x -expand yes - pack $notebook -expand yes - pack $logo $tfinfo -side left -expand yes - pack $mainframe -fill both -expand yes - update idletasks -} - - -proc jp3dVM::main {} { - variable VMDIR - - lappend ::auto_path [file dirname $VMDIR] - namespace inscope :: package require BWidget - - option add *TitleFrame.l.font {helvetica 11 bold italic} - - wm withdraw . - wm title . "JP3D Verification Model @ LPI" - - jp3dVM::create - BWidget::place . 0 0 center - wm deiconify . - raise . - focus -force . -} - -jp3dVM::main -wm geom . [wm geom .] diff --git a/jp3d/tcltk/Thumbs.db b/jp3d/tcltk/Thumbs.db deleted file mode 100755 index 5d6ffdf99eb8ebe582a94fa45d711c3e0bb856ca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 18944 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 Be`5du diff --git a/jp3d/tcltk/decoder.tcl b/jp3d/tcltk/decoder.tcl deleted file mode 100755 index 6fadbb18..00000000 --- a/jp3d/tcltk/decoder.tcl +++ /dev/null @@ -1,272 +0,0 @@ - -namespace eval VMDecoder { - variable var - variable JP3Ddecoder "../bin/jp3d_vm_dec.exe" - #variable JP3Ddecoder "jp3d_vm_dec.exe" -} - - -proc VMDecoder::create { nb } { - variable var - - set frameD [$nb insert end VMDecoder -text "Decoder"] - set topfD [frame $frameD.topfD] - set medfD [frame $frameD.medfD] - set bottomfD [frame $frameD.bottomfD] - set srcfD [TitleFrame $topfD.srcfD -text "Source"] - set dstfD [TitleFrame $topfD.dstfD -text "Destination"] - set paramfD [TitleFrame $medfD.paramfD -text "Decoding parameters"] - set infofD [TitleFrame $medfD.infofD -text "Distortion measures"] - - set frame1 [$srcfD getframe] - _sourceD $frame1 - set frame2 [$dstfD getframe] - _destinationD $frame2 - set frame3 [$infofD getframe] - _originalD $frame3 - set frame4 [$paramfD getframe] - _paramsD $frame4 - - set butD [Button $bottomfD.butD -text "Decode!" \ - -command "VMDecoder::_decode $frame1 $frame2 $frame3" \ - -helptext "Decoding trigger button"] - set butR [Button $bottomfD.butR -text "Save info" \ - -command "VMDecoder::_save $frame3" \ - -helptext "Save information"] - - pack $srcfD $dstfD -side left -fill both -padx 10 -ipadx 5 -expand yes - pack $topfD -pady 4 -fill x - - pack $paramfD $infofD -side left -fill both -padx 10 -pady 2 -ipadx 5 -expand yes - pack $medfD -pady 4 -fill x - - pack $butD $butR -side left -padx 4 -pady 5 -expand yes - pack $bottomfD -pady 4 -fill x - -return $frameD -} - - -proc fileDialogD {w ent operation} { - - variable file - - if {$operation == "open"} { - #-----Type names---------Extension(s)--- - set types { - {"JP3D Files" {.jp3d} } - {"All files" *} - } - set file [tk_getOpenFile -filetypes $types -parent $w ] - } elseif {$operation == "original"} { - #-----Type names---------Extension(s)--- - set types { - {"BIN Raw Image Files" {.bin} } - {"PGX Raw Image Files" {.pgx} } - {"All files" *} - } - set file [tk_getOpenFile -filetypes $types -parent $w ] - } else { - #-----Type names---------Extension(s)--- - set types { - {"BIN Raw Image Files" {.bin} } - {"PGX Raw Image Files" {.pgx} } - {"All files" *} - } - set file [tk_getSaveFile -filetypes $types -parent $w -initialfile Untitled -defaultextension "*.bin"] - } - if {[string compare $file ""]} { - $ent delete 0 end - $ent insert end $file - $ent xview moveto 1 - } -} - -proc VMDecoder::_sourceD { parent } { - - variable var - - set labsrcD [LabelFrame $parent.labsrcD -text "Select compressed file: " -side top \ - -anchor w -relief flat -borderwidth 0] - set subsrcD [$labsrcD getframe] - set listD [entry $subsrcD.entrysrcD -width 40 -textvariable VMDecoder::var(sourceD)] - - set labbrw [LabelFrame $parent.labbrw -side top -anchor w -relief flat -borderwidth 0] - set subbrw [$labbrw getframe] - set butbrw [button $subbrw.butbrw -image [Bitmap::get open] \ - -relief raised -borderwidth 1 -padx 1 -pady 1 \ - -command "fileDialogD . $subsrcD.entrysrcD open"] - - pack $listD -side top - pack $butbrw -side top - pack $labsrcD $labbrw -side left -fill both -expand yes - - -} - -proc VMDecoder::_destinationD { parent } { - - variable var - - set labdstD [LabelFrame $parent.labdstD -text "Save decompressed volume file(s) as: " -side top \ - -anchor w -relief flat -borderwidth 0] - set subdstD [$labdstD getframe] - set listD [entry $subdstD.entrydstD -width 40 -textvariable VMDecoder::var(destinationD)] - - set labbrw [LabelFrame $parent.labbrw -side top -anchor w -relief flat -borderwidth 0] - set subbrw [$labbrw getframe] - set butbrw [button $subbrw.butbrw -image [Bitmap::get save] \ - -relief raised -borderwidth 1 -padx 1 -pady 1 \ - -command "fileDialogD . $subdstD.entrydstD save"] - - pack $listD -side top - pack $butbrw -side top - pack $labdstD $labbrw -side left -fill both -expand yes -} - -proc VMDecoder::_originalD { parent } { - - variable var - - set laborgD [LabelFrame $parent.laborgD -text "Select original file: " -side top \ - -anchor w -relief flat -borderwidth 0] - set suborgD [$laborgD getframe] - set listorgD [entry $suborgD.entryorgD -width 30 -textvariable VMDecoder::var(originalD)] - - set labbrw2 [LabelFrame $parent.labbrw2 -side top -anchor w -relief flat -borderwidth 0] - set subbrw2 [$labbrw2 getframe] - set butbrw2 [button $subbrw2.butbrw2 -image [Bitmap::get open] \ - -relief raised -borderwidth 1 -padx 1 -pady 1 \ - -command "fileDialogD . $suborgD.entryorgD original"] - - set infoD [Label $parent.infoD -relief sunken -textvariable VMDecoder::var(decodinfo) -justify left] - - pack $listorgD -side left -anchor n - pack $butbrw2 -side left -anchor n - pack $infoD -side bottom -anchor nw -pady 4 -ipadx 150 -ipady 20 -expand yes - pack $laborgD $labbrw2 -side left -fill both - - -} - -proc VMDecoder::_paramsD { parent } { - - variable var - - ########### DECODING ############# - set labcod [LabelFrame $parent.labcod -side top -anchor w -relief sunken -borderwidth 1] - set subcod [$labcod getframe] - - set frameres [frame $subcod.frameres -borderwidth 1] - set labres [LabelEntry $frameres.labres -label "Resolutions to discard: " -labelwidth 20 -labelanchor w \ - -textvariable VMDecoder::var(resdiscard) -editable 1 \ - -helptext "Number of highest resolution levels to be discarded on each dimension" ] - set VMDecoder::var(resdiscard) "0,0,0" - - set framelayer [frame $subcod.framelayer -borderwidth 1] - set lablayer [LabelEntry $framelayer.lablayer -label "Layers to decode: " -labelwidth 20 -labelanchor w \ - -textvariable VMDecoder::var(layer) -editable 1 \ - -helptext "Maximum number of quality layers to decode" ] - set VMDecoder::var(layer) "All" - - set framebe [frame $subcod.framebe -borderwidth 1] - set chkbe [checkbutton $framebe.chkbe -text "Write decoded file with BigEndian byte order" \ - -variable VMDecoder::var(be) -onvalue 1 -offvalue 0 ] - - pack $labres -side left -padx 2 -anchor n - pack $lablayer -side left -padx 2 -anchor n - pack $chkbe -side left -padx 2 -anchor w - pack $frameres $framelayer $framebe -side top -anchor w - - pack $subcod -anchor n - pack $labcod -side left -fill both -padx 4 -expand yes -} - - -proc VMDecoder::_decode { framesrc framedst frameinfo} { - - variable var - - set sourceD [$framesrc.labsrcD.f.entrysrcD get ] - set destinationD [$framedst.labdstD.f.entrydstD get ] - set originD [$frameinfo.laborgD.f.entryorgD get ] - set cond1 [string match *.pgx [string tolower $destinationD]] - set cond2 [string match *\**.pgx [string tolower $destinationD]] - set cond3 [string match *.bin [string tolower $destinationD]] - - #comprobamos datos son correctos - if {($cond1 == 1) && ($cond2 == 0)} { - set pgx "*.pgx" - set pattern [string range $destinationD 0 [expr [string length $destinationD]-5]] - set destinationD $pattern$img - } elseif {$sourceD == ""} { - MessageDlg .msgdlg -parent . -message "Error : Source file is not defined !" -type ok -icon error - } elseif {$destinationD == ""} { - MessageDlg .msgdlg -parent . -message "Error : Destination file is not defined !" -type ok -icon error - } else { - - #creamos datain a partir de los parametros de entrada - #set dirJP3Ddecoder [mk_relativepath $VMDecoder::JP3Ddecoder] - set dirJP3Ddecoder $VMDecoder::JP3Ddecoder - set datain [concat " $dirJP3Ddecoder -i [mk_relativepath $sourceD] "] - set datain [concat " $datain -o [mk_relativepath $destinationD] "] - if {$originD != ""} { - set datain [concat " $datain -O [mk_relativepath $originD] "] - if {$cond3 == 1} { - set img ".img" - set pattern [string range $originD 0 [expr [string length $originD]-5]] - set pattern $pattern$img - if {[file exists $pattern]} { - set datain [concat " $datain -m [mk_relativepath $pattern] "] - } else { - MessageDlg .msgdlg -parent . -message "Error : IMG file associated to original BIN volume file not found in same directory !" -type ok -icon info - } - } - } - if {$VMDecoder::var(resdiscard) != "0,0,0"} { - set datain [concat " $datain -r $VMDecoder::var(resdiscard) "] - } - if {$VMDecoder::var(layer) != "All" && $VMDecoder::var(layer) > 0} { - set datain [concat " $datain -l $VMDecoder::var(layer) "] - } - if {$VMDecoder::var(be) == 1} { - set datain [concat " $datain -BE"] - } - - set VMDecoder::var(progval) 10 - ProgressDlg .progress -parent . -title "Wait..." \ - -type infinite \ - -width 20 \ - -textvariable "Compute in progress..."\ - -variable VMDecoder::progval \ - -stop "Stop" \ - -command {destroy .progress} - - after 200 set VMDecoder::var(progval) 2 - - set fp [open "| $datain " r+] - fconfigure $fp -buffering line - set jp3dVM::dataout [concat "EXECUTED PROGRAM:\n\t$datain"] - while {-1 != [gets $fp tmp]} { - set jp3dVM::dataout [concat "$jp3dVM::dataout\n$tmp"] - } - close $fp - destroy .progress - set cond [string first "ERROR" $jp3dVM::dataout] - set cond2 [string first "PSNR" $jp3dVM::dataout] - set cond3 [string first "RESULT" $jp3dVM::dataout] - if {$cond != -1} { - MessageDlg .msgdlg -parent . -message [string range $jp3dVM::dataout [expr $cond-1] end] -type ok -icon error - } elseif {$cond3 != -1} { - if {$cond2 != -1} { - set VMDecoder::var(decodinfo) [string range $jp3dVM::dataout [expr $cond2-1] end] - } - MessageDlg .msgdlg -parent . -message [string range $jp3dVM::dataout [expr $cond3-1] end] -type ok -icon info - } - } -} - -proc VMDecoder::_save { frameinfo } { - -} - diff --git a/jp3d/tcltk/encoder.tcl b/jp3d/tcltk/encoder.tcl deleted file mode 100755 index dc174b71..00000000 --- a/jp3d/tcltk/encoder.tcl +++ /dev/null @@ -1,470 +0,0 @@ - -namespace eval VMEncoder { - variable var - variable JP3Dencoder "../bin/jp3d_vm_enc.exe" -} - -proc VMEncoder::create { nb } { - - set frame [$nb insert end VMEncoder -text "Encoder"] - set topf [frame $frame.topf] - set midf [frame $frame.midf] - set bottomf [frame $frame.bottomf] - set srcf [TitleFrame $topf.srcf -text "Source"] - set dstf [TitleFrame $topf.dstf -text "Destination"] - set Tparf [TitleFrame $midf.parfT -text "Transform Parameters"] - set Cparf [TitleFrame $midf.parfC -text "Coding Parameters"] - - set frame1 [$srcf getframe] - VMEncoder::_sourceE $frame1 - - set frame2 [$dstf getframe] - VMEncoder::_destinationE $frame2 - - set frame3 [$Tparf getframe] - VMEncoder::_transformE $frame3 - - set frame4 [$Cparf getframe] - VMEncoder::_codingE $frame4 - - set butE [Button $bottomf.butE -text "Encode!" \ - -command "VMEncoder::_encode $frame1 $frame2" \ - -helptext "Encoding trigger button"] - set butR [Button $bottomf.butR -text "Restore defaults" \ - -command "VMEncoder::_reset $frame1 $frame2 $frame3 $frame4" \ - -helptext "Reset to default values"] - - pack $srcf $dstf -side left -fill y -padx 4 -expand yes - pack $topf -pady 2 -fill x - - pack $Tparf $Cparf -side left -fill both -padx 4 -expand yes - pack $midf -pady 2 -fill x - - pack $butE $butR -side left -padx 40 -pady 5 -fill y -expand yes - pack $bottomf -pady 2 -fill x - - return $frame -} - -proc VMEncoder::_sourceE { parent } { - - variable var - - set labsrc [LabelFrame $parent.labsrc -text "Select volume file to encode: " -side top \ - -anchor w -relief flat -borderwidth 0] - set subsrc [$labsrc getframe] - set list [entry $subsrc.entrysrc -width 30 -textvariable VMDecoder::var(source)] - - set labbrw [LabelFrame $parent.labbrw -side top -anchor w -relief flat -borderwidth 0] - set subbrw [$labbrw getframe] - set butbrw [button $subbrw.butbrw -image [Bitmap::get open] \ - -relief raised -borderwidth 1 -padx 1 -pady 1 \ - -command "fileDialogE . $subsrc.entrysrc open"] - - pack $list -side top - pack $butbrw -side top - pack $labsrc $labbrw -side left -fill both -expand yes -} - -proc VMEncoder::_destinationE { parent } { - - variable var - - set labdst [LabelFrame $parent.labdst -text "Save compressed volume as: " -side top \ - -anchor w -relief flat -borderwidth 0] - set subdst [$labdst getframe] - set list [entry $subdst.entrydst -width 30 -textvariable VMDecoder::var(destination)] - - set labbrw [LabelFrame $parent.labbrw -side top -anchor w -relief flat -borderwidth 0] - set subbrw [$labbrw getframe] - set butbrw [button $subbrw.butbrw -image [Bitmap::get save] \ - -relief raised -borderwidth 1 -padx 1 -pady 1 \ - -command "fileDialogE . $subdst.entrydst save"] - - pack $list -side top - pack $butbrw -side top - pack $labdst $labbrw -side left -fill both -expand yes -} - -proc VMEncoder::_codingE { parent } { - - - ########### CODING ############# - set labcod [LabelFrame $parent.labcod -side top -anchor w -relief sunken -borderwidth 1] - set subcod [$labcod getframe] - - set framerate [frame $subcod.framerate -borderwidth 1] - set labrate [LabelEntry $framerate.labrate -label "Rates: " -labelwidth 9 -labelanchor w \ - -textvariable VMEncoder::var(rate) -editable 1 \ - -helptext "Compression ratios for different layers (R1, R2, R3,...). If R=1, lossless coding" ] - set VMEncoder::var(rate) "1" - - set framecblk [frame $subcod.framecblk -borderwidth 1] - set labcblk [LabelEntry $framecblk.labcblk -label "Codeblock: " -labelwidth 9 -labelanchor w \ - -textvariable VMEncoder::var(cblksize) -editable 1 \ - -helptext "Codeblock size (X, Y, Z)" ] - set VMEncoder::var(cblksize) "64,64,64" - - set frametile [frame $subcod.frametile -borderwidth 1] - set labtile [LabelEntry $frametile.labtile -label "Tile size: " -labelwidth 9 -labelanchor w \ - -textvariable VMEncoder::var(tilesize) -editable 1 \ - -helptext "Tile size (X, Y, Z)" ] - set VMEncoder::var(tilesize) "512,512,512" - - set framesop [frame $subcod.framesop -borderwidth 1] - set chksop [checkbutton $framesop.chksop -text "Write SOP marker" \ - -variable VMEncoder::var(sop) -onvalue 1 -offvalue 0 ] - set frameeph [frame $subcod.frameeph -borderwidth 1] - set chkeph [checkbutton $frameeph.chkeph -text "Write EPH marker" \ - -variable VMEncoder::var(eph) -onvalue 1 -offvalue 0 ] - - set framepoc [frame $subcod.framepoc -borderwidth 1] - set labpoc [label $framepoc.labpoc -text "Progression order: " ] - set progorder [ComboBox $framepoc.progorder \ - -text {Choose a progression order} \ - -width 10 \ - -textvariable VMEncoder::var(progorder) \ - -values {"LRCP" "RLCP" "RPCL" "PCRL" "CPRL"} \ - -helptext "Progression order"] - set VMEncoder::var(progorder) "LRCP" - - pack $labrate -side left -padx 2 -anchor n - pack $labcblk -side left -padx 2 -anchor n - pack $labpoc $progorder -side left -padx 2 -anchor w - #pack $labtile -side left -padx 2 -anchor n - pack $chksop -side left -padx 2 -anchor w - pack $chkeph -side left -padx 2 -anchor w - ########### ENTROPY CODING ############# - set labent [LabelFrame $parent.labent -text "Entropy Coding" -side top -anchor w -relief sunken -borderwidth 1] - set subent [$labent getframe] - foreach entval {2EB 3EB} entropy {2D_EBCOT 3D_EBCOT} { - set rad [radiobutton $subent.$entval \ - -text $entropy \ - -variable VMEncoder::var(encoding) \ - -command "disableGR $entval $labcblk $progorder $labrate $chksop $chkeph" \ - -value $entval ] - pack $rad -anchor w - } - $subent.2EB select - - pack $subent -padx 2 -anchor n - - pack $framerate $framecblk $framepoc $framesop $frameeph -side top -anchor w - pack $subcod -anchor n - - pack $labent $labcod -side left -fill both -padx 4 -expand yes - - -} - -proc VMEncoder::_transformE { parent } { - - variable var - - ########### TRANSFORM ############# - set labtrf [LabelFrame $parent.labtrf -text "Transform" -side top -anchor w -relief sunken -borderwidth 1] - set subtrf [$labtrf getframe] - set labres [LabelFrame $parent.labres -side top -anchor w -relief sunken -borderwidth 1] - set subres [$labres getframe] - - ########### ATK ############# - set frameatk [frame $subres.frameatk -borderwidth 1] - set labatk [label $frameatk.labatk -text "Wavelet kernel: " -anchor w] - set atk [ComboBox $frameatk.atk \ - -textvariable VMEncoder::var(atk) \ - -width 20 \ - -text {Choose a wavelet kernel} \ - -editable false \ - -values {"R5.3" "I9.7"} ] - set VMEncoder::var(atk) "R5.3" - pack $labatk $atk -side left -anchor w - ########### RESOLUTIONS ############# - set frameres1 [frame $subres.frameres1 -borderwidth 1] - set labresolution [label $frameres1.labresol -text "Resolutions: " -anchor w ] - set frameres2 [frame $subres.frameres2 -borderwidth 1] - set labresX [label $frameres2.labresX -text " X" -anchor w ] - set labresY [label $frameres2.labresY -text " Y" -anchor w ] - set labresZ [label $frameres2.labresZ -text " Z" -anchor w ] - - - set resX [SpinBox $frameres2.spinresX \ - -range {1 6 1} -textvariable VMEncoder::var(resX) \ - -helptext "Number of resolutions in X" \ - -width 3 \ - -editable false ] - set resY [SpinBox $frameres2.spinresY \ - -range {1 6 1} -textvariable VMEncoder::var(resY) \ - -helptext "Number of resolutions in Y" \ - -width 3 \ - -editable false ] - set resZ [SpinBox $frameres2.spinresZ \ - -range {1 6 1} -textvariable VMEncoder::var(resZ) \ - -helptext "Number of resolutions in Z" \ - -width 3 \ - -editable false \ - -state disabled ] - set VMEncoder::var(resX) 3 - set VMEncoder::var(resY) 3 - set VMEncoder::var(resZ) 3 - - ########### TRF ############# - foreach trfval {2DWT 3DWT} trf {2D-DWT 3D-DWT} { - set rad [radiobutton $subtrf.$trfval -text $trf \ - -variable VMEncoder::var(transform) \ - -command "disable3RLS $trfval $atk $resX $resY $resZ"\ - -value $trfval ] - pack $rad -anchor w - } - $subtrf.2DWT select - - pack $subtrf -side left -padx 2 -pady 4 - - pack $labresolution -padx 2 -side left -anchor w - pack $labresX $resX -padx 2 -side left -anchor w - pack $labresY $resY -padx 2 -side left -anchor w - pack $labresZ $resZ -padx 2 -side left -anchor w - - pack $frameres1 -side top -fill x - pack $frameres2 $frameatk -side top -padx 2 -pady 4 -anchor n - - pack $subres -side left -padx 2 -pady 4 - pack $labtrf $labres -side left -fill both -padx 4 -expand yes -} - - -proc VMEncoder::_encode { framesrc framedst } { - - variable var - - set source [$framesrc.labsrc.f.entrysrc get ] - set destination [$framedst.labdst.f.entrydst get ] - set cond1 [string match *.pgx [string tolower $source]] - set cond2 [string match *-*.pgx [string tolower $source]] - set cond3 [string match *.bin [string tolower $source]] - - set img ".img" - set pattern [string range $source 0 [expr [string length $source]-5]] - set pattern $pattern$img - set exist [file exists $pattern] - - #comprobamos datos son correctos - if {($cond1 == 1) && ($cond2 == 0)} { - MessageDlg .msgdlg -parent . -message "Info : Really want to encode an slice instead of a volume?.\n For a group of .pgx slices, name must contain a - denoting a sequential index!" -type ok -icon info - } - - if {$source == ""} { - MessageDlg .msgdlg -parent . -message "Error : Source file is not defined !" -type ok -icon error - } elseif {$destination == ""} { - MessageDlg .msgdlg -parent . -message "Error : Destination file is not defined !" -type ok -icon error - } elseif { ($VMEncoder::var(transform) != "3RLS") && ($VMEncoder::var(atk) == "Choose a wavelet transformation kernel") } { - MessageDlg .msgdlg -parent . -title "Info" -message "Please choose a wavelet transformation kernel"\ - -type ok -icon warning - } elseif {($exist == 0) && ($cond1 == 0) && ($cond3 == 1)} { - MessageDlg .msgdlg -parent . -message "Error : IMG file associated to BIN volume file not found in same directory !" -type ok -icon info - } else { - - #creamos datain a partir de los parametros de entrada -# set dirJP3Dencoder [mk_relativepath $VMEncoder::JP3Dencoder] - set dirJP3Dencoder $VMEncoder::JP3Dencoder - set datain [concat " $dirJP3Dencoder -i [mk_relativepath $source] "] - if {$cond3 == 1} { - set datain [concat " $datain -m [mk_relativepath $pattern] "] - } - set datain [concat " $datain -o [mk_relativepath $destination] "] - if {$VMEncoder::var(encoding) != "2EB"} { - set datain [concat " $datain -C $VMEncoder::var(encoding) "] - } - if {$VMEncoder::var(transform) == "2DWT"} { - set datain [concat " $datain -n $VMEncoder::var(resX),$VMEncoder::var(resY) "] - } elseif {$VMEncoder::var(transform) == "3DWT"} { - set datain [concat " $datain -n $VMEncoder::var(resX),$VMEncoder::var(resY),$VMEncoder::var(resZ) "] - } - - set datain [concat " $datain -r $VMEncoder::var(rate) "] - - if {$VMEncoder::var(atk) == "I9.7"} { - set datain [concat " $datain -I "] - } - if {$VMEncoder::var(sop) == 1} { - set datain [concat " $datain -SOP "] - } - if {$VMEncoder::var(eph) == 1} { - set datain [concat " $datain -EPH "] - } - if {$VMEncoder::var(progorder) != "LRCP"} { - set datain [concat " $datain -p $VMEncoder::var(progorder) "] - } - if {$VMEncoder::var(cblksize) != "64,64,64"} { - set datain [concat " $datain -b $VMEncoder::var(cblksize) "] - } - - - #Making this work would be great !!! - set VMEncoder::var(progval) 10 - ProgressDlg .progress -parent . -title "Wait..." \ - -type infinite \ - -width 20 \ - -textvariable "Compute in progress..."\ - -variable VMEncoder::progval \ - -stop "Stop" \ - -command {destroy .progress} - after 200 set VMEncoder::var(progval) 2 - set fp [open "| $datain " r+] - fconfigure $fp -buffering line - set jp3dVM::dataout [concat "EXECUTED PROGRAM:\n\t$datain"] - while {-1 != [gets $fp tmp]} { - set jp3dVM::dataout [concat "$jp3dVM::dataout\n$tmp"] - } - destroy .progress - set cond [string first "ERROR" $jp3dVM::dataout] - set cond2 [string first "RESULT" $jp3dVM::dataout] - if {$cond != -1} { - MessageDlg .msgdlg -parent . -message [string range $jp3dVM::dataout [expr $cond-1] end] -type ok -icon error - } elseif {$cond2 != -1} { - MessageDlg .msgdlg -parent . -message [string range $jp3dVM::dataout [expr $cond2+7] end] -type ok -icon info - close $fp - } else { - #Must do something with this !!! [pid $fp] - close $fp - } - } -} - -proc VMEncoder::_reset { framesrc framedst frametrf framecod} { - - variable var - - #Restore defaults values - set VMEncoder::var(transform) 2DWT - set VMEncoder::var(encoding) 2EB - set VMEncoder::var(atk) "R5.3" - set VMEncoder::var(progorder) "LRCP" - set atk $frametrf.labres.f.frameatk.atk - set resX $frametrf.labres.f.frameres2.spinresX - set resY $frametrf.labres.f.frameres2.spinresY - set resZ $frametrf.labres.f.frameres2.spinresZ - disable3RLS 2DWT $atk $resX $resY $resZ - set labcblk $framecod.labcod.f.framecblk.labcblk - set progorder $framecod.labcod.f.framepoc.progorder - set labrate $framecod.labcod.f.framerate.labrate - set chksop $framecod.labcod.f.framesop.chksop - set chkeph $framecod.labcod.f.frameeph.chkeph - disableGR 3EB $labcblk $progorder $labrate $chksop $chkeph - - $framesrc.labsrc.f.entrysrc delete 0 end - $framedst.labdst.f.entrydst delete 0 end -} - -proc fileDialogE {w ent operation} { - - variable file - variable i j - - if {$operation == "open"} { - set types { - {"Source Image Files" {.pgx .bin} } - {"All files" *} - } - set file [tk_getOpenFile -filetypes $types -parent $w] - if {[string compare $file ""]} { - $ent delete 0 end - $ent insert end $file - $ent xview moveto 1 - } - } else { - set types { - {"JP3D Files" {.jp3d} } - {"JPEG2000 Files" {.j2k} } - {"All files" *} - } - set file [tk_getSaveFile -filetypes $types -parent $w \ - -initialfile Untitled -defaultextension .jp3d] - if {[string compare $file ""]} { - $ent delete 0 end - $ent insert end $file - $ent xview moveto 1 - } - } -} - -proc mk_relativepath {abspath} { - - set mydir [split [string trimleft [pwd] {/}] {/}] - set abspathcomps [split [string trimleft $abspath {/}] {/}] - - set i 0 - while {$i<[llength $mydir]} { - if {![string compare [lindex $abspathcomps $i] [lindex $mydir $i]]} { - incr i - } else { - break - } - } - set h [expr [llength $mydir]-$i] - set j [expr [llength $abspathcomps]-$i] - - if {!$h} { - set relpath "./" - } else { - set relpath "" - while { $h > 0 } { - set relpath "../$relpath" - incr h -1 - } - } - - set h [llength $abspathcomps] - while { $h > $i } { - set relpath [concat $relpath[lindex $abspathcomps [expr [llength $abspathcomps]-$j]]/] - incr h -1 - incr j -1 - } - return [string trim $relpath {/}] -} - -proc disable3RLS {flag atk resX resY resZ} { - - if {$flag == "3RLS"} { - $atk configure -state disabled - $resX configure -state disabled - $resY configure -state disabled - $resZ configure -state disabled - } elseif {$flag == "2DWT"} { - $atk configure -state normal - $resX configure -state normal - $resY configure -state normal - $resZ configure -state disabled - } elseif {$flag == "3DWT"} { - $atk configure -state normal - $resX configure -state normal - $resY configure -state normal - $resZ configure -state normal - } -} - -proc disableGR {flag labcblk progorder labrate chksop chkeph} { - - if {$flag == "2EB"} { - $labcblk configure -state normal - $progorder configure -state normal - $labrate configure -state normal - $chksop configure -state normal - $chkeph configure -state normal - set VMEncoder::var(cblksize) "64,64,64" - set VMEncoder::var(tilesize) "512,512,512" - } elseif {$flag == "3EB"} { - $labcblk configure -state normal - $progorder configure -state normal - $labrate configure -state normal - $chksop configure -state normal - $chkeph configure -state normal - set VMEncoder::var(cblksize) "64,64,64" - set VMEncoder::var(tilesize) "512,512,512" - } else { - $labcblk configure -state disabled - $progorder configure -state disabled - $labrate configure -state disabled - $chksop configure -state disabled - $chkeph configure -state disabled - } -} \ No newline at end of file diff --git a/jp3d/tcltk/logoLPI.gif b/jp3d/tcltk/logoLPI.gif deleted file mode 100755 index df79515057f4163e12943482993fc337eafe2002..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5212 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 HVCw$>l!K-J diff --git a/libopenjpeg/CMakeLists.txt b/libopenjpeg/CMakeLists.txt index 2814ad40..e310e1bb 100644 --- a/libopenjpeg/CMakeLists.txt +++ b/libopenjpeg/CMakeLists.txt @@ -1,6 +1,7 @@ INCLUDE_REGULAR_EXPRESSION("^.*$") # Defines the source code for the library SET(OPENJPEG_SRCS + tcd.c bio.c cio.c dwt.c @@ -16,9 +17,33 @@ SET(OPENJPEG_SRCS pi.c raw.c t1.c - t2.c - tcd.c tgt.c + profile.c + invert.c + function_list.c + t2.c + bio.h + cio.h + dwt.h + event.h + image.h + j2k.h + j2k_lib.h + jp2.h + jpt.h + mct.h + mqc.h + openjpeg.h + pi.h + int.h + raw.h + t1.h + t2.h + tcd.h + tgt.h + profile.h + invert.h + function_list.h ) # Pass proper definition to preprocessor to generate shared lib @@ -30,6 +55,10 @@ IF(WIN32) ENDIF(BUILD_SHARED_LIBS) ENDIF(WIN32) +IF(ENABLE_PROFILING) + ADD_DEFINITIONS(-D_PROFILE) +ENDIF(ENABLE_PROFILING) + # Create the library ADD_LIBRARY(${OPENJPEG_LIBRARY_NAME} ${OPENJPEG_SRCS}) SET_TARGET_PROPERTIES(${OPENJPEG_LIBRARY_NAME} PROPERTIES diff --git a/libopenjpeg/bio.c b/libopenjpeg/bio.c index 4c02f464..78fefa79 100644 --- a/libopenjpeg/bio.c +++ b/libopenjpeg/bio.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +30,8 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "opj_includes.h" +#include "bio.h" +#include "opj_malloc.h" /** @defgroup BIO BIO - Individual bit input-output stream */ /*@{*/ @@ -42,25 +44,25 @@ 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); +static void bio_putbit(opj_bio_t *bio, OPJ_UINT32 b); /** Read a bit @param bio BIO handle @return Returns the read bit */ -static int bio_getbit(opj_bio_t *bio); +static OPJ_UINT32 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); +static bool 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); +static bool bio_bytein(opj_bio_t *bio); /*@}*/ @@ -72,27 +74,27 @@ static int bio_bytein(opj_bio_t *bio); ========================================================== */ -static int bio_byteout(opj_bio_t *bio) { +static bool 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; + return true; } *bio->bp++ = bio->buf >> 8; - return 0; + return false; } -static int bio_bytein(opj_bio_t *bio) { +static bool 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; + return true; } bio->buf |= *bio->bp++; - return 0; + return false; } -static void bio_putbit(opj_bio_t *bio, int b) { +static void bio_putbit(opj_bio_t *bio, OPJ_UINT32 b) { if (bio->ct == 0) { bio_byteout(bio); } @@ -100,7 +102,7 @@ static void bio_putbit(opj_bio_t *bio, int b) { bio->buf |= b << bio->ct; } -static int bio_getbit(opj_bio_t *bio) { +static OPJ_UINT32 bio_getbit(opj_bio_t *bio) { if (bio->ct == 0) { bio_bytein(bio); } @@ -125,11 +127,11 @@ void bio_destroy(opj_bio_t *bio) { } } -int bio_numbytes(opj_bio_t *bio) { +OPJ_UINT32 bio_numbytes(opj_bio_t *bio) { return (bio->bp - bio->start); } -void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) { +void bio_init_enc(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) { bio->start = bp; bio->end = bp + len; bio->bp = bp; @@ -137,7 +139,7 @@ void bio_init_enc(opj_bio_t *bio, unsigned char *bp, int len) { bio->ct = 8; } -void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) { +void bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 len) { bio->start = bp; bio->end = bp + len; bio->bp = bp; @@ -145,43 +147,43 @@ void bio_init_dec(opj_bio_t *bio, unsigned char *bp, int len) { bio->ct = 0; } -void bio_write(opj_bio_t *bio, int v, int n) { - int i; - for (i = n - 1; i >= 0; i--) { +void bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 n) { + OPJ_UINT32 i; + for (i = n - 1; i != -1 ; --i) { bio_putbit(bio, (v >> i) & 1); } } -int bio_read(opj_bio_t *bio, int n) { - int i, v; +OPJ_UINT32 bio_read(opj_bio_t *bio, OPJ_UINT32 n) { + OPJ_UINT32 i, v; v = 0; - for (i = n - 1; i >= 0; i--) { + for (i = n - 1; i != -1 ; --i) { v += bio_getbit(bio) << i; } return v; } -int bio_flush(opj_bio_t *bio) { +bool bio_flush(opj_bio_t *bio) { bio->ct = 0; if (bio_byteout(bio)) { - return 1; + return true; } if (bio->ct == 7) { bio->ct = 0; if (bio_byteout(bio)) { - return 1; + return true; } } - return 0; + return false; } -int bio_inalign(opj_bio_t *bio) { +bool bio_inalign(opj_bio_t *bio) { bio->ct = 0; if ((bio->buf & 0xff) == 0xff) { if (bio_bytein(bio)) { - return 1; + return true; } bio->ct = 0; } - return 0; + return false; } diff --git a/libopenjpeg/bio.h b/libopenjpeg/bio.h index 764d7cb2..cc25aa39 100644 --- a/libopenjpeg/bio.h +++ b/libopenjpeg/bio.h @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -37,7 +38,7 @@ The functions in BIO.C have for goal to realize an individual bit input - output. */ - +#include "openjpeg.h" /** @defgroup BIO BIO - Individual bit input-output stream */ /*@{*/ @@ -46,15 +47,15 @@ Individual bit input-output stream (BIO) */ typedef struct opj_bio { /** pointer to the start of the buffer */ - unsigned char *start; + OPJ_BYTE *start; /** pointer to the end of the buffer */ - unsigned char *end; + OPJ_BYTE *end; /** pointer to the present position in the buffer */ - unsigned char *bp; + OPJ_BYTE *bp; /** temporary place where each byte is read or written */ - unsigned int buf; + OPJ_UINT32 buf; /** coder : number of bits free to write. decoder : number of bits read */ - int ct; + OPJ_UINT32 ct; } opj_bio_t; /** @name Exported functions */ @@ -75,47 +76,47 @@ Number of bytes written. @param bio BIO handle @return Returns the number of bytes written */ -int bio_numbytes(opj_bio_t *bio); +OPJ_UINT32 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); +void bio_init_enc(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 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); +void bio_init_dec(opj_bio_t *bio, OPJ_BYTE *bp, OPJ_UINT32 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); +void bio_write(opj_bio_t *bio, OPJ_UINT32 v, OPJ_UINT32 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); +OPJ_UINT32 bio_read(opj_bio_t *bio, OPJ_UINT32 n); /** Flush bits @param bio BIO handle @return Returns 1 if successful, returns 0 otherwise */ -int bio_flush(opj_bio_t *bio); +bool 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); +bool bio_inalign(opj_bio_t *bio); /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/cio.c b/libopenjpeg/cio.c index 2ac262a1..05c7101c 100644 --- a/libopenjpeg/cio.c +++ b/libopenjpeg/cio.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,162 +30,790 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "cio.h" #include "opj_includes.h" +#include "opj_malloc.h" +#include "event.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; + +/** + * Write some bytes to the given data buffer, this function is used in Big Endian cpus. + * @param p_buffer pointer the data buffer to write data to. + * @param p_value the value to write + * @param p_nb_bytes the number of bytes to write +*/ +void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes) +{ + const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes; + assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32)); + memcpy(p_buffer,l_data_ptr,p_nb_bytes); +} + +/** + * Write some bytes to the given data buffer, this function is used in Little Endian cpus. + * @param p_buffer pointer the data buffer to write data to. + * @param p_value the value to write + * @param p_nb_bytes the number of bytes to write + * @return the number of bytes written or -1 if an error occured +*/ +void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes) +{ + const OPJ_BYTE * l_data_ptr = ((const OPJ_BYTE *) &p_value) + p_nb_bytes - 1; + OPJ_UINT32 i; + + assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32)); + for + (i=0;iopenmode = OPJ_STREAM_WRITE; - switch(cinfo->codec_format) { - case CODEC_J2K: - cp = ((opj_j2k_t*)cinfo->j2k_handle)->cp; - break; - case CODEC_JP2: - cp = ((opj_jp2_t*)cinfo->jp2_handle)->j2k->cp; - break; - default: - opj_free(cio); - return NULL; +} + +/** + * Reads some bytes from the given data buffer, this function is used in Big Endian cpus. + * @param p_buffer pointer the data buffer to read data from. + * @param p_value pointer to the value that will store the data. + * @param p_nb_bytes the nb bytes to read. + * @return the number of bytes read or -1 if an error occured. + */ +void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes) +{ + OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value); + assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32)); + *p_value = 0; + memcpy(l_data_ptr+4-p_nb_bytes,p_buffer,p_nb_bytes); +} + +/** + * Reads some bytes from the given data buffer, this function is used in Little Endian cpus. + * @param p_buffer pointer the data buffer to read data from. + * @param p_value pointer to the value that will store the data. + * @param p_nb_bytes the nb bytes to read. + * @return the number of bytes read or -1 if an error occured. + */ +void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes) +{ + OPJ_BYTE * l_data_ptr = ((OPJ_BYTE *) p_value) + p_nb_bytes-1; + OPJ_UINT32 i; + + assert(p_nb_bytes > 0 && p_nb_bytes <= sizeof(OPJ_UINT32)); + *p_value = 0; + for + (i=0;im_buffer_size = p_size; + l_stream->m_stored_data = (OPJ_BYTE *) opj_malloc(p_size); + if + (! l_stream->m_stored_data) + { + opj_free(l_stream); + return 00; + } + l_stream->m_current_data = l_stream->m_stored_data; + if + (l_is_input) + { + l_stream->m_status |= opj_stream_e_input; + l_stream->m_opj_skip = opj_stream_read_skip; + l_stream->m_opj_seek = opj_stream_read_seek; + } + else + { + l_stream->m_status |= opj_stream_e_output; + l_stream->m_opj_skip = opj_stream_write_skip; + l_stream->m_opj_seek = opj_stream_write_seek; + } + l_stream->m_read_fn = opj_stream_default_read; + l_stream->m_write_fn = opj_stream_default_write; + l_stream->m_skip_fn = opj_stream_default_skip; + l_stream->m_seek_fn = opj_stream_default_seek; + + return (opj_stream_t *) l_stream; +} + +/** + * Creates an abstract stream. This function does nothing except allocating memory and initializing the abstract stream. + * @return a stream object. +*/ +opj_stream_t* opj_stream_default_create(bool l_is_input) +{ + return opj_stream_create(J2K_STREAM_CHUNK_SIZE,l_is_input); +} + +/** + * Destroys a stream created by opj_create_stream. This function does NOT close the abstract stream. If needed the user must + * close its own implementation of the stream. + */ +OPJ_API void OPJ_CALLCONV opj_stream_destroy(opj_stream_t* p_stream) +{ + opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; + if + (l_stream) + { + opj_free(l_stream->m_stored_data); + l_stream->m_stored_data = 00; + opj_free(l_stream); + } + +} + +/** + * Sets the given function to be used as a read function. + * @param p_stream the stream to modify + * @param p_function the function to use a read function. +*/ +OPJ_API void OPJ_CALLCONV opj_stream_set_read_function(opj_stream_t* p_stream, opj_stream_read_fn p_function) +{ + opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; + if + ((!l_stream) || (! (l_stream->m_status & opj_stream_e_input))) + { + return; + } + l_stream->m_read_fn = p_function; +} + +OPJ_API void OPJ_CALLCONV opj_stream_set_seek_function(opj_stream_t* p_stream, opj_stream_seek_fn p_function) +{ + opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; + if + (!l_stream) + { + return; + } + l_stream->m_seek_fn = p_function; +} + +/** + * Sets the given function to be used as a write function. + * @param p_stream the stream to modify + * @param p_function the function to use a write function. +*/ +OPJ_API void OPJ_CALLCONV opj_stream_set_write_function(opj_stream_t* p_stream, opj_stream_write_fn p_function) +{ + opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; + if + ((!l_stream )|| (! (l_stream->m_status & opj_stream_e_output))) + { + return; + } + l_stream->m_write_fn = p_function; +} + +/** + * Sets the given function to be used as a skip function. + * @param p_stream the stream to modify + * @param p_function the function to use a skip function. +*/ +OPJ_API void OPJ_CALLCONV opj_stream_set_skip_function(opj_stream_t* p_stream, opj_stream_skip_fn p_function) +{ + opj_stream_private_t* l_stream = (opj_stream_private_t*) p_stream; + if + (! l_stream) + { + return; + } + l_stream->m_skip_fn = p_function; +} + +/** + * Sets the given data to be used as a user data for the stream. + * @param p_stream the stream to modify + * @param p_data the data to set. +*/ +OPJ_API 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; + l_stream->m_user_data = p_data; +} + +/** + * Reads some bytes from the stream. + * @param p_stream the stream to read data from. + * @param p_buffer pointer to the data buffer that will receive the data. + * @param p_size number of bytes to read. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes read, or -1 if an error occured or if the stream is at the end. + */ +OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, opj_event_mgr_t * p_event_mgr) +{ + OPJ_UINT32 l_read_nb_bytes = 0; + if + (p_stream->m_bytes_in_buffer >= p_size) + { + memcpy(p_buffer,p_stream->m_current_data,p_size); + p_stream->m_current_data += p_size; + p_stream->m_bytes_in_buffer -= p_size; + l_read_nb_bytes += p_size; + p_stream->m_byte_offset += p_size; + return l_read_nb_bytes; + } + + // we are now in the case when the remaining data if not sufficient + if + (p_stream->m_status & opj_stream_e_end) + { + l_read_nb_bytes += p_stream->m_bytes_in_buffer; + memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); + p_stream->m_current_data += p_stream->m_bytes_in_buffer; + p_stream->m_byte_offset += p_stream->m_bytes_in_buffer; + p_stream->m_bytes_in_buffer = 0; + return l_read_nb_bytes ? l_read_nb_bytes : -1; + } + + // the flag is not set, we copy data and then do an actual read on the stream + if + (p_stream->m_bytes_in_buffer) + { + l_read_nb_bytes += p_stream->m_bytes_in_buffer; + memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); + p_stream->m_current_data = p_stream->m_stored_data; + p_buffer += p_stream->m_bytes_in_buffer; + p_size -= p_stream->m_bytes_in_buffer; + p_stream->m_byte_offset += p_stream->m_bytes_in_buffer; + p_stream->m_bytes_in_buffer = 0; + } + + while + (true) + { + // we should read less than a chunk -> read a chunk + if + (p_size < p_stream->m_buffer_size) + { + // we should do an actual read on the media + p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_stream->m_stored_data,p_stream->m_buffer_size,p_stream->m_user_data); + if + (p_stream->m_bytes_in_buffer == -1) + { + // end of stream + opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n"); + p_stream->m_bytes_in_buffer = 0; + p_stream->m_status |= opj_stream_e_end; + // end of stream + return l_read_nb_bytes ? l_read_nb_bytes : -1; + } + else if + (p_stream->m_bytes_in_buffer < p_size) + { + // not enough data + l_read_nb_bytes += p_stream->m_bytes_in_buffer; + memcpy(p_buffer,p_stream->m_current_data,p_stream->m_bytes_in_buffer); + p_stream->m_current_data = p_stream->m_stored_data; + p_buffer += p_stream->m_bytes_in_buffer; + p_size -= p_stream->m_bytes_in_buffer; + p_stream->m_byte_offset += p_stream->m_bytes_in_buffer; + p_stream->m_bytes_in_buffer = 0; + } + else + { + l_read_nb_bytes += p_size; + memcpy(p_buffer,p_stream->m_current_data,p_size); + p_stream->m_current_data += p_size; + p_stream->m_bytes_in_buffer -= p_size; + p_stream->m_byte_offset += p_size; + return l_read_nb_bytes; + } } - cio->length = (unsigned int) (0.1625 * cp->img_size + 2000); /* 0.1625 = 1.3/8 and 2000 bytes as a minimum for headers */ - 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 + { + // direct read on the dest buffer + p_stream->m_bytes_in_buffer = p_stream->m_read_fn(p_buffer,p_size,p_stream->m_user_data); + if + (p_stream->m_bytes_in_buffer == -1) + { + // end of stream + opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n"); + p_stream->m_bytes_in_buffer = 0; + p_stream->m_status |= opj_stream_e_end; + // end of stream + return l_read_nb_bytes ? l_read_nb_bytes : -1; + } + else if + (p_stream->m_bytes_in_buffer < p_size) + { + // not enough data + l_read_nb_bytes += p_stream->m_bytes_in_buffer; + p_stream->m_current_data = p_stream->m_stored_data; + p_buffer += p_stream->m_bytes_in_buffer; + p_size -= p_stream->m_bytes_in_buffer; + p_stream->m_byte_offset += p_stream->m_bytes_in_buffer; + p_stream->m_bytes_in_buffer = 0; + } + else + { + // we have read the exact size + l_read_nb_bytes += p_stream->m_bytes_in_buffer; + p_stream->m_byte_offset += p_stream->m_bytes_in_buffer; + p_stream->m_current_data = p_stream->m_stored_data; + p_stream->m_bytes_in_buffer = 0; + return l_read_nb_bytes; + } } } - 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); +/** + * Writes some bytes from the stream. + * @param p_stream the stream to write data to. + * @param p_buffer pointer to the data buffer holds the data to be writtent. + * @param p_size number of bytes to write. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes writtent, or -1 if an error occured. + */ +OPJ_UINT32 opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer,OPJ_UINT32 p_size, opj_event_mgr_t * p_event_mgr) +{ + OPJ_UINT32 l_remaining_bytes = 0; + OPJ_UINT32 l_write_nb_bytes = 0; + + if + (p_stream->m_status & opj_stream_e_error) + { + return -1; + } + + while + (true) + { + l_remaining_bytes = p_stream->m_buffer_size - p_stream->m_bytes_in_buffer; + // we have more memory than required + if + (l_remaining_bytes >= p_size) + { + memcpy(p_stream->m_current_data,p_buffer,p_size); + p_stream->m_current_data += p_size; + p_stream->m_bytes_in_buffer += p_size; + l_write_nb_bytes += p_size; + p_stream->m_byte_offset += p_size; + return l_write_nb_bytes; + } + + // we copy data and then do an actual read on the stream + if + (l_remaining_bytes) + { + l_write_nb_bytes += l_remaining_bytes; + memcpy(p_stream->m_current_data,p_buffer,l_remaining_bytes); + p_stream->m_current_data = p_stream->m_stored_data; + p_buffer += l_remaining_bytes; + p_size -= l_remaining_bytes; + p_stream->m_bytes_in_buffer += l_remaining_bytes; + p_stream->m_byte_offset += l_remaining_bytes; + } + if + (! opj_stream_flush(p_stream, p_event_mgr)) + { + return -1; } - /* destroy the cio */ - opj_free(cio); } + } - -/* ----------------------------------------------------------------------- */ - -/* - * Get position in byte stream. +/** + * Writes the content of the stream buffer to the stream. + * @param p_stream the stream to write data to. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes written, or -1 if an error occured. */ -int OPJ_CALLCONV cio_tell(opj_cio_t *cio) { - return cio->bp - cio->start; -} +bool opj_stream_flush (opj_stream_private_t * p_stream, opj_event_mgr_t * p_event_mgr) +{ + // the number of bytes written on the media. + OPJ_UINT32 l_current_write_nb_bytes = 0; + p_stream->m_current_data = p_stream->m_stored_data; -/* - * 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. - */ -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; + while + (p_stream->m_bytes_in_buffer) + { + // we should do an actual write on the media + l_current_write_nb_bytes = p_stream->m_write_fn(p_stream->m_current_data,p_stream->m_bytes_in_buffer,p_stream->m_user_data); + if + (l_current_write_nb_bytes == -1) + { + p_stream->m_status |= opj_stream_e_error; + opj_event_msg(p_event_mgr, EVT_INFO, "Error on writting stream!\n"); + return false; + } + p_stream->m_current_data += l_current_write_nb_bytes; + p_stream->m_bytes_in_buffer -= l_current_write_nb_bytes; } - *cio->bp++ = v; + p_stream->m_current_data = p_stream->m_stored_data; return true; } -/* - * Read a byte. +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. */ -unsigned char cio_bytein(opj_cio_t *cio) { - if (cio->bp >= cio->end) { - opj_event_msg(cio->cinfo, EVT_ERROR, "read error: passed the end of the codestream (start = %d, current = %d, end = %d\n", cio->start, cio->bp, cio->end); - return 0; +OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr) +{ + OPJ_SIZE_T l_skip_nb_bytes = 0; + OPJ_SIZE_T l_current_skip_nb_bytes = 0; + + if + (p_stream->m_bytes_in_buffer >= p_size) + { + p_stream->m_current_data += p_size; + p_stream->m_bytes_in_buffer -= p_size; + l_skip_nb_bytes += p_size; + p_stream->m_byte_offset += l_skip_nb_bytes; + return l_skip_nb_bytes; } - 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; + // we are now in the case when the remaining data if not sufficient + if + (p_stream->m_status & opj_stream_e_end) + { + l_skip_nb_bytes += p_stream->m_bytes_in_buffer; + p_stream->m_current_data += p_stream->m_bytes_in_buffer; + p_stream->m_bytes_in_buffer = 0; + p_stream->m_byte_offset += l_skip_nb_bytes; + return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1; } - 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); + + // the flag is not set, we copy data and then do an actual skip on the stream + if + (p_stream->m_bytes_in_buffer) + { + l_skip_nb_bytes += p_stream->m_bytes_in_buffer; + p_stream->m_current_data = p_stream->m_stored_data; + p_size -= p_stream->m_bytes_in_buffer; + p_stream->m_bytes_in_buffer = 0; } - return v; + + while + (p_size > 0) + { + // we should do an actual skip on the media + l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data); + if + (l_current_skip_nb_bytes == (OPJ_SIZE_T) -1) + { + opj_event_msg(p_event_mgr, EVT_INFO, "Stream reached its end !\n"); + p_stream->m_status |= opj_stream_e_end; + p_stream->m_byte_offset += l_skip_nb_bytes; + // end if stream + return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T) -1; + } + p_size -= l_current_skip_nb_bytes; + l_skip_nb_bytes += l_current_skip_nb_bytes; + } + p_stream->m_byte_offset += l_skip_nb_bytes; + return l_skip_nb_bytes; } -/* - * Skip some bytes. - * - * n : number of bytes to skip +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. */ -void cio_skip(opj_cio_t *cio, int n) { - cio->bp += n; +OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr) +{ + bool l_is_written = 0; + OPJ_SIZE_T l_current_skip_nb_bytes = 0; + OPJ_SIZE_T l_skip_nb_bytes = 0; + + if + (p_stream->m_status & opj_stream_e_error) + { + return (OPJ_SIZE_T) -1; + } + + // we should flush data + l_is_written = opj_stream_flush (p_stream, p_event_mgr); + 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_SIZE_T) -1; + } + // then skip + + while + (p_size > 0) + { + // we should do an actual skip on the media + l_current_skip_nb_bytes = p_stream->m_skip_fn(p_size, p_stream->m_user_data); + if + (l_current_skip_nb_bytes == (OPJ_SIZE_T)-1) + { + opj_event_msg(p_event_mgr, EVT_INFO, "Stream error!\n"); + p_stream->m_status |= opj_stream_e_error; + p_stream->m_byte_offset += l_skip_nb_bytes; + // end if stream + return l_skip_nb_bytes ? l_skip_nb_bytes : (OPJ_SIZE_T)-1; + } + p_size -= l_current_skip_nb_bytes; + l_skip_nb_bytes += l_current_skip_nb_bytes; + } + p_stream->m_byte_offset += l_skip_nb_bytes; + return l_skip_nb_bytes; +} + +/** + * Tells the byte offset on the stream (similar to ftell). + * + * @param p_stream the stream to get the information from. + * + * @return the current position o fthe stream. + */ +OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream) +{ + return p_stream->m_byte_offset; +} + +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. + */ +OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr) +{ + return p_stream->m_opj_skip(p_stream,p_size,p_event_mgr); +} + + +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. + */ +bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr) +{ + p_stream->m_current_data = p_stream->m_stored_data; + p_stream->m_bytes_in_buffer = 0; + if + (! p_stream->m_seek_fn(p_size,p_stream->m_user_data)) + { + p_stream->m_status |= opj_stream_e_end; + return false; + } + else + { + // reset stream status + p_stream->m_status &= (~opj_stream_e_end); + p_stream->m_byte_offset = p_size; + + } + return true; +} + +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. + */ +bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, opj_event_mgr_t * p_event_mgr) +{ + if + (! opj_stream_flush(p_stream,p_event_mgr)) + { + p_stream->m_status |= opj_stream_e_error; + return false; + } + + p_stream->m_current_data = p_stream->m_stored_data; + p_stream->m_bytes_in_buffer = 0; + + if + (! p_stream->m_seek_fn(p_size,p_stream->m_user_data)) + { + p_stream->m_status |= opj_stream_e_error; + return false; + } + else + { + p_stream->m_byte_offset = p_size; + } + return true; +} + + +/** + * Seeks a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return true if the stream is seekable. + */ +bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr) +{ + return p_stream->m_opj_seek(p_stream,p_size,p_event_mgr); +} + +/** + * Tells if the given stream is seekable. + */ +bool opj_stream_has_seek (const opj_stream_private_t * p_stream) +{ + return p_stream->m_seek_fn != opj_stream_default_seek; +} + + + + + +OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data) +{ + return (OPJ_UINT32) -1; +} +OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data) +{ + return (OPJ_UINT32) -1; +} +OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data) +{ + return (OPJ_SIZE_T) -1; +} + +bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data) +{ + return false; } diff --git a/libopenjpeg/cio.h b/libopenjpeg/cio.h index 580bf9c0..12055ff0 100644 --- a/libopenjpeg/cio.h +++ b/libopenjpeg/cio.h @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -41,42 +42,314 @@ The functions in CIO.C have for goal to realize a byte input / output process. /** @defgroup CIO CIO - byte input-output stream */ /*@{*/ +#include "openjpeg.h" +#include "opj_configure.h" +struct opj_event_mgr; /** @name Exported functions (see also openjpeg.h) */ /*@{*/ /* ----------------------------------------------------------------------- */ + +#if defined(OPJ_BIG_ENDIAN) + #if !defined(OPJ_LITTLE_ENDIAN) + #define opj_write_bytes opj_write_bytes_BE + #define opj_read_bytes opj_read_bytes_BE + #define opj_write_double opj_write_double_BE + #define opj_read_double opj_read_double_BE + #define opj_write_float opj_write_float_BE + #define opj_read_float opj_read_float_BE + #else + #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not both." + #endif +#else + #if defined(OPJ_LITTLE_ENDIAN) + #define opj_write_bytes opj_write_bytes_LE + #define opj_read_bytes opj_read_bytes_LE + #define opj_write_double opj_write_double_LE + #define opj_read_double opj_read_double_LE + #define opj_write_float opj_write_float_LE + #define opj_read_float opj_read_float_LE + #else + #error "Either BIG_ENDIAN or LITTLE_ENDIAN must be #defined, but not none." + #endif +#endif + + + +typedef enum +{ + opj_stream_e_output = 0x1, + opj_stream_e_input = 0x2, + opj_stream_e_end = 0x4, + opj_stream_e_error = 0x8 +} +opj_stream_flag ; + /** -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 +Byte input-output stream. */ -int cio_numbytesleft(opj_cio_t *cio); +typedef struct opj_stream_private +{ + /** + * User data, be it files, ... The actual data depends on the type of the stream. + */ + void * m_user_data; + + /** + * Pointer to actual read function (NULL at the initialization of the cio. + */ + opj_stream_read_fn m_read_fn; + + /** + * Pointer to actual write function (NULL at the initialization of the cio. + */ + opj_stream_write_fn m_write_fn; + + /** + * Pointer to actual skip function (NULL at the initialization of the cio. + * There is no seek function to prevent from back and forth slow procedures. + */ + opj_stream_skip_fn m_skip_fn; + + /** + * Pointer to actual seek function (if available). + */ + opj_stream_seek_fn m_seek_fn; + + + + + /** + * Actual data stored into the stream if readed from. Data is read by chunk of fixed size. + * you should never access this data directly. + */ + OPJ_BYTE * m_stored_data; + + /** + * Pointer to the current read data. + */ + OPJ_BYTE * m_current_data; + + OPJ_SIZE_T (* m_opj_skip)(struct opj_stream_private * ,OPJ_SIZE_T , struct opj_event_mgr *); + + bool (* m_opj_seek) (struct opj_stream_private * , OPJ_SIZE_T , struct opj_event_mgr *); + + /** + * number of bytes containing in the buffer. + */ + OPJ_UINT32 m_bytes_in_buffer; + + /** + * The number of bytes read/written. + */ + OPJ_SIZE_T m_byte_offset; + + /** + * The size of the buffer. + */ + OPJ_UINT32 m_buffer_size; + + /** + * Flags to tell the status of the stream. + */ + OPJ_UINT32 m_status; + +} +opj_stream_private_t; + + /** -Get pointer to the current position in the stream -@param cio CIO handle -@return Returns a pointer to the current position + * Write some bytes to the given data buffer, this function is used in Big Endian cpus. + * @param p_buffer pointer the data buffer to write data to. + * @param p_value the value to write + * @param p_nb_bytes the number of bytes to write */ -unsigned char *cio_getbp(opj_cio_t *cio); +void opj_write_bytes_BE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes); + /** -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); + * Reads some bytes from the given data buffer, this function is used in Big Endian cpus. + * @param p_buffer pointer the data buffer to read data from. + * @param p_value pointer to the value that will store the data. + * @param p_nb_bytes the nb bytes to read. + * @return the number of bytes read or -1 if an error occured. + */ +void opj_read_bytes_BE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes); + /** -Read some bytes -@param cio CIO handle -@param n Number of bytes to read -@return Returns the value of the n bytes read + * Write some bytes to the given data buffer, this function is used in Little Endian cpus. + * @param p_buffer pointer the data buffer to write data to. + * @param p_value the value to write + * @param p_nb_bytes the number of bytes to write + * @return the number of bytes written or -1 if an error occured */ -unsigned int cio_read(opj_cio_t *cio, int n); +void opj_write_bytes_LE (OPJ_BYTE * p_buffer, OPJ_UINT32 p_value, OPJ_UINT32 p_nb_bytes); + /** -Skip some bytes -@param cio CIO handle -@param n Number of bytes to skip -*/ -void cio_skip(opj_cio_t *cio, int n); + * Reads some bytes from the given data buffer, this function is used in Little Endian cpus. + * @param p_buffer pointer the data buffer to read data from. + * @param p_value pointer to the value that will store the data. + * @param p_nb_bytes the nb bytes to read. + * @return the number of bytes read or -1 if an error occured. + */ +void opj_read_bytes_LE(const OPJ_BYTE * p_buffer, OPJ_UINT32 * p_value, OPJ_UINT32 p_nb_bytes); + + +/** + * Write some bytes to the given data buffer, this function is used in Little Endian cpus. + * @param p_buffer pointer the data buffer to write data to. + * @param p_value the value to write + */ +void opj_write_double_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value); + +/*** + * Write some bytes to the given data buffer, this function is used in Big Endian cpus. + * @param p_buffer pointer the data buffer to write data to. + * @param p_value the value to write + */ +void opj_write_double_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT64 p_value); + +/** + * Reads some bytes from the given data buffer, this function is used in Little Endian cpus. + * @param p_buffer pointer the data buffer to read data from. + * @param p_value pointer to the value that will store the data. + */ +void opj_read_double_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value); + +/** + * Reads some bytes from the given data buffer, this function is used in Big Endian cpus. + * @param p_buffer pointer the data buffer to read data from. + * @param p_value pointer to the value that will store the data. + */ +void opj_read_double_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT64 * p_value); + +/** + * Reads some bytes from the given data buffer, this function is used in Little Endian cpus. + * @param p_buffer pointer the data buffer to read data from. + * @param p_value pointer to the value that will store the data. + */ +void opj_read_float_LE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value); + +/** + * Reads some bytes from the given data buffer, this function is used in Big Endian cpus. + * @param p_buffer pointer the data buffer to read data from. + * @param p_value pointer to the value that will store the data. + */ +void opj_read_float_BE(const OPJ_BYTE * p_buffer, OPJ_FLOAT32 * p_value); + +/** + * Write some bytes to the given data buffer, this function is used in Little Endian cpus. + * @param p_buffer pointer the data buffer to write data to. + * @param p_value the value to write + */ +void opj_write_float_LE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value); + +/*** + * Write some bytes to the given data buffer, this function is used in Big Endian cpus. + * @param p_buffer pointer the data buffer to write data to. + * @param p_value the value to write + */ +void opj_write_float_BE(OPJ_BYTE * p_buffer, OPJ_FLOAT32 p_value); + +/** + * Reads some bytes from the stream. + * @param p_stream the stream to read data from. + * @param p_buffer pointer to the data buffer that will receive the data. + * @param p_size number of bytes to read. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes read, or -1 if an error occured or if the stream is at the end. + */ +OPJ_UINT32 opj_stream_read_data (opj_stream_private_t * p_stream,OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, struct opj_event_mgr * p_event_mgr); + +/** + * Writes some bytes to the stream. + * @param p_stream the stream to write data to. + * @param p_buffer pointer to the data buffer holds the data to be writtent. + * @param p_size number of bytes to write. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes writtent, or -1 if an error occured. + */ +OPJ_UINT32 opj_stream_write_data (opj_stream_private_t * p_stream,const OPJ_BYTE * p_buffer, OPJ_UINT32 p_size, struct opj_event_mgr * p_event_mgr); + +/** + * Writes the content of the stream buffer to the stream. + * @param p_stream the stream to write data to. + * @param p_event_mgr the user event manager to be notified of special events. + * @return true if the data could be flushed, false else. + */ +bool opj_stream_flush (opj_stream_private_t * p_stream, struct opj_event_mgr * p_event_mgr); + +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. + */ +OPJ_SIZE_T opj_stream_skip (opj_stream_private_t * p_stream,OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr); + +/** + * Tells the byte offset on the stream (similar to ftell). + * + * @param p_stream the stream to get the information from. + * + * @return the current position o fthe stream. + */ +OPJ_SIZE_T opj_stream_tell (const opj_stream_private_t * p_stream); + +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. + */ +OPJ_SIZE_T opj_stream_write_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr); + +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. + */ +OPJ_SIZE_T opj_stream_read_skip (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr); + +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. + */ +bool opj_stream_read_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr); + +/** + * Skips a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return the number of bytes skipped, or -1 if an error occured. + */ +bool opj_stream_write_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr); + +/** + * Seeks a number of bytes from the stream. + * @param p_stream the stream to skip data from. + * @param p_size the number of bytes to skip. + * @param p_event_mgr the user event manager to be notified of special events. + * @return true if the stream is seekable. + */ +bool opj_stream_seek (opj_stream_private_t * p_stream, OPJ_SIZE_T p_size, struct opj_event_mgr * p_event_mgr); + +/** + * Tells if the given stream is seekable. + */ +bool opj_stream_has_seek (const opj_stream_private_t * p_stream); + +OPJ_UINT32 opj_stream_default_read (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data); +OPJ_UINT32 opj_stream_default_write (void * p_buffer, OPJ_UINT32 p_nb_bytes, void * p_user_data); +OPJ_SIZE_T opj_stream_default_skip (OPJ_SIZE_T p_nb_bytes, void * p_user_data); +bool opj_stream_default_seek (OPJ_SIZE_T p_nb_bytes, void * p_user_data); + /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/dwt.c b/libopenjpeg/dwt.c index 78d18d17..a6ffd180 100644 --- a/libopenjpeg/dwt.c +++ b/libopenjpeg/dwt.c @@ -7,6 +7,7 @@ * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2007, Jonathan Ballard * Copyright (c) 2007, Callum Lerwick + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,7 +36,12 @@ #include #endif -#include "opj_includes.h" +#include "dwt.h" +#include "j2k.h" +#include "tcd.h" +#include "fix.h" +#include "opj_malloc.h" +#include "int.h" /** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ /*@{*/ @@ -47,31 +53,31 @@ /*@{*/ typedef struct dwt_local { - int* mem; - int dn; - int sn; - int cas; + OPJ_INT32* mem; + OPJ_INT32 dn; + OPJ_INT32 sn; + OPJ_INT32 cas; } dwt_t; typedef union { - float f[4]; + OPJ_FLOAT32 f[4]; } v4; typedef struct v4dwt_local { v4* wavelet ; - int dn ; - int sn ; - int cas ; + OPJ_INT32 dn ; + OPJ_INT32 sn ; + OPJ_INT32 cas ; } v4dwt_t ; -static const float dwt_alpha = 1.586134342f; // 12994 -static const float dwt_beta = 0.052980118f; // 434 -static const float dwt_gamma = -0.882911075f; // -7233 -static const float dwt_delta = -0.443506852f; // -3633 +static const OPJ_FLOAT32 dwt_alpha = 1.586134342f; // 12994 +static const OPJ_FLOAT32 dwt_beta = 0.052980118f; // 434 +static const OPJ_FLOAT32 dwt_gamma = -0.882911075f; // -7233 +static const OPJ_FLOAT32 delta = -0.443506852f; // -3633 -static const float K = 1.230174105f; // 10078 +static const OPJ_FLOAT32 K = 1.230174105f; // 10078 /* FIXME: What is this constant? */ -static const float c13318 = 1.625732422f; +static const OPJ_FLOAT32 c13318 = 1.625732422f; /*@}*/ @@ -86,23 +92,23 @@ typedef void (*DWT1DFN)(dwt_t* v); /** Forward lazy transform (horizontal) */ -static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas); +static void dwt_deinterleave_h(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas); /** Forward lazy transform (vertical) */ -static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas); +static void dwt_deinterleave_v(OPJ_INT32 *a, OPJ_INT32 *b, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 x, OPJ_INT32 cas); /** Inverse lazy transform (horizontal) */ -static void dwt_interleave_h(dwt_t* h, int *a); +static void dwt_interleave_h(dwt_t* h, OPJ_INT32 *a); /** Inverse lazy transform (vertical) */ -static void dwt_interleave_v(dwt_t* v, int *a, int x); +static void dwt_interleave_v(dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x); /** Forward 5-3 wavelet transform in 1-D */ -static void dwt_encode_1(int *a, int dn, int sn, int cas); +static void dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas); /** Inverse 5-3 wavelet transform in 1-D */ @@ -110,16 +116,19 @@ static void dwt_decode_1(dwt_t *v); /** Forward 9-7 wavelet transform in 1-D */ -static void dwt_encode_1_real(int *a, int dn, int sn, int cas); +static void dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas); /** Explicit calculation of the Quantization Stepsizes */ -static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize); +static void dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_t *bandno_stepsize); /** Inverse wavelet transform in 2-D. */ -static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int i, DWT1DFN fn); +static bool dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 i, DWT1DFN fn); +static OPJ_UINT32 dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i); + +static INLINE bool dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) ); /*@}*/ /*@}*/ @@ -135,7 +144,7 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int i, DWT1DFN fn); /* */ /* This table contains the norms of the 5-3 wavelets for different bands. */ /* */ -static const double dwt_norms[4][10] = { +static const OPJ_FLOAT64 dwt_norms[4][10] = { {1.000, 1.500, 2.750, 5.375, 10.68, 21.34, 42.67, 85.33, 170.7, 341.3}, {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, {1.038, 1.592, 2.919, 5.703, 11.33, 22.64, 45.25, 90.48, 180.9}, @@ -145,7 +154,7 @@ static const double dwt_norms[4][10] = { /* */ /* This table contains the norms of the 9-7 wavelets for different bands. */ /* */ -static const double dwt_norms_real[4][10] = { +static const OPJ_FLOAT64 dwt_norms_real[4][10] = { {1.000, 1.965, 4.177, 8.403, 16.90, 33.84, 67.69, 135.3, 270.6, 540.9}, {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0}, {2.022, 3.989, 8.355, 17.04, 34.27, 68.63, 137.3, 274.6, 549.0}, @@ -161,48 +170,88 @@ static const double dwt_norms_real[4][10] = { /* */ /* Forward lazy transform (horizontal). */ /* */ -static void dwt_deinterleave_h(int *a, int *b, int dn, int sn, int cas) { - int i; - for (i=0; i */ /* Forward lazy transform (vertical). */ /* */ -static void dwt_deinterleave_v(int *a, int *b, int dn, int sn, int x, int cas) { - int i; - for (i=0; i */ /* Inverse lazy transform (horizontal). */ /* */ -static void dwt_interleave_h(dwt_t* h, int *a) { - int *ai = a; - int *bi = h->mem + h->cas; - int i = h->sn; - while( i-- ) { - *bi = *(ai++); - bi += 2; +static void dwt_interleave_h(dwt_t* h, OPJ_INT32 *a) { + OPJ_INT32 *ai = a; + OPJ_INT32 *bi = h->mem + h->cas; + OPJ_INT32 i = h->sn; + while + ( i-- ) + { + *bi = *(ai++); + bi += 2; } ai = a + h->sn; bi = h->mem + 1 - h->cas; i = h->dn ; - while( i-- ) { - *bi = *(ai++); - bi += 2; + while + ( i-- ) + { + *bi = *(ai++); + bi += 2; } } /* */ /* Inverse lazy transform (vertical). */ /* */ -static void dwt_interleave_v(dwt_t* v, int *a, int x) { - int *ai = a; - int *bi = v->mem + v->cas; - int i = v->sn; +static void dwt_interleave_v(dwt_t* v, OPJ_INT32 *a, OPJ_INT32 x) { + OPJ_INT32 *ai = a; + OPJ_INT32 *bi = v->mem + v->cas; + OPJ_INT32 i = v->sn; while( i-- ) { *bi = *ai; bi += 2; @@ -222,8 +271,8 @@ static void dwt_interleave_v(dwt_t* v, int *a, int x) { /* */ /* Forward 5-3 wavelet transform in 1-D. */ /* */ -static void dwt_encode_1(int *a, int dn, int sn, int cas) { - int i; +static void dwt_encode_1(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) { + OPJ_INT32 i; if (!cas) { if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ @@ -243,8 +292,8 @@ static void dwt_encode_1(int *a, int dn, int sn, int cas) { /* */ /* Inverse 5-3 wavelet transform in 1-D. */ /* */ -static void dwt_decode_1_(int *a, int dn, int sn, int cas) { - int i; +static void dwt_decode_1_(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) { + OPJ_INT32 i; if (!cas) { if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ @@ -271,8 +320,8 @@ static void dwt_decode_1(dwt_t *v) { /* */ /* Forward 9-7 wavelet transform in 1-D. */ /* */ -static void dwt_encode_1_real(int *a, int dn, int sn, int cas) { - int i; +static void dwt_encode_1_real(OPJ_INT32 *a, OPJ_INT32 dn, OPJ_INT32 sn, OPJ_INT32 cas) { + OPJ_INT32 i; if (!cas) { if ((dn > 0) || (sn > 1)) { /* NEW : CASE ONE ELEMENT */ for (i = 0; i < dn; i++) @@ -306,8 +355,8 @@ static void dwt_encode_1_real(int *a, int dn, int sn, int cas) { } } -static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno_stepsize) { - int p, n; +static void dwt_encode_stepsize(OPJ_INT32 stepsize, OPJ_INT32 numbps, opj_stepsize_t *bandno_stepsize) { + OPJ_INT32 p, n; p = int_floorlog2(stepsize) - 13; n = 11 - int_floorlog2(stepsize); bandno_stepsize->mant = (n < 0 ? stepsize >> -n : stepsize << n) & 0x7ff; @@ -323,71 +372,105 @@ static void dwt_encode_stepsize(int stepsize, int numbps, opj_stepsize_t *bandno /* */ /* Forward 5-3 wavelet transform in 2-D. */ /* */ -void dwt_encode(opj_tcd_tilecomp_t * tilec) { - int i, j, k; - int *a = NULL; - int *aj = NULL; - int *bj = NULL; - int w, l; +INLINE bool dwt_encode_procedure(opj_tcd_tilecomp_t * tilec,void (*p_function)(OPJ_INT32 *, OPJ_INT32,OPJ_INT32,OPJ_INT32) ) +{ + OPJ_INT32 i, j, k; + OPJ_INT32 *a = 00; + OPJ_INT32 *aj = 00; + OPJ_INT32 *bj = 00; + OPJ_INT32 w, l; + OPJ_INT32 rw; /* width of the resolution level computed */ + OPJ_INT32 rh; /* height of the resolution level computed */ + OPJ_INT32 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; a = tilec->data; - for (i = 0; i < l; i++) { - int rw; /* width of the resolution level computed */ - int rh; /* height of the resolution level computed */ - int rw1; /* width of the resolution level once lower than computed one */ - int rh1; /* height of the resolution level once lower than computed one */ - int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ - int dn, sn; + 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 = dwt_max_resolution( tilec->resolutions,tilec->numresolutions) * sizeof(OPJ_INT32); + bj = opj_malloc(l_data_size); + if + (! bj) + { + return false; + } + i = l; + + while + (i--) + { + OPJ_INT32 rw1; /* width of the resolution level once lower than computed one */ + OPJ_INT32 rh1; /* height of the resolution level once lower than computed one */ + OPJ_INT32 cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ + OPJ_INT32 cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ + OPJ_INT32 dn, sn; - rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0; - rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0; - rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0; - rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0; + rw = l_cur_res->x1 - l_cur_res->x0; + rh = l_cur_res->y1 - l_cur_res->y0; + rw1 = l_last_res->x1 - l_last_res->x0; + rh1 = l_last_res->y1 - l_last_res->y0; - cas_row = tilec->resolutions[l - i].x0 % 2; - cas_col = tilec->resolutions[l - i].y0 % 2; + cas_row = l_cur_res->x0 & 1; + cas_col = l_cur_res->y0 & 1; sn = rh1; dn = rh - rh1; - bj = (int*)opj_malloc(rh * sizeof(int)); - for (j = 0; j < rw; j++) { + for + (j = 0; j < rw; ++j) + { aj = a + j; - for (k = 0; k < rh; k++) bj[k] = aj[k*w]; - dwt_encode_1(bj, dn, sn, cas_col); + for + (k = 0; k < rh; ++k) + { + bj[k] = aj[k*w]; + } + (*p_function) (bj, dn, sn, cas_col); dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); } - opj_free(bj); - sn = rw1; dn = rw - rw1; - bj = (int*)opj_malloc(rw * sizeof(int)); - for (j = 0; j < rh; j++) { + for (j = 0; j < rh; j++) + { aj = a + j * w; for (k = 0; k < rw; k++) bj[k] = aj[k]; - dwt_encode_1(bj, dn, sn, cas_row); + (*p_function) (bj, dn, sn, cas_row); dwt_deinterleave_h(bj, aj, dn, sn, cas_row); } - opj_free(bj); + l_cur_res = l_last_res; + --l_last_res; } + opj_free(bj); + return true; +} +/* Forward 5-3 wavelet transform in 2-D. */ +/* */ +bool dwt_encode(opj_tcd_tilecomp_t * tilec) +{ + return dwt_encode_procedure(tilec,dwt_encode_1); } - /* */ /* Inverse 5-3 wavelet transform in 2-D. */ /* */ -void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres) { - dwt_decode_tile(tilec, numres, &dwt_decode_1); +bool dwt_decode(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres) { + return dwt_decode_tile(tilec, numres, &dwt_decode_1); } /* */ /* Get gain of 5-3 wavelet transform. */ /* */ -int dwt_getgain(int orient) { +OPJ_UINT32 dwt_getgain(OPJ_UINT32 orient) { if (orient == 0) return 0; if (orient == 1 || orient == 2) @@ -398,71 +481,24 @@ int dwt_getgain(int orient) { /* */ /* Get norm of 5-3 wavelet. */ /* */ -double dwt_getnorm(int level, int orient) { +OPJ_FLOAT64 dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient) { return dwt_norms[orient][level]; } /* */ /* Forward 9-7 wavelet transform in 2-D. */ /* */ - -void dwt_encode_real(opj_tcd_tilecomp_t * tilec) { - int i, j, k; - int *a = NULL; - int *aj = NULL; - int *bj = NULL; - int w, l; - - w = tilec->x1-tilec->x0; - l = tilec->numresolutions-1; - a = tilec->data; - - for (i = 0; i < l; i++) { - int rw; /* width of the resolution level computed */ - int rh; /* height of the resolution level computed */ - int rw1; /* width of the resolution level once lower than computed one */ - int rh1; /* height of the resolution level once lower than computed one */ - int cas_col; /* 0 = non inversion on horizontal filtering 1 = inversion between low-pass and high-pass filtering */ - int cas_row; /* 0 = non inversion on vertical filtering 1 = inversion between low-pass and high-pass filtering */ - int dn, sn; - - rw = tilec->resolutions[l - i].x1 - tilec->resolutions[l - i].x0; - rh = tilec->resolutions[l - i].y1 - tilec->resolutions[l - i].y0; - rw1= tilec->resolutions[l - i - 1].x1 - tilec->resolutions[l - i - 1].x0; - rh1= tilec->resolutions[l - i - 1].y1 - tilec->resolutions[l - i - 1].y0; - - cas_row = tilec->resolutions[l - i].x0 % 2; - cas_col = tilec->resolutions[l - i].y0 % 2; - - sn = rh1; - dn = rh - rh1; - bj = (int*)opj_malloc(rh * sizeof(int)); - for (j = 0; j < rw; j++) { - aj = a + j; - for (k = 0; k < rh; k++) bj[k] = aj[k*w]; - dwt_encode_1_real(bj, dn, sn, cas_col); - dwt_deinterleave_v(bj, aj, dn, sn, w, cas_col); - } - opj_free(bj); - - sn = rw1; - dn = rw - rw1; - bj = (int*)opj_malloc(rw * sizeof(int)); - for (j = 0; j < rh; j++) { - aj = a + j * w; - for (k = 0; k < rw; k++) bj[k] = aj[k]; - dwt_encode_1_real(bj, dn, sn, cas_row); - dwt_deinterleave_h(bj, aj, dn, sn, cas_row); - } - opj_free(bj); - } +bool dwt_encode_real(opj_tcd_tilecomp_t * tilec) +{ + return dwt_encode_procedure(tilec,dwt_encode_1_real); } + /* */ /* Get gain of 9-7 wavelet transform. */ /* */ -int dwt_getgain_real(int orient) { +OPJ_UINT32 dwt_getgain_real(OPJ_UINT32 orient) { (void)orient; return 0; } @@ -470,16 +506,16 @@ int dwt_getgain_real(int orient) { /* */ /* Get norm of 9-7 wavelet. */ /* */ -double dwt_getnorm_real(int level, int orient) { +OPJ_FLOAT64 dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient) { return dwt_norms_real[orient][level]; } -void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) { - int numbands, bandno; +void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, OPJ_UINT32 prec) { + OPJ_UINT32 numbands, bandno; numbands = 3 * tccp->numresolutions - 2; for (bandno = 0; bandno < numbands; bandno++) { - double stepsize; - int resno, level, orient, gain; + OPJ_FLOAT64 stepsize; + OPJ_UINT32 resno, level, orient, gain; resno = (bandno == 0) ? 0 : ((bandno - 1) / 3 + 1); orient = (bandno == 0) ? 0 : ((bandno - 1) % 3 + 1); @@ -488,10 +524,10 @@ void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) { if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { stepsize = 1.0; } else { - double norm = dwt_norms_real[orient][level]; + OPJ_FLOAT64 norm = dwt_norms_real[orient][level]; stepsize = (1 << (gain)) / norm; } - dwt_encode_stepsize((int) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]); + dwt_encode_stepsize((OPJ_INT32) floor(stepsize * 8192.0), prec + gain, &tccp->stepsizes[bandno]); } } @@ -499,11 +535,11 @@ void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec) { /* */ /* Determine maximum computed resolution level for inverse wavelet transform */ /* */ -static int dwt_decode_max_resolution(opj_tcd_resolution_t* restrict r, int i) { - int mr = 1; - int w; +static OPJ_UINT32 dwt_max_resolution(opj_tcd_resolution_t* restrict r, OPJ_UINT32 i) { + OPJ_UINT32 mr = 0; + OPJ_UINT32 w; while( --i ) { - r++; + ++r; if( mr < ( w = r->x1 - r->x0 ) ) mr = w ; if( mr < ( w = r->y1 - r->y0 ) ) @@ -516,23 +552,29 @@ static int dwt_decode_max_resolution(opj_tcd_resolution_t* restrict r, int i) { /* */ /* Inverse wavelet transform in 2-D. */ /* */ -static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1D) { +static bool dwt_decode_tile(opj_tcd_tilecomp_t* tilec, OPJ_UINT32 numres, DWT1DFN dwt_1D) { dwt_t h; dwt_t v; opj_tcd_resolution_t* tr = tilec->resolutions; - int rw = tr->x1 - tr->x0; /* width of the resolution level computed */ - int rh = tr->y1 - tr->y0; /* height of the resolution level computed */ + 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 */ - int w = tilec->x1 - tilec->x0; + OPJ_UINT32 w = tilec->x1 - tilec->x0; + + h.mem = opj_aligned_malloc(dwt_max_resolution(tr, numres) * sizeof(OPJ_INT32)); + if + (! h.mem) + { + return false; + } - h.mem = opj_aligned_malloc(dwt_decode_max_resolution(tr, numres) * sizeof(int)); v.mem = h.mem; while( --numres) { - int * restrict tiledp = tilec->data; - int j; + OPJ_INT32 * restrict tiledp = tilec->data; + OPJ_UINT32 j; ++tr; h.sn = rw; @@ -547,14 +589,14 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1 for(j = 0; j < rh; ++j) { dwt_interleave_h(&h, &tiledp[j*w]); (dwt_1D)(&h); - memcpy(&tiledp[j*w], h.mem, rw * sizeof(int)); + memcpy(&tiledp[j*w], h.mem, rw * sizeof(OPJ_INT32)); } v.dn = rh - v.sn; v.cas = tr->y0 % 2; for(j = 0; j < rw; ++j){ - int k; + OPJ_UINT32 k; dwt_interleave_v(&v, &tiledp[j], w); (dwt_1D)(&v); for(k = 0; k < rh; ++k) { @@ -563,61 +605,62 @@ static void dwt_decode_tile(opj_tcd_tilecomp_t* tilec, int numres, DWT1DFN dwt_1 } } opj_aligned_free(h.mem); + return true; } -static void v4dwt_interleave_h(v4dwt_t* restrict w, float* restrict a, int x, int size){ - float* restrict bi = (float*) (w->wavelet + w->cas); - int count = w->sn; - int i, k; +static void v4dwt_interleave_h(v4dwt_t* restrict w, OPJ_FLOAT32* restrict a, OPJ_INT32 x, OPJ_INT32 size){ + OPJ_FLOAT32* restrict bi = (OPJ_FLOAT32*) (w->wavelet + w->cas); + OPJ_INT32 count = w->sn; + OPJ_INT32 i, k; for(k = 0; k < 2; ++k){ for(i = 0; i < count; ++i){ - int j = i; + OPJ_INT32 j = i; bi[i*8 ] = a[j]; j += x; - if(j > size) continue; + if(j >= size) continue; bi[i*8 + 1] = a[j]; j += x; - if(j > size) continue; + if(j >= size) continue; bi[i*8 + 2] = a[j]; j += x; - if(j > size) continue; + if(j >= size) continue; bi[i*8 + 3] = a[j]; } - bi = (float*) (w->wavelet + 1 - w->cas); + bi = (OPJ_FLOAT32*) (w->wavelet + 1 - w->cas); a += w->sn; size -= w->sn; count = w->dn; } } -static void v4dwt_interleave_v(v4dwt_t* restrict v , float* restrict a , int x){ +static void v4dwt_interleave_v(v4dwt_t* restrict v , OPJ_FLOAT32* restrict a , OPJ_INT32 x){ v4* restrict bi = v->wavelet + v->cas; - int i; + OPJ_INT32 i; for(i = 0; i < v->sn; ++i){ - memcpy(&bi[i*2], &a[i*x], 4 * sizeof(float)); + memcpy(&bi[i*2], &a[i*x], 4 * 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], 4 * sizeof(float)); + memcpy(&bi[i*2], &a[i*x], 4 * sizeof(OPJ_FLOAT32)); } } #ifdef __SSE__ -static void v4dwt_decode_step1_sse(v4* w, int count, const __m128 c){ +static void v4dwt_decode_step1_sse(v4* w, OPJ_INT32 count, const __m128 c){ __m128* restrict vw = (__m128*) w; - int i; + OPJ_INT32 i; for(i = 0; i < count; ++i){ __m128 tmp = vw[i*2]; vw[i*2] = tmp * c; } } -static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){ +static void v4dwt_decode_step2_sse(v4* l, v4* w, OPJ_INT32 k, OPJ_INT32 m, __m128 c){ __m128* restrict vl = (__m128*) l; __m128* restrict vw = (__m128*) w; - int i; + OPJ_INT32 i; for(i = 0; i < m; ++i){ __m128 tmp1 = vl[ 0]; __m128 tmp2 = vw[-1]; @@ -640,14 +683,14 @@ static void v4dwt_decode_step2_sse(v4* l, v4* w, int k, int m, __m128 c){ #else -static void v4dwt_decode_step1(v4* w, int count, const float c){ - float* restrict fw = (float*) w; - int i; +static void v4dwt_decode_step1(v4* w, OPJ_INT32 count, const OPJ_FLOAT32 c){ + OPJ_FLOAT32* restrict fw = (OPJ_FLOAT32*) w; + OPJ_INT32 i; for(i = 0; i < count; ++i){ - float tmp1 = fw[i*8 ]; - float tmp2 = fw[i*8 + 1]; - float tmp3 = fw[i*8 + 2]; - float tmp4 = fw[i*8 + 3]; + OPJ_FLOAT32 tmp1 = fw[i*8 ]; + OPJ_FLOAT32 tmp2 = fw[i*8 + 1]; + OPJ_FLOAT32 tmp3 = fw[i*8 + 2]; + OPJ_FLOAT32 tmp4 = fw[i*8 + 3]; fw[i*8 ] = tmp1 * c; fw[i*8 + 1] = tmp2 * c; fw[i*8 + 2] = tmp3 * c; @@ -655,23 +698,23 @@ static void v4dwt_decode_step1(v4* w, int count, const float c){ } } -static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){ - float* restrict fl = (float*) l; - float* restrict fw = (float*) w; - int i; +static void v4dwt_decode_step2(v4* l, v4* w, OPJ_INT32 k, OPJ_INT32 m, OPJ_FLOAT32 c){ + OPJ_FLOAT32* restrict fl = (OPJ_FLOAT32*) l; + OPJ_FLOAT32* restrict fw = (OPJ_FLOAT32*) w; + OPJ_INT32 i; for(i = 0; i < m; ++i){ - float tmp1_1 = fl[0]; - float tmp1_2 = fl[1]; - float tmp1_3 = fl[2]; - float tmp1_4 = fl[3]; - float tmp2_1 = fw[-4]; - float tmp2_2 = fw[-3]; - float tmp2_3 = fw[-2]; - float tmp2_4 = fw[-1]; - float tmp3_1 = fw[0]; - float tmp3_2 = fw[1]; - float tmp3_3 = fw[2]; - float tmp3_4 = fw[3]; + OPJ_FLOAT32 tmp1_1 = fl[0]; + OPJ_FLOAT32 tmp1_2 = fl[1]; + OPJ_FLOAT32 tmp1_3 = fl[2]; + OPJ_FLOAT32 tmp1_4 = fl[3]; + OPJ_FLOAT32 tmp2_1 = fw[-4]; + OPJ_FLOAT32 tmp2_2 = fw[-3]; + OPJ_FLOAT32 tmp2_3 = fw[-2]; + OPJ_FLOAT32 tmp2_4 = fw[-1]; + OPJ_FLOAT32 tmp3_1 = fw[0]; + OPJ_FLOAT32 tmp3_2 = fw[1]; + OPJ_FLOAT32 tmp3_3 = fw[2]; + OPJ_FLOAT32 tmp3_4 = fw[3]; fw[-4] = tmp2_1 + ((tmp1_1 + tmp3_1) * c); fw[-3] = tmp2_2 + ((tmp1_2 + tmp3_2) * c); fw[-2] = tmp2_3 + ((tmp1_3 + tmp3_3) * c); @@ -680,20 +723,20 @@ static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){ fw += 8; } if(m < k){ - float c1; - float c2; - float c3; - float c4; + OPJ_FLOAT32 c1; + OPJ_FLOAT32 c2; + OPJ_FLOAT32 c3; + OPJ_FLOAT32 c4; c += c; c1 = fl[0] * c; c2 = fl[1] * c; c3 = fl[2] * c; c4 = fl[3] * c; for(; m < k; ++m){ - float tmp1 = fw[-4]; - float tmp2 = fw[-3]; - float tmp3 = fw[-2]; - float tmp4 = fw[-1]; + OPJ_FLOAT32 tmp1 = fw[-4]; + OPJ_FLOAT32 tmp2 = fw[-3]; + OPJ_FLOAT32 tmp3 = fw[-2]; + OPJ_FLOAT32 tmp4 = fw[-1]; fw[-4] = tmp1 + c1; fw[-3] = tmp2 + c2; fw[-2] = tmp3 + c3; @@ -709,7 +752,7 @@ static void v4dwt_decode_step2(v4* l, v4* w, int k, int m, float c){ /* Inverse 9-7 wavelet transform in 1-D. */ /* */ static void v4dwt_decode(v4dwt_t* restrict dwt){ - int a, b; + OPJ_INT32 a, b; if(dwt->cas == 0) { if(!((dwt->dn > 0) || (dwt->sn > 1))){ return; @@ -726,14 +769,14 @@ static void v4dwt_decode(v4dwt_t* restrict dwt){ #ifdef __SSE__ v4dwt_decode_step1_sse(dwt->wavelet+a, dwt->sn, _mm_set1_ps(K)); v4dwt_decode_step1_sse(dwt->wavelet+b, dwt->dn, _mm_set1_ps(c13318)); - v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_delta)); + v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(delta)); v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_gamma)); v4dwt_decode_step2_sse(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), _mm_set1_ps(dwt_beta)); v4dwt_decode_step2_sse(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), _mm_set1_ps(dwt_alpha)); #else v4dwt_decode_step1(dwt->wavelet+a, dwt->sn, K); v4dwt_decode_step1(dwt->wavelet+b, dwt->dn, c13318); - v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_delta); + v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), delta); v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_gamma); v4dwt_decode_step2(dwt->wavelet+b, dwt->wavelet+a+1, dwt->sn, int_min(dwt->sn, dwt->dn-a), dwt_beta); v4dwt_decode_step2(dwt->wavelet+a, dwt->wavelet+b+1, dwt->dn, int_min(dwt->dn, dwt->sn-b), dwt_alpha); @@ -743,24 +786,24 @@ static void v4dwt_decode(v4dwt_t* restrict dwt){ /* */ /* Inverse 9-7 wavelet transform in 2-D. */ /* */ -void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){ +bool dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, OPJ_UINT32 numres){ v4dwt_t h; v4dwt_t v; opj_tcd_resolution_t* res = tilec->resolutions; - int rw = res->x1 - res->x0; /* width of the resolution level computed */ - int rh = res->y1 - res->y0; /* height of the resolution level computed */ + 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 */ - int w = tilec->x1 - tilec->x0; + OPJ_UINT32 w = tilec->x1 - tilec->x0; - h.wavelet = (v4*) opj_aligned_malloc((dwt_decode_max_resolution(res, numres)+5) * sizeof(v4)); + h.wavelet = (v4*) opj_aligned_malloc((dwt_max_resolution(res, numres)+5) * sizeof(v4)); v.wavelet = h.wavelet; while( --numres) { - float * restrict aj = (float*) tilec->data; - int bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0); - int j; + OPJ_FLOAT32 * restrict aj = (OPJ_FLOAT32*) tilec->data; + OPJ_UINT32 bufsize = (tilec->x1 - tilec->x0) * (tilec->y1 - tilec->y0); + OPJ_INT32 j; h.sn = rw; v.sn = rh; @@ -771,22 +814,26 @@ void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){ rh = res->y1 - res->y0; /* height of the resolution level computed */ h.dn = rw - h.sn; - h.cas = res->x0 % 2; + h.cas = res->x0 & 1; for(j = rh; j > 0; j -= 4){ v4dwt_interleave_h(&h, aj, w, bufsize); v4dwt_decode(&h); if(j >= 4){ - int k; - for(k = rw; --k >= 0;){ + OPJ_INT32 k = rw; + while + (--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]; } }else{ - int k; - for(k = rw; --k >= 0;){ + OPJ_INT32 k = rw; + while + (--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]; @@ -801,19 +848,19 @@ void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){ v.dn = rh - v.sn; v.cas = res->y0 % 2; - aj = (float*) tilec->data; + aj = (OPJ_FLOAT32*) tilec->data; for(j = rw; j > 0; j -= 4){ v4dwt_interleave_v(&v, aj, w); v4dwt_decode(&v); if(j >= 4){ - int k; + OPJ_UINT32 k; for(k = 0; k < rh; ++k){ - memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(float)); + memcpy(&aj[k*w], &v.wavelet[k], 4 * sizeof(OPJ_FLOAT32)); } }else{ - int k; + OPJ_UINT32 k; for(k = 0; k < rh; ++k){ - memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(float)); + memcpy(&aj[k*w], &v.wavelet[k], j * sizeof(OPJ_FLOAT32)); } } aj += 4; @@ -821,5 +868,6 @@ void dwt_decode_real(opj_tcd_tilecomp_t* restrict tilec, int numres){ } opj_aligned_free(h.wavelet); + return true; } diff --git a/libopenjpeg/dwt.h b/libopenjpeg/dwt.h index adf73e54..d200b065 100644 --- a/libopenjpeg/dwt.h +++ b/libopenjpeg/dwt.h @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -39,6 +40,10 @@ The functions in DWT.C have for goal to realize forward and inverse discret wave transform with filter 5-3 (reversible) and filter 9-7 (irreversible). The functions in DWT.C are used by some function in TCD.C. */ +#include "openjpeg.h" + +struct opj_tcd_tilecomp; +struct opj_tccp; /** @defgroup DWT DWT - Implementation of a discrete wavelet transform */ /*@{*/ @@ -52,59 +57,59 @@ Forward 5-3 wavelet tranform in 2-D. Apply a reversible DWT transform to a component of an image. @param tilec Tile component information (current tile) */ -void dwt_encode(opj_tcd_tilecomp_t * tilec); +bool dwt_encode(struct opj_tcd_tilecomp * tilec); /** Inverse 5-3 wavelet tranform in 2-D. Apply a reversible inverse DWT transform to a component of an image. @param tilec Tile component information (current tile) @param numres Number of resolution levels to decode */ -void dwt_decode(opj_tcd_tilecomp_t* tilec, int numres); +bool dwt_decode(struct opj_tcd_tilecomp* tilec, OPJ_UINT32 numres); /** Get the gain of a subband for the reversible 5-3 DWT. @param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH) @return Returns 0 if orient = 0, returns 1 if orient = 1 or 2, returns 2 otherwise */ -int dwt_getgain(int orient); +OPJ_UINT32 dwt_getgain(OPJ_UINT32 orient); /** Get the norm of a wavelet function of a subband at a specified level for the reversible 5-3 DWT. @param level Level of the wavelet function @param orient Band of the wavelet function @return Returns the norm of the wavelet function */ -double dwt_getnorm(int level, int orient); +OPJ_FLOAT64 dwt_getnorm(OPJ_UINT32 level, OPJ_UINT32 orient); /** Forward 9-7 wavelet transform in 2-D. Apply an irreversible DWT transform to a component of an image. @param tilec Tile component information (current tile) */ -void dwt_encode_real(opj_tcd_tilecomp_t * tilec); +bool dwt_encode_real(struct opj_tcd_tilecomp * tilec); /** Inverse 9-7 wavelet transform in 2-D. Apply an irreversible inverse DWT transform to a component of an image. @param tilec Tile component information (current tile) @param numres Number of resolution levels to decode */ -void dwt_decode_real(opj_tcd_tilecomp_t* tilec, int numres); +bool dwt_decode_real(struct opj_tcd_tilecomp* tilec, OPJ_UINT32 numres); /** Get the gain of a subband for the irreversible 9-7 DWT. @param orient Number that identifies the subband (0->LL, 1->HL, 2->LH, 3->HH) @return Returns the gain of the 9-7 wavelet transform */ -int dwt_getgain_real(int orient); +OPJ_UINT32 dwt_getgain_real(OPJ_UINT32 orient); /** Get the norm of a wavelet function of a subband at a specified level for the irreversible 9-7 DWT @param level Level of the wavelet function @param orient Band of the wavelet function @return Returns the norm of the 9-7 wavelet */ -double dwt_getnorm_real(int level, int orient); +OPJ_FLOAT64 dwt_getnorm_real(OPJ_UINT32 level, OPJ_UINT32 orient); /** Explicit calculation of the Quantization Stepsizes @param tccp Tile-component coding parameters @param prec Precint analyzed */ -void dwt_calc_explicit_stepsizes(opj_tccp_t * tccp, int prec); +void dwt_calc_explicit_stepsizes(struct opj_tccp * tccp, OPJ_UINT32 prec); /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/event.c b/libopenjpeg/event.c index 291ff585..eb40c6aa 100644 --- a/libopenjpeg/event.c +++ b/libopenjpeg/event.c @@ -24,84 +24,59 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "event.h" +#include "openjpeg.h" #include "opj_includes.h" + /* ========================================================== Utility functions ==========================================================*/ #if !defined(_MSC_VER) && !defined(__MINGW32__) -static char* -i2a(unsigned i, char *a, unsigned r) { +static OPJ_CHAR* +i2a(OPJ_UINT32 i, OPJ_CHAR *a, OPJ_UINT32 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 */ - +#endif /* ----------------------------------------------------------------------- */ -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, ...) { +bool opj_event_msg(opj_event_mgr_t * p_event_mgr, OPJ_INT32 event_type, const OPJ_CHAR *fmt, ...) { #define MSG_SIZE 512 /* 512 bytes should be more than enough for a short message */ - opj_msg_callback msg_handler = NULL; + opj_msg_callback msg_handler = 00; + void * l_data = 00; - opj_event_mgr_t *event_mgr = cinfo->event_mgr; - if(event_mgr != NULL) { + + if(p_event_mgr != 00) { switch(event_type) { case EVT_ERROR: - msg_handler = event_mgr->error_handler; + msg_handler = p_event_mgr->error_handler; + l_data = p_event_mgr->m_error_data; break; case EVT_WARNING: - msg_handler = event_mgr->warning_handler; + msg_handler = p_event_mgr->warning_handler; + l_data = p_event_mgr->m_warning_data; break; case EVT_INFO: - msg_handler = event_mgr->info_handler; + msg_handler = p_event_mgr->info_handler; + l_data = p_event_mgr->m_info_data; break; default: break; } - if(msg_handler == NULL) { + if(msg_handler == 00) { return false; } } else { return false; } - if ((fmt != NULL) && (event_mgr != NULL)) { + if ((fmt != 00) && (p_event_mgr != 00)) { va_list arg; - int str_length/*, i, j*/; /* UniPG */ - char message[MSG_SIZE]; + OPJ_INT32 str_length/*, i, j*/; /* UniPG */ + OPJ_CHAR message[MSG_SIZE]; memset(message, 0, MSG_SIZE); /* initialize the optional parameter list */ va_start(arg, fmt); @@ -113,7 +88,7 @@ bool opj_event_msg(opj_common_ptr cinfo, int event_type, const char *fmt, ...) { va_end(arg); /* output the message to the user program */ - msg_handler(message, cinfo->client_data); + msg_handler(message, l_data); } return true; diff --git a/libopenjpeg/event.h b/libopenjpeg/event.h index 11910b0e..4c035a88 100644 --- a/libopenjpeg/event.h +++ b/libopenjpeg/event.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -25,12 +26,39 @@ */ #ifndef __EVENT_H #define __EVENT_H + +#include "openjpeg.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. */ +/** +Message handler object +used for +
    +
  • Error messages +
  • Warning messages +
  • Debugging messages +
+*/ +typedef struct opj_event_mgr +{ + /** Data to call the event manager upon */ + void * m_error_data; + /** Data to call the event manager upon */ + void * m_warning_data; + /** Data to call the event manager upon */ + void * m_info_data; + /** 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; #define EVT_ERROR 1 /**< Error event type */ #define EVT_WARNING 2 /**< Warning event type */ @@ -43,13 +71,13 @@ The functions in EVENT.C have for goal to send output messages (errors, warnings /*@{*/ /* ----------------------------------------------------------------------- */ /** -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 + * Writes formatted data to a string and send the string to a user callback. + * @param p_event_mgr the event manager to display messages. + * @param event_type Event type of 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, ...); +bool opj_event_msg(struct opj_event_mgr * p_event_mgr, OPJ_INT32 event_type, const OPJ_CHAR *fmt, ...); /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/fix.h b/libopenjpeg/fix.h index bcb2acb5..f4bb87f6 100644 --- a/libopenjpeg/fix.h +++ b/libopenjpeg/fix.h @@ -31,11 +31,8 @@ #ifndef __FIX_H #define __FIX_H -#if defined(_MSC_VER) || defined(__BORLANDC__) -#define int64 __int64 -#else -#define int64 long long -#endif +#include "openjpeg.h" +#include "opj_includes.h" /** @file fix.h @@ -43,7 +40,6 @@ The functions in FIX.H have for goal to realize specific multiplication. */ - /** @defgroup FIX FIX - Implementation of operations of specific multiplication */ /*@{*/ @@ -54,7 +50,7 @@ Multiply two fixed-precision rational numbers. @return Returns a * b */ static INLINE int fix_mul(int a, int b) { - int64 temp = (int64) a * (int64) b ; + OPJ_INT64 temp = (OPJ_INT64) a * (OPJ_INT64) b ; temp += temp & 4096; return (int) (temp >> 13) ; } diff --git a/libopenjpeg/function_list.c b/libopenjpeg/function_list.c new file mode 100644 index 00000000..29eab611 --- /dev/null +++ b/libopenjpeg/function_list.c @@ -0,0 +1,147 @@ +/* + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes + * 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 "function_list.h" +#include "opj_includes.h" +#include "opj_malloc.h" +/** + * Default size of the validation list, if not sufficient, data will be reallocated with a double size. + */ +#define OPJ_VALIDATION_SIZE 10 + +/** + * Creates a validation list. + * + * @return the newly created validation list. + */ +opj_procedure_list_t * opj_procedure_list_create() +{ + /* memory allocation */ + opj_procedure_list_t * l_validation = (opj_procedure_list_t *) opj_malloc(sizeof(opj_procedure_list_t)); + if + (! l_validation) + { + return 00; + } + /* initialization */ + memset(l_validation,0,sizeof(opj_procedure_list_t)); + l_validation->m_nb_max_procedures = OPJ_VALIDATION_SIZE; + l_validation->m_procedures = opj_malloc(OPJ_VALIDATION_SIZE * sizeof(opj_procedure)); + if + (! l_validation->m_procedures) + { + opj_free(l_validation); + return 00; + } + memset(l_validation->m_procedures,0,OPJ_VALIDATION_SIZE * sizeof(opj_procedure)); + return l_validation; +} + + + +/** + * Destroys a validation list. + * + * @param p_list the list to destroy. + */ +void opj_procedure_list_destroy(opj_procedure_list_t * p_list) +{ + if + (! p_list) + { + return; + } + /* initialization */ + if + (p_list->m_procedures) + { + opj_free(p_list->m_procedures); + } + opj_free(p_list); +} + +/** + * Adds a new validation procedure. + * + * @param p_validation_list the list of procedure to modify. + * @param p_procedure the procedure to add. + */ +bool opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure) +{ + if + (p_validation_list->m_nb_max_procedures == p_validation_list->m_nb_procedures) + { + p_validation_list->m_nb_max_procedures += OPJ_VALIDATION_SIZE; + p_validation_list->m_procedures = opj_realloc(p_validation_list->m_procedures,p_validation_list->m_nb_max_procedures * sizeof(opj_procedure)); + if + (! p_validation_list->m_procedures) + { + p_validation_list->m_nb_max_procedures = 0; + p_validation_list->m_nb_procedures = 0; + return false; + } + } + p_validation_list->m_procedures[p_validation_list->m_nb_procedures] = p_procedure; + ++p_validation_list->m_nb_procedures; + return true; +} + +/** + * Gets the number of validation procedures. + * + * @param p_validation_list the list of procedure to modify. + * + * @return the number of validation procedures. + */ +OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_validation_list) +{ + return p_validation_list->m_nb_procedures; +} + +/** + * Gets the pointer on the first validation procedure. This function is similar to the C++ + * iterator class to iterate through all the procedures inside the validation list. + * the caller does not take ownership of the pointer. + * + * @param p_validation_list the list of procedure to get the first procedure from. + * + * @return a pointer to the first procedure. + */ +opj_procedure* opj_procedure_list_get_first_procedure (opj_procedure_list_t * p_validation_list) +{ + return p_validation_list->m_procedures; +} + +/** + * Clears the list of validation procedures. + * + * @param p_validation_list the list of procedure to clear. + * + */ +void opj_procedure_list_clear (opj_procedure_list_t * p_validation_list) +{ + p_validation_list->m_nb_procedures = 0; +} diff --git a/libopenjpeg/function_list.h b/libopenjpeg/function_list.h new file mode 100644 index 00000000..7cfedf10 --- /dev/null +++ b/libopenjpeg/function_list.h @@ -0,0 +1,131 @@ +/* + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes + * 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 __FUNCTION_LIST_H +#define __FUNCTION_LIST_H + +/** + * @file function_list.h + * @brief Implementation of a list of procedures. + + * The functions in validation.c aims to have access to a list of procedures. +*/ + +/** @defgroup validation validation procedure*/ +/*@{*/ + +#include "openjpeg.h" +/************************************************************************************************** + ***************************************** FORWARD DECLARATION ************************************ + **************************************************************************************************/ +struct opj_jp2; + +/** + * ARGGGG, when will the template be added to the C language ??? + * in order not to have to duplicate the code in a vast number of times, use void * and downcast + * it after => UGLY but faster and easier + * TODO : make the class template in C++, use STL vector or duplicate code for each procedure type. + */ +typedef void * opj_procedure; + +/** + * A list of procedures. +*/ +typedef struct opj_procedure_list +{ + /** + * The number of validation procedures. + */ + OPJ_UINT32 m_nb_procedures; + /** + * The number of the array of validation procedures. + */ + OPJ_UINT32 m_nb_max_procedures; + /** + * The array of procedures. + */ + opj_procedure * m_procedures; + +} opj_procedure_list_t; + +/* ----------------------------------------------------------------------- */ + +/** + * Creates a validation list. + * + * @return the newly created validation list. + */ +opj_procedure_list_t * opj_procedure_list_create(); + +/** + * Destroys a validation list. + * + * @param p_list the list to destroy. + */ +void opj_procedure_list_destroy(opj_procedure_list_t * p_list); + +/** + * Adds a new validation procedure. + * + * @param p_validation_list the list of procedure to modify. + * @param p_procedure the procedure to add. + * + * @return true if the procedure could ne added. + */ +bool opj_procedure_list_add_procedure (opj_procedure_list_t * p_validation_list, opj_procedure p_procedure); + +/** + * Gets the number of validation procedures. + * + * @param p_validation_list the list of procedure to modify. + * + * @return the number of validation procedures. + */ +OPJ_UINT32 opj_procedure_list_get_nb_procedures (opj_procedure_list_t * p_validation_list); + +/** + * Gets the pointer on the first validation procedure. This function is similar to the C++ + * iterator class to iterate through all the procedures inside the validation list. + * the caller does not take ownership of the pointer. + * + * @param p_validation_list the list of procedure to get the first procedure from. + * + * @return a pointer to the first procedure. + */ +opj_procedure* opj_procedure_list_get_first_procedure (opj_procedure_list_t * p_validation_list); + + +/** + * Clears the list of validation procedures. + * + * @param p_validation_list the list of procedure to clear. + * + */ +void opj_procedure_list_clear (opj_procedure_list_t * p_validation_list); + + +#endif /* __FUNCTION_LIST_H */ + diff --git a/libopenjpeg/image.c b/libopenjpeg/image.c index 30b7d139..c6faffd9 100644 --- a/libopenjpeg/image.c +++ b/libopenjpeg/image.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -23,29 +24,38 @@ * 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 "image.h" +#include "openjpeg.h" +#include "opj_malloc.h" +#include "j2k.h" +#include "int.h" opj_image_t* opj_image_create0(void) { - opj_image_t *image = (opj_image_t*)opj_calloc(1, sizeof(opj_image_t)); + opj_image_t *image = (opj_image_t*)opj_malloc(sizeof(opj_image_t)); + memset(image,0,sizeof(opj_image_t)); return image; } -opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) { - int compno; - opj_image_t *image = NULL; +opj_image_t* OPJ_CALLCONV opj_image_create(OPJ_UINT32 numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) { + OPJ_UINT32 compno; + opj_image_t *image = 00; - image = (opj_image_t*) opj_calloc(1, sizeof(opj_image_t)); - if(image) { + image = (opj_image_t*) opj_malloc(sizeof(opj_image_t)); + if + (image) + { + memset(image,0,sizeof(opj_image_t)); 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)); - if(!image->comps) { - fprintf(stderr,"Unable to allocate memory for image.\n"); + if + (!image->comps) + { opj_image_destroy(image); - return NULL; + return 00; } + memset(image->comps,0,image->numcomps * sizeof(opj_image_comp_t)); /* create the individual image components */ for(compno = 0; compno < numcmpts; compno++) { opj_image_comp_t *comp = &image->comps[compno]; @@ -56,24 +66,64 @@ opj_image_t* OPJ_CALLCONV opj_image_create(int numcmpts, opj_image_cmptparm_t *c comp->x0 = cmptparms[compno].x0; comp->y0 = cmptparms[compno].y0; comp->prec = cmptparms[compno].prec; - comp->bpp = cmptparms[compno].bpp; comp->sgnd = cmptparms[compno].sgnd; - comp->data = (int*) opj_calloc(comp->w * comp->h, sizeof(int)); - if(!comp->data) { - fprintf(stderr,"Unable to allocate memory for image.\n"); + comp->data = (OPJ_INT32*) opj_calloc(comp->w * comp->h, sizeof(OPJ_INT32)); + if + (!comp->data) + { opj_image_destroy(image); - return NULL; + return 00; } } } + return image; +} +opj_image_t* OPJ_CALLCONV opj_image_tile_create(OPJ_UINT32 numcmpts, opj_image_cmptparm_t *cmptparms, OPJ_COLOR_SPACE clrspc) { + OPJ_UINT32 compno; + opj_image_t *image = 00; + + image = (opj_image_t*) opj_malloc(sizeof(opj_image_t)); + if + (image) + { + memset(image,0,sizeof(opj_image_t)); + 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)); + if + (!image->comps) + { + opj_image_destroy(image); + return 00; + } + memset(image->comps,0,image->numcomps * sizeof(opj_image_comp_t)); + /* create the individual image components */ + for(compno = 0; compno < numcmpts; compno++) { + opj_image_comp_t *comp = &image->comps[compno]; + comp->dx = cmptparms[compno].dx; + comp->dy = cmptparms[compno].dy; + comp->w = cmptparms[compno].w; + comp->h = cmptparms[compno].h; + comp->x0 = cmptparms[compno].x0; + comp->y0 = cmptparms[compno].y0; + comp->prec = cmptparms[compno].prec; + comp->sgnd = cmptparms[compno].sgnd; + comp->data = 0; + } + } return image; } void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) { - int i; - if(image) { - if(image->comps) { + OPJ_UINT32 i; + if + (image) + { + if + (image->comps) + { /* image components */ for(i = 0; i < image->numcomps; i++) { opj_image_comp_t *image_comp = &image->comps[i]; @@ -87,3 +137,39 @@ void OPJ_CALLCONV opj_image_destroy(opj_image_t *image) { } } +/** + * Updates the components of the image from the coding parameters. + * + * @param p_image the image to update. + * @param p_cp the coding parameters from which to update the image. + */ +void opj_image_comp_update(opj_image_t * p_image,const opj_cp_t * p_cp) +{ + OPJ_UINT32 i, l_width, l_height; + OPJ_INT32 l_x0,l_y0,l_x1,l_y1; + OPJ_INT32 l_comp_x0,l_comp_y0,l_comp_x1,l_comp_y1; + opj_image_comp_t * l_img_comp = 00; + + l_x0 = int_max(p_cp->tx0 , p_image->x0); + l_y0 = int_max(p_cp->ty0 , p_image->y0); + l_x1 = int_min(p_cp->tx0 + p_cp->tw * p_cp->tdx, p_image->x1); + l_y1 = int_min(p_cp->ty0 + p_cp->th * p_cp->tdy, p_image->y1); + + l_img_comp = p_image->comps; + for + (i = 0; i < p_image->numcomps; ++i) + { + l_comp_x0 = int_ceildiv(l_x0, l_img_comp->dx); + l_comp_y0 = int_ceildiv(l_y0, l_img_comp->dy); + l_comp_x1 = int_ceildiv(l_x1, l_img_comp->dx); + l_comp_y1 = int_ceildiv(l_y1, l_img_comp->dy); + l_width = int_ceildivpow2(l_comp_x1 - l_comp_x0, l_img_comp->factor); + l_height = int_ceildivpow2(l_comp_y1 - l_comp_y0, l_img_comp->factor); + l_img_comp->w = l_width; + l_img_comp->h = l_height; + l_img_comp->x0 = l_x0; + l_img_comp->y0 = l_y0; + ++l_img_comp; + } +} + diff --git a/libopenjpeg/image.h b/libopenjpeg/image.h index 04c362eb..91582543 100644 --- a/libopenjpeg/image.h +++ b/libopenjpeg/image.h @@ -1,5 +1,6 @@ /* * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -31,7 +32,8 @@ The functions in IMAGE.C have for goal to realize operations on images. */ - +struct opj_image; +struct opj_cp; /** @defgroup IMAGE IMAGE - Implementation of operations on images */ /*@{*/ @@ -40,7 +42,15 @@ Create an empty image @todo this function should be removed @return returns an empty image if successful, returns NULL otherwise */ -opj_image_t* opj_image_create0(void); +struct opj_image* opj_image_create0(void); + +/** + * Updates the components of the image from the coding parameters. + * + * @param p_image the image to update. + * @param p_cp the coding parameters from which to update the image. + */ +void opj_image_comp_update(struct opj_image * p_image,const struct opj_cp * p_cp); /*@}*/ diff --git a/libopenjpeg/int.h b/libopenjpeg/int.h index 4e5fe08e..0bc58fa9 100644 --- a/libopenjpeg/int.h +++ b/libopenjpeg/int.h @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -36,7 +37,8 @@ The functions in INT.H have for goal to realize operations on integers. */ - +#include "openjpeg.h" +#include "opj_includes.h" /** @defgroup INT INT - Implementation of operations on integers */ /*@{*/ @@ -47,14 +49,31 @@ The functions in INT.H have for goal to realize operations on integers. Get the minimum of two integers @return Returns a if a < b else b */ -static INLINE int int_min(int a, int b) { +static INLINE OPJ_INT32 int_min(OPJ_INT32 a, OPJ_INT32 b) { return a < b ? a : b; } + +/** +Get the minimum of two integers +@return Returns a if a < b else b +*/ +static INLINE OPJ_UINT32 uint_min(OPJ_UINT32 a, OPJ_UINT32 b) { + return a < b ? a : b; +} + /** Get the maximum of two integers @return Returns a if a > b else b */ -static INLINE int int_max(int a, int b) { +static INLINE OPJ_INT32 int_max(OPJ_INT32 a, OPJ_INT32 b) { + return (a > b) ? a : b; +} + +/** +Get the maximum of two integers +@return Returns a if a > b else b +*/ +static INLINE OPJ_UINT32 uint_max(OPJ_UINT32 a, OPJ_UINT32 b) { return (a > b) ? a : b; } /** @@ -66,7 +85,7 @@ Clamp an integer inside an interval
  • Returns min if (a < min) */ -static INLINE int int_clamp(int a, int min, int max) { +static INLINE OPJ_INT32 int_clamp(OPJ_INT32 a, OPJ_INT32 min, OPJ_INT32 max) { if (a < min) return min; if (a > max) @@ -76,41 +95,62 @@ static INLINE int int_clamp(int a, int min, int max) { /** @return Get absolute value of integer */ -static INLINE int int_abs(int a) { +static INLINE OPJ_INT32 int_abs(OPJ_INT32 a) { return a < 0 ? -a : a; } /** Divide an integer and round upwards @return Returns a divided by b */ -static INLINE int int_ceildiv(int a, int b) { +static INLINE OPJ_INT32 int_ceildiv(OPJ_INT32 a, OPJ_INT32 b) { + return (a + b - 1) / b; +} + +/** +Divide an integer and round upwards +@return Returns a divided by b +*/ +static INLINE OPJ_UINT32 uint_ceildiv(OPJ_UINT32 a, OPJ_UINT32 b) { return (a + b - 1) / b; } /** Divide an integer by a power of 2 and round upwards @return Returns a divided by 2^b */ -static INLINE int int_ceildivpow2(int a, int b) { +static INLINE OPJ_INT32 int_ceildivpow2(OPJ_INT32 a, OPJ_INT32 b) { return (a + (1 << b) - 1) >> b; } /** Divide an integer by a power of 2 and round downwards @return Returns a divided by 2^b */ -static INLINE int int_floordivpow2(int a, int b) { +static INLINE OPJ_INT32 int_floordivpow2(OPJ_INT32 a, OPJ_INT32 b) { return a >> b; } /** Get logarithm of an integer and round downwards @return Returns log2(a) */ -static INLINE int int_floorlog2(int a) { - int l; +static INLINE OPJ_INT32 int_floorlog2(OPJ_INT32 a) { + OPJ_INT32 l; for (l = 0; a > 1; l++) { a >>= 1; } return l; } + +/** +Get logarithm of an integer and round downwards +@return Returns log2(a) +*/ +static INLINE OPJ_UINT32 uint_floorlog2(OPJ_UINT32 a) { + OPJ_UINT32 l; + for (l = 0; a > 1; ++l) + { + a >>= 1; + } + return l; +} /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/invert.c b/libopenjpeg/invert.c new file mode 100644 index 00000000..1fce6d7a --- /dev/null +++ b/libopenjpeg/invert.c @@ -0,0 +1,291 @@ +/* + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes + * 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 "invert.h" +#include "opj_malloc.h" + + +bool opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations, OPJ_FLOAT32 * p_swap_area,OPJ_UINT32 n); +void opj_lupSolve(OPJ_FLOAT32 * pResult, OPJ_FLOAT32* pMatrix, OPJ_FLOAT32* pVector, OPJ_UINT32* pPermutations, OPJ_UINT32 n,OPJ_FLOAT32 * p_intermediate_data); +void opj_lupInvert (OPJ_FLOAT32 * pSrcMatrix, + OPJ_FLOAT32 * pDestMatrix, + OPJ_UINT32 n, + OPJ_UINT32 * pPermutations, + OPJ_FLOAT32 * p_src_temp, + OPJ_FLOAT32 * p_dest_temp, + OPJ_FLOAT32 * p_swap_area); + +/** + * Matrix inversion. + */ +bool opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,OPJ_FLOAT32 * pDestMatrix, OPJ_UINT32 n) +{ + OPJ_BYTE * l_data = 00; + OPJ_UINT32 l_permutation_size = n * sizeof(OPJ_UINT32); + OPJ_UINT32 l_swap_size = n * 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; + + l_data = (OPJ_BYTE *) opj_malloc(l_total_size); + if + (l_data == 0) + { + return false; + } + lPermutations = (OPJ_UINT32 *) l_data; + l_double_data = (OPJ_FLOAT32 *) (l_data + l_permutation_size); + memset(lPermutations,0,l_permutation_size); + + if + (! opj_lupDecompose(pSrcMatrix,lPermutations,l_double_data,n)) + { + opj_free(l_data); + return false; + } + opj_lupInvert(pSrcMatrix,pDestMatrix,n,lPermutations,l_double_data,l_double_data + n,l_double_data + 2*n); + opj_free(l_data); + return true; +} + + +/** + * LUP decomposition + */ +bool opj_lupDecompose(OPJ_FLOAT32 * matrix,OPJ_UINT32 * permutations, OPJ_FLOAT32 * p_swap_area,OPJ_UINT32 n) +{ + OPJ_UINT32 * tmpPermutations = permutations; + OPJ_UINT32 * dstPermutations; + OPJ_UINT32 k2=0,t; + OPJ_FLOAT32 temp; + OPJ_UINT32 i,j,k; + OPJ_FLOAT32 p; + OPJ_UINT32 lLastColum = n - 1; + OPJ_UINT32 lSwapSize = n * sizeof(OPJ_FLOAT32); + OPJ_FLOAT32 * lTmpMatrix = matrix; + OPJ_FLOAT32 * lColumnMatrix,* lDestMatrix; + OPJ_UINT32 offset = 1; + OPJ_UINT32 lStride = n-1; + + //initialize permutations + for + (i = 0; i < n; ++i) + { + *tmpPermutations++ = i; + } + + + + // now make a pivot with colum switch + tmpPermutations = permutations; + for + (k = 0; k < lLastColum; ++k) + { + p = 0.0; + + // take the middle element + lColumnMatrix = lTmpMatrix + k; + + // make permutation with the biggest value in the column + for + (i = k; i < n; ++i) + { + temp = ((*lColumnMatrix > 0) ? *lColumnMatrix : -(*lColumnMatrix)); + if + (temp > p) + { + p = temp; + k2 = i; + } + // next line + lColumnMatrix += n; + } + + // a whole rest of 0 -> non singular + if + (p == 0.0) + { + return false; + } + + // should we permute ? + if + (k2 != k) + { + //exchange of line + // k2 > k + dstPermutations = tmpPermutations + k2 - k; + // swap indices + t = *tmpPermutations; + *tmpPermutations = *dstPermutations; + *dstPermutations = t; + + // and swap entire line. + lColumnMatrix = lTmpMatrix + (k2 - k) * n; + memcpy(p_swap_area,lColumnMatrix,lSwapSize); + memcpy(lColumnMatrix,lTmpMatrix,lSwapSize); + memcpy(lTmpMatrix,p_swap_area,lSwapSize); + } + + // now update data in the rest of the line and line after + lDestMatrix = lTmpMatrix + k; + lColumnMatrix = lDestMatrix + n; + // take the middle element + temp = *(lDestMatrix++); + + // now compute up data (i.e. coeff up of the diagonal). + for (i = offset; i < n; ++i) + { + //lColumnMatrix; + // divide the lower column elements by the diagonal value + + // matrix[i][k] /= matrix[k][k]; + // p = matrix[i][k] + p = *lColumnMatrix / temp; + *(lColumnMatrix++) = p; + for + (j = /* k + 1 */ offset; j < n; ++j) + { + // matrix[i][j] -= matrix[i][k] * matrix[k][j]; + *(lColumnMatrix++) -= p * (*(lDestMatrix++)); + } + // come back to the k+1th element + lDestMatrix -= lStride; + // go to kth element of the next line + lColumnMatrix += k; + } + // offset is now k+2 + ++offset; + // 1 element less for stride + --lStride; + // next line + lTmpMatrix+=n; + // next permutation element + ++tmpPermutations; + } + return true; +} + + + +/** + * LUP solving + */ +void opj_lupSolve (OPJ_FLOAT32 * pResult, OPJ_FLOAT32 * pMatrix, OPJ_FLOAT32 * pVector, OPJ_UINT32* pPermutations, OPJ_UINT32 n,OPJ_FLOAT32 * p_intermediate_data) +{ + OPJ_UINT32 i,j; + OPJ_FLOAT32 sum; + OPJ_FLOAT32 u; + OPJ_UINT32 lStride = n+1; + OPJ_FLOAT32 * lCurrentPtr; + OPJ_FLOAT32 * lIntermediatePtr; + OPJ_FLOAT32 * lDestPtr; + OPJ_FLOAT32 * lTmpMatrix; + OPJ_FLOAT32 * lLineMatrix = pMatrix; + OPJ_FLOAT32 * lBeginPtr = pResult + n - 1; + OPJ_FLOAT32 * lGeneratedData; + OPJ_UINT32 * lCurrentPermutationPtr = pPermutations; + + + lIntermediatePtr = p_intermediate_data; + lGeneratedData = p_intermediate_data + n - 1; + + for + (i = 0; i < n; ++i) + { + sum = 0.0; + lCurrentPtr = p_intermediate_data; + lTmpMatrix = lLineMatrix; + for + (j = 1; j <= i; ++j) + { + // sum += matrix[i][j-1] * y[j-1]; + sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++)); + } + //y[i] = pVector[pPermutations[i]] - sum; + *(lIntermediatePtr++) = pVector[*(lCurrentPermutationPtr++)] - sum; + lLineMatrix += n; + } + + // we take the last point of the matrix + lLineMatrix = pMatrix + n*n - 1; + + // and we take after the last point of the destination vector + lDestPtr = pResult + n; + + for + (i = n - 1; i != -1 ; --i) + { + sum = 0.0; + lTmpMatrix = lLineMatrix; + u = *(lTmpMatrix++); + lCurrentPtr = lDestPtr--; + for + (j = i + 1; j < n; ++j) + { + // sum += matrix[i][j] * x[j] + sum += (*(lTmpMatrix++)) * (*(lCurrentPtr++)); + } + //x[i] = (y[i] - sum) / u; + *(lBeginPtr--) = (*(lGeneratedData--) - sum) / u; + lLineMatrix -= lStride; + } +} + +/** LUP inversion (call with the result of lupDecompose) + */ +void opj_lupInvert ( + OPJ_FLOAT32 * pSrcMatrix, + OPJ_FLOAT32 * pDestMatrix, + OPJ_UINT32 n, + OPJ_UINT32 * pPermutations, + OPJ_FLOAT32 * p_src_temp, + OPJ_FLOAT32 * p_dest_temp, + OPJ_FLOAT32 * p_swap_area + ) +{ + OPJ_UINT32 j,i; + OPJ_FLOAT32 * lCurrentPtr; + OPJ_FLOAT32 * lLineMatrix = pDestMatrix; + OPJ_UINT32 lSwapSize = n * sizeof(OPJ_FLOAT32); + + for + (j = 0; j < n; ++j) + { + lCurrentPtr = lLineMatrix++; + memset(p_src_temp,0,lSwapSize); + p_src_temp[j] = 1.0; + opj_lupSolve(p_dest_temp,pSrcMatrix,p_src_temp, pPermutations, n , p_swap_area); + + for + (i = 0; i < n; ++i) + { + *(lCurrentPtr) = p_dest_temp[i]; + lCurrentPtr+=n; + } + } +} + diff --git a/indexer_JPIP/fix.c b/libopenjpeg/invert.h similarity index 67% rename from indexer_JPIP/fix.c rename to libopenjpeg/invert.h index 9699bf6b..8a39d363 100644 --- a/indexer_JPIP/fix.c +++ b/libopenjpeg/invert.h @@ -1,7 +1,5 @@ /* - * Copyright (c) 2001-2002, David Janssens - * Copyright (c) 2003, Yannick Verschueren - * Copyright (c) 2003, Communications and remote sensing Laboratory, Universite catholique de Louvain, Belgium + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -26,17 +24,17 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "fix.h" - -#ifdef WIN32 -#define int64 __int64 -#else -#define int64 long long +#ifndef __INVERT_H +#define __INVERT_H +#include "openjpeg.h" +/** + * Calculates a n x n double matrix inversion with a LUP method. Data is aligned, rows after rows (or columns after columns). + * The function does not take ownership of any memory block, data must be fred by the user. + * + * @param pSrcMatrix the matrix to invert. + * @param pDestMatrix data to store the inverted matrix. + * @return 1 if the inversion is successful, 0 if the matrix is singular. + */ +bool opj_matrix_inversion_f(OPJ_FLOAT32 * pSrcMatrix,OPJ_FLOAT32 * pDestMatrix, OPJ_UINT32 n); #endif -/// -/// Multiply two fixed-precision rational numbers. -/// -int fix_mul(int a, int b) { - return (int)((int64)a*(int64)b>>13); -} diff --git a/libopenjpeg/j2k.c b/libopenjpeg/j2k.c index 563efd68..451d57e0 100644 --- a/libopenjpeg/j2k.c +++ b/libopenjpeg/j2k.c @@ -6,6 +6,7 @@ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2006-2007, Parvatha Elangovan + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -30,216 +31,1224 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include "j2k.h" +#include "opj_malloc.h" #include "opj_includes.h" +#include "pi.h" +#include "event.h" +#include "cio.h" +#include "int.h" +#include "tcd.h" +#include "function_list.h" +#include "invert.h" +#include "dwt.h" +#include "mct.h" +#include "image.h" /** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ /*@{*/ + +/*************************************************************************** + ********************** TYPEDEFS ******************************************* + ***************************************************************************/ +/** + * Correspondance prog order <-> string representation + */ +typedef struct j2k_prog_order +{ + OPJ_PROG_ORDER enum_prog; + OPJ_CHAR str_prog[4]; +} +j2k_prog_order_t; + +typedef struct opj_dec_memory_marker_handler +{ + /** marker value */ + OPJ_UINT32 id; + /** value of the state when the marker can appear */ + OPJ_UINT32 states; + /** action linked to the marker */ + bool (*handler) ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); +} +opj_dec_memory_marker_handler_t; + + + /** @name Local static functions */ /*@{*/ +/** + * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile. + * + * @param p_comp_no the component number to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. + * +*/ +static bool j2k_write_SPCod_SPCoc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_header_size, + struct opj_event_mgr * p_manager + ); /** -Write the SOC marker (Start Of Codestream) -@param j2k J2K handle + * Reads a SPCod or SPCoc element, i.e. the coding style of a given component of a tile. + * @param p_header_data the data contained in the COM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the COM marker. + * @param p_manager the user event manager. */ -static void j2k_write_soc(opj_j2k_t *j2k); +static bool j2k_read_SPCod_SPCoc( + opj_j2k_t *p_j2k, + OPJ_UINT32 compno, + OPJ_BYTE * p_header_data, + OPJ_UINT32 * p_header_size, + struct opj_event_mgr * p_manager + ); + /** -Read the SOC marker (Start of Codestream) -@param j2k J2K handle -*/ -static void j2k_read_soc(opj_j2k_t *j2k); + * Gets the size taken by writting a SPCod or SPCoc for the given tile and component. + * + * @param p_tile_no the tile indix. + * @param p_comp_no the component being outputted. + * @param p_j2k the J2K codec. + * + * @return the number of bytes taken by the SPCod element. + */ +static OPJ_UINT32 j2k_get_SPCod_SPCoc_size ( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no + ); + /** -Write the SIZ marker (image and tile size) -@param j2k J2K handle + * Writes a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. + * + * @param p_tile_no the tile to output. + * @param p_comp_no the component number to output. + * @param p_data the data buffer. + * @param p_header_size pointer to the size of the data buffer, it is changed by the function. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. + * */ -static void j2k_write_siz(opj_j2k_t *j2k); +static bool j2k_write_SQcd_SQcc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_header_size, + struct opj_event_mgr * p_manager + ); + /** -Read the SIZ marker (image and tile size) -@param j2k J2K handle + * Reads a SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. + * + * @param p_tile_no the tile to output. + * @param p_comp_no the component number to output. + * @param p_data the data buffer. + * @param p_header_size pointer to the size of the data buffer, it is changed by the function. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. + * */ -static void j2k_read_siz(opj_j2k_t *j2k); +static bool j2k_read_SQcd_SQcc( + opj_j2k_t *p_j2k, + OPJ_UINT32 compno, + OPJ_BYTE * p_header_data, + OPJ_UINT32 * p_header_size, + struct opj_event_mgr * p_manager + ); /** -Write the COM marker (comment) -@param j2k J2K handle -*/ -static void j2k_write_com(opj_j2k_t *j2k); + * Updates the Tile Length Marker. + */ +static void j2k_update_tlm ( + opj_j2k_t * p_j2k, + OPJ_UINT32 p_tile_part_size); + /** -Read the COM marker (comment) -@param j2k J2K handle -*/ -static void j2k_read_com(opj_j2k_t *j2k); + * Gets the size taken by writting SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. + * + * @param p_tile_no the tile indix. + * @param p_comp_no the component being outputted. + * @param p_j2k the J2K codec. + * + * @return the number of bytes taken by the SPCod element. + */ +static OPJ_UINT32 j2k_get_SQcd_SQcc_size ( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no + + ); + /** -Write the value concerning the specified component in the marker COD and COC -@param j2k J2K handle -@param compno Number of the component concerned by the information written -*/ -static void j2k_write_cox(opj_j2k_t *j2k, int compno); + * Copies the tile component parameters of all the component from the first tile component. + * + * @param p_j2k the J2k codec. + */ +static void j2k_copy_tile_component_parameters( + opj_j2k_t *p_j2k + ); + /** -Read the value concerning the specified component in the marker COD and COC -@param j2k J2K handle -@param compno Number of the component concerned by the information read + * Writes the SOC marker (Start Of Codestream) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_read_cox(opj_j2k_t *j2k, int compno); + +static bool j2k_write_soc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); /** -Write the COD marker (coding style default) -@param j2k J2K handle + * Reads a SOC marker (Start of Codestream) + * @param p_header_data the data contained in the SOC box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the SOC marker. + * @param p_manager the user event manager. */ -static void j2k_write_cod(opj_j2k_t *j2k); +static bool j2k_read_soc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); /** -Read the COD marker (coding style default) -@param j2k J2K handle + * Writes the SIZ marker (image and tile size) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_read_cod(opj_j2k_t *j2k); +static bool j2k_write_siz( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); /** -Write the COC marker (coding style component) -@param j2k J2K handle -@param compno Number of the component concerned by the information written + * Writes the CBD-MCT-MCC-MCO markers (Multi components transform) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_write_coc(opj_j2k_t *j2k, int compno); +static bool j2k_write_mct_data_group( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + /** -Read the COC marker (coding style component) -@param j2k J2K handle + * Reads a SIZ marker (image and tile size) + * @param p_header_data the data contained in the SIZ box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the SIZ marker. + * @param p_manager the user event manager. */ -static void j2k_read_coc(opj_j2k_t *j2k); +static bool j2k_read_siz ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); /** -Write the value concerning the specified component in the marker QCD and QCC -@param j2k J2K handle -@param compno Number of the component concerned by the information written + * Writes the COM marker (comment) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_write_qcx(opj_j2k_t *j2k, int compno); +static bool j2k_write_com( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); /** -Read the value concerning the specified component in the marker QCD and QCC -@param j2k J2K 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 + * Reads a COM marker (comments) + * @param p_header_data the data contained in the COM box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the COM marker. + * @param p_manager the user event manager. */ -static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len); +static bool j2k_read_com ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); + + + /** -Write the QCD marker (quantization default) -@param j2k J2K handle + * Writes the COD marker (Coding style default) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_write_qcd(opj_j2k_t *j2k); +static bool j2k_write_cod( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); /** -Read the QCD marker (quantization default) -@param j2k J2K handle + * Reads a COD marker (Coding Styke defaults) + * @param p_header_data the data contained in the COD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the COD marker. + * @param p_manager the user event manager. */ -static void j2k_read_qcd(opj_j2k_t *j2k); +static bool j2k_read_cod ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); + /** -Write the QCC marker (quantization component) -@param j2k J2K handle -@param compno Number of the component concerned by the information written + * Writes the COC marker (Coding style component) + * + * @param p_comp_number the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_write_qcc(opj_j2k_t *j2k, int compno); +static bool j2k_write_coc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_number, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + /** -Read the QCC marker (quantization component) -@param j2k J2K handle + * Writes the COC marker (Coding style component) + * + * @param p_comp_no the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_read_qcc(opj_j2k_t *j2k); +static void j2k_write_coc_in_memory( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_no, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + struct opj_event_mgr * p_manager + ); /** -Write the POC marker (progression order change) -@param j2k J2K handle -*/ -static void j2k_write_poc(opj_j2k_t *j2k); + * Gets the maximum size taken by a coc. + * + * @param p_j2k the jpeg2000 codec to use. + */ +static OPJ_UINT32 j2k_get_max_coc_size(opj_j2k_t *p_j2k); + /** -Read the POC marker (progression order change) -@param j2k J2K handle + * Reads a COC marker (Coding Style Component) + * @param p_header_data the data contained in the COC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the COC marker. + * @param p_manager the user event manager. */ -static void j2k_read_poc(opj_j2k_t *j2k); +static bool j2k_read_coc ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); + /** -Read the CRG marker (component registration) -@param j2k J2K handle + * Writes the QCD marker (quantization default) + * + * @param p_comp_number the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_read_crg(opj_j2k_t *j2k); +static bool j2k_write_qcd( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + + /** -Read the TLM marker (tile-part lengths) -@param j2k J2K handle + * Reads a QCD marker (Quantization defaults) + * @param p_header_data the data contained in the QCD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the QCD marker. + * @param p_manager the user event manager. */ -static void j2k_read_tlm(opj_j2k_t *j2k); +static bool j2k_read_qcd ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); /** -Read the PLM marker (packet length, main header) -@param j2k J2K handle + * Writes the QCC marker (quantization component) + * + * @param p_comp_no the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_read_plm(opj_j2k_t *j2k); +static bool j2k_write_qcc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_no, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); /** -Read the PLT marker (packet length, tile-part header) -@param j2k J2K handle + * Writes the QCC marker (quantization component) + * + * @param p_comp_no the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_read_plt(opj_j2k_t *j2k); +static void j2k_write_qcc_in_memory( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_no, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + struct opj_event_mgr * p_manager + ); /** -Read the PPM marker (packet packet headers, main header) -@param j2k J2K handle -*/ -static void j2k_read_ppm(opj_j2k_t *j2k); + * Gets the maximum size taken by a qcc. + */ +static OPJ_UINT32 j2k_get_max_qcc_size (opj_j2k_t *p_j2k); + /** -Read the PPT marker (packet packet headers, tile-part header) -@param j2k J2K handle + * Reads a QCC marker (Quantization component) + * @param p_header_data the data contained in the QCC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the QCC marker. + * @param p_manager the user event manager. */ -static void j2k_read_ppt(opj_j2k_t *j2k); +static bool j2k_read_qcc( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager); /** -Write the TLM marker (Mainheader) -@param j2k J2K handle + * Writes the POC marker (Progression Order Change) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_write_tlm(opj_j2k_t *j2k); +static bool j2k_write_poc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + /** -Write the SOT marker (start of tile-part) -@param j2k J2K handle + * Writes the updated tlm. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. */ -static void j2k_write_sot(opj_j2k_t *j2k); +static bool j2k_write_updated_tlm( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + /** -Read the SOT marker (start of tile-part) -@param j2k J2K handle -*/ -static void j2k_read_sot(opj_j2k_t *j2k); + * Writes the POC marker (Progression Order Change) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. + */ +static void j2k_write_poc_in_memory( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + struct opj_event_mgr * p_manager + ); + /** -Write the SOD marker (start of data) -@param j2k J2K handle -@param tile_coder Pointer to a TCD handle -*/ -static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder); + * Gets the maximum size taken by the writting of a POC. + */ +static OPJ_UINT32 j2k_get_max_poc_size(opj_j2k_t *p_j2k); + /** -Read the SOD marker (start of data) -@param j2k J2K handle -*/ -static void j2k_read_sod(opj_j2k_t *j2k); + * Gets the maximum size taken by the toc headers of all the tile parts of any given tile. + */ +static OPJ_UINT32 j2k_get_max_toc_size (opj_j2k_t *p_j2k); + /** -Write the RGN marker (region-of-interest) -@param j2k J2K 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 j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno); + * Gets the maximum size taken by the headers of the SOT. + * + * @param p_j2k the jpeg2000 codec to use. + */ +static OPJ_UINT32 j2k_get_specific_header_sizes(opj_j2k_t *p_j2k); + /** -Read the RGN marker (region-of-interest) -@param j2k J2K handle + * Reads a POC marker (Progression Order Change) + * + * @param p_header_data the data contained in the POC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the POC marker. + * @param p_manager the user event manager. */ -static void j2k_read_rgn(opj_j2k_t *j2k); +static bool j2k_read_poc ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); /** -Write the EOC marker (end of codestream) -@param j2k J2K handle + * Reads a CRG marker (Component registration) + * + * @param p_header_data the data contained in the TLM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the TLM marker. + * @param p_manager the user event manager. */ -static void j2k_write_eoc(opj_j2k_t *j2k); +static bool j2k_read_crg ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); /** -Read the EOC marker (end of codestream) -@param j2k J2K handle + * Reads a TLM marker (Tile Length Marker) + * + * @param p_header_data the data contained in the TLM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the TLM marker. + * @param p_manager the user event manager. */ -static void j2k_read_eoc(opj_j2k_t *j2k); +static bool j2k_read_tlm ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); /** -Read an unknown marker -@param j2k J2K handle + * Reads a PLM marker (Packet length, main header marker) + * + * @param p_header_data the data contained in the TLM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the TLM marker. + * @param p_manager the user event manager. */ -static void j2k_read_unk(opj_j2k_t *j2k); +static bool j2k_read_plm ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); +/** + * Reads a PLT marker (Packet length, tile-part header) + * + * @param p_header_data the data contained in the PLT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the PLT marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_plt ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); +/** + * Reads a PPM marker (Packed packet headers, main header) + * + * @param p_header_data the data contained in the POC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the POC marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_ppm ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); +/** + * Reads a PPT marker (Packed packet headers, tile-part header) + * + * @param p_header_data the data contained in the PPT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the PPT marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_ppt ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); +/** + * Writes the TLM marker (Tile Length Marker) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_tlm( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Writes the SOT marker (Start of tile-part) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_sot( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + const struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Reads a PPT marker (Packed packet headers, tile-part header) + * + * @param p_header_data the data contained in the PPT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the PPT marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_sot ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); +/** + * Writes the SOD marker (Start of data) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_sod( + opj_j2k_t *p_j2k, + struct opj_tcd * p_tile_coder, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + OPJ_UINT32 p_total_data_size, + const struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Reads a SOD marker (Start Of Data) + * + * @param p_header_data the data contained in the SOD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the SOD marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_sod ( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Writes the RGN marker (Region Of Interest) + * + * @param p_tile_no the tile to output + * @param p_comp_no the component to output + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_rgn( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Reads a RGN marker (Region Of Interest) + * + * @param p_header_data the data contained in the POC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the POC marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_rgn ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) ; +/** + * Writes the EOC marker (End of Codestream) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_eoc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Copies the tile component parameters of all the component from the first tile component. + * + * @param p_j2k the J2k codec. + */ +static void j2k_copy_tile_quantization_parameters( + opj_j2k_t *p_j2k + ); + +/** + * Reads a EOC marker (End Of Codestream) + * + * @param p_header_data the data contained in the SOD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the SOD marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_eoc ( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) ; + +/** + * Inits the Info + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_init_info( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Reads an unknown marker + * + * @param p_stream the stream object to read from. + * @param p_j2k the jpeg2000 codec. + * @param p_manager the user event manager. + * + * @return true if the marker could be deduced. +*/ +static bool j2k_read_unk ( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Ends the encoding, i.e. frees memory. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_end_encoding( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Writes the CBD marker (Component bit depth definition) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_cbd( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a CBD marker (Component bit depth definition) + * @param p_header_data the data contained in the CBD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the CBD marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_cbd ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager); + +/** + * Writes the MCT marker (Multiple Component Transform) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_mct_record( + opj_j2k_t *p_j2k, + opj_mct_data_t * p_mct_record, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a MCT marker (Multiple Component Transform) + * + * @param p_header_data the data contained in the MCT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the MCT marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_mct ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); + +/** + * Writes the MCC marker (Multiple Component Collection) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_mcc_record( + opj_j2k_t *p_j2k, + struct opj_simple_mcc_decorrelation_data * p_mcc_record, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a MCC marker (Multiple Component Collection) + * + * @param p_header_data the data contained in the MCC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the MCC marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_mcc ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); + +/** + * Writes the MCO marker (Multiple component transformation ordering) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_mco( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a MCO marker (Multiple Component Transform Ordering) + * + * @param p_header_data the data contained in the MCO box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the MCO marker. + * @param p_manager the user event manager. +*/ +static bool j2k_read_mco ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ); +/** + * Writes the image components. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_image_components( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Writes regions of interests. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_regions( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Writes EPC ???? + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_write_epc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Checks the progression order changes values. Tells of the poc given as input are valid. + * A nice message is outputted at errors. + * + * @param p_pocs the progression order changes. + * @param p_nb_pocs the number of progression order changes. + * @param p_nb_resolutions the number of resolutions. + * @param numcomps the number of components + * @param numlayers the number of layers. + * + * @return true if the pocs are valid. + */ +static bool j2k_check_poc_val( + const opj_poc_t *p_pocs, + OPJ_UINT32 p_nb_pocs, + OPJ_UINT32 p_nb_resolutions, + OPJ_UINT32 numcomps, + OPJ_UINT32 numlayers, + opj_event_mgr_t * p_manager); + +/** + * Gets the number of tile parts used for the given change of progression (if any) and the given tile. + * + * @param cp the coding parameters. + * @param pino the offset of the given poc (i.e. its position in the coding parameter). + * @param tileno the given tile. + * + * @return the number of tile parts. + */ +static OPJ_UINT32 j2k_get_num_tp( + opj_cp_t *cp, + OPJ_UINT32 pino, + OPJ_UINT32 tileno); +/** + * Calculates the total number of tile parts needed by the encoder to + * encode such an image. If not enough memory is available, then the function return false. + * + * @param p_nb_tiles pointer that will hold the number of tile parts. + * @param cp the coding parameters for the image. + * @param image the image to encode. + * @param p_j2k the p_j2k encoder. + * @param p_manager the user event manager. + * + * @return true if the function was successful, false else. + */ +static bool j2k_calculate_tp( + opj_j2k_t *p_j2k, + opj_cp_t *cp, + OPJ_UINT32 * p_nb_tiles, + opj_image_t *image, + opj_event_mgr_t * p_manager); + +static bool j2k_write_first_tile_part ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + OPJ_UINT32 p_total_data_size, + opj_stream_private_t *p_stream, + struct opj_event_mgr * p_manager + ); +static bool j2k_write_all_tile_parts( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + OPJ_UINT32 p_total_data_size, + opj_stream_private_t *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Reads the lookup table containing all the marker, status and action, and returns the handler associated + * with the marker value. + * @param p_id Marker value to look up + * + * @return the handler associated with the id. +*/ +static const struct opj_dec_memory_marker_handler * j2k_get_marker_handler (OPJ_UINT32 p_id); + +/** + * Destroys a tile coding parameter structure. + * + * @param p_tcp the tile coding parameter to destroy. + */ +static void j2k_tcp_destroy (opj_tcp_t *p_tcp); + +static void j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data); + +/** + * Destroys a coding parameter structure. + * + * @param p_cp the coding parameter to destroy. + */ +static void j2k_cp_destroy (opj_cp_t *p_cp); + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +static void j2k_setup_encoding_validation (opj_j2k_t *p_j2k); + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +static void j2k_setup_decoding_validation (opj_j2k_t *p_j2k); + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +static void j2k_setup_end_compress (opj_j2k_t *p_j2k); + +/** + * Creates a tile-coder decoder. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_create_tcd( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * Excutes the given procedures on the given codec. + * + * @param p_procedure_list the list of procedures to execute + * @param p_j2k the jpeg2000 codec to execute the procedures on. + * @param p_stream the stream to execute the procedures on. + * @param p_manager the user manager. + * + * @return true if all the procedures were successfully executed. + */ +static bool j2k_exec ( + opj_j2k_t * p_j2k, + opj_procedure_list_t * p_procedure_list, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); +/** + * Updates the rates of the tcp. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_update_rates( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +/** + * The default encoding validation procedure without any extension. + * + * @param p_j2k the jpeg2000 codec to validate. + * @param p_stream the input stream to validate. + * @param p_manager the user event manager. + * + * @return true if the parameters are correct. + */ +bool j2k_encoding_validation ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); +/** + * The read header procedure. + */ +bool j2k_read_header_procedure( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager); + +/** + * The default decoding validation procedure without any extension. + * + * @param p_j2k the jpeg2000 codec to validate. + * @param p_stream the input stream to validate. + * @param p_manager the user event manager. + * + * @return true if the parameters are correct. + */ +bool j2k_decoding_validation ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); +/** + * Reads the tiles. + */ +bool j2k_decode_tiles ( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager); + +/** + * The mct encoding validation procedure. + * + * @param p_j2k the jpeg2000 codec to validate. + * @param p_stream the input stream to validate. + * @param p_manager the user event manager. + * + * @return true if the parameters are correct. + */ +bool j2k_mct_validation ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); +/** + * Builds the tcd decoder to use to decode tile. + */ +bool j2k_build_decoder ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); +/** + * Builds the tcd encoder to use to encode tile. + */ +bool j2k_build_encoder ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); +/** + * Copies the decoding tile parameters onto all the tile parameters. + * Creates also the tile decoder. + */ +bool j2k_copy_default_tcp_and_create_tcd( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); +/** + * Destroys the memory associated with the decoding of headers. + */ +bool j2k_destroy_header_memory ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); + +/** + * Sets up the procedures to do on writting header. Developpers wanting to extend the library can add their own writting procedures. + */ +void j2k_setup_header_writting (opj_j2k_t *p_j2k); + +/** + * Sets up the procedures to do on reading header. Developpers wanting to extend the library can add their own reading procedures. + */ +void j2k_setup_header_reading (opj_j2k_t *p_j2k); + +/** + * Writes a tile. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +static bool j2k_post_write_tile ( + opj_j2k_t * p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); + +static bool j2k_pre_write_tile ( + opj_j2k_t * p_j2k, + OPJ_UINT32 p_tile_index, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ); +static bool j2k_update_image_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data); + +static bool j2k_add_mct(opj_tcp_t * p_tcp,opj_image_t * p_image, OPJ_UINT32 p_index); +/** + * Gets the offset of the header. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +static bool j2k_get_end_header( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + +static void j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_read_int32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_read_float32_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_read_float64_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); + +static void j2k_read_int16_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_read_int32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_read_float32_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_read_float64_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); + +static void j2k_write_float_to_int16 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_write_float_to_int32 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_write_float_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); +static void j2k_write_float_to_float64 (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); + + /*@}*/ /*@}*/ /* ----------------------------------------------------------------------- */ -typedef struct j2k_prog_order{ - OPJ_PROG_ORDER enum_prog; - char str_prog[4]; -}j2k_prog_order_t; -j2k_prog_order_t j2k_prog_order_list[] = { + + +/**************************************************************************** + ********************* CONSTANTS ******************************************** + ****************************************************************************/ + + + + +/** + * List of progression orders. + */ +const j2k_prog_order_t j2k_prog_order_list [] = +{ {CPRL, "CPRL"}, {LRCP, "LRCP"}, {PCRL, "PCRL"}, @@ -248,264 +1257,884 @@ j2k_prog_order_t j2k_prog_order_list[] = { {-1, ""} }; -char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order){ - j2k_prog_order_t *po; - for(po = j2k_prog_order_list; po->enum_prog != -1; po++ ){ - if(po->enum_prog == prg_order){ - break; +const OPJ_UINT32 MCT_ELEMENT_SIZE [] = +{ + 2, + 4, + 4, + 8 +}; + +typedef void (* j2k_mct_function) (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem); + +const j2k_mct_function j2k_mct_read_functions_to_float [] = +{ + j2k_read_int16_to_float, + j2k_read_int32_to_float, + j2k_read_float32_to_float, + j2k_read_float64_to_float +}; + +const j2k_mct_function j2k_mct_read_functions_to_int32 [] = +{ + j2k_read_int16_to_int32, + j2k_read_int32_to_int32, + j2k_read_float32_to_int32, + j2k_read_float64_to_int32 +}; + +const j2k_mct_function j2k_mct_write_functions_from_float [] = +{ + j2k_write_float_to_int16, + j2k_write_float_to_int32, + j2k_write_float_to_float, + j2k_write_float_to_float64 +}; + + + + +/*const opj_dec_stream_marker_handler_t j2k_stream_marker_handler_tab[] = +{ + {J2K_MS_SOC, J2K_DEC_STATE_MHSOC, j2k_read_soc}, + {J2K_MS_SOD, J2K_DEC_STATE_TPH, j2k_read_sod}, + {J2K_MS_EOC, J2K_DEC_STATE_TPHSOT, j2k_read_eoc}, + {J2K_MS_SOP, 0, 0}, +#ifdef USE_JPWL + {J2K_MS_EPC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_epc}, + {J2K_MS_EPB, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_epb}, + {J2K_MS_ESD, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_esd}, + {J2K_MS_RED, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_red}, +#endif +#ifdef USE_JPSEC + {J2K_MS_SEC, J2K_DEC_STATE_MH, j2k_read_sec}, + {J2K_MS_INSEC, 0, j2k_read_insec}, +#endif + + {0, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_unk} +};*/ + +const opj_dec_memory_marker_handler_t j2k_memory_marker_handler_tab [] = +{ + {J2K_MS_SOT, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPHSOT, j2k_read_sot}, + {J2K_MS_COD, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_cod}, + {J2K_MS_COC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_coc}, + {J2K_MS_RGN, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_rgn}, + {J2K_MS_QCD, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_qcd}, + {J2K_MS_QCC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_qcc}, + {J2K_MS_POC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_poc}, + {J2K_MS_SIZ, J2K_DEC_STATE_MHSIZ , j2k_read_siz}, + {J2K_MS_TLM, J2K_DEC_STATE_MH, j2k_read_tlm}, + {J2K_MS_PLM, J2K_DEC_STATE_MH, j2k_read_plm}, + {J2K_MS_PLT, J2K_DEC_STATE_TPH, j2k_read_plt}, + {J2K_MS_PPM, J2K_DEC_STATE_MH, j2k_read_ppm}, + {J2K_MS_PPT, J2K_DEC_STATE_TPH, j2k_read_ppt}, + {J2K_MS_SOP, 0, 0}, + {J2K_MS_CRG, J2K_DEC_STATE_MH, j2k_read_crg}, + {J2K_MS_COM, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_com}, + {J2K_MS_MCT, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_mct}, + {J2K_MS_CBD, J2K_DEC_STATE_MH , j2k_read_cbd}, + {J2K_MS_MCC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_mcc}, + {J2K_MS_MCO, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_mco} +#ifdef USE_JPWL + {J2K_MS_EPC, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_epc}, + {J2K_MS_EPB, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_epb}, + {J2K_MS_ESD, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_esd}, + {J2K_MS_RED, J2K_DEC_STATE_MH | J2K_DEC_STATE_TPH, j2k_read_red}, +#endif /* USE_JPWL */ +#ifdef USE_JPSEC + {J2K_MS_SEC, J2K_DEC_STATE_MH, j2k_read_sec}, + {J2K_MS_INSEC, 0, j2k_read_insec} +#endif /* USE_JPSEC */ +}; + +void j2k_read_int16_to_float (const void * p_src_data, void * p_dest_data, OPJ_UINT32 p_nb_elem) +{ + OPJ_BYTE * l_src_data = (OPJ_BYTE *) p_src_data; + OPJ_FLOAT32 * l_dest_data = (OPJ_FLOAT32 *) p_dest_data; + OPJ_UINT32 i; + OPJ_UINT32 l_temp; + + for + (i=0;ienum_prog != -1; ++po ) + { + if + (po->enum_prog == p_prg_order) + { + return po->str_prog; } } return po->str_prog; } -void j2k_dump_image(FILE *fd, opj_image_t * img) { - int compno; - fprintf(fd, "image {\n"); - fprintf(fd, " x0=%d, y0=%d, x1=%d, y1=%d\n", img->x0, img->y0, img->x1, img->y1); - fprintf(fd, " numcomps=%d\n", img->numcomps); - for (compno = 0; compno < img->numcomps; compno++) { - opj_image_comp_t *comp = &img->comps[compno]; - fprintf(fd, " comp %d {\n", compno); - fprintf(fd, " dx=%d, dy=%d\n", comp->dx, comp->dy); - fprintf(fd, " prec=%d\n", comp->prec); - fprintf(fd, " sgnd=%d\n", comp->sgnd); - fprintf(fd, " }\n"); + + + + + + +/** + * Checks the progression order changes values. Tells if the poc given as input are valid. + * + * @param p_pocs the progression order changes. + * @param p_nb_pocs the number of progression order changes. + * @param p_nb_resolutions the number of resolutions. + * @param numcomps the number of components + * @param numlayers the number of layers. + * @param p_manager the user event manager. + * + * @return true if the pocs are valid. + */ +bool j2k_check_poc_val(const opj_poc_t *p_pocs, OPJ_UINT32 p_nb_pocs, OPJ_UINT32 p_nb_resolutions, OPJ_UINT32 p_num_comps, OPJ_UINT32 p_num_layers, opj_event_mgr_t * p_manager) +{ + OPJ_UINT32* packet_array; + OPJ_UINT32 index , resno, compno, layno; + OPJ_UINT32 i; + OPJ_UINT32 step_c = 1; + OPJ_UINT32 step_r = p_num_comps * step_c; + OPJ_UINT32 step_l = p_nb_resolutions * step_r; + bool loss = false; + OPJ_UINT32 layno0 = 0; + + packet_array = (OPJ_UINT32*) opj_calloc(step_l * p_num_layers, sizeof(OPJ_UINT32)); + if + (packet_array == 00) + { + opj_event_msg(p_manager , EVT_ERROR, "Not enough memory for checking the poc values.\n"); + return false; } - fprintf(fd, "}\n"); + memset(packet_array,0,step_l * p_num_layers* sizeof(OPJ_UINT32)); + if + (p_nb_pocs == 0) + { + return true; + } + + index = step_r * p_pocs->resno0; + // take each resolution for each poc + for + (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno) + { + OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c; + // take each comp of each resolution for each poc + for + (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) + { + OPJ_UINT32 comp_index = res_index + layno0 * step_l; + // and finally take each layer of each res of ... + for + (layno = layno0; layno < p_pocs->layno1 ; ++layno) + { + //index = step_r * resno + step_c * compno + step_l * layno; + packet_array[comp_index] = 1; + comp_index += step_l; + } + res_index += step_c; + } + index += step_r; + } + ++p_pocs; + // iterate through all the pocs + for + (i = 1; i < p_nb_pocs ; ++i) + { + OPJ_UINT32 l_last_layno1 = (p_pocs-1)->layno1 ; + layno0 = (p_pocs->layno1 > l_last_layno1)? l_last_layno1 : 0; + index = step_r * p_pocs->resno0; + // take each resolution for each poc + for + (resno = p_pocs->resno0 ; resno < p_pocs->resno1 ; ++resno) + { + OPJ_UINT32 res_index = index + p_pocs->compno0 * step_c; + // take each comp of each resolution for each poc + for + (compno = p_pocs->compno0 ; compno < p_pocs->compno1 ; ++compno) + { + OPJ_UINT32 comp_index = res_index + layno0 * step_l; + // and finally take each layer of each res of ... + for + (layno = layno0; layno < p_pocs->layno1 ; ++layno) + { + //index = step_r * resno + step_c * compno + step_l * layno; + packet_array[comp_index] = 1; + comp_index += step_l; + } + res_index += step_c; + } + index += step_r; + } + ++p_pocs; + } + + index = 0; + for + (layno = 0; layno < p_num_layers ; ++layno) + { + for + (resno = 0; resno < p_nb_resolutions; ++resno) + { + for + (compno = 0; compno < p_num_comps; ++compno) + { + loss |= (packet_array[index]!=1); + //index = step_r * resno + step_c * compno + step_l * layno; + index += step_c; + } + } + } + if + (loss) + { + opj_event_msg(p_manager , EVT_ERROR, "Missing packets possible loss of data\n"); + } + opj_free(packet_array); + return !loss; } -void j2k_dump_cp(FILE *fd, opj_image_t * img, opj_cp_t * cp) { - int tileno, compno, layno, bandno, resno, numbands; - fprintf(fd, "coding parameters {\n"); - fprintf(fd, " tx0=%d, ty0=%d\n", cp->tx0, cp->ty0); - fprintf(fd, " tdx=%d, tdy=%d\n", cp->tdx, cp->tdy); - fprintf(fd, " tw=%d, th=%d\n", cp->tw, cp->th); - for (tileno = 0; tileno < cp->tw * cp->th; 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, "%.1f ", tcp->rates[layno]); - } - fprintf(fd, "\n"); - for (compno = 0; compno < img->numcomps; compno++) { - opj_tccp_t *tccp = &tcp->tccps[compno]; - fprintf(fd, " comp %d {\n", compno); - fprintf(fd, " csty=%x\n", tccp->csty); - fprintf(fd, " numresolutions=%d\n", tccp->numresolutions); - fprintf(fd, " cblkw=%d\n", tccp->cblkw); - fprintf(fd, " cblkh=%d\n", tccp->cblkh); - fprintf(fd, " cblksty=%x\n", tccp->cblksty); - fprintf(fd, " qmfbid=%d\n", tccp->qmfbid); - fprintf(fd, " qntsty=%d\n", tccp->qntsty); - fprintf(fd, " numgbits=%d\n", tccp->numgbits); - fprintf(fd, " roishift=%d\n", tccp->roishift); - fprintf(fd, " stepsizes="); - numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 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 & J2K_CCP_CSTY_PRT) { - fprintf(fd, " prcw="); - for (resno = 0; resno < tccp->numresolutions; resno++) { - fprintf(fd, "%d ", tccp->prcw[resno]); - } - fprintf(fd, "\n"); - fprintf(fd, " prch="); - for (resno = 0; resno < tccp->numresolutions; resno++) { - fprintf(fd, "%d ", tccp->prch[resno]); - } - fprintf(fd, "\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, " }\n"); - } - fprintf(fd, "}\n"); -} /* ----------------------------------------------------------------------- */ -static int j2k_get_num_tp(opj_cp_t *cp,int pino,int tileno){ - char *prog; - int i; - int tpnum=1,tpend=0; - opj_tcp_t *tcp = &cp->tcps[tileno]; + +/** + * Gets the number of tile parts used for the given change of progression (if any) and the given tile. + * + * @param cp the coding parameters. + * @param pino the offset of the given poc (i.e. its position in the coding parameter). + * @param tileno the given tile. + * + * @return the number of tile parts. + */ +OPJ_UINT32 j2k_get_num_tp(opj_cp_t *cp,OPJ_UINT32 pino,OPJ_UINT32 tileno) +{ + const OPJ_CHAR *prog = 00; + OPJ_UINT32 i; + OPJ_UINT32 tpnum = 1; + opj_tcp_t *tcp = 00; + opj_poc_t * l_current_poc = 00; + + // preconditions only in debug + assert(tileno < (cp->tw * cp->th)); + assert(pino < (cp->tcps[tileno].numpocs + 1)); + + // get the given tile coding parameter + tcp = &cp->tcps[tileno]; + assert(tcp != 00); + l_current_poc = &(tcp->pocs[pino]); + assert(l_current_poc != 0); + + // get the progression order as a character string prog = j2k_convert_progression_order(tcp->prg); + assert(strlen(prog) > 0); - if(cp->tp_on == 1){ - for(i=0;i<4;i++){ - if(tpend!=1){ - if( cp->tp_flag == prog[i] ){ - tpend=1;cp->tp_pos=i; - } - switch(prog[i]){ + if + (cp->m_specific_param.m_enc.m_tp_on == 1) + { + for + (i=0;i<4;++i) + { + switch + (prog[i]) + { + // component wise case 'C': - tpnum= tpnum * tcp->pocs[pino].compE; + tpnum *= l_current_poc->compE; break; + // resolution wise case 'R': - tpnum= tpnum * tcp->pocs[pino].resE; + tpnum *= l_current_poc->resE; break; + // precinct wise case 'P': - tpnum= tpnum * tcp->pocs[pino].prcE; + tpnum *= l_current_poc->prcE; break; + // layer wise case 'L': - tpnum= tpnum * tcp->pocs[pino].layE; + tpnum *= l_current_poc->layE; break; - } + } + // whould we split here ? + if + ( cp->m_specific_param.m_enc.m_tp_flag == prog[i] ) + { + cp->m_specific_param.m_enc.m_tp_pos=i; + break; } } - }else{ + } + else + { tpnum=1; } return tpnum; } -/** mem allocation for TLM marker*/ -int j2k_calculate_tp(opj_cp_t *cp,int img_numcomp,opj_image_t *image,opj_j2k_t *j2k ){ - int pino,tileno,totnum_tp=0; - j2k->cur_totnum_tp = (int *) opj_malloc(cp->tw * cp->th * sizeof(int)); - for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { - int cur_totnum_tp = 0; - opj_tcp_t *tcp = &cp->tcps[tileno]; - for(pino = 0; pino <= tcp->numpocs; pino++) { - int tp_num=0; - opj_pi_iterator_t *pi = pi_initialise_encode(image, cp, tileno,FINAL_PASS); - if(!pi) { return -1;} - tp_num = j2k_get_num_tp(cp,pino,tileno); - totnum_tp = totnum_tp + tp_num; - cur_totnum_tp = cur_totnum_tp + tp_num; - pi_destroy(pi, cp, tileno); +/** + * Calculates the total number of tile parts needed by the encoder to + * encode such an image. If not enough memory is available, then the function return false. + * + * @param p_nb_tiles pointer that will hold the number of tile parts. + * @param cp the coding parameters for the image. + * @param image the image to encode. + * @param p_j2k the p_j2k encoder. + * @param p_manager the user event manager. + * + * @return true if the function was successful, false else. + */ +bool j2k_calculate_tp( + opj_j2k_t *p_j2k, + opj_cp_t *cp, + OPJ_UINT32 * p_nb_tiles, + opj_image_t *image, + opj_event_mgr_t * p_manager) +{ + OPJ_UINT32 pino,tileno; + OPJ_UINT32 l_nb_tiles; + opj_tcp_t *tcp; + + // preconditions + assert(p_nb_tiles != 00); + assert(cp != 00); + assert(image != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_nb_tiles = cp->tw * cp->th; + * p_nb_tiles = 0; + tcp = cp->tcps; + + /* INDEX >> */ + if + (p_j2k->cstr_info) + { + opj_tile_info_t * l_info_tile_ptr = p_j2k->cstr_info->tile; + for + (tileno = 0; tileno < l_nb_tiles; ++tileno) + { + OPJ_UINT32 cur_totnum_tp = 0; + pi_update_encoding_parameters(image,cp,tileno); + for + (pino = 0; pino <= tcp->numpocs; ++pino) + { + OPJ_UINT32 tp_num = j2k_get_num_tp(cp,pino,tileno); + *p_nb_tiles = *p_nb_tiles + tp_num; + cur_totnum_tp += tp_num; + } + tcp->m_nb_tile_parts = cur_totnum_tp; + l_info_tile_ptr->tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t)); + if + (l_info_tile_ptr->tp == 00) + { + return false; + } + memset(l_info_tile_ptr->tp,0,cur_totnum_tp * sizeof(opj_tp_info_t)); + l_info_tile_ptr->num_tps = cur_totnum_tp; + ++l_info_tile_ptr; + ++tcp; } - j2k->cur_totnum_tp[tileno] = cur_totnum_tp; - /* INDEX >> */ - if (j2k->cstr_info) { - j2k->cstr_info->tile[tileno].num_tps = cur_totnum_tp; - j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(cur_totnum_tp * sizeof(opj_tp_info_t)); - } - /* << INDEX */ } - return totnum_tp; + else + { + for + (tileno = 0; tileno < l_nb_tiles; ++tileno) + { + OPJ_UINT32 cur_totnum_tp = 0; + pi_update_encoding_parameters(image,cp,tileno); + for + (pino = 0; pino <= tcp->numpocs; ++pino) + { + OPJ_UINT32 tp_num=0; + tp_num = j2k_get_num_tp(cp,pino,tileno); + *p_nb_tiles = *p_nb_tiles + tp_num; + cur_totnum_tp += tp_num; + } + tcp->m_nb_tile_parts = cur_totnum_tp; + ++tcp; + } + } + return true; } -static void j2k_write_soc(opj_j2k_t *j2k) { - opj_cio_t *cio = j2k->cio; - cio_write(cio, J2K_MS_SOC, 2); +/** + * Writes the SOC marker (Start Of Codestream) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_soc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + /* 2 bytes will be written */ + OPJ_BYTE * l_start_stream = 00; + + // preconditions + assert(p_stream != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_start_stream = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + + /* write SOC identifier */ + opj_write_bytes(l_start_stream,J2K_MS_SOC,2); + if + (opj_stream_write_data(p_stream,l_start_stream,2,p_manager) != 2) + { + return false; + } /* UniPG>> */ #ifdef USE_JPWL - /* update markers struct */ - j2k_add_marker(j2k->cstr_info, J2K_MS_SOC, cio_tell(cio) - 2, 2); - + j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOC, p_stream_tell(p_stream) - 2, 2); #endif /* USE_JPWL */ + return true; /* <state = J2K_STATE_MHSIZ; +/** + * Reads a SOC marker (Start of Codestream) + * @param p_header_data the data contained in the SOC box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the SOC marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_soc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) + +{ + OPJ_BYTE l_data [2]; + OPJ_UINT32 l_marker; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + if + (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) + { + return false; + } + opj_read_bytes(l_data,&l_marker,2); + if + (l_marker != J2K_MS_SOC) + { + return false; + } + /* assure length of data is correct (0) */ + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_MHSIZ; /* Index */ - if (j2k->cstr_info) { - j2k->cstr_info->main_head_start = cio_tell(j2k->cio) - 2; - j2k->cstr_info->codestream_size = cio_numbytesleft(j2k->cio) + 2 - j2k->cstr_info->main_head_start; + if + (p_j2k->cstr_info) + { + //TODO p_j2k->cstr_info->main_head_start = opj_stream_tell(p_stream) - 2; // why - 2 ? + p_j2k->cstr_info->codestream_size = 0;/*p_stream_numbytesleft(p_j2k->p_stream) + 2 - p_j2k->cstr_info->main_head_start*/; } + return true; } -static void j2k_write_siz(opj_j2k_t *j2k) { - int i; - int lenp, len; +/** + * Writes the SIZ marker (image and tile size) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_siz( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + OPJ_UINT32 l_size_len; + OPJ_BYTE * l_current_ptr; + opj_image_t * l_image = 00; + opj_cp_t *cp = 00; + opj_image_comp_t * l_img_comp = 00; - opj_cio_t *cio = j2k->cio; - opj_image_t *image = j2k->image; - opj_cp_t *cp = j2k->cp; + // preconditions + assert(p_stream != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_image = p_j2k->m_image; + cp = &(p_j2k->m_cp); + l_size_len = 40 + 3 * l_image->numcomps; + l_img_comp = l_image->comps; - cio_write(cio, J2K_MS_SIZ, 2); /* SIZ */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, cp->rsiz, 2); /* Rsiz (capabilities) */ - cio_write(cio, image->x1, 4); /* Xsiz */ - cio_write(cio, image->y1, 4); /* Ysiz */ - cio_write(cio, image->x0, 4); /* X0siz */ - cio_write(cio, image->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, image->numcomps, 2); /* Csiz */ - for (i = 0; i < image->numcomps; i++) { - cio_write(cio, image->comps[i].prec - 1 + (image->comps[i].sgnd << 7), 1); /* Ssiz_i */ - cio_write(cio, image->comps[i].dx, 1); /* XRsiz_i */ - cio_write(cio, image->comps[i].dy, 1); /* YRsiz_i */ + if + (l_size_len > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_size_len); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_size_len; } - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lsiz */ - cio_seek(cio, lenp + len); + + l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + + /* write SOC identifier */ + opj_write_bytes(l_current_ptr,J2K_MS_SIZ,2); /* SIZ */ + l_current_ptr+=2; + opj_write_bytes(l_current_ptr,l_size_len-2,2); /* L_SIZ */ + l_current_ptr+=2; + opj_write_bytes(l_current_ptr, cp->rsiz, 2); /* Rsiz (capabilities) */ + l_current_ptr+=2; + opj_write_bytes(l_current_ptr, l_image->x1, 4); /* Xsiz */ + l_current_ptr+=4; + opj_write_bytes(l_current_ptr, l_image->y1, 4); /* Ysiz */ + l_current_ptr+=4; + opj_write_bytes(l_current_ptr, l_image->x0, 4); /* X0siz */ + l_current_ptr+=4; + opj_write_bytes(l_current_ptr, l_image->y0, 4); /* Y0siz */ + l_current_ptr+=4; + opj_write_bytes(l_current_ptr, cp->tdx, 4); /* XTsiz */ + l_current_ptr+=4; + opj_write_bytes(l_current_ptr, cp->tdy, 4); /* YTsiz */ + l_current_ptr+=4; + opj_write_bytes(l_current_ptr, cp->tx0, 4); /* XT0siz */ + l_current_ptr+=4; + opj_write_bytes(l_current_ptr, cp->ty0, 4); /* YT0siz */ + l_current_ptr+=4; + opj_write_bytes(l_current_ptr, l_image->numcomps, 2); /* Csiz */ + l_current_ptr+=2; + for + (i = 0; i < l_image->numcomps; ++i) + { + // TODO here with MCT ? + opj_write_bytes(l_current_ptr, l_img_comp->prec - 1 + (l_img_comp->sgnd << 7), 1); /* Ssiz_i */ + ++l_current_ptr; + opj_write_bytes(l_current_ptr, l_img_comp->dx, 1); /* XRsiz_i */ + ++l_current_ptr; + opj_write_bytes(l_current_ptr, l_img_comp->dy, 1); /* YRsiz_i */ + ++l_current_ptr; + ++l_img_comp; + } + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_size_len,p_manager) != l_size_len) + { + return false; + } + return true; } -static void j2k_read_siz(opj_j2k_t *j2k) { - int len, i; +/** + * Reads a SIZ marker (image and tile size) + * @param p_header_data the data contained in the SIZ box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the SIZ marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_siz ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_size, i; + OPJ_UINT32 l_nb_comp; + OPJ_UINT32 l_nb_comp_remain; + OPJ_UINT32 l_remaining_size; + OPJ_UINT32 l_nb_tiles; + OPJ_UINT32 l_tmp; + opj_image_t *l_image = 00; + opj_cp_t *l_cp = 00; + opj_image_comp_t * l_img_comp = 00; + opj_tcp_t * l_current_tile_param = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_header_data != 00); - opj_cio_t *cio = j2k->cio; - opj_image_t *image = j2k->image; - opj_cp_t *cp = j2k->cp; - - len = cio_read(cio, 2); /* Lsiz */ - cio_read(cio, 2); /* Rsiz (capabilities) */ - image->x1 = cio_read(cio, 4); /* Xsiz */ - image->y1 = cio_read(cio, 4); /* Ysiz */ - image->x0 = cio_read(cio, 4); /* X0siz */ - image->y0 = cio_read(cio, 4); /* Y0siz */ - 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 */ - - if ((image->x0<0)||(image->x1<0)||(image->y0<0)||(image->y1<0)) { - opj_event_msg(j2k->cinfo, EVT_ERROR, - "%s: invalid image size (x0:%d, x1:%d, y0:%d, y1:%d)\n", - image->x0,image->x1,image->y0,image->y1); - return; + l_image = p_j2k->m_image; + l_cp = &(p_j2k->m_cp); + if + (p_header_size < 36) + { + opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n"); + return false; + } + l_remaining_size = p_header_size - 36; + + l_nb_comp = l_remaining_size / 3; + l_nb_comp_remain = l_remaining_size % 3; + if + (l_nb_comp_remain != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n"); + return false; + } + l_size = p_header_size + 2; /* Lsiz */ + + opj_read_bytes(p_header_data,&l_tmp ,2); /* Rsiz (capabilities) */ + p_header_data+=2; + l_cp->rsiz = (OPJ_RSIZ_CAPABILITIES) l_tmp; + opj_read_bytes(p_header_data,(OPJ_UINT32 *) (&l_image->x1) ,4); /* Xsiz */ + p_header_data+=4; + opj_read_bytes(p_header_data,(OPJ_UINT32*) (&l_image->y1),4); /* Ysiz */ + p_header_data+=4; + opj_read_bytes(p_header_data,(OPJ_UINT32*) &l_image->x0,4); /* X0siz */ + p_header_data+=4; + opj_read_bytes(p_header_data,(OPJ_UINT32*) &l_image->y0,4); /* Y0siz */ + p_header_data+=4; + opj_read_bytes(p_header_data, (&l_cp->tdx),4); /* XTsiz */ + p_header_data+=4; + opj_read_bytes(p_header_data,&l_cp->tdy,4); /* YTsiz */ + p_header_data+=4; + opj_read_bytes(p_header_data,(OPJ_UINT32 *) (&l_cp->tx0),4); /* XT0siz */ + p_header_data+=4; + opj_read_bytes(p_header_data,(OPJ_UINT32 *) (&l_cp->ty0),4); /* YT0siz */ + p_header_data+=4; + opj_read_bytes(p_header_data,(&l_image->numcomps),2); /* Csiz */ + p_header_data+=2; + if + (l_image->numcomps != l_nb_comp) + { + opj_event_msg(p_manager, EVT_ERROR, "Error with SIZ marker size\n"); + return false; } - - image->numcomps = cio_read(cio, 2); /* Csiz */ #ifdef USE_JPWL - if (j2k->cp->correct) { + if (p_j2k->m_cp->correct) { /* if JPWL is on, we check whether TX errors have damaged too much the SIZ parameters */ if (!(image->x1 * image->y1)) { - opj_event_msg(j2k->cinfo, EVT_ERROR, + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: bad image size (%d x %d)\n", image->x1, image->y1); if (!JPWL_ASSUME || JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } } if (image->numcomps != ((len - 38) / 3)) { - opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + opj_event_msg(p_j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, "JPWL: Csiz is %d => space in SIZ only for %d comps.!!!\n", image->numcomps, ((len - 38) / 3)); if (!JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } /* we try to correct */ - opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"); + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- trying to adjust this\n"); if (image->numcomps < ((len - 38) / 3)) { len = 38 + 3 * image->numcomps; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n", + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- setting Lsiz to %d => HYPOTHESIS!!!\n", len); } else { image->numcomps = ((len - 38) / 3); - opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n", + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- setting Csiz to %d => HYPOTHESIS!!!\n", image->numcomps); } } @@ -514,498 +2143,1579 @@ static void j2k_read_siz(opj_j2k_t *j2k) { cp->exp_comps = image->numcomps; } #endif /* USE_JPWL */ - - image->comps = (opj_image_comp_t*) opj_calloc(image->numcomps, sizeof(opj_image_comp_t)); - for (i = 0; i < image->numcomps; i++) { - int tmp, w, h; - tmp = cio_read(cio, 1); /* Ssiz_i */ - image->comps[i].prec = (tmp & 0x7f) + 1; - image->comps[i].sgnd = tmp >> 7; - image->comps[i].dx = cio_read(cio, 1); /* XRsiz_i */ - image->comps[i].dy = cio_read(cio, 1); /* YRsiz_i */ - + + l_image->comps = (opj_image_comp_t*) opj_calloc(l_image->numcomps, sizeof(opj_image_comp_t)); + if + (l_image->comps == 00) + { + l_image->numcomps = 0; + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n"); + return false; + } + memset(l_image->comps,0,l_image->numcomps * sizeof(opj_image_comp_t)); + l_img_comp = l_image->comps; + for + (i = 0; i < l_image->numcomps; ++i) + { + OPJ_UINT32 tmp; + opj_read_bytes(p_header_data,&tmp,1); /* Ssiz_i */ + ++p_header_data; + l_img_comp->prec = (tmp & 0x7f) + 1; + l_img_comp->sgnd = tmp >> 7; + opj_read_bytes(p_header_data,&l_img_comp->dx,1); /* XRsiz_i */ + ++p_header_data; + opj_read_bytes(p_header_data,&l_img_comp->dy,1); /* YRsiz_i */ + ++p_header_data; #ifdef USE_JPWL - if (j2k->cp->correct) { + if (p_j2k->m_cp->correct) { /* if JPWL is on, we check whether TX errors have damaged too much the SIZ parameters, again */ if (!(image->comps[i].dx * image->comps[i].dy)) { - opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + opj_event_msg(p_j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, "JPWL: bad XRsiz_%d/YRsiz_%d (%d x %d)\n", i, i, image->comps[i].dx, image->comps[i].dy); if (!JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } /* we try to correct */ - opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); if (!image->comps[i].dx) { image->comps[i].dx = 1; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n", + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- setting XRsiz_%d to %d => HYPOTHESIS!!!\n", i, image->comps[i].dx); } if (!image->comps[i].dy) { image->comps[i].dy = 1; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n", + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- setting YRsiz_%d to %d => HYPOTHESIS!!!\n", i, image->comps[i].dy); } } } #endif /* USE_JPWL */ - - /* TODO: unused ? */ - w = int_ceildiv(image->x1 - image->x0, image->comps[i].dx); - h = int_ceildiv(image->y1 - image->y0, image->comps[i].dy); - - image->comps[i].resno_decoded = 0; /* number of resolution decoded */ - image->comps[i].factor = cp->reduce; /* reducing factor per component */ + l_img_comp->resno_decoded = 0; /* number of resolution decoded */ + l_img_comp->factor = l_cp->m_specific_param.m_dec.m_reduce; /* reducing factor per component */ + ++l_img_comp; } - cp->tw = int_ceildiv(image->x1 - cp->tx0, cp->tdx); - cp->th = int_ceildiv(image->y1 - cp->ty0, cp->tdy); + l_cp->tw = int_ceildiv(l_image->x1 - l_cp->tx0, l_cp->tdx); + l_cp->th = int_ceildiv(l_image->y1 - l_cp->ty0, l_cp->tdy); + l_nb_tiles = l_cp->tw * l_cp->th; + 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 = 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 = int_ceildiv((p_j2k->m_specific_param.m_decoder.m_end_tile_y - l_cp->ty0), l_cp->tdy); + } + else + { + p_j2k->m_specific_param.m_decoder.m_start_tile_x = 0; + p_j2k->m_specific_param.m_decoder.m_start_tile_y = 0; + p_j2k->m_specific_param.m_decoder.m_end_tile_x = l_cp->tw; + p_j2k->m_specific_param.m_decoder.m_end_tile_y = l_cp->th; + } #ifdef USE_JPWL - if (j2k->cp->correct) { + if (p_j2k->m_cp->correct) { /* if JPWL is on, we check whether TX errors have damaged too much the SIZ parameters */ if ((cp->tw < 1) || (cp->th < 1) || (cp->tw > cp->max_tiles) || (cp->th > cp->max_tiles)) { - opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + opj_event_msg(p_j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, "JPWL: bad number of tiles (%d x %d)\n", cp->tw, cp->th); if (!JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } /* we try to correct */ - opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- trying to adjust them\n"); if (cp->tw < 1) { cp->tw= 1; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n", + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- setting %d tiles in x => HYPOTHESIS!!!\n", cp->tw); } if (cp->tw > cp->max_tiles) { cp->tw= 1; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large x, increase expectance of %d\n" + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- too large x, increase expectance of %d\n" "- setting %d tiles in x => HYPOTHESIS!!!\n", cp->max_tiles, cp->tw); } if (cp->th < 1) { cp->th= 1; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n", + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- setting %d tiles in y => HYPOTHESIS!!!\n", cp->th); } if (cp->th > cp->max_tiles) { cp->th= 1; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- too large y, increase expectance of %d to continue\n", + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- too large y, increase expectance of %d to continue\n", "- setting %d tiles in y => HYPOTHESIS!!!\n", cp->max_tiles, cp->th); } } } #endif /* USE_JPWL */ - - cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t)); - cp->tileno = (int*) opj_malloc(cp->tw * cp->th * sizeof(int)); - cp->tileno_size = 0; + /* memory allocations */ + l_cp->tcps = (opj_tcp_t*) opj_calloc(l_nb_tiles, sizeof(opj_tcp_t)); + if + (l_cp->tcps == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n"); + return false; + } + memset(l_cp->tcps,0,l_nb_tiles*sizeof(opj_tcp_t)); #ifdef USE_JPWL - if (j2k->cp->correct) { + if (p_j2k->m_cp->correct) { if (!cp->tcps) { - opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + opj_event_msg(p_j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, "JPWL: could not alloc tcps field of cp\n"); if (!JPWL_ASSUME || JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } } } #endif /* USE_JPWL */ - for (i = 0; i < cp->tw * cp->th; i++) { - cp->tcps[i].POC = 0; - cp->tcps[i].numpocs = 0; - cp->tcps[i].first = 1; + p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps = (opj_tccp_t*) opj_calloc(l_image->numcomps, sizeof(opj_tccp_t)); + if + (p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n"); + return false; } + memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps ,0,l_image->numcomps*sizeof(opj_tccp_t)); - /* Initialization for PPM marker */ - cp->ppm = 0; - cp->ppm_data = NULL; - cp->ppm_data_first = NULL; - cp->ppm_previous = 0; - cp->ppm_store = 0; + p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records = opj_malloc(J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t)); + if + (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n"); + return false; + } + memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mct_records,0,J2K_MCT_DEFAULT_NB_RECORDS * sizeof(opj_mct_data_t)); + p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mct_records = J2K_MCT_DEFAULT_NB_RECORDS; + + p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records = opj_malloc(J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t)); + if + (! p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n"); + return false; + } + memset(p_j2k->m_specific_param.m_decoder.m_default_tcp->m_mcc_records,0,J2K_MCC_DEFAULT_NB_RECORDS * sizeof(opj_simple_mcc_decorrelation_data_t)); + p_j2k->m_specific_param.m_decoder.m_default_tcp->m_nb_max_mcc_records = J2K_MCC_DEFAULT_NB_RECORDS; + + /* set up default dc level shift */ + for + (i=0;inumcomps;++i) + { + if + (! l_image->comps[i].sgnd) + { + p_j2k->m_specific_param.m_decoder.m_default_tcp->tccps[i].m_dc_level_shift = 1 << (l_image->comps[i].prec - 1); + } + } + + l_current_tile_param = l_cp->tcps; + for + (i = 0; i < l_nb_tiles; ++i) + { + l_current_tile_param->tccps = (opj_tccp_t*) opj_malloc(l_image->numcomps * sizeof(opj_tccp_t)); + if + (l_current_tile_param->tccps == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n"); + return false; + } + memset(l_current_tile_param->tccps,0,l_image->numcomps * sizeof(opj_tccp_t)); + + ++l_current_tile_param; - j2k->default_tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t)); - for (i = 0; i < cp->tw * cp->th; i++) { - cp->tcps[i].tccps = (opj_tccp_t*) opj_malloc(image->numcomps * sizeof(opj_tccp_t)); } - j2k->tile_data = (unsigned char**) opj_calloc(cp->tw * cp->th, sizeof(unsigned char*)); - j2k->tile_len = (int*) opj_calloc(cp->tw * cp->th, sizeof(int)); - j2k->state = J2K_STATE_MH; + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_MH; + opj_image_comp_update(l_image,l_cp); /* Index */ - if (j2k->cstr_info) { - opj_codestream_info_t *cstr_info = j2k->cstr_info; - cstr_info->image_w = image->x1 - image->x0; - cstr_info->image_h = image->y1 - image->y0; - cstr_info->numcomps = image->numcomps; - cstr_info->tw = cp->tw; - cstr_info->th = cp->th; - cstr_info->tile_x = cp->tdx; - cstr_info->tile_y = cp->tdy; - cstr_info->tile_Ox = cp->tx0; - cstr_info->tile_Oy = cp->ty0; - cstr_info->tile = (opj_tile_info_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tile_info_t)); - } -} - -static void j2k_write_com(opj_j2k_t *j2k) { - unsigned int i; - int lenp, len; - - if(j2k->cp->comment) { - opj_cio_t *cio = j2k->cio; - char *comment = j2k->cp->comment; - - cio_write(cio, J2K_MS_COM, 2); - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, 1, 2); /* General use (IS 8859-15:1999 (Latin) values) */ - for (i = 0; i < strlen(comment); i++) { - cio_write(cio, comment[i], 1); + if + (p_j2k->cstr_info) + { + opj_codestream_info_t *cstr_info = p_j2k->cstr_info; + cstr_info->image_w = l_image->x1 - l_image->x0; + cstr_info->image_h = l_image->y1 - l_image->y0; + cstr_info->numcomps = l_image->numcomps; + cstr_info->tw = l_cp->tw; + cstr_info->th = l_cp->th; + cstr_info->tile_x = l_cp->tdx; + cstr_info->tile_y = l_cp->tdy; + cstr_info->tile_Ox = l_cp->tx0; + cstr_info->tile_Oy = l_cp->ty0; + cstr_info->tile = (opj_tile_info_t*) opj_calloc(l_nb_tiles, sizeof(opj_tile_info_t)); + if + (cstr_info->tile == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to take in charge SIZ marker\n"); + return false; } - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); - cio_seek(cio, lenp + len); + memset(cstr_info->tile,0,l_nb_tiles * sizeof(opj_tile_info_t)); } + return true; } -static void j2k_read_com(opj_j2k_t *j2k) { - int len; - - opj_cio_t *cio = j2k->cio; +/** + * Writes the COM marker (comment) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_com( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_comment_size; + OPJ_UINT32 l_total_com_size; + const OPJ_CHAR *l_comment; + OPJ_BYTE * l_current_ptr = 00; - len = cio_read(cio, 2); - cio_skip(cio, len - 2); -} - -static void j2k_write_cox(opj_j2k_t *j2k, int compno) { - int i; - - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_cio_t *cio = j2k->cio; + // preconditions + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); - cio_write(cio, tccp->numresolutions - 1, 1); /* SPcox (D) */ - cio_write(cio, tccp->cblkw - 2, 1); /* SPcox (E) */ - cio_write(cio, tccp->cblkh - 2, 1); /* SPcox (F) */ - cio_write(cio, tccp->cblksty, 1); /* SPcox (G) */ - cio_write(cio, tccp->qmfbid, 1); /* SPcox (H) */ - - if (tccp->csty & J2K_CCP_CSTY_PRT) { - for (i = 0; i < tccp->numresolutions; i++) { - cio_write(cio, tccp->prcw[i] + (tccp->prch[i] << 4), 1); /* SPcox (I_i) */ + l_comment = p_j2k->m_cp.comment; + l_comment_size = 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) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_total_com_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_total_com_size; + } + l_current_ptr = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + opj_write_bytes(l_current_ptr,J2K_MS_COM , 2); /* COM */ + l_current_ptr+=2; + opj_write_bytes(l_current_ptr,l_total_com_size - 2 , 2); /* L_COM */ + l_current_ptr+=2; + opj_write_bytes(l_current_ptr,1 , 2); /* General use (IS 8859-15:1999 (Latin) values) */ + l_current_ptr+=2, + memcpy( l_current_ptr,l_comment,l_comment_size); + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_total_com_size,p_manager) != l_total_com_size) + { + return false; + } + return true; +} + +/** + * Reads a COM marker (comments) + * @param p_header_data the data contained in the COM box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the COM marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_com ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_header_data != 00); + return true; +} + +/** + * Gets the size taken by writting a SPCod or SPCoc for the given tile and component. + * + * @param p_tile_no the tile indix. + * @param p_comp_no the component being outputted. + * @param p_j2k the J2K codec. + * + * @return the number of bytes taken by the SPCod element. + */ +OPJ_UINT32 j2k_get_SPCod_SPCoc_size ( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no + ) +{ + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; + + // preconditions + assert(p_j2k != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_tile_no]; + l_tccp = &l_tcp->tccps[p_comp_no]; + + // preconditions again + assert(p_tile_no < (l_cp->tw * l_cp->th)); + assert(p_comp_no < p_j2k->m_image->numcomps); + + if + (l_tccp->csty & J2K_CCP_CSTY_PRT) + { + return 5 + l_tccp->numresolutions; + } + else + { + return 5; } } -static void j2k_read_cox(opj_j2k_t *j2k, int compno) { - int i; - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_cio_t *cio = j2k->cio; +/** + * Writes a SPCod or SPCoc element, i.e. the coding style of a given component of a tile. + * + * @param p_comp_no the component number to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. + * +*/ +bool j2k_write_SPCod_SPCoc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; - tccp->numresolutions = cio_read(cio, 1) + 1; /* SPcox (D) */ + // preconditions + assert(p_j2k != 00); + assert(p_header_size != 00); + assert(p_manager != 00); + assert(p_data != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_tile_no]; + l_tccp = &l_tcp->tccps[p_comp_no]; + + // preconditions again + assert(p_tile_no < (l_cp->tw * l_cp->th)); + assert(p_comp_no <(p_j2k->m_image->numcomps)); + + if + (*p_header_size < 5) + { + opj_event_msg(p_manager, EVT_ERROR, "Error writting SPCod SPCoc element\n"); + return false; + } + + opj_write_bytes(p_data,l_tccp->numresolutions - 1, 1); /* SPcoc (D) */ + ++p_data; + opj_write_bytes(p_data,l_tccp->cblkw - 2, 1); /* SPcoc (E) */ + ++p_data; + opj_write_bytes(p_data,l_tccp->cblkh - 2, 1); /* SPcoc (F) */ + ++p_data; + opj_write_bytes(p_data,l_tccp->cblksty, 1); /* SPcoc (G) */ + ++p_data; + opj_write_bytes(p_data,l_tccp->qmfbid, 1); /* SPcoc (H) */ + ++p_data; + + *p_header_size = *p_header_size - 5; + if + (l_tccp->csty & J2K_CCP_CSTY_PRT) + { + if + (*p_header_size < l_tccp->numresolutions) + { + opj_event_msg(p_manager, EVT_ERROR, "Error writting SPCod SPCoc element\n"); + return false; + } + for + (i = 0; i < l_tccp->numresolutions; ++i) + { + opj_write_bytes(p_data,l_tccp->prcw[i] + (l_tccp->prch[i] << 4), 1); /* SPcoc (I_i) */ + ++p_data; + } + *p_header_size = *p_header_size - l_tccp->numresolutions; + + } + return true; +} + + +/** + * Reads a SPCod or SPCoc element, i.e. the coding style of a given component of a tile. + * @param p_header_data the data contained in the COM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the COM marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_SPCod_SPCoc( + opj_j2k_t *p_j2k, + OPJ_UINT32 compno, + OPJ_BYTE * p_header_data, + OPJ_UINT32 * p_header_size, + struct opj_event_mgr * p_manager + ) +{ + // loop + OPJ_UINT32 i; + + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; + OPJ_BYTE * l_current_ptr = 00; + OPJ_UINT32 l_tmp; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_header_data != 00); + + + l_cp = &(p_j2k->m_cp); + l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH ? &l_cp->tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + + // precondition again + assert(compno < p_j2k->m_image->numcomps); + l_tccp = &l_tcp->tccps[compno]; + l_current_ptr = p_header_data; + + + // make sure room is sufficient + if + (* p_header_size < 5) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n"); + return false; + } + opj_read_bytes(l_current_ptr, &l_tccp->numresolutions ,1); /* SPcox (D) */ + ++l_tccp->numresolutions; /* tccp->numresolutions = read() + 1 */ + ++l_current_ptr; // If user wants to remove more resolutions than the codestream contains, return error - if (cp->reduce >= tccp->numresolutions) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number " + if + (l_cp->m_specific_param.m_dec.m_reduce >= l_tccp->numresolutions) + { + opj_event_msg(p_manager, EVT_ERROR, "Error decoding component %d.\nThe number of resolutions to remove is higher than the number " "of resolutions of this component\nModify the cp_reduce parameter.\n\n", compno); - j2k->state |= J2K_STATE_ERR; + p_j2k->m_specific_param.m_decoder.m_state |= J2K_DEC_STATE_ERR; + return false; } + + opj_read_bytes(l_current_ptr,&l_tccp->cblkw ,1); /* SPcoc (E) */ + ++l_current_ptr; + l_tccp->cblkw += 2; - tccp->cblkw = cio_read(cio, 1) + 2; /* SPcox (E) */ - tccp->cblkh = cio_read(cio, 1) + 2; /* SPcox (F) */ - tccp->cblksty = cio_read(cio, 1); /* SPcox (G) */ - tccp->qmfbid = cio_read(cio, 1); /* SPcox (H) */ - if (tccp->csty & J2K_CP_CSTY_PRT) { - for (i = 0; i < tccp->numresolutions; i++) { - int tmp = cio_read(cio, 1); /* SPcox (I_i) */ - tccp->prcw[i] = tmp & 0xf; - tccp->prch[i] = tmp >> 4; + opj_read_bytes(l_current_ptr,&l_tccp->cblkh ,1); /* SPcoc (F) */ + ++l_current_ptr; + l_tccp->cblkh += 2; + + opj_read_bytes(l_current_ptr,&l_tccp->cblksty ,1); /* SPcoc (G) */ + ++l_current_ptr; + + opj_read_bytes(l_current_ptr,&l_tccp->qmfbid ,1); /* SPcoc (H) */ + ++l_current_ptr; + + * p_header_size = * p_header_size - 5; + + // use custom precinct size ? + if + (l_tccp->csty & J2K_CCP_CSTY_PRT) + { + if + (* p_header_size < l_tccp->numresolutions) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading SPCod SPCoc element\n"); + return false; + } + for + (i = 0; i < l_tccp->numresolutions; ++i) + { + opj_read_bytes(l_current_ptr,&l_tmp ,1); /* SPcoc (I_i) */ + ++l_current_ptr; + l_tccp->prcw[i] = l_tmp & 0xf; + l_tccp->prch[i] = l_tmp >> 4; + } + * p_header_size = * p_header_size - l_tccp->numresolutions; + } + else + { + /* set default size for the precinct width and height */ + for + (i = 0; i < l_tccp->numresolutions; ++i) + { + l_tccp->prcw[i] = 15; + l_tccp->prch[i] = 15; } } /* INDEX >> */ - if(j2k->cstr_info && compno == 0) { - for (i = 0; i < tccp->numresolutions; i++) { - if (tccp->csty & J2K_CP_CSTY_PRT) { - j2k->cstr_info->tile[j2k->curtileno].pdx[i] = tccp->prcw[i]; - j2k->cstr_info->tile[j2k->curtileno].pdy[i] = tccp->prch[i]; - } - else { - j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15; - j2k->cstr_info->tile[j2k->curtileno].pdx[i] = 15; - } - } + if + (p_j2k->cstr_info && compno == 0) + { + OPJ_UINT32 l_data_size = l_tccp->numresolutions * sizeof(OPJ_UINT32); + memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdx,l_tccp->prcw, l_data_size); + memcpy(p_j2k->cstr_info->tile[p_j2k->m_current_tile_number].pdy,l_tccp->prch, l_data_size); } /* << INDEX */ + return true; } -static void j2k_write_cod(opj_j2k_t *j2k) { - opj_cp_t *cp = NULL; - opj_tcp_t *tcp = NULL; - int lenp, len; +/** + * Copies the tile component parameters of all the component from the first tile component. + * + * @param p_j2k the J2k codec. + */ +void j2k_copy_tile_component_parameters( + opj_j2k_t *p_j2k + ) +{ + // loop + OPJ_UINT32 i; + + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_ref_tccp = 00; + opj_tccp_t *l_copied_tccp = 00; + OPJ_UINT32 l_prc_size; + // preconditions + assert(p_j2k != 00); - opj_cio_t *cio = j2k->cio; + l_cp = &(p_j2k->m_cp); + l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH ? &l_cp->tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; - cio_write(cio, J2K_MS_COD, 2); /* COD */ - - lenp = cio_tell(cio); - cio_skip(cio, 2); - - cp = j2k->cp; - tcp = &cp->tcps[j2k->curtileno]; + l_ref_tccp = &l_tcp->tccps[0]; + l_copied_tccp = l_ref_tccp + 1; + l_prc_size = l_ref_tccp->numresolutions * sizeof(OPJ_UINT32); - cio_write(cio, tcp->csty, 1); /* Scod */ - cio_write(cio, tcp->prg, 1); /* SGcod (A) */ - cio_write(cio, tcp->numlayers, 2); /* SGcod (B) */ - cio_write(cio, tcp->mct, 1); /* SGcod (C) */ - - j2k_write_cox(j2k, 0); - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lcod */ - cio_seek(cio, lenp + len); -} - -static void j2k_read_cod(opj_j2k_t *j2k) { - int len, i, pos; - - opj_cio_t *cio = j2k->cio; - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; - opj_image_t *image = j2k->image; - - len = cio_read(cio, 2); /* Lcod */ - tcp->csty = cio_read(cio, 1); /* Scod */ - tcp->prg = (OPJ_PROG_ORDER)cio_read(cio, 1); /* SGcod (A) */ - tcp->numlayers = cio_read(cio, 2); /* SGcod (B) */ - tcp->mct = cio_read(cio, 1); /* SGcod (C) */ - - pos = cio_tell(cio); - for (i = 0; i < image->numcomps; i++) { - tcp->tccps[i].csty = tcp->csty & J2K_CP_CSTY_PRT; - cio_seek(cio, pos); - j2k_read_cox(j2k, i); + for + (i=1;im_image->numcomps;++i) + { + l_copied_tccp->numresolutions = l_ref_tccp->numresolutions; + l_copied_tccp->cblkw = l_ref_tccp->cblkw; + l_copied_tccp->cblkh = l_ref_tccp->cblkh; + l_copied_tccp->cblksty = l_ref_tccp->cblksty; + l_copied_tccp->qmfbid = l_ref_tccp->qmfbid; + memcpy(l_copied_tccp->prcw,l_ref_tccp->prcw,l_prc_size); + memcpy(l_copied_tccp->prch,l_ref_tccp->prch,l_prc_size); + ++l_copied_tccp; } +} + + + +/** + * Writes the COD marker (Coding style default) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_cod( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + OPJ_UINT32 l_code_size,l_remaining_size; + OPJ_BYTE * l_current_data = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; + l_code_size = 9 + j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,0); + l_remaining_size = l_code_size; + + if + (l_code_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_code_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_code_size; + } + + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + + opj_write_bytes(l_current_data,J2K_MS_COD,2); /* COD */ + l_current_data += 2; + + opj_write_bytes(l_current_data,l_code_size-2,2); /* L_COD */ + l_current_data += 2; + + opj_write_bytes(l_current_data,l_tcp->csty,1); /* Scod */ + ++l_current_data; + + opj_write_bytes(l_current_data,l_tcp->prg,1); /* SGcod (A) */ + ++l_current_data; + + opj_write_bytes(l_current_data,l_tcp->numlayers,2); /* SGcod (B) */ + l_current_data+=2; + + opj_write_bytes(l_current_data,l_tcp->mct,1); /* SGcod (C) */ + ++l_current_data; + + l_remaining_size -= 9; + + if + (! j2k_write_SPCod_SPCoc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error writting COD marker\n"); + return false; + } + if + (l_remaining_size != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error writting COD marker\n"); + return false; + } + + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_code_size,p_manager) != l_code_size) + { + return false; + } + return true; +} + +/** + * Reads a COD marker (Coding Styke defaults) + * @param p_header_data the data contained in the COD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the COD marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_cod ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + // loop + OPJ_UINT32 i; + OPJ_UINT32 l_tmp; + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_image_t *l_image = 00; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH) ? &l_cp->tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + l_image = p_j2k->m_image; + + // make sure room is sufficient + if + (p_header_size < 5) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n"); + return false; + } + + opj_read_bytes(p_header_data,&l_tcp->csty,1); /* Scod */ + ++p_header_data; + opj_read_bytes(p_header_data,&l_tmp,1); /* SGcod (A) */ + ++p_header_data; + l_tcp->prg = (OPJ_PROG_ORDER) l_tmp; + opj_read_bytes(p_header_data,&l_tcp->numlayers,2); /* SGcod (B) */ + p_header_data+=2; + if + (l_cp->m_specific_param.m_dec.m_layer) + { + l_tcp->num_layers_to_decode = l_cp->m_specific_param.m_dec.m_layer; + } + else + { + l_tcp->num_layers_to_decode = l_tcp->numlayers; + } + + opj_read_bytes(p_header_data,&l_tcp->mct,1); /* SGcod (C) */ + ++p_header_data; + + p_header_size -= 5; + for + (i = 0; i < l_image->numcomps; ++i) + { + l_tcp->tccps[i].csty = l_tcp->csty & J2K_CCP_CSTY_PRT; + } + + if + (! j2k_read_SPCod_SPCoc(p_j2k,0,p_header_data,&p_header_size,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n"); + return false; + } + if + (p_header_size != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading COD marker\n"); + return false; + } + j2k_copy_tile_component_parameters(p_j2k); + /* Index */ - if (j2k->cstr_info) { - opj_codestream_info_t *cstr_info = j2k->cstr_info; - cstr_info->prog = tcp->prg; - cstr_info->numlayers = tcp->numlayers; - cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int)); - for (i = 0; i < image->numcomps; i++) { - cstr_info->numdecompos[i] = tcp->tccps[i].numresolutions - 1; + if + (p_j2k->cstr_info) + { + opj_codestream_info_t *l_cstr_info = p_j2k->cstr_info; + l_cstr_info->prog = l_tcp->prg; + l_cstr_info->numlayers = l_tcp->numlayers; + l_cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(l_image->numcomps * sizeof(OPJ_UINT32)); + for + (i = 0; i < l_image->numcomps; ++i) + { + l_cstr_info->numdecompos[i] = l_tcp->tccps[i].numresolutions - 1; } } + return true; +} + +/** + * Writes the COC marker (Coding style component) + * + * @param p_comp_no the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_coc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_no, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_coc_size,l_remaining_size; + OPJ_UINT32 l_comp_room; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_comp_room = (p_j2k->m_image->numcomps <= 256) ? 1 : 2; + + l_coc_size = 5 + l_comp_room + j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no); + if + (l_coc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_coc_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_coc_size; + } + + j2k_write_coc_in_memory(p_j2k,p_comp_no,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_remaining_size,p_manager); + + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_coc_size,p_manager) != l_coc_size) + { + return false; + } + return true; +} + +/** + * Gets the maximum size taken by a coc. + * + * @param p_j2k the jpeg2000 codec to use. + */ +OPJ_UINT32 j2k_get_max_coc_size(opj_j2k_t *p_j2k) +{ + OPJ_UINT32 i,j; + OPJ_UINT32 l_nb_comp; + OPJ_UINT32 l_nb_tiles; + OPJ_UINT32 l_max = 0; + + // preconditions + + l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ; + l_nb_comp = p_j2k->m_image->numcomps; + + for + (i=0;im_cp.tcps; + l_nb_tiles = p_j2k->m_cp.tw * p_j2k->m_cp.th ; + + for + (i=0;im_nb_tile_parts); + ++l_tcp; + } + return 12 * l_max; +} + + +/** + * Gets the maximum size taken by the headers of the SOT. + * + * @param p_j2k the jpeg2000 codec to use. + */ +OPJ_UINT32 j2k_get_specific_header_sizes(opj_j2k_t *p_j2k) +{ + OPJ_UINT32 l_nb_bytes = 0; + OPJ_UINT32 l_nb_comps; + OPJ_UINT32 l_coc_bytes,l_qcc_bytes; + + + l_nb_comps = p_j2k->m_image->numcomps - 1; + l_nb_bytes += j2k_get_max_toc_size(p_j2k); + if + (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == 0) + { + l_coc_bytes = j2k_get_max_coc_size(p_j2k); + l_nb_bytes += l_nb_comps * l_coc_bytes; + l_qcc_bytes = j2k_get_max_qcc_size(p_j2k); + l_nb_bytes += l_nb_comps * l_qcc_bytes; + } + l_nb_bytes += j2k_get_max_poc_size(p_j2k); + /*** DEVELOPER CORNER, Add room for your headers ***/ + + + return l_nb_bytes; +} + + +/** + * Writes the COC marker (Coding style component) + * + * @param p_comp_no the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +void j2k_write_coc_in_memory( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_no, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + struct opj_event_mgr * p_manager + ) +{ + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + OPJ_UINT32 l_coc_size,l_remaining_size; + OPJ_BYTE * l_current_data = 00; + opj_image_t *l_image = 00; + OPJ_UINT32 l_comp_room; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; + l_image = p_j2k->m_image; + l_comp_room = (l_image->numcomps <= 256) ? 1 : 2; + + l_coc_size = 5 + l_comp_room + j2k_get_SPCod_SPCoc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no); + l_remaining_size = l_coc_size; + + l_current_data = p_data; + + opj_write_bytes(l_current_data,J2K_MS_COC,2); /* COC */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_coc_size-2,2); /* L_COC */ + l_current_data += 2; + opj_write_bytes(l_current_data,p_comp_no, l_comp_room); /* Ccoc */ + l_current_data+=l_comp_room; + opj_write_bytes(l_current_data, l_tcp->tccps[p_comp_no].csty, 1); /* Scoc */ + ++l_current_data; + l_remaining_size -= (5 + l_comp_room); + 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; +} + + +/** + * Reads a COC marker (Coding Style Component) + * @param p_header_data the data contained in the COC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the COC marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_coc ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_image_t *l_image = 00; + OPJ_UINT32 l_comp_room; + OPJ_UINT32 l_comp_no; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH) ? &l_cp->tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + l_image = p_j2k->m_image; + + l_comp_room = l_image->numcomps <= 256 ? 1 : 2; + // make sure room is sufficient + if + (p_header_size < l_comp_room + 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n"); + return false; + } + p_header_size -= l_comp_room + 1; + + opj_read_bytes(p_header_data,&l_comp_no,l_comp_room); /* Ccoc */ + p_header_data += l_comp_room; + if + (l_comp_no >= l_image->numcomps) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker (bad number of components)\n"); + return false; + } + opj_read_bytes(p_header_data,&l_tcp->tccps[l_comp_no].csty,1); /* Scoc */ + ++p_header_data ; + + if + (! j2k_read_SPCod_SPCoc(p_j2k,l_comp_no,p_header_data,&p_header_size,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n"); + return false; + } + if + (p_header_size != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading COC marker\n"); + return false; + } + return true; +} + +/** + * Gets the size taken by writting SQcd or SQcc element, i.e. the quantization values of a band in the QCD or QCC. + * + * @param p_tile_no the tile indix. + * @param p_comp_no the component being outputted. + * @param p_j2k the J2K codec. + * + * @return the number of bytes taken by the SPCod element. + */ +OPJ_UINT32 j2k_get_SQcd_SQcc_size ( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no + ) +{ + OPJ_UINT32 l_num_bands; + + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; + + // preconditions + assert(p_j2k != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_tile_no]; + l_tccp = &l_tcp->tccps[p_comp_no]; + + // preconditions again + assert(p_tile_no < l_cp->tw * l_cp->th); + assert(p_comp_no < p_j2k->m_image->numcomps); + + l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (l_tccp->numresolutions * 3 - 2); + + if + (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) + { + return 1 + l_num_bands; + } + else + { + return 1 + 2*l_num_bands; + } } -static void j2k_write_coc(opj_j2k_t *j2k, int compno) { - int lenp, len; +/** + * Writes a SQcd or SQcc element, i.e. the quantization values of a band. + * + * @param p_tile_no the tile to output. + * @param p_comp_no the component number to output. + * @param p_data the data buffer. + * @param p_header_size pointer to the size of the data buffer, it is changed by the function. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. + * +*/ +bool j2k_write_SQcd_SQcc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_header_size; + OPJ_UINT32 l_band_no, l_num_bands; + OPJ_UINT32 l_expn,l_mant; + + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; - opj_image_t *image = j2k->image; - opj_cio_t *cio = j2k->cio; - - cio_write(cio, J2K_MS_COC, 2); /* COC */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, compno, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ - cio_write(cio, tcp->tccps[compno].csty, 1); /* Scoc */ - j2k_write_cox(j2k, compno); - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lcoc */ - cio_seek(cio, lenp + len); -} + // preconditions + assert(p_j2k != 00); + assert(p_header_size != 00); + assert(p_manager != 00); + assert(p_data != 00); -static void j2k_read_coc(opj_j2k_t *j2k) { - int len, compno; - - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; - opj_image_t *image = j2k->image; - opj_cio_t *cio = j2k->cio; + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_tile_no]; + l_tccp = &l_tcp->tccps[p_comp_no]; - len = cio_read(cio, 2); /* Lcoc */ - compno = cio_read(cio, image->numcomps <= 256 ? 1 : 2); /* Ccoc */ - tcp->tccps[compno].csty = cio_read(cio, 1); /* Scoc */ - j2k_read_cox(j2k, compno); -} - -static void j2k_write_qcx(opj_j2k_t *j2k, int compno) { - int bandno, numbands; - int expn, mant; + // preconditions again + assert(p_tile_no < l_cp->tw * l_cp->th); + assert(p_comp_no m_image->numcomps); - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_cio_t *cio = j2k->cio; + l_num_bands = (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? 1 : (l_tccp->numresolutions * 3 - 2); - cio_write(cio, tccp->qntsty + (tccp->numgbits << 5), 1); /* Sqcx */ - numbands = tccp->qntsty == J2K_CCP_QNTSTY_SIQNT ? 1 : tccp->numresolutions * 3 - 2; - - for (bandno = 0; bandno < numbands; bandno++) { - expn = tccp->stepsizes[bandno].expn; - mant = tccp->stepsizes[bandno].mant; - - if (tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) { - cio_write(cio, expn << 3, 1); /* SPqcx_i */ - } else { - cio_write(cio, (expn << 11) + mant, 2); /* SPqcx_i */ + if + (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) + { + l_header_size = 1 + l_num_bands; + if + (*p_header_size < l_header_size) + { + opj_event_msg(p_manager, EVT_ERROR, "Error writting SQcd SQcc element\n"); + return false; + } + opj_write_bytes(p_data,l_tccp->qntsty + (l_tccp->numgbits << 5), 1); /* Sqcx */ + ++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; + opj_write_bytes(p_data, l_expn << 3, 1); /* SPqcx_i */ + ++p_data; } } + else + { + l_header_size = 1 + 2*l_num_bands; + if + (*p_header_size < l_header_size) + { + opj_event_msg(p_manager, EVT_ERROR, "Error writting SQcd SQcc element\n"); + return false; + } + opj_write_bytes(p_data,l_tccp->qntsty + (l_tccp->numgbits << 5), 1); /* Sqcx */ + ++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; + opj_write_bytes(p_data, (l_expn << 11) + l_mant, 2); /* SPqcx_i */ + p_data += 2; + } + } + *p_header_size = *p_header_size - l_header_size; + return true; } -static void j2k_read_qcx(opj_j2k_t *j2k, int compno, int len) { - int tmp; - int bandno, numbands; +/** + * Reads a SQcd or SQcc element, i.e. the quantization values of a band. + * + * @param p_comp_no the component being targeted. + * @param p_header_data the data contained in the COM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the COM marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_SQcd_SQcc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_no, + OPJ_BYTE* p_header_data, + OPJ_UINT32 * p_header_size, + struct opj_event_mgr * p_manager + ) +{ + // loop + OPJ_UINT32 l_band_no; + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; + OPJ_BYTE * l_current_ptr = 00; + OPJ_UINT32 l_tmp; + OPJ_UINT32 l_num_band; - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; - opj_tccp_t *tccp = &tcp->tccps[compno]; - opj_cio_t *cio = j2k->cio; + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_header_data != 00); - tmp = cio_read(cio, 1); /* Sqcx */ - tccp->qntsty = tmp & 0x1f; - tccp->numgbits = tmp >> 5; - numbands = (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) ? - 1 : ((tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ? len - 1 : (len - 1) / 2); + l_cp = &(p_j2k->m_cp); + l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH ? &l_cp->tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + // precondition again + assert(p_comp_no < p_j2k->m_image->numcomps); + l_tccp = &l_tcp->tccps[p_comp_no]; + l_current_ptr = p_header_data; + + if + (* p_header_size < 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading SQcd or SQcc element\n"); + return false; + } + * p_header_size -= 1; + + opj_read_bytes(l_current_ptr, &l_tmp ,1); /* Sqcx */ + ++l_current_ptr; + + l_tccp->qntsty = l_tmp & 0x1f; + l_tccp->numgbits = l_tmp >> 5; + if + (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) + { + l_num_band = 1; + } + else + { + l_num_band = (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) ? (*p_header_size) : (*p_header_size) / 2; + } #ifdef USE_JPWL - if (j2k->cp->correct) { + if (p_j2k->m_cp->correct) { /* if JPWL is on, we check whether there are too many subbands */ if ((numbands < 0) || (numbands >= J2K_MAXBANDS)) { - opj_event_msg(j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, + opj_event_msg(p_j2k->cinfo, JPWL_ASSUME ? EVT_WARNING : EVT_ERROR, "JPWL: bad number of subbands in Sqcx (%d)\n", numbands); if (!JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } /* we try to correct */ numbands = 1; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust them\n" + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- trying to adjust them\n" "- setting number of bands to %d => HYPOTHESIS!!!\n", numbands); }; }; #endif /* USE_JPWL */ - - for (bandno = 0; bandno < numbands; bandno++) { - int expn, mant; - if (tccp->qntsty == J2K_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; + if + (l_tccp->qntsty == J2K_CCP_QNTSTY_NOQNT) + { + for + (l_band_no = 0; l_band_no < l_num_band; l_band_no++) + { + opj_read_bytes(l_current_ptr, &l_tmp ,1); /* SPqcx_i */ + ++l_current_ptr; + l_tccp->stepsizes[l_band_no].expn = l_tmp>>3; + l_tccp->stepsizes[l_band_no].mant = 0; + } + * p_header_size = * p_header_size - l_num_band; + } + else + { + for + (l_band_no = 0; l_band_no < l_num_band; l_band_no++) + { + opj_read_bytes(l_current_ptr, &l_tmp ,2); /* SPqcx_i */ + l_current_ptr+=2; + l_tccp->stepsizes[l_band_no].expn = l_tmp >> 11; + l_tccp->stepsizes[l_band_no].mant = l_tmp & 0x7ff; } - tccp->stepsizes[bandno].expn = expn; - tccp->stepsizes[bandno].mant = mant; + * p_header_size = * p_header_size - 2*l_num_band; } /* Add Antonin : if scalar_derived -> compute other stepsizes */ - if (tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) { - for (bandno = 1; bandno < J2K_MAXBANDS; bandno++) { - tccp->stepsizes[bandno].expn = - ((tccp->stepsizes[0].expn) - ((bandno - 1) / 3) > 0) ? - (tccp->stepsizes[0].expn) - ((bandno - 1) / 3) : 0; - tccp->stepsizes[bandno].mant = tccp->stepsizes[0].mant; + if + (l_tccp->qntsty == J2K_CCP_QNTSTY_SIQNT) + { + for + (l_band_no = 1; l_band_no < 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; + l_tccp->stepsizes[l_band_no].mant = l_tccp->stepsizes[0].mant; } + } - /* ddA */ + return true; } -static void j2k_write_qcd(opj_j2k_t *j2k) { - int lenp, len; - opj_cio_t *cio = j2k->cio; + +/** + * Copies the tile component parameters of all the component from the first tile component. + * + * @param p_j2k the J2k codec. + */ +void j2k_copy_tile_quantization_parameters( + opj_j2k_t *p_j2k + ) +{ + // loop + OPJ_UINT32 i; - cio_write(cio, J2K_MS_QCD, 2); /* QCD */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - j2k_write_qcx(j2k, 0); - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lqcd */ - cio_seek(cio, lenp + len); -} + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_ref_tccp = 00; + opj_tccp_t *l_copied_tccp = 00; + OPJ_UINT32 l_size; + // preconditions + assert(p_j2k != 00); -static void j2k_read_qcd(opj_j2k_t *j2k) { - int len, i, pos; - - opj_cio_t *cio = j2k->cio; - opj_image_t *image = j2k->image; + l_cp = &(p_j2k->m_cp); + l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH ? &l_cp->tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + // precondition again + l_ref_tccp = &l_tcp->tccps[0]; + l_copied_tccp = l_ref_tccp + 1; + l_size = J2K_MAXBANDS * sizeof(opj_stepsize_t); - len = cio_read(cio, 2); /* Lqcd */ - pos = cio_tell(cio); - for (i = 0; i < image->numcomps; i++) { - cio_seek(cio, pos); - j2k_read_qcx(j2k, i, len - 2); + for + (i=1;im_image->numcomps;++i) + { + l_copied_tccp->qntsty = l_ref_tccp->qntsty; + l_copied_tccp->numgbits = l_ref_tccp->numgbits; + memcpy(l_copied_tccp->stepsizes,l_ref_tccp->stepsizes,l_size); + ++l_copied_tccp; } } -static void j2k_write_qcc(opj_j2k_t *j2k, int compno) { - int lenp, len; - opj_cio_t *cio = j2k->cio; + +/** + * Writes the QCD marker (quantization default) + * + * @param p_comp_number the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_qcd( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + OPJ_UINT32 l_qcd_size,l_remaining_size; + OPJ_BYTE * l_current_data = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; + l_qcd_size = 4 + j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,0); + l_remaining_size = l_qcd_size; - cio_write(cio, J2K_MS_QCC, 2); /* QCC */ - lenp = cio_tell(cio); - cio_skip(cio, 2); - cio_write(cio, compno, j2k->image->numcomps <= 256 ? 1 : 2); /* Cqcc */ - j2k_write_qcx(j2k, compno); - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lqcc */ - cio_seek(cio, lenp + len); + if + (l_qcd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_qcd_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcd_size; + } + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + + opj_write_bytes(l_current_data,J2K_MS_QCD,2); /* QCD */ + l_current_data += 2; + + opj_write_bytes(l_current_data,l_qcd_size-2,2); /* L_QCD */ + l_current_data += 2; + + l_remaining_size -= 4; + + if + (! j2k_write_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,0,l_current_data,&l_remaining_size,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error writting QCD marker\n"); + return false; + } + if + (l_remaining_size != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error writting QCD marker\n"); + return false; + } + + if + (opj_stream_write_data(p_stream, p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_qcd_size,p_manager) != l_qcd_size) + { + return false; + } + return true; } -static void j2k_read_qcc(opj_j2k_t *j2k) { - int len, compno; - int numcomp = j2k->image->numcomps; - opj_cio_t *cio = j2k->cio; +/** + * Reads a QCD marker (Quantization defaults) + * @param p_header_data the data contained in the QCD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the QCD marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_qcd ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); - len = cio_read(cio, 2); /* Lqcc */ - compno = cio_read(cio, numcomp <= 256 ? 1 : 2); /* Cqcc */ + if + (! j2k_read_SQcd_SQcc(p_j2k,0,p_header_data,&p_header_size,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading QCD marker\n"); + return false; + } + if + (p_header_size != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading QCD marker\n"); + return false; + } + j2k_copy_tile_quantization_parameters(p_j2k); + return true; +} + + +/** + * Writes the QCC marker (quantization component) + * + * @param p_comp_no the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_qcc( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_no, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_qcc_size,l_remaining_size; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_qcc_size = 6 + j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no); + l_remaining_size = l_qcc_size; + if + (l_qcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_qcc_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_qcc_size; + } + j2k_write_qcc_in_memory(p_j2k,p_comp_no,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_remaining_size,p_manager); + + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_qcc_size,p_manager) != l_qcc_size) + { + return false; + } + return true; +} + + +/** + * Writes the QCC marker (quantization component) + * + * @param p_comp_no the index of the component to output. + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +void j2k_write_qcc_in_memory( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_comp_no, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_qcc_size,l_remaining_size; + OPJ_BYTE * l_current_data = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + + l_qcc_size = 6 + j2k_get_SQcd_SQcc_size(p_j2k,p_j2k->m_current_tile_number,p_comp_no); + l_remaining_size = l_qcc_size; + + l_current_data = p_data; + + opj_write_bytes(l_current_data,J2K_MS_QCC,2); /* QCC */ + l_current_data += 2; + + if + (p_j2k->m_image->numcomps <= 256) + { + --l_qcc_size; + opj_write_bytes(l_current_data,l_qcc_size-2,2); /* L_QCC */ + l_current_data += 2; + opj_write_bytes(l_current_data, p_comp_no, 1); /* Cqcc */ + ++l_current_data; + // in the case only one byte is sufficient the last byte allocated is useless -> still do -6 for available + l_remaining_size -= 6; + } + else + { + opj_write_bytes(l_current_data,l_qcc_size-2,2); /* L_QCC */ + l_current_data += 2; + opj_write_bytes(l_current_data, p_comp_no, 2); /* Cqcc */ + l_current_data+=2; + l_remaining_size -= 6; + } + j2k_write_SQcd_SQcc(p_j2k,p_j2k->m_current_tile_number,p_comp_no,l_current_data,&l_remaining_size,p_manager); + * p_data_written = l_qcc_size; +} + +/** + * Gets the maximum size taken by a qcc. + */ +OPJ_UINT32 j2k_get_max_qcc_size (opj_j2k_t *p_j2k) +{ + return j2k_get_max_coc_size(p_j2k); +} + +/** + * Reads a QCC marker (Quantization component) + * @param p_header_data the data contained in the QCC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the QCC marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_qcc( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager) +{ + OPJ_UINT32 l_num_comp,l_comp_no; + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_num_comp = p_j2k->m_image->numcomps; #ifdef USE_JPWL - if (j2k->cp->correct) { + if (p_j2k->m_cp->correct) { - static int backup_compno = 0; + static OPJ_UINT32 backup_compno = 0; /* compno is negative or larger than the number of components!!! */ if ((compno < 0) || (compno >= numcomp)) { - opj_event_msg(j2k->cinfo, EVT_ERROR, + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: bad component number in QCC (%d out of a maximum of %d)\n", compno, numcomp); if (!JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } /* we try to correct */ compno = backup_compno % numcomp; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" "- setting component number to %d\n", compno); } @@ -1014,292 +3724,2175 @@ static void j2k_read_qcc(opj_j2k_t *j2k) { backup_compno++; }; #endif /* USE_JPWL */ - - j2k_read_qcx(j2k, compno, len - 2 - (numcomp <= 256 ? 1 : 2)); -} - -static void j2k_write_poc(opj_j2k_t *j2k) { - int len, numpchgs, i; - - int numcomps = j2k->image->numcomps; - - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = &cp->tcps[j2k->curtileno]; - opj_tccp_t *tccp = &tcp->tccps[0]; - opj_cio_t *cio = j2k->cio; - - numpchgs = 1 + tcp->numpocs; - cio_write(cio, J2K_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->numresolutions); - 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 */ + if + (l_num_comp <= 256) + { + if + (p_header_size < 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n"); + return false; + } + opj_read_bytes(p_header_data,&l_comp_no,1); + ++p_header_data; + --p_header_size; } + else + { + if + (p_header_size < 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n"); + return false; + } + opj_read_bytes(p_header_data,&l_comp_no,2); + p_header_data+=2; + p_header_size-=2; + } + if + (! j2k_read_SQcd_SQcc(p_j2k,l_comp_no,p_header_data,&p_header_size,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n"); + return false; + } + if + (p_header_size != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading QCC marker\n"); + return false; + } + return true; + } -static void j2k_read_poc(opj_j2k_t *j2k) { - int len, numpchgs, i, old_poc; - int numcomps = j2k->image->numcomps; +/** + * Writes the CBD marker (Component bit depth definition) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_cbd( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + OPJ_UINT32 l_cbd_size; + OPJ_BYTE * l_current_data = 00; + opj_image_t *l_image = 00; + opj_image_comp_t * l_comp = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_image = p_j2k->m_image; + l_cbd_size = 6 + p_j2k->m_image->numcomps; - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; - opj_cio_t *cio = j2k->cio; + if + (l_cbd_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_cbd_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_cbd_size; + } + + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + opj_write_bytes(l_current_data,J2K_MS_CBD,2); /* CBD */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_cbd_size-2,2); /* L_CBD */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_image->numcomps, 2); /* Ncbd */ + l_current_data+=2; + l_comp = l_image->comps; + for + (i=0;inumcomps;++i) + { + opj_write_bytes(l_current_data, (l_comp->sgnd << 7) | (l_comp->prec - 1), 1); /* Component bit depth */ + ++l_current_data; + ++l_comp; + } + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_cbd_size,p_manager) != l_cbd_size) + { + return false; + } + return true; +} + +/** + * Reads a CBD marker (Component bit depth definition) + * @param p_header_data the data contained in the CBD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the CBD marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_cbd ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager) +{ + OPJ_UINT32 l_nb_comp,l_num_comp; + OPJ_UINT32 l_comp_def; + OPJ_UINT32 i; + opj_image_comp_t * l_comp = 00; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_num_comp = p_j2k->m_image->numcomps; - 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)); + if + (p_header_size != (p_j2k->m_image->numcomps + 2)) + { + opj_event_msg(p_manager, EVT_ERROR, "Crror reading CBD marker\n"); + return false; + } + opj_read_bytes(p_header_data,&l_nb_comp,2); /* Ncbd */ + p_header_data+=2; + if + (l_nb_comp != l_num_comp) + { + opj_event_msg(p_manager, EVT_ERROR, "Crror reading CBD marker\n"); + return false; + } + + l_comp = p_j2k->m_image->comps; + for + (i=0;isgnd = (l_comp_def>>7) & 1; + l_comp->prec = (l_comp_def&0x7f) + 1; + ++l_comp; + } + return true; +} + +/** + * Writes the MCC marker (Multiple Component Collection) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_mcc_record( + opj_j2k_t *p_j2k, + struct opj_simple_mcc_decorrelation_data * p_mcc_record, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + OPJ_UINT32 l_mcc_size; + OPJ_BYTE * l_current_data = 00; + OPJ_UINT32 l_nb_bytes_for_comp; + OPJ_UINT32 l_mask; + OPJ_UINT32 l_tmcc; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); - 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 = cio_read(cio, 2); /* LYEpoc_i */ - poc->resno1 = cio_read(cio, 1); /* 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 */ + if + (p_mcc_record->m_nb_comps > 255 ) + { + l_nb_bytes_for_comp = 2; + l_mask = 0x8000; + } + else + { + l_nb_bytes_for_comp = 1; + l_mask = 0; + } + + l_mcc_size = p_mcc_record->m_nb_comps * 2 * l_nb_bytes_for_comp + 19; + if + (l_mcc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_mcc_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mcc_size; + } + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + opj_write_bytes(l_current_data,J2K_MS_MCC,2); /* MCC */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_mcc_size-2,2); /* Lmcc */ + l_current_data += 2; + + /* first marker */ + opj_write_bytes(l_current_data,0,2); /* Zmcc */ + l_current_data += 2; + opj_write_bytes(l_current_data,p_mcc_record->m_index,1); /* Imcc -> no need for other values, take the first */ + ++l_current_data; + /* only one marker atm */ + opj_write_bytes(l_current_data,0,2); /* Ymcc */ + l_current_data+=2; + opj_write_bytes(l_current_data,1,2); /* Qmcc -> number of collections -> 1 */ + l_current_data+=2; + opj_write_bytes(l_current_data,0x1,1); /* Xmcci type of component transformation -> array based decorrelation */ + ++l_current_data; + + opj_write_bytes(l_current_data,p_mcc_record->m_nb_comps | l_mask,2); /* Nmcci number of input components involved and size for each component offset = 8 bits */ + l_current_data+=2; + + for + (i=0;im_nb_comps;++i) + { + opj_write_bytes(l_current_data,i,l_nb_bytes_for_comp); /* Cmccij Component offset*/ + l_current_data+=l_nb_bytes_for_comp; + } + + opj_write_bytes(l_current_data,p_mcc_record->m_nb_comps|l_mask,2); /* Mmcci number of output components involved and size for each component offset = 8 bits */ + l_current_data+=2; + for + (i=0;im_nb_comps;++i) + { + opj_write_bytes(l_current_data,i,l_nb_bytes_for_comp); /* Wmccij Component offset*/ + l_current_data+=l_nb_bytes_for_comp; + } + l_tmcc = ((!p_mcc_record->m_is_irreversible)&1)<<16; + if + (p_mcc_record->m_decorrelation_array) + { + l_tmcc |= p_mcc_record->m_decorrelation_array->m_index; + } + if + (p_mcc_record->m_offset_array) + { + l_tmcc |= ((p_mcc_record->m_offset_array->m_index)<<8); + } + opj_write_bytes(l_current_data,l_tmcc,3); /* Tmcci : use MCT defined as number 1 and irreversible array based. */ + l_current_data+=3; + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mcc_size,p_manager) != l_mcc_size) + { + return false; + } + return true; +} + + +/** + * Reads a MCC marker (Multiple Component Collection) + * + * @param p_header_data the data contained in the MCC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the MCC marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_mcc ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i,j; + OPJ_UINT32 l_tmp; + OPJ_UINT32 l_indix; + opj_tcp_t * l_tcp; + opj_simple_mcc_decorrelation_data_t * l_mcc_record; + opj_mct_data_t * l_mct_data; + OPJ_UINT32 l_nb_collections; + OPJ_UINT32 l_nb_comps; + OPJ_UINT32 l_nb_bytes_by_comp; + + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH ? &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + + if + (p_header_size < 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); + return false; } - tcp->numpocs = numpchgs + old_poc - 1; -} - -static void j2k_read_crg(opj_j2k_t *j2k) { - int len, i, Xcrg_i, Ycrg_i; - - opj_cio_t *cio = j2k->cio; - int numcomps = j2k->image->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 */ + /* first marker */ + opj_read_bytes(p_header_data,&l_tmp,2); /* Zmcc */ + p_header_data += 2; + if + (l_tmp != 0) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n"); + return true; } -} - -static void j2k_read_tlm(opj_j2k_t *j2k) { - int len, Ztlm, Stlm, ST, SP, tile_tlm, i; - long int Ttlm_i, Ptlm_i; - - opj_cio_t *cio = j2k->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 */ + if + (p_header_size < 7) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); + return false; } -} - -static void j2k_read_plm(opj_j2k_t *j2k) { - int len, i, Zplm, Nplm, add, packet_len = 0; + opj_read_bytes(p_header_data,&l_indix,1); /* Imcc -> no need for other values, take the first */ + ++p_header_data; - opj_cio_t *cio = j2k->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; + l_mcc_record = l_tcp->m_mcc_records; + for + (i=0;im_nb_mcc_records;++i) + { + if + (l_mcc_record->m_index == l_indix) + { + break; + } + ++l_mcc_record; + } + /** NOT FOUND */ + if + (i == l_tcp->m_nb_mcc_records) + { + if + (l_tcp->m_nb_mcc_records == l_tcp->m_nb_max_mcc_records) + { + l_tcp->m_nb_max_mcc_records += J2K_MCC_DEFAULT_NB_RECORDS; + l_tcp->m_mcc_records = opj_realloc(l_tcp->m_mcc_records,l_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t)); + if + (! l_tcp->m_mcc_records) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); + return false; + } + l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records; + memset(l_mcc_record,0,(l_tcp->m_nb_max_mcc_records-l_tcp->m_nb_mcc_records) * sizeof(opj_simple_mcc_decorrelation_data_t)); + } + l_mcc_record = l_tcp->m_mcc_records + l_tcp->m_nb_mcc_records; + } + l_mcc_record->m_index = l_indix; + + /* only one marker atm */ + opj_read_bytes(p_header_data,&l_tmp,2); /* Ymcc */ + p_header_data+=2; + if + (l_tmp != 0) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple data spanning\n"); + return true; + } + opj_read_bytes(p_header_data,&l_nb_collections,2); /* Qmcc -> number of collections -> 1 */ + p_header_data+=2; + if + (l_nb_collections > 1) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple collections\n"); + return true; + } + p_header_size -= 7; + for + (i=0;i array based decorrelation */ + ++p_header_data; + if + (l_tmp != 1) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections other than array decorrelation\n"); + return true; + } + opj_read_bytes(p_header_data,&l_nb_comps,2); + p_header_data+=2; + p_header_size-=3; + l_nb_bytes_by_comp = 1 + (l_nb_comps>>15); + l_mcc_record->m_nb_comps = l_nb_comps & 0x7fff; + if + (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); + return false; + } + p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 2); + for + (j=0;jm_nb_comps;++j) + { + opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp); /* Cmccij Component offset*/ + p_header_data+=l_nb_bytes_by_comp; + if + (l_tmp != j) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n"); + return true; + } + } + opj_read_bytes(p_header_data,&l_nb_comps,2); + p_header_data+=2; + l_nb_bytes_by_comp = 1 + (l_nb_comps>>15); + l_nb_comps &= 0x7fff; + if + (l_nb_comps != l_mcc_record->m_nb_comps) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections without same number of indixes\n"); + return true; + } + if + (p_header_size < (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); + return false; + } + p_header_size -= (l_nb_bytes_by_comp * l_mcc_record->m_nb_comps + 3); + for + (j=0;jm_nb_comps;++j) + { + opj_read_bytes(p_header_data,&l_tmp,l_nb_bytes_by_comp); /* Wmccij Component offset*/ + p_header_data+=l_nb_bytes_by_comp; + if + (l_tmp != j) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge collections with indix shuffle\n"); + return true; + } + } + opj_read_bytes(p_header_data,&l_tmp,3); /* Wmccij Component offset*/ + p_header_data += 3; + l_mcc_record->m_is_irreversible = ! ((l_tmp>>16) & 1); + l_mcc_record->m_decorrelation_array = 00; + l_mcc_record->m_offset_array = 00; + l_indix = l_tmp & 0xff; + if + (l_indix != 0) + { + l_mct_data = l_tcp->m_mct_records; + for + (j=0;jm_nb_mct_records;++j) + { + if + (l_mct_data->m_index == l_indix) + { + l_mcc_record->m_decorrelation_array = l_mct_data; + break; + } + ++l_mct_data; + } + if + (l_mcc_record->m_decorrelation_array == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); + return false; + } + } + l_indix = (l_tmp >> 8) & 0xff; + if + (l_indix != 0) + { + l_mct_data = l_tcp->m_mct_records; + for + (j=0;jm_nb_mct_records;++j) + { + if + (l_mct_data->m_index == l_indix) + { + l_mcc_record->m_offset_array = l_mct_data; + break; + } + ++l_mct_data; + } + if + (l_mcc_record->m_offset_array == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); + return false; } - if (len <= 0) - break; } } + if + (p_header_size != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCC marker\n"); + return false; + } + ++l_tcp->m_nb_mcc_records; + return true; } -static void j2k_read_plt(opj_j2k_t *j2k) { - int len, i, Zplt, packet_len = 0, add; +/** + * Writes the MCT marker (Multiple Component Transform) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_mct_record( + opj_j2k_t *p_j2k, + opj_mct_data_t * p_mct_record, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_mct_size; + OPJ_BYTE * l_current_data = 00; + OPJ_UINT32 l_tmp; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_mct_size = 10 + p_mct_record->m_data_size; + if + (l_mct_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_mct_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mct_size; + } - opj_cio_t *cio = j2k->cio; + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; - 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; + opj_write_bytes(l_current_data,J2K_MS_MCT,2); /* MCT */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_mct_size-2,2); /* Lmct */ + l_current_data += 2; + opj_write_bytes(l_current_data,0,2); /* Zmct */ + l_current_data += 2; + /* only one marker atm */ + l_tmp = (p_mct_record->m_index & 0xff) | (p_mct_record->m_array_type << 8) | (p_mct_record->m_element_type << 10); + opj_write_bytes(l_current_data,l_tmp,2); + l_current_data += 2; + opj_write_bytes(l_current_data,0,2); /* Ymct */ + l_current_data+=2; + + memcpy(l_current_data,p_mct_record->m_data,p_mct_record->m_data_size); + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mct_size,p_manager) != l_mct_size) + { + return false; + } + return true; +} + +/** + * Reads a MCT marker (Multiple Component Transform) + * + * @param p_header_data the data contained in the MCT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the MCT marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_mct ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + opj_tcp_t *l_tcp = 00; + OPJ_UINT32 l_tmp; + OPJ_UINT32 l_indix; + opj_mct_data_t * l_mct_data; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + + l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH ? &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + + if + (p_header_size < 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n"); + return false; + } + /* first marker */ + opj_read_bytes(p_header_data,&l_tmp,2); /* Zmct */ + p_header_data += 2; + if + (l_tmp != 0) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge mct data within multiple MCT records\n"); + return true; + } + if + (p_header_size <= 6) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n"); + return false; + } + opj_read_bytes(p_header_data,&l_tmp,2); /* Imct -> no need for other values, take the first, type is double with decorrelation x0000 1101 0000 0000*/ + p_header_data += 2; + + l_indix = l_tmp & 0xff; + l_mct_data = l_tcp->m_mct_records; + for + (i=0;im_nb_mct_records;++i) + { + if + (l_mct_data->m_index == l_indix) + { + break; + } + ++l_mct_data; + } + /* NOT FOUND */ + if + (i == l_tcp->m_nb_mct_records) + { + if + (l_tcp->m_nb_mct_records == l_tcp->m_nb_max_mct_records) + { + l_tcp->m_nb_max_mct_records += J2K_MCT_DEFAULT_NB_RECORDS; + l_tcp->m_mct_records = opj_realloc(l_tcp->m_mct_records,l_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t)); + if + (! l_tcp->m_mct_records) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n"); + return false; + } + l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records; + memset(l_mct_data ,0,(l_tcp->m_nb_max_mct_records - l_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t)); + } + l_mct_data = l_tcp->m_mct_records + l_tcp->m_nb_mct_records; + } + if + (l_mct_data->m_data) + { + opj_free(l_mct_data->m_data); + l_mct_data->m_data = 00; + } + l_mct_data->m_index = l_indix; + l_mct_data->m_array_type = (l_tmp >> 8) & 3; + l_mct_data->m_element_type = (l_tmp >> 10) & 3; + + opj_read_bytes(p_header_data,&l_tmp,2); /* Ymct */ + p_header_data+=2; + if + (l_tmp != 0) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple MCT markers\n"); + return true; + } + p_header_size -= 6; + l_mct_data->m_data = opj_malloc(p_header_size); + if + (! l_mct_data->m_data) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCT marker\n"); + return false; + } + memcpy(l_mct_data->m_data,p_header_data,p_header_size); + l_mct_data->m_data_size = p_header_size; + ++l_tcp->m_nb_mct_records; + return true; +} + +bool j2k_setup_mct_encoding (opj_tcp_t * p_tcp,opj_image_t * p_image) +{ + OPJ_UINT32 i; + OPJ_UINT32 l_indix = 1; + opj_mct_data_t * l_mct_deco_data = 00,* l_mct_offset_data = 00; + opj_simple_mcc_decorrelation_data_t * l_mcc_data; + OPJ_UINT32 l_mct_size,l_nb_elem; + OPJ_FLOAT32 * l_data, * l_current_data; + opj_tccp_t * l_tccp; + + // preconditions + assert(p_tcp != 00); + + if + (p_tcp->mct != 2) + { + return true; + } + + if + (p_tcp->m_mct_decoding_matrix) + { + if + (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) + { + p_tcp->m_nb_max_mct_records += J2K_MCT_DEFAULT_NB_RECORDS; + p_tcp->m_mct_records = opj_realloc(p_tcp->m_mct_records,p_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t)); + if + (! p_tcp->m_mct_records) + { + return false; + } + l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records; + memset(l_mct_deco_data ,0,(p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t)); + } + l_mct_deco_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records; + + if + (l_mct_deco_data->m_data) + { + opj_free(l_mct_deco_data->m_data); + l_mct_deco_data->m_data = 00; + } + l_mct_deco_data->m_index = l_indix++; + l_mct_deco_data->m_array_type = MCT_TYPE_DECORRELATION; + l_mct_deco_data->m_element_type = MCT_TYPE_FLOAT; + l_nb_elem = p_image->numcomps * p_image->numcomps; + l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_deco_data->m_element_type]; + l_mct_deco_data->m_data = opj_malloc(l_mct_size ); + if + (! l_mct_deco_data->m_data) + { + return false; + } + j2k_mct_write_functions_from_float[l_mct_deco_data->m_element_type](p_tcp->m_mct_decoding_matrix,l_mct_deco_data->m_data,l_nb_elem); + l_mct_deco_data->m_data_size = l_mct_size; + ++p_tcp->m_nb_mct_records; + } + + if + (p_tcp->m_nb_mct_records == p_tcp->m_nb_max_mct_records) + { + p_tcp->m_nb_max_mct_records += J2K_MCT_DEFAULT_NB_RECORDS; + p_tcp->m_mct_records = opj_realloc(p_tcp->m_mct_records,p_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t)); + if + (! p_tcp->m_mct_records) + { + return false; + } + l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records; + memset(l_mct_offset_data ,0,(p_tcp->m_nb_max_mct_records - p_tcp->m_nb_mct_records) * sizeof(opj_mct_data_t)); + if + (l_mct_deco_data) + { + l_mct_deco_data = l_mct_offset_data - 1; } } + l_mct_offset_data = p_tcp->m_mct_records + p_tcp->m_nb_mct_records; + if + (l_mct_offset_data->m_data) + { + opj_free(l_mct_offset_data->m_data); + l_mct_offset_data->m_data = 00; + } + + l_mct_offset_data->m_index = l_indix++; + l_mct_offset_data->m_array_type = MCT_TYPE_OFFSET; + l_mct_offset_data->m_element_type = MCT_TYPE_FLOAT; + l_nb_elem = p_image->numcomps; + l_mct_size = l_nb_elem * MCT_ELEMENT_SIZE[l_mct_offset_data->m_element_type]; + l_mct_offset_data->m_data = opj_malloc(l_mct_size ); + if + (! l_mct_offset_data->m_data) + { + return false; + } + l_data = opj_malloc(l_nb_elem * sizeof(OPJ_FLOAT32)); + if + (! l_data) + { + opj_free(l_mct_offset_data->m_data); + l_mct_offset_data->m_data = 00; + return false; + } + l_tccp = p_tcp->tccps; + l_current_data = l_data; + for + (i=0;im_dc_level_shift); + ++l_tccp; + } + j2k_mct_write_functions_from_float[l_mct_offset_data->m_element_type](l_data,l_mct_offset_data->m_data,l_nb_elem); + opj_free(l_data); + l_mct_offset_data->m_data_size = l_mct_size; + ++p_tcp->m_nb_mct_records; + + if + (p_tcp->m_nb_mcc_records == p_tcp->m_nb_max_mcc_records) + { + p_tcp->m_nb_max_mcc_records += J2K_MCT_DEFAULT_NB_RECORDS; + p_tcp->m_mcc_records = opj_realloc(p_tcp->m_mcc_records,p_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t)); + if + (! p_tcp->m_mcc_records) + { + return false; + } + l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records; + memset(l_mcc_data ,0,(p_tcp->m_nb_max_mcc_records - p_tcp->m_nb_mcc_records) * sizeof(opj_simple_mcc_decorrelation_data_t)); + + } + l_mcc_data = p_tcp->m_mcc_records + p_tcp->m_nb_mcc_records; + l_mcc_data->m_decorrelation_array = l_mct_deco_data; + l_mcc_data->m_is_irreversible = 1; + l_mcc_data->m_nb_comps = p_image->numcomps; + l_mcc_data->m_index = l_indix++; + l_mcc_data->m_offset_array = l_mct_offset_data; + ++p_tcp->m_nb_mcc_records; + return true; } -static void j2k_read_ppm(opj_j2k_t *j2k) { - int len, Z_ppm, i, j; - int N_ppm; +/** + * Writes the MCO marker (Multiple component transformation ordering) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_mco( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_BYTE * l_current_data = 00; + OPJ_UINT32 l_mco_size; + opj_tcp_t * l_tcp = 00; + opj_simple_mcc_decorrelation_data_t * l_mcc_record; + OPJ_UINT32 i; - opj_cp_t *cp = j2k->cp; - opj_cio_t *cio = j2k->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; + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_tcp =&(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]); + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + l_mco_size = 5 + l_tcp->m_nb_mcc_records; + if + (l_mco_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_mco_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; } - 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)); + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_mco_size; + } + + opj_write_bytes(l_current_data,J2K_MS_MCO,2); /* MCO */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_mco_size-2,2); /* Lmco */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_tcp->m_nb_mcc_records,1); /* Nmco : only one tranform stage*/ + ++l_current_data; + + l_mcc_record = l_tcp->m_mcc_records; + for + (i=0;im_nb_mcc_records;++i) + { + opj_write_bytes(l_current_data,l_mcc_record->m_index,1); /* Imco -> use the mcc indicated by 1*/ + ++l_current_data; + ++l_mcc_record; + } + + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_mco_size,p_manager) != l_mco_size) + { + return false; + } + return true; +} +/** + * Reads a MCO marker (Multiple Component Transform Ordering) + * + * @param p_header_data the data contained in the MCO box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the MCO marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_mco ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_tmp, i; + OPJ_UINT32 l_nb_stages; + opj_tcp_t * l_tcp; + opj_tccp_t * l_tccp; + opj_image_t * l_image; + opj_image_comp_t * l_img_comp; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_image = p_j2k->m_image; + l_tcp = p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH ? &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + if + (p_header_size < 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading MCO marker\n"); + return false; + } + + opj_read_bytes(p_header_data,&l_nb_stages,1); /* Nmco : only one tranform stage*/ + ++p_header_data; + if + (l_nb_stages > 1) + { + opj_event_msg(p_manager, EVT_WARNING, "Cannot take in charge multiple transformation stages.\n"); + return true; + } + if + (p_header_size != l_nb_stages + 1) + { + opj_event_msg(p_manager, EVT_WARNING, "Error reading MCO marker\n"); + return false; + } + + l_tccp = l_tcp->tccps; + l_img_comp = l_image->comps; + for + (i=0;inumcomps;++i) + { + l_tccp->m_dc_level_shift = 0; + ++l_tccp; + } + if + (l_tcp->m_mct_decoding_matrix) + { + opj_free(l_tcp->m_mct_decoding_matrix); + l_tcp->m_mct_decoding_matrix = 00; + } + + for + (i=0;im_image,l_tmp)) + { + return false; + } + } + return true; +} + +bool j2k_add_mct(opj_tcp_t * p_tcp,opj_image_t * p_image, OPJ_UINT32 p_index) +{ + OPJ_UINT32 i; + opj_simple_mcc_decorrelation_data_t * l_mcc_record; + opj_mct_data_t * l_deco_array, * l_offset_array; + OPJ_UINT32 l_data_size,l_mct_size, l_offset_size; + OPJ_UINT32 l_nb_elem; + OPJ_UINT32 * l_offset_data, * l_current_offset_data; + opj_tccp_t * l_tccp; + + + // preconditions + assert(p_tcp != 00); + + l_mcc_record = p_tcp->m_mcc_records; + for + (i=0;im_nb_mcc_records;++i) + { + if + (l_mcc_record->m_index == p_index) + { + break; + } + } + if + (i==p_tcp->m_nb_mcc_records) + { + /** element discarded **/ + return true; + } + if + (l_mcc_record->m_nb_comps != p_image->numcomps) + { + /** do not support number of comps != image */ + return true; + } + l_deco_array = l_mcc_record->m_decorrelation_array; + if + (l_deco_array) + { + l_data_size = MCT_ELEMENT_SIZE[l_deco_array->m_element_type] * p_image->numcomps * p_image->numcomps; + if + (l_deco_array->m_data_size != l_data_size) + { + return false; + } + l_nb_elem = p_image->numcomps * p_image->numcomps; + l_mct_size = l_nb_elem * sizeof(OPJ_FLOAT32); + p_tcp->m_mct_decoding_matrix = opj_malloc(l_mct_size); + if + (! p_tcp->m_mct_decoding_matrix ) + { + return false; + } + j2k_mct_read_functions_to_float[l_deco_array->m_element_type](l_deco_array->m_data,p_tcp->m_mct_decoding_matrix,l_nb_elem); + } + l_offset_array = l_mcc_record->m_offset_array; + if + (l_offset_array) + { + l_data_size = MCT_ELEMENT_SIZE[l_offset_array->m_element_type] * p_image->numcomps; + if + (l_offset_array->m_data_size != l_data_size) + { + return false; + } + l_nb_elem = p_image->numcomps; + l_offset_size = l_nb_elem * sizeof(OPJ_UINT32); + l_offset_data = opj_malloc(l_offset_size); + if + (! l_offset_data ) + { + return false; + } + j2k_mct_read_functions_to_int32[l_offset_array->m_element_type](l_offset_array->m_data,l_offset_data,l_nb_elem); + l_tccp = p_tcp->tccps; + l_current_offset_data = l_offset_data; + for + (i=0;inumcomps;++i) + { + l_tccp->m_dc_level_shift = *(l_current_offset_data++); + ++l_tccp; + } + opj_free(l_offset_data); + } + return true; +} + +/** + * Writes the MCT marker (Multiple Component Transform) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_mct_data_group( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + opj_simple_mcc_decorrelation_data_t * l_mcc_record; + opj_mct_data_t * l_mct_record; + opj_tcp_t * l_tcp; + + // preconditions + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + + if + (! j2k_write_cbd(p_j2k,p_stream,p_manager)) + { + return false; + } + l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]); + l_mct_record = l_tcp->m_mct_records; + for + (i=0;im_nb_mct_records;++i) + { + if + (! j2k_write_mct_record(p_j2k,l_mct_record,p_stream,p_manager)) + { + return false; + } + ++l_mct_record; + } + l_mcc_record = l_tcp->m_mcc_records; + for + (i=0;im_nb_mcc_records;++i) + { + if + (! j2k_write_mcc_record(p_j2k,l_mcc_record,p_stream,p_manager)) + { + return false; + } + ++l_mcc_record; + } + if + (! j2k_write_mco(p_j2k,p_stream,p_manager)) + { + return false; + } + return true; +} + + +/** + * Writes the POC marker (Progression Order Change) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_poc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_nb_comp; + OPJ_UINT32 l_nb_poc; + OPJ_UINT32 l_poc_size; + OPJ_UINT32 l_written_size = 0; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; + OPJ_UINT32 l_poc_room; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]; + l_tccp = &l_tcp->tccps[0]; + l_nb_comp = p_j2k->m_image->numcomps; + l_nb_poc = 1 + l_tcp->numpocs; + if + (l_nb_comp <= 256) + { + l_poc_room = 1; + } + else + { + l_poc_room = 2; + } + l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc; + if + (l_poc_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_poc_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_poc_size; + } + + j2k_write_poc_in_memory(p_j2k,p_j2k->m_specific_param.m_encoder.m_header_tile_data,&l_written_size,p_manager); + + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_poc_size,p_manager) != l_poc_size) + { + return false; + } + return true; +} + + +/** + * Writes EPC ???? + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_epc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + opj_codestream_info_t * l_info = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_info = p_j2k->cstr_info; + if + (l_info) + { + l_info->codestream_size = 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_info->codestream_size -= l_info->main_head_start; + /* <correct) { - if (!cp->ppm_data) { - opj_event_msg(j2k->cinfo, EVT_ERROR, - "JPWL: failed memory allocation during PPM marker parsing (pos. %x)\n", - cio_tell(cio)); - if (!JPWL_ASSUME || JPWL_ASSUME) { - opj_free(cp->ppm_data); - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); - return; - } - } + /* + preparation of JPWL marker segments + */ + if(cp->epc_on) { + + /* encode according to JPWL */ + jpwl_encode(p_j2k, p_stream, image); + + } +#endif /* USE_JPWL */ + return true; +} + + +/** + * Gets the maximum size taken by the writting of a POC. + */ +OPJ_UINT32 j2k_get_max_poc_size(opj_j2k_t *p_j2k) +{ + opj_tcp_t * l_tcp = 00; + OPJ_UINT32 l_nb_tiles = 0; + OPJ_UINT32 l_max_poc = 0; + OPJ_UINT32 i; + + l_tcp = p_j2k->m_cp.tcps; + l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; + + for + (i=0;inumpocs); + ++l_tcp; + } + ++l_max_poc; + return 4 + 9 * l_max_poc; +} + + +/** + * Writes the POC marker (Progression Order Change) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +void j2k_write_poc_in_memory( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + OPJ_BYTE * l_current_data = 00; + OPJ_UINT32 l_nb_comp; + OPJ_UINT32 l_nb_poc; + OPJ_UINT32 l_poc_size; + opj_image_t *l_image = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; + opj_poc_t *l_current_poc = 00; + OPJ_UINT32 l_poc_room; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + + l_tcp = &p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]; + l_tccp = &l_tcp->tccps[0]; + l_image = p_j2k->m_image; + l_nb_comp = l_image->numcomps; + l_nb_poc = 1 + l_tcp->numpocs; + if + (l_nb_comp <= 256) + { + l_poc_room = 1; + } + else + { + l_poc_room = 2; + } + l_poc_size = 4 + (5 + 2 * l_poc_room) * l_nb_poc; + + l_current_data = p_data; + + opj_write_bytes(l_current_data,J2K_MS_POC,2); /* POC */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_poc_size-2,2); /* Lpoc */ + l_current_data += 2; + + l_current_poc = l_tcp->pocs; + for + (i = 0; i < l_nb_poc; ++i) + { + opj_write_bytes(l_current_data,l_current_poc->resno0,1); /* RSpoc_i */ + ++l_current_data; + opj_write_bytes(l_current_data,l_current_poc->compno0,l_poc_room); /* CSpoc_i */ + l_current_data+=l_poc_room; + opj_write_bytes(l_current_data,l_current_poc->layno1,2); /* LYEpoc_i */ + l_current_data+=2; + opj_write_bytes(l_current_data,l_current_poc->resno1,1); /* REpoc_i */ + ++l_current_data; + opj_write_bytes(l_current_data,l_current_poc->compno1,l_poc_room); /* CEpoc_i */ + l_current_data+=l_poc_room; + opj_write_bytes(l_current_data,l_current_poc->prg,1); /* Ppoc_i */ + ++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 = int_min(l_current_poc->layno1, l_tcp->numlayers); + l_current_poc->resno1 = int_min(l_current_poc->resno1, l_tccp->numresolutions); + l_current_poc->compno1 = int_min(l_current_poc->compno1, l_nb_comp); + ++l_current_poc; + } + * p_data_written = l_poc_size; +} + + +/** + * Reads a POC marker (Progression Order Change) + * + * @param p_header_data the data contained in the POC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the POC marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_poc ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + OPJ_UINT32 l_nb_comp; + opj_image_t * l_image = 00; + OPJ_UINT32 l_old_poc_nb,l_current_poc_nb,l_current_poc_remaining; + OPJ_UINT32 l_chunk_size; + OPJ_UINT32 l_tmp; + + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_poc_t *l_current_poc = 00; + OPJ_UINT32 l_comp_room; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_image = p_j2k->m_image; + l_nb_comp = l_image->numcomps; + if + (l_nb_comp <= 256) + { + l_comp_room = 1; + } + else + { + l_comp_room = 2; + } + l_chunk_size = 5 + 2 * l_comp_room; + l_current_poc_nb = p_header_size / l_chunk_size; + l_current_poc_remaining = p_header_size % l_chunk_size; + + if + ((l_current_poc_nb <= 0) || (l_current_poc_remaining != 0)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading POC marker\n"); + return false; + } + + l_cp = &(p_j2k->m_cp); + l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH) ? &l_cp->tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + l_old_poc_nb = l_tcp->POC ? l_tcp->numpocs + 1 : 0; + l_current_poc_nb += l_old_poc_nb; + assert(l_current_poc_nb < 32); + + /* now poc is in use.*/ + l_tcp->POC = 1; + + l_current_poc = &l_tcp->pocs[l_old_poc_nb]; + for + (i = l_old_poc_nb; i < l_current_poc_nb; ++i) + { + opj_read_bytes(p_header_data,&(l_current_poc->resno0),1); /* RSpoc_i */ + ++p_header_data; + 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 */ + p_header_data+=2; + opj_read_bytes(p_header_data,&(l_current_poc->resno1),1); /* REpoc_i */ + ++p_header_data; + opj_read_bytes(p_header_data,&(l_current_poc->compno1),l_comp_room); /* CEpoc_i */ + p_header_data+=l_comp_room; + opj_read_bytes(p_header_data,&l_tmp,1); /* Ppoc_i */ + ++p_header_data; + l_current_poc->prg = (OPJ_PROG_ORDER) l_tmp; + /* make sure comp is in acceptable bounds */ + l_current_poc->compno1 = uint_min(l_current_poc->compno1, l_nb_comp); + ++l_current_poc; + } + l_tcp->numpocs = l_current_poc_nb - 1; + return true; +} + +/** + * Writes the RGN marker (Region Of Interest) + * + * @param p_tile_no the tile to output + * @param p_comp_no the component to output + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_rgn( + opj_j2k_t *p_j2k, + OPJ_UINT32 p_tile_no, + OPJ_UINT32 p_comp_no, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_BYTE * l_current_data = 00; + OPJ_UINT32 l_nb_comp; + OPJ_UINT32 l_rgn_size; + opj_image_t *l_image = 00; + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + opj_tccp_t *l_tccp = 00; + OPJ_UINT32 l_comp_room; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_tile_no]; + l_tccp = &l_tcp->tccps[p_comp_no]; + + l_nb_comp = l_image->numcomps; + + if + (l_nb_comp <= 256) + { + l_comp_room = 1; + } + else + { + l_comp_room = 2; + } + l_rgn_size = 6 + l_comp_room; + + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + + opj_write_bytes(l_current_data,J2K_MS_RGN,2); /* RGN */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_rgn_size-2,2); /* Lrgn */ + l_current_data += 2; + opj_write_bytes(l_current_data,p_comp_no,l_comp_room); /* Crgn */ + l_current_data+=l_comp_room; + opj_write_bytes(l_current_data, 0,1); /* Srgn */ + ++l_current_data; + opj_write_bytes(l_current_data, 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) + { + return false; + } + return true; +} + +/** + * Reads a RGN marker (Region Of Interest) + * + * @param p_header_data the data contained in the POC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the POC marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_rgn ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_nb_comp; + opj_image_t * l_image = 00; + + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + OPJ_UINT32 l_comp_room; + OPJ_UINT32 l_comp_no; + OPJ_UINT32 l_roi_sty; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_image = p_j2k->m_image; + l_nb_comp = l_image->numcomps; + if + (l_nb_comp <= 256) + { + l_comp_room = 1; + } + else + { + l_comp_room = 2; + } + if + (p_header_size != 2 + l_comp_room) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading RGN marker\n"); + return false; + } + + l_cp = &(p_j2k->m_cp); + l_tcp = (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_TPH) ? &l_cp->tcps[p_j2k->m_current_tile_number] : p_j2k->m_specific_param.m_decoder.m_default_tcp; + + opj_read_bytes(p_header_data,&l_comp_no,l_comp_room); /* Crgn */ + p_header_data+=l_comp_room; + opj_read_bytes(p_header_data,&l_roi_sty,1); /* Srgn */ + ++p_header_data; + +#ifdef USE_JPWL + if (p_j2k->m_cp->correct) { + /* totlen is negative or larger than the bytes left!!! */ + if (compno >= numcomps) { + opj_event_msg(p_j2k->cinfo, EVT_ERROR, + "JPWL: bad component number in RGN (%d when there are only %d)\n", + compno, numcomps); + if (!JPWL_ASSUME || JPWL_ASSUME) { + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + return; } -#endif - - 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 */ + }; +#endif /* USE_JPWL */ + + opj_read_bytes(p_header_data,(OPJ_UINT32 *) (&(l_tcp->tccps[l_comp_no].roishift)),1); /* SPrgn */ + ++p_header_data; + return true; + +} + +/** + * Writes the TLM marker (Tile Length Marker) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_tlm( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_BYTE * l_current_data = 00; + OPJ_UINT32 l_tlm_size; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_tlm_size = 6 + (5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts); + if + (l_tlm_size > p_j2k->m_specific_param.m_encoder.m_header_tile_data_size) + { + p_j2k->m_specific_param.m_encoder.m_header_tile_data + = opj_realloc( + p_j2k->m_specific_param.m_encoder.m_header_tile_data, + l_tlm_size); + if + (! p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + return false; } - cp->ppm_previous = i - 1; - cp->ppm_store = j; + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = l_tlm_size; } + l_current_data = p_j2k->m_specific_param.m_encoder.m_header_tile_data; + + /* change the way data is written to avoid seeking if possible */ + // TODO + p_j2k->m_specific_param.m_encoder.m_tlm_start = opj_stream_tell(p_stream); + + opj_write_bytes(l_current_data,J2K_MS_TLM,2); /* TLM */ + l_current_data += 2; + opj_write_bytes(l_current_data,l_tlm_size-2,2); /* Lpoc */ + l_current_data += 2; + opj_write_bytes(l_current_data,0,1); /* Ztlm=0*/ + ++l_current_data; + opj_write_bytes(l_current_data,0x50,1); /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */ + ++l_current_data; + /* do nothing on the 5 * l_j2k->m_specific_param.m_encoder.m_total_tile_parts remaining data */ + + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_header_tile_data,l_tlm_size,p_manager) != l_tlm_size) + { + return false; + } + return true; } -static void j2k_read_ppt(opj_j2k_t *j2k) { - int len, Z_ppt, i, j = 0; - - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = cp->tcps + j2k->curtileno; - opj_cio_t *cio = j2k->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; +/** + * Reads a TLM marker (Tile Length Marker) + * + * @param p_header_data the data contained in the TLM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the TLM marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_tlm ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_Ztlm, l_Stlm, l_ST, l_SP, l_tot_num_tp, l_tot_num_tp_remaining, l_quotient, l_Ptlm_size; + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + if + (p_header_size < 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker\n"); + return false; } - j = tcp->ppt_store; - for (i = len - 3; i > 0; i--) { - tcp->ppt_data[j] = cio_read(cio, 1); - j++; + p_header_size -= 2; + + + opj_read_bytes(p_header_data,&l_Ztlm,1); /* Ztlm */ + ++p_header_data; + opj_read_bytes(p_header_data,&l_Stlm,1); /* Stlm */ + ++p_header_data; + + l_ST = ((l_Stlm >> 4) & 0x3); + l_SP = (l_Stlm >> 6) & 0x1; + + l_Ptlm_size = (l_SP + 1) * 2; + l_quotient = l_Ptlm_size + l_ST; + + l_tot_num_tp = p_header_size / l_quotient; + l_tot_num_tp_remaining = p_header_size % l_quotient; + if + (l_tot_num_tp_remaining != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading TLM marker\n"); + return false; } - tcp->ppt_store = j; + /* Do not care of this at the moment since only local variables are set here */ + /* + for + (i = 0; i < l_tot_num_tp; ++i) + { + opj_read_bytes(p_header_data,&l_Ttlm_i,l_ST); // Ttlm_i + p_header_data += l_ST; + opj_read_bytes(p_header_data,&l_Ptlm_i,l_Ptlm_size); // Ptlm_i + p_header_data += l_Ptlm_size; + }*/ + return true; } -static void j2k_write_tlm(opj_j2k_t *j2k){ - int lenp; - opj_cio_t *cio = j2k->cio; - j2k->tlm_start = cio_tell(cio); - cio_write(cio, J2K_MS_TLM, 2);/* TLM */ - lenp = 4 + (5*j2k->totnum_tp); - cio_write(cio,lenp,2); /* Ltlm */ - cio_write(cio, 0,1); /* Ztlm=0*/ - cio_write(cio,80,1); /* Stlm ST=1(8bits-255 tiles max),SP=1(Ptlm=32bits) */ - cio_skip(cio,5*j2k->totnum_tp); +/** + * Reads a CRG marker (Component registration) + * + * @param p_header_data the data contained in the TLM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the TLM marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_crg ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_nb_comp; + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + l_nb_comp = p_j2k->m_image->numcomps; + + if + (p_header_size != l_nb_comp *4) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading CRG marker\n"); + return false; + } + /* Do not care of this at the moment since only local variables are set here */ + /* + for + (i = 0; i < l_nb_comp; ++i) + { + opj_read_bytes(p_header_data,&l_Xcrg_i,2); // Xcrg_i + p_header_data+=2; + opj_read_bytes(p_header_data,&l_Ycrg_i,2); // Xcrg_i + p_header_data+=2; + } + */ + return true; } -static void j2k_write_sot(opj_j2k_t *j2k) { - int lenp, len; +/** + * Reads a PLM marker (Packet length, main header marker) + * + * @param p_header_data the data contained in the TLM box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the TLM marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_plm ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + if + (p_header_size < 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n"); + return false; + } + /* Do not care of this at the moment since only local variables are set here */ + /* + opj_read_bytes(p_header_data,&l_Zplm,1); // Zplm + ++p_header_data; + --p_header_size; - opj_cio_t *cio = j2k->cio; + while + (p_header_size > 0) + { + opj_read_bytes(p_header_data,&l_Nplm,1); // Nplm + ++p_header_data; + p_header_size -= (1+l_Nplm); + if + (p_header_size < 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n"); + return false; + } + for + (i = 0; i < l_Nplm; ++i) + { + opj_read_bytes(p_header_data,&l_tmp,1); // Iplm_ij + ++p_header_data; + // take only the last seven bytes + l_packet_len |= (l_tmp & 0x7f); + if + (l_tmp & 0x80) + { + l_packet_len <<= 7; + } + else + { + // store packet length and proceed to next packet + l_packet_len = 0; + } + } + if + (l_packet_len != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n"); + return false; + } + } + */ + return true; +} - j2k->sot_start = cio_tell(cio); - cio_write(cio, J2K_MS_SOT, 2); /* SOT */ - lenp = cio_tell(cio); - cio_skip(cio, 2); /* Lsot (further) */ - cio_write(cio, j2k->curtileno, 2); /* Isot */ - cio_skip(cio, 4); /* Psot (further in j2k_write_sod) */ - cio_write(cio, j2k->cur_tp_num , 1); /* TPsot */ - cio_write(cio, j2k->cur_totnum_tp[j2k->curtileno], 1); /* TNsot */ - len = cio_tell(cio) - lenp; - cio_seek(cio, lenp); - cio_write(cio, len, 2); /* Lsot */ - cio_seek(cio, lenp + len); +/** + * Reads a PLT marker (Packet length, tile-part header) + * + * @param p_header_data the data contained in the PLT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the PLT marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_plt ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_Zplt, l_tmp, l_packet_len = 0, i; + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + if + (p_header_size < 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n"); + return false; + } + + opj_read_bytes(p_header_data,&l_Zplt,1); // Zplt + ++p_header_data; + --p_header_size; + for + (i = 0; i < p_header_size; ++i) + { + opj_read_bytes(p_header_data,&l_tmp,1); // Iplm_ij + ++p_header_data; + // take only the last seven bytes + l_packet_len |= (l_tmp & 0x7f); + if + (l_tmp & 0x80) + { + l_packet_len <<= 7; + } + else + { + // store packet length and proceed to next packet + l_packet_len = 0; + } + } + if + (l_packet_len != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PLM marker\n"); + return false; + } + return true; +} + +/** + * Reads a PPM marker (Packed packet headers, main header) + * + * @param p_header_data the data contained in the POC box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the POC marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_ppm ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + + opj_cp_t *l_cp = 00; + OPJ_UINT32 l_remaining_data, l_Z_ppm, l_N_ppm; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + if + (p_header_size < 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading RGN marker\n"); + return false; + } + l_cp = &(p_j2k->m_cp); + l_cp->ppm = 1; + + opj_read_bytes(p_header_data,&l_Z_ppm,1); /* Z_ppm */ + ++p_header_data; + --p_header_size; + + // first PPM marker + if + (l_Z_ppm == 0) + { + if + (p_header_size < 4) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PPM marker\n"); + return false; + } + // read a N_ppm + opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm */ + p_header_data+=4; + p_header_size-=4; + /* First PPM marker */ + l_cp->ppm_len = l_N_ppm; + l_cp->ppm_data_size = 0; + l_cp->ppm_buffer = (OPJ_BYTE *) opj_malloc(l_cp->ppm_len); + l_cp->ppm_data = l_cp->ppm_buffer; + if + (l_cp->ppm_buffer == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n"); + return false; + } + memset(l_cp->ppm_buffer,0,l_cp->ppm_len); + } + + while + (true) + { + if + (l_cp->ppm_data_size == l_cp->ppm_len) + { + if + (p_header_size >= 4) + { + // read a N_ppm + opj_read_bytes(p_header_data,&l_N_ppm,4); /* N_ppm */ + p_header_data+=4; + p_header_size-=4; + l_cp->ppm_len += l_N_ppm ; + l_cp->ppm_buffer = (OPJ_BYTE *) opj_realloc(l_cp->ppm_buffer, l_cp->ppm_len); + l_cp->ppm_data = l_cp->ppm_buffer; + if + (l_cp->ppm_buffer == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading ppm marker\n"); + return false; + } + memset(l_cp->ppm_buffer+l_cp->ppm_data_size,0,l_N_ppm); + } + else + { + return false; + } + } + l_remaining_data = l_cp->ppm_len - l_cp->ppm_data_size; + if + (l_remaining_data <= p_header_size) + { + /* we must store less information than available in the packet */ + memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , l_remaining_data); + l_cp->ppm_data_size = l_cp->ppm_len; + p_header_size -= l_remaining_data; + p_header_data += l_remaining_data; + } + else + { + memcpy(l_cp->ppm_buffer + l_cp->ppm_data_size , p_header_data , p_header_size); + l_cp->ppm_data_size += p_header_size; + p_header_data += p_header_size; + p_header_size = 0; + break; + } + } + return true; +} + +/** + * Reads a PPT marker (Packed packet headers, tile-part header) + * + * @param p_header_data the data contained in the PPT box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the PPT marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_ppt ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_header_data, + OPJ_UINT32 p_header_size, + struct opj_event_mgr * p_manager + ) +{ + + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + OPJ_UINT32 l_Z_ppt; + + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + if + (p_header_size < 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading PPT marker\n"); + return false; + } + + l_cp = &(p_j2k->m_cp); + l_tcp = &(l_cp->tcps[p_j2k->m_current_tile_number]); + l_tcp->ppt = 1; + + opj_read_bytes(p_header_data,&l_Z_ppt,1); /* Z_ppt */ + ++p_header_data; + --p_header_size; + + // first PPM marker + if + (l_Z_ppt == 0) + { + /* First PPM marker */ + l_tcp->ppt_len = p_header_size; + l_tcp->ppt_data_size = 0; + l_tcp->ppt_buffer = (OPJ_BYTE *) opj_malloc(l_tcp->ppt_len); + l_tcp->ppt_data = l_tcp->ppt_buffer; + if + (l_tcp->ppt_buffer == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading PPT marker\n"); + return false; + } + memset(l_tcp->ppt_buffer,0,l_tcp->ppt_len); + } + else + { + l_tcp->ppt_len += p_header_size; + l_tcp->ppt_buffer = (OPJ_BYTE *) opj_realloc(l_tcp->ppt_buffer,l_tcp->ppt_len); + if + (l_tcp->ppt_buffer == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory reading PPT marker\n"); + return false; + } + l_tcp->ppt_data = l_tcp->ppt_buffer; + memset(l_tcp->ppt_buffer+l_tcp->ppt_data_size,0,p_header_size); + } + memcpy(l_tcp->ppt_buffer+l_tcp->ppt_data_size,p_header_data,p_header_size); + l_tcp->ppt_data_size += p_header_size; + return true; +} + +/** + * Writes the SOT marker (Start of tile-part) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_sot( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + const struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + opj_write_bytes(p_data,J2K_MS_SOT,2); /* SOT */ + p_data += 2; + + opj_write_bytes(p_data,10,2); /* Lsot */ + p_data += 2; + + opj_write_bytes(p_data, p_j2k->m_current_tile_number,2); /* Isot */ + p_data += 2; + + /* Psot */ + p_data += 4; + + opj_write_bytes(p_data, p_j2k->m_specific_param.m_encoder.m_current_tile_part_number,1); /* TPsot */ + ++p_data; + + opj_write_bytes(p_data, p_j2k->m_cp.tcps[p_j2k->m_current_tile_number].m_nb_tile_parts,1); /* TNsot */ + ++p_data; /* UniPG>> */ #ifdef USE_JPWL /* update markers struct */ - j2k_add_marker(j2k->cstr_info, J2K_MS_SOT, j2k->sot_start, len + 2); + j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOT, p_j2k->sot_start, len + 2); #endif /* USE_JPWL */ - /* <cp; - opj_cio_t *cio = j2k->cio; + opj_cp_t *l_cp = 00; + opj_tcp_t *l_tcp = 00; + OPJ_UINT32 l_tot_len, l_num_parts = 0; + OPJ_UINT32 l_current_part; + OPJ_UINT32 l_tile_x,l_tile_y; - len = cio_read(cio, 2); - tileno = cio_read(cio, 2); + // preconditions + assert(p_header_data != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + if + (p_header_size != 8) + { + opj_event_msg(p_manager, EVT_ERROR, "Error reading SOT marker\n"); + return false; + } + l_cp = &(p_j2k->m_cp); + opj_read_bytes(p_header_data,&(p_j2k->m_current_tile_number),2); /* Isot */ + p_header_data+=2; + + + 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; #ifdef USE_JPWL - if (j2k->cp->correct) { + if (p_j2k->m_cp->correct) { static int backup_tileno = 0; /* tileno is negative or larger than the number of tiles!!! */ if ((tileno < 0) || (tileno > (cp->tw * cp->th))) { - opj_event_msg(j2k->cinfo, EVT_ERROR, + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: bad tile number (%d out of a maximum of %d)\n", tileno, (cp->tw * cp->th)); if (!JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } /* we try to correct */ tileno = backup_tileno; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" "- setting tile number to %d\n", tileno); } @@ -1309,38 +5902,28 @@ static void j2k_read_sot(opj_j2k_t *j2k) { }; #endif /* USE_JPWL */ - 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); + /* look for the tile in the list of already processed tile (in parts). */ + /* Optimization possible here with a more complex data structure and with the removing of tiles */ + /* since the time taken by this function can only grow at the time */ + + opj_read_bytes(p_header_data,&l_tot_len,4); /* Psot */ + p_header_data+=4; #ifdef USE_JPWL - if (j2k->cp->correct) { + if (p_j2k->m_cp->correct) { /* totlen is negative or larger than the bytes left!!! */ - if ((totlen < 0) || (totlen > (cio_numbytesleft(cio) + 8))) { - opj_event_msg(j2k->cinfo, EVT_ERROR, + if ((totlen < 0) || (totlen > (p_stream_numbytesleft(p_stream) + 8))) { + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: bad tile byte size (%d bytes against %d bytes left)\n", - totlen, cio_numbytesleft(cio) + 8); + totlen, p_stream_numbytesleft(p_stream) + 8); if (!JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); return; } /* we try to correct */ totlen = 0; - opj_event_msg(j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" + opj_event_msg(p_j2k->cinfo, EVT_WARNING, "- trying to adjust this\n" "- setting Psot to %d => assuming it is the last tile\n", totlen); } @@ -1348,316 +5931,866 @@ static void j2k_read_sot(opj_j2k_t *j2k) { }; #endif /* USE_JPWL */ - if (!totlen) - totlen = cio_numbytesleft(cio) + 8; - - partno = cio_read(cio, 1); - numparts = cio_read(cio, 1); - - j2k->curtileno = tileno; - j2k->cur_tp_num = partno; - j2k->eot = cio_getbp(cio) - 12 + totlen; - j2k->state = J2K_STATE_TPH; - tcp = &cp->tcps[j2k->curtileno]; + if + (!l_tot_len) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot read data with no size known, giving up\n"); + return false; + } + opj_read_bytes(p_header_data,&l_current_part ,1); /* Psot */ + ++p_header_data; + + opj_read_bytes(p_header_data,&l_num_parts ,1); /* Psot */ + ++p_header_data; + + if + (l_num_parts != 0) + { + l_tcp->m_nb_tile_parts = l_num_parts; + } + if + (l_tcp->m_nb_tile_parts) + { + if + (l_tcp->m_nb_tile_parts == (l_current_part + 1)) + { + p_j2k->m_specific_param.m_decoder.m_can_decode = 1; + } + } + p_j2k->m_specific_param.m_decoder.m_sot_length = l_tot_len - 12; + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_TPH; + p_j2k->m_specific_param.m_decoder.m_skip_data = + (l_tile_x < p_j2k->m_specific_param.m_decoder.m_start_tile_x) + || (l_tile_x >= p_j2k->m_specific_param.m_decoder.m_end_tile_x) + || (l_tile_y < p_j2k->m_specific_param.m_decoder.m_start_tile_y) + || (l_tile_y >= p_j2k->m_specific_param.m_decoder.m_end_tile_y); /* Index */ - if (j2k->cstr_info) { - if (tcp->first) { - if (tileno == 0) - j2k->cstr_info->main_head_end = cio_tell(cio) - 13; - j2k->cstr_info->tile[tileno].tileno = tileno; - j2k->cstr_info->tile[tileno].start_pos = cio_tell(cio) - 12; - j2k->cstr_info->tile[tileno].end_pos = j2k->cstr_info->tile[tileno].start_pos + totlen - 1; - j2k->cstr_info->tile[tileno].num_tps = numparts; - if (numparts) - j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t)); - else - j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10) - } - else { - j2k->cstr_info->tile[tileno].end_pos += totlen; - } - j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = cio_tell(cio) - 12; - j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos = - j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1; - } - if (tcp->first == 1) { - /* Initialization PPT */ - opj_tccp_t *tmp = tcp->tccps; - memcpy(tcp, j2k->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 < j2k->image->numcomps; i++) { - tcp->tccps[i] = j2k->default_tcp->tccps[i]; + /* move this onto a separate method to call before reading any SOT */ + /*if + TODO + (p_j2k->cstr_info) + { + if + (l_tcp->first) + { + if + (tileno == 0) + { + p_j2k->cstr_info->main_head_end = p_stream_tell(p_stream) - 13; + } + p_j2k->cstr_info->tile[tileno].tileno = tileno; + p_j2k->cstr_info->tile[tileno].start_pos = p_stream_tell(p_stream) - 12; + p_j2k->cstr_info->tile[tileno].end_pos = p_j2k->cstr_info->tile[tileno].start_pos + totlen - 1; + p_j2k->cstr_info->tile[tileno].num_tps = numparts; + if + (numparts) + { + p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(numparts * sizeof(opj_tp_info_t)); + } + else + { + p_j2k->cstr_info->tile[tileno].tp = (opj_tp_info_t *) opj_malloc(10 * sizeof(opj_tp_info_t)); // Fixme (10) + } } - cp->tcps[j2k->curtileno].first = 0; - } + else + { + p_j2k->cstr_info->tile[tileno].end_pos += totlen; + } + p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos = p_stream_tell(p_stream) - 12; + p_j2k->cstr_info->tile[tileno].tp[partno].tp_end_pos = + p_j2k->cstr_info->tile[tileno].tp[partno].tp_start_pos + totlen - 1; + }*/ + return true; } -static void j2k_write_sod(opj_j2k_t *j2k, void *tile_coder) { - int l, layno; - int totlen; - opj_tcp_t *tcp = NULL; - opj_codestream_info_t *cstr_info = NULL; - - opj_tcd_t *tcd = (opj_tcd_t*)tile_coder; /* cast is needed because of conflicts in header inclusions */ - opj_cp_t *cp = j2k->cp; - opj_cio_t *cio = j2k->cio; +/** + * Writes the SOD marker (Start of data) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_sod( + opj_j2k_t *p_j2k, + struct opj_tcd * p_tile_coder, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + OPJ_UINT32 p_total_data_size, + const struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + opj_tcp_t *l_tcp = 00; + opj_codestream_info_t *l_cstr_info = 00; + opj_cp_t *l_cp = 00; - tcd->tp_num = j2k->tp_num ; - tcd->cur_tp_num = j2k->cur_tp_num; - - cio_write(cio, J2K_MS_SOD, 2); - if (j2k->curtileno == 0) { - j2k->sod_start = cio_tell(cio) + j2k->pos_correction; - } + OPJ_UINT32 l_size_tile; + OPJ_UINT32 l_remaining_data; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + opj_write_bytes(p_data,J2K_MS_SOD,2); /* SOD */ + p_data += 2; + + /* make room for the EOF marker */ + l_remaining_data = p_total_data_size - 4; + + l_cp = &(p_j2k->m_cp); + l_tcp = &l_cp->tcps[p_j2k->m_current_tile_number]; + l_cstr_info = p_j2k->cstr_info; + + /* update tile coder */ + p_tile_coder->tp_num = p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number ; + p_tile_coder->cur_tp_num = p_j2k->m_specific_param.m_encoder.m_current_tile_part_number; + l_size_tile = l_cp->th * l_cp->tw; /* INDEX >> */ - cstr_info = j2k->cstr_info; - if (cstr_info) { - if (!j2k->cur_tp_num ) { - cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; - j2k->cstr_info->tile[j2k->curtileno].tileno = j2k->curtileno; + if + (l_cstr_info) + { + if + (!p_j2k->m_specific_param.m_encoder.m_current_tile_part_number ) + { + //TODO cstr_info->tile[p_j2k->m_current_tile_number].end_header = p_stream_tell(p_stream) + p_j2k->pos_correction - 1; + l_cstr_info->tile[p_j2k->m_current_tile_number].tileno = p_j2k->m_current_tile_number; } - else{ - if(cstr_info->tile[j2k->curtileno].packet[cstr_info->packno - 1].end_pos < cio_tell(cio)) - cstr_info->tile[j2k->curtileno].packet[cstr_info->packno].start_pos = cio_tell(cio); + else + { + /* + TODO + if + (cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno - 1].end_pos < p_stream_tell(p_stream)) + { + cstr_info->tile[p_j2k->m_current_tile_number].packet[cstr_info->packno].start_pos = p_stream_tell(p_stream); + }*/ + } /* UniPG>> */ #ifdef USE_JPWL /* update markers struct */ - j2k_add_marker(j2k->cstr_info, J2K_MS_SOD, j2k->sod_start, 2); + j2k_add_marker(p_j2k->cstr_info, J2K_MS_SOD, p_j2k->sod_start, 2); #endif /* USE_JPWL */ /* <tcps[j2k->curtileno]; - for (layno = 0; layno < tcp->numlayers; layno++) { - if (tcp->rates[layno]>(j2k->sod_start / (cp->th * cp->tw))) { - tcp->rates[layno]-=(j2k->sod_start / (cp->th * cp->tw)); - } else if (tcp->rates[layno]) { - tcp->rates[layno]=1; + if + (p_j2k->m_specific_param.m_encoder.m_current_tile_part_number == 0) + { + p_tile_coder->tcd_image->tiles->packno = 0; + if + (l_cstr_info) + { + l_cstr_info->packno = 0; } } - if(j2k->cur_tp_num == 0){ - tcd->tcd_image->tiles->packno = 0; - if(cstr_info) - cstr_info->packno = 0; + *p_data_written = 0; + if + (! tcd_encode_tile(p_tile_coder, p_j2k->m_current_tile_number, p_data, p_data_written, l_remaining_data , l_cstr_info)) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot encode tile\n"); + return false; } - - l = tcd_encode_tile(tcd, j2k->curtileno, cio_getbp(cio), cio_numbytesleft(cio) - 2, cstr_info); - - /* Writing Psot in SOT marker */ - totlen = cio_tell(cio) + l - j2k->sot_start; - cio_seek(cio, j2k->sot_start + 6); - cio_write(cio, totlen, 4); - cio_seek(cio, j2k->sot_start + totlen); - /* Writing Ttlm and Ptlm in TLM marker */ - if(cp->cinema){ - cio_seek(cio, j2k->tlm_start + 6 + (5*j2k->cur_tp_num)); - cio_write(cio, j2k->curtileno, 1); - cio_write(cio, totlen, 4); - } - cio_seek(cio, j2k->sot_start + totlen); + *p_data_written += 2; + return true; } -static void j2k_read_sod(opj_j2k_t *j2k) { - int len, truncate = 0, i; - unsigned char *data = NULL, *data_ptr = NULL; +/** + * Updates the Tile Length Marker. + */ +void j2k_update_tlm ( + opj_j2k_t * p_j2k, + OPJ_UINT32 p_tile_part_size + ) +{ + opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_j2k->m_current_tile_number,1); /* PSOT */ + ++p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current; + opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current,p_tile_part_size,4); /* PSOT */ + p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current += 4; +} - opj_cio_t *cio = j2k->cio; - int curtileno = j2k->curtileno; + +/** + * Reads a SOD marker (Start Of Data) + * + * @param p_header_data the data contained in the SOD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the SOD marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_sod ( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_current_read_size; + opj_codestream_info_t * l_cstr_info = 00; + OPJ_BYTE ** l_current_data = 00; + opj_tcp_t * l_tcp = 00; + OPJ_UINT32 * l_tile_len = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_tcp = &(p_j2k->m_cp.tcps[p_j2k->m_current_tile_number]); + p_j2k->m_specific_param.m_decoder.m_sot_length -= 2; + l_cstr_info = p_j2k->cstr_info; + + l_current_data = &(l_tcp->m_data); + l_tile_len = &l_tcp->m_data_size; + + if + (! *l_current_data) + { + *l_current_data = (OPJ_BYTE*) my_opj_malloc(p_j2k->m_specific_param.m_decoder.m_sot_length); + } + else + { + *l_current_data = (OPJ_BYTE*) my_opj_realloc(*l_current_data, *l_tile_len + p_j2k->m_specific_param.m_decoder.m_sot_length); + } + if + (*l_current_data == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile\n"); + return false; + } /* Index */ - if (j2k->cstr_info) { - j2k->cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header = - cio_tell(cio) + j2k->pos_correction - 1; - if (j2k->cur_tp_num == 0) - j2k->cstr_info->tile[j2k->curtileno].end_header = cio_tell(cio) + j2k->pos_correction - 1; - j2k->cstr_info->packno = 0; - } - - len = int_min(j2k->eot - cio_getbp(cio), cio_numbytesleft(cio) + 1); - - if (len == cio_numbytesleft(cio) + 1) { - truncate = 1; /* Case of a truncate codestream */ - } - - data = j2k->tile_data[curtileno]; - data = (unsigned char*) opj_realloc(data, (j2k->tile_len[curtileno] + len) * sizeof(unsigned char)); - - data_ptr = data + j2k->tile_len[curtileno]; - for (i = 0; i < len; i++) { - data_ptr[i] = cio_read(cio, 1); - } - - j2k->tile_len[curtileno] += len; - j2k->tile_data[curtileno] = data; - - if (!truncate) { - j2k->state = J2K_STATE_TPHSOT; - } else { - j2k->state = J2K_STATE_NEOC; /* RAJOUTE !! */ - } - j2k->cur_tp_num++; -} - -static void j2k_write_rgn(opj_j2k_t *j2k, int compno, int tileno) { - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = &cp->tcps[tileno]; - opj_cio_t *cio = j2k->cio; - int numcomps = j2k->image->numcomps; - - cio_write(cio, J2K_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 j2k_read_rgn(opj_j2k_t *j2k) { - int len, compno, roisty; - - opj_cp_t *cp = j2k->cp; - opj_tcp_t *tcp = j2k->state == J2K_STATE_TPH ? &cp->tcps[j2k->curtileno] : j2k->default_tcp; - opj_cio_t *cio = j2k->cio; - int numcomps = j2k->image->numcomps; - - len = cio_read(cio, 2); /* Lrgn */ - compno = cio_read(cio, numcomps <= 256 ? 1 : 2); /* Crgn */ - roisty = cio_read(cio, 1); /* Srgn */ - -#ifdef USE_JPWL - if (j2k->cp->correct) { - /* totlen is negative or larger than the bytes left!!! */ - if (compno >= numcomps) { - opj_event_msg(j2k->cinfo, EVT_ERROR, - "JPWL: bad component number in RGN (%d when there are only %d)\n", - compno, numcomps); - if (!JPWL_ASSUME || JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "JPWL: giving up\n"); - return; - } + if + (l_cstr_info) + { + OPJ_SIZE_T l_current_pos = opj_stream_tell(p_stream)-1; + l_cstr_info->tile[p_j2k->m_current_tile_number].tp[p_j2k->m_specific_param.m_encoder.m_current_tile_part_number].tp_end_header = l_current_pos; + if + (p_j2k->m_specific_param.m_encoder.m_current_tile_part_number == 0) + { + l_cstr_info->tile[p_j2k->m_current_tile_number].end_header = l_current_pos; } - }; -#endif /* USE_JPWL */ - - tcp->tccps[compno].roishift = cio_read(cio, 1); /* SPrgn */ + l_cstr_info->packno = 0; + } + l_current_read_size = opj_stream_read_data(p_stream, *l_current_data + *l_tile_len , p_j2k->m_specific_param.m_decoder.m_sot_length,p_manager); + if + (l_current_read_size != p_j2k->m_specific_param.m_decoder.m_sot_length) + { + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_NEOC; + } + else + { + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_TPHSOT; + } + *l_tile_len += l_current_read_size; + return true; } -static void j2k_write_eoc(opj_j2k_t *j2k) { - opj_cio_t *cio = j2k->cio; - /* opj_event_msg(j2k->cinfo, "%.8x: EOC\n", cio_tell(cio) + j2k->pos_correction); */ - cio_write(cio, J2K_MS_EOC, 2); +/** + * Writes the EOC marker (End of Codestream) + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_eoc( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + opj_write_bytes(p_j2k->m_specific_param.m_encoder.m_header_tile_data,J2K_MS_EOC,2); /* EOC */ + /* UniPG>> */ #ifdef USE_JPWL /* update markers struct */ - j2k_add_marker(j2k->cstr_info, J2K_MS_EOC, cio_tell(cio) - 2, 2); + j2k_add_marker(p_j2k->cstr_info, J2K_MS_EOC, p_stream_tell(p_stream) - 2, 2); #endif /* USE_JPWL */ -/* <m_specific_param.m_encoder.m_header_tile_data,2,p_manager) != 2) + { + return false; + } + if + (! opj_stream_flush(p_stream,p_manager)) + { + return false; + } + return true; } -static void j2k_read_eoc(opj_j2k_t *j2k) { - int i, tileno; - bool success; - /* if packets should be decoded */ - if (j2k->cp->limit_decoding != DECODE_ALL_BUT_PACKETS) { - opj_tcd_t *tcd = tcd_create(j2k->cinfo); - tcd_malloc_decode(tcd, j2k->image, j2k->cp); - for (i = 0; i < j2k->cp->tileno_size; i++) { - tcd_malloc_decode_tile(tcd, j2k->image, j2k->cp, i, j2k->cstr_info); - tileno = j2k->cp->tileno[i]; - success = tcd_decode_tile(tcd, j2k->tile_data[tileno], j2k->tile_len[tileno], tileno, j2k->cstr_info); - opj_free(j2k->tile_data[tileno]); - j2k->tile_data[tileno] = NULL; - tcd_free_decode_tile(tcd, i); - if (success == false) { - j2k->state |= J2K_STATE_ERR; +/** + * Inits the Info + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_init_info( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + opj_codestream_info_t * l_cstr_info = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + l_cstr_info = p_j2k->cstr_info; + + if + (l_cstr_info) + { + OPJ_UINT32 compno; + l_cstr_info->tile = (opj_tile_info_t *) opj_malloc(p_j2k->m_cp.tw * p_j2k->m_cp.th * sizeof(opj_tile_info_t)); + l_cstr_info->image_w = p_j2k->m_image->x1 - p_j2k->m_image->x0; + l_cstr_info->image_h = p_j2k->m_image->y1 - p_j2k->m_image->y0; + l_cstr_info->prog = (&p_j2k->m_cp.tcps[0])->prg; + l_cstr_info->tw = p_j2k->m_cp.tw; + l_cstr_info->th = p_j2k->m_cp.th; + l_cstr_info->tile_x = p_j2k->m_cp.tdx; /* new version parser */ + l_cstr_info->tile_y = p_j2k->m_cp.tdy; /* new version parser */ + l_cstr_info->tile_Ox = p_j2k->m_cp.tx0; /* new version parser */ + l_cstr_info->tile_Oy = p_j2k->m_cp.ty0; /* new version parser */ + l_cstr_info->numcomps = p_j2k->m_image->numcomps; + l_cstr_info->numlayers = (&p_j2k->m_cp.tcps[0])->numlayers; + l_cstr_info->numdecompos = (OPJ_INT32*) opj_malloc(p_j2k->m_image->numcomps * sizeof(OPJ_INT32)); + for (compno=0; compno < p_j2k->m_image->numcomps; compno++) { + l_cstr_info->numdecompos[compno] = (&p_j2k->m_cp.tcps[0])->tccps->numresolutions - 1; + } + l_cstr_info->D_max = 0.0; /* ADD Marcela */ + l_cstr_info->main_head_start = opj_stream_tell(p_stream); /* position of SOC */ + l_cstr_info->maxmarknum = 100; + l_cstr_info->marker = (opj_marker_info_t *) opj_malloc(l_cstr_info->maxmarknum * sizeof(opj_marker_info_t)); + l_cstr_info->marknum = 0; + } + return j2k_calculate_tp(p_j2k,&(p_j2k->m_cp),&p_j2k->m_specific_param.m_encoder.m_total_tile_parts,p_j2k->m_image,p_manager); +} + +/** + * Creates a tile-coder decoder. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_create_tcd( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + p_j2k->m_tcd = tcd_create(false); + if + (! p_j2k->m_tcd) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to create Tile Coder\n"); + return false; + } + if + (! tcd_init(p_j2k->m_tcd,p_j2k->m_image,&p_j2k->m_cp)) + { + tcd_destroy(p_j2k->m_tcd); + p_j2k->m_tcd = 00; + return false; + } + return true; +} + +OPJ_FLOAT32 get_tp_stride (opj_tcp_t * p_tcp) +{ + return (OPJ_FLOAT32) ((p_tcp->m_nb_tile_parts - 1) * 14); +} + +OPJ_FLOAT32 get_default_stride (opj_tcp_t * p_tcp) +{ + return 0; +} + +/** + * Updates the rates of the tcp. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_update_rates( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + opj_cp_t * l_cp = 00; + opj_image_t * l_image = 00; + opj_tcp_t * l_tcp = 00; + opj_image_comp_t * l_img_comp = 00; + + OPJ_UINT32 i,j,k; + OPJ_INT32 l_x0,l_y0,l_x1,l_y1; + OPJ_FLOAT32 * l_rates = 0; + OPJ_FLOAT32 l_sot_remove; + OPJ_UINT32 l_bits_empty, l_size_pixel; + OPJ_UINT32 l_tile_size = 0; + OPJ_UINT32 l_last_res; + OPJ_FLOAT32 (* l_tp_stride_func)(opj_tcp_t *) = 00; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + + l_cp = &(p_j2k->m_cp); + l_image = p_j2k->m_image; + l_tcp = l_cp->tcps; + + 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); + + if + (l_cp->m_specific_param.m_enc.m_tp_on) + { + l_tp_stride_func = get_tp_stride; + } + else + { + l_tp_stride_func = get_default_stride; + } + + for + (i=0;ith;++i) + { + for + (j=0;jtw;++j) + { + OPJ_FLOAT32 l_offset = ((*l_tp_stride_func)(l_tcp)) / l_tcp->numlayers; + /* 4 borders of the tile rescale on the image if necessary */ + l_x0 = int_max(l_cp->tx0 + j * l_cp->tdx, l_image->x0); + l_y0 = int_max(l_cp->ty0 + i * l_cp->tdy, l_image->y0); + l_x1 = int_min(l_cp->tx0 + (j + 1) * l_cp->tdx, l_image->x1); + l_y1 = int_min(l_cp->ty0 + (i + 1) * l_cp->tdy, l_image->y1); + l_rates = l_tcp->rates; + + /* Modification of the RATE >> */ + if + (*l_rates) + { + *l_rates = (( (float) (l_size_pixel * (l_x1 - l_x0) * (l_y1 - l_y0))) + / + ((*l_rates) * l_bits_empty) + ) + - + l_offset; + } + ++l_rates; + 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) * l_bits_empty) + ) + - + l_offset; + } + ++l_rates; + } + ++l_tcp; + } + } + + l_tcp = l_cp->tcps; + for + (i=0;ith;++i) + { + for + (j=0;jtw;++j) + { + l_rates = l_tcp->rates; + if + (*l_rates) + { + *l_rates -= l_sot_remove; + if + (*l_rates < 30) + { + *l_rates = 30; + } + } + ++l_rates; + l_last_res = l_tcp->numlayers - 1; + for + (k = 1; k < l_last_res; ++k) + { + if + (*l_rates) + { + *l_rates -= l_sot_remove; + if + (*l_rates < *(l_rates - 1) + 10) + { + *l_rates = (*(l_rates - 1)) + 20; + } + } + ++l_rates; + } + if + (*l_rates) + { + *l_rates -= (l_sot_remove + 2.f); + if + (*l_rates < *(l_rates - 1) + 10) + { + *l_rates = (*(l_rates - 1)) + 20; + } + } + ++l_tcp; + } + } + + l_img_comp = l_image->comps; + l_tile_size = 0; + for + (i=0;inumcomps;++i) + { + l_tile_size += ( uint_ceildiv(l_cp->tdx,l_img_comp->dx) + * + uint_ceildiv(l_cp->tdy,l_img_comp->dy) + * + l_img_comp->prec + ); + ++l_img_comp; + } + + l_tile_size = (OPJ_UINT32) (l_tile_size * 0.1625); /* 1.3/8 = 0.1625 */ + l_tile_size += j2k_get_specific_header_sizes(p_j2k); + + p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = l_tile_size; + p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = (OPJ_BYTE *) my_opj_malloc(p_j2k->m_specific_param.m_encoder.m_encoded_tile_size); + if + (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data == 00) + { + return false; + } + if + (l_cp->m_specific_param.m_enc.m_cinema) + { + p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = (OPJ_BYTE *) opj_malloc(5*p_j2k->m_specific_param.m_encoder.m_total_tile_parts); + if + (! p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) + { + return false; + } + p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer; + } + return true; +} + +/** + * Reads a EOC marker (End Of Codestream) + * + * @param p_header_data the data contained in the SOD box. + * @param p_j2k the jpeg2000 codec. + * @param p_header_size the size of the data contained in the SOD marker. + * @param p_manager the user event manager. +*/ +bool j2k_read_eoc ( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 i; + opj_tcd_t * l_tcd = 00; + OPJ_UINT32 l_nb_tiles; + opj_tcp_t * l_tcp = 00; + bool l_success; + + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; + l_tcp = p_j2k->m_cp.tcps; + + l_tcd = tcd_create(true); + if + (l_tcd == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); + return false; + } + + + + for + (i = 0; i < l_nb_tiles; ++i) + { + if + (l_tcp->m_data) + { + if + (! tcd_init_decode_tile(l_tcd, i)) + { + tcd_destroy(l_tcd); + opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); + return false; + } + l_success = tcd_decode_tile(l_tcd, l_tcp->m_data, l_tcp->m_data_size, i, p_j2k->cstr_info); + /* cleanup */ + if + (! l_success) + { + p_j2k->m_specific_param.m_decoder.m_state |= J2K_DEC_STATE_ERR; break; } } - tcd_free_decode(tcd); - tcd_destroy(tcd); + j2k_tcp_destroy(l_tcp); + ++l_tcp; } - /* if packets should not be decoded */ - else { - for (i = 0; i < j2k->cp->tileno_size; i++) { - tileno = j2k->cp->tileno[i]; - opj_free(j2k->tile_data[tileno]); - j2k->tile_data[tileno] = NULL; - } - } - if (j2k->state & J2K_STATE_ERR) - j2k->state = J2K_STATE_MT + J2K_STATE_ERR; - else - j2k->state = J2K_STATE_MT; + tcd_destroy(l_tcd); + return true; } -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_j2k_t *j2k); -} opj_dec_mstabent_t; +/** + * Writes the image components. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_image_components( + 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 = 1; compno < p_j2k->m_image->numcomps; ++compno) + { + if + (! j2k_write_coc(p_j2k,compno,p_stream, p_manager)) + { + return false; + } + if + (! j2k_write_qcc(p_j2k,compno,p_stream, p_manager)) + { + return false; + } + } + return true; +} -opj_dec_mstabent_t j2k_dec_mstab[] = { - {J2K_MS_SOC, J2K_STATE_MHSOC, j2k_read_soc}, - {J2K_MS_SOT, J2K_STATE_MH | J2K_STATE_TPHSOT, j2k_read_sot}, - {J2K_MS_SOD, J2K_STATE_TPH, j2k_read_sod}, - {J2K_MS_EOC, J2K_STATE_TPHSOT, j2k_read_eoc}, - {J2K_MS_SIZ, J2K_STATE_MHSIZ, j2k_read_siz}, - {J2K_MS_COD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_cod}, - {J2K_MS_COC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_coc}, - {J2K_MS_RGN, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_rgn}, - {J2K_MS_QCD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcd}, - {J2K_MS_QCC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_qcc}, - {J2K_MS_POC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_poc}, - {J2K_MS_TLM, J2K_STATE_MH, j2k_read_tlm}, - {J2K_MS_PLM, J2K_STATE_MH, j2k_read_plm}, - {J2K_MS_PLT, J2K_STATE_TPH, j2k_read_plt}, - {J2K_MS_PPM, J2K_STATE_MH, j2k_read_ppm}, - {J2K_MS_PPT, J2K_STATE_TPH, j2k_read_ppt}, - {J2K_MS_SOP, 0, 0}, - {J2K_MS_CRG, J2K_STATE_MH, j2k_read_crg}, - {J2K_MS_COM, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_com}, +/** + * Writes regions of interests. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_regions( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 compno; + const opj_tccp_t *l_tccp = 00; + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_tccp = p_j2k->m_cp.tcps->tccps; + for + (compno = 0; compno < p_j2k->m_image->numcomps; ++compno) + { + if + (l_tccp->roishift) + { + if + (! j2k_write_rgn(p_j2k,0,compno,p_stream,p_manager)) + { + return false; + } + } + ++l_tccp; + } + return true; +} +/** + * Writes the updated tlm. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_write_updated_tlm( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 l_tlm_size; + OPJ_SIZE_T l_tlm_position, l_current_position; + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + l_tlm_size = 5 * p_j2k->m_specific_param.m_encoder.m_total_tile_parts; + l_tlm_position = 6 + p_j2k->m_specific_param.m_encoder.m_tlm_start; + l_current_position = opj_stream_tell(p_stream); + + if + (! opj_stream_seek(p_stream,l_tlm_position,p_manager)) + { + return false; + } + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer,l_tlm_size,p_manager) != l_tlm_size) + { + return false; + } + if + (! opj_stream_seek(p_stream,l_current_position,p_manager)) + { + return false; + } + return true; +} + +/** + * Ends the encoding, i.e. frees memory. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_end_encoding( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + tcd_destroy(p_j2k->m_tcd); + p_j2k->m_tcd = 00; + + if + (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) + { + opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer); + p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 0; + p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 0; + } + if + (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) + { + opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data); + p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 0; + } + p_j2k->m_specific_param.m_encoder.m_encoded_tile_size = 0; + + return true; +} + +/** + * Gets the offset of the header. + * + * @param p_stream the stream to write data to. + * @param p_j2k J2K codec. + * @param p_manager the user event manager. +*/ +bool j2k_get_end_header( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + p_j2k->cstr_info->main_head_end = opj_stream_tell(p_stream); + return true; +} + + + + +/** + * Reads an unknown marker + * + * @param p_stream the stream object to read from. + * @param p_j2k the jpeg2000 codec. + * @param p_manager the user event manager. + * + * @return true if the marker could be deduced. +*/ +bool j2k_read_unk ( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_BYTE l_data [2]; + OPJ_UINT32 l_unknown_size; + // preconditions + assert(p_j2k != 00); + assert(p_manager != 00); + assert(p_stream != 00); + + opj_event_msg(p_manager, EVT_WARNING, "Unknown marker\n"); + #ifdef USE_JPWL - {J2K_MS_EPC, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epc}, - {J2K_MS_EPB, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_epb}, - {J2K_MS_ESD, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_esd}, - {J2K_MS_RED, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_red}, -#endif /* USE_JPWL */ -#ifdef USE_JPSEC - {J2K_MS_SEC, J2K_STATE_MH, j2k_read_sec}, - {J2K_MS_INSEC, 0, j2k_read_insec}, -#endif /* USE_JPSEC */ - - {0, J2K_STATE_MH | J2K_STATE_TPH, j2k_read_unk} -}; - -static void j2k_read_unk(opj_j2k_t *j2k) { - opj_event_msg(j2k->cinfo, EVT_WARNING, "Unknown marker\n"); - -#ifdef USE_JPWL - if (j2k->cp->correct) { - int m = 0, id, i; - int min_id = 0, min_dist = 17, cur_dist = 0, tmp_id; - cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); - id = cio_read(j2k->cio, 2); - opj_event_msg(j2k->cinfo, EVT_ERROR, + if (p_j2k->m_cp->correct) { + OPJ_INT32 m = 0, id, i; + OPJ_INT32 min_id = 0, min_dist = 17, cur_dist = 0, tmp_id; + p_stream_seek(p_j2k->p_stream, p_stream_tell(p_j2k->p_stream) - 2); + id = p_stream_read(p_j2k->p_stream, 2); + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "JPWL: really don't know this marker %x\n", id); if (!JPWL_ASSUME) { - opj_event_msg(j2k->cinfo, EVT_ERROR, + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "- possible synch loss due to uncorrectable codestream errors => giving up\n"); return; } @@ -1688,358 +6821,940 @@ static void j2k_read_unk(opj_j2k_t *j2k) { /* do we substitute the marker? */ if (min_dist < JPWL_MAXIMUM_HAMMING) { - opj_event_msg(j2k->cinfo, EVT_ERROR, + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "- marker %x is at distance %d from the read %x\n", min_id, min_dist, id); - opj_event_msg(j2k->cinfo, EVT_ERROR, + opj_event_msg(p_j2k->cinfo, EVT_ERROR, "- trying to substitute in place and crossing fingers!\n"); - cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); - cio_write(j2k->cio, min_id, 2); + p_stream_seek(p_j2k->p_stream, p_stream_tell(p_j2k->p_stream) - 2); + p_stream_write(p_j2k->p_stream, min_id, 2); /* rewind */ - cio_seek(j2k->cio, cio_tell(j2k->cio) - 2); + p_stream_seek(p_j2k->p_stream, p_stream_tell(p_j2k->p_stream) - 2); } }; #endif /* USE_JPWL */ + if + (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) + { + opj_event_msg(p_manager, EVT_WARNING, "Unknown marker\n"); + return false; + } + opj_read_bytes(l_data,&l_unknown_size,2); + if + (l_unknown_size < 2) + { + return false; + } + l_unknown_size-=2; + if + (opj_stream_skip(p_stream,l_unknown_size,p_manager) != l_unknown_size) + { + return false; + } + return true; } /** -Read the lookup table containing all the marker, status and action -@param id Marker value + * Reads the lookup table containing all the marker, status and action, and returns the handler associated + * with the marker value. + * @param p_id Marker value to look up + * + * @return the handler associated with the id. */ -static opj_dec_mstabent_t *j2k_dec_mstab_lookup(int id) { - opj_dec_mstabent_t *e; - for (e = j2k_dec_mstab; e->id != 0; e++) { - if (e->id == id) { +const opj_dec_memory_marker_handler_t * j2k_get_marker_handler (OPJ_UINT32 p_id) +{ + const opj_dec_memory_marker_handler_t *e; + for + (e = j2k_memory_marker_handler_tab; e->id != 0; ++e) + { + if + (e->id == p_id) + { break; } } return e; } +/** + * Destroys a tile coding parameter structure. + * + * @param p_tcp the tile coding parameter to destroy. + */ +void j2k_tcp_destroy (opj_tcp_t *p_tcp) +{ + if + (p_tcp == 00) + { + return; + } + if + (p_tcp->ppt_buffer != 00) + { + opj_free(p_tcp->ppt_buffer); + p_tcp->ppt_buffer = 00; + } + if + (p_tcp->tccps != 00) + { + opj_free(p_tcp->tccps); + p_tcp->tccps = 00; + } + if + (p_tcp->m_mct_coding_matrix != 00) + { + opj_free(p_tcp->m_mct_coding_matrix); + p_tcp->m_mct_coding_matrix = 00; + } + if + (p_tcp->m_mct_decoding_matrix != 00) + { + opj_free(p_tcp->m_mct_decoding_matrix); + p_tcp->m_mct_decoding_matrix = 00; + } + if + (p_tcp->m_mcc_records) + { + opj_free(p_tcp->m_mcc_records); + p_tcp->m_mcc_records = 00; + p_tcp->m_nb_max_mcc_records = 0; + p_tcp->m_nb_mcc_records = 0; + } + if + (p_tcp->m_mct_records) + { + opj_mct_data_t * l_mct_data = p_tcp->m_mct_records; + OPJ_UINT32 i; + for + (i=0;im_nb_mct_records;++i) + { + if + (l_mct_data->m_data) + { + opj_free(l_mct_data->m_data); + l_mct_data->m_data = 00; + } + ++l_mct_data; + } + opj_free(p_tcp->m_mct_records); + p_tcp->m_mct_records = 00; + } + + if + (p_tcp->mct_norms != 00) + { + opj_free(p_tcp->mct_norms); + p_tcp->mct_norms = 00; + } + if + (p_tcp->m_data) + { + opj_free(p_tcp->m_data); + p_tcp->m_data = 00; + } +} + +/** + * Destroys a coding parameter structure. + * + * @param p_cp the coding parameter to destroy. + */ +void j2k_cp_destroy (opj_cp_t *p_cp) +{ + OPJ_UINT32 l_nb_tiles; + opj_tcp_t * l_current_tile = 00; + OPJ_UINT32 i; + + if + (p_cp == 00) + { + return; + } + if + (p_cp->tcps != 00) + { + l_current_tile = p_cp->tcps; + l_nb_tiles = p_cp->th * p_cp->tw; + + for + (i = 0; i < l_nb_tiles; ++i) + { + j2k_tcp_destroy(l_current_tile); + ++l_current_tile; + } + opj_free(p_cp->tcps); + p_cp->tcps = 00; + } + if + (p_cp->ppm_buffer != 00) + { + opj_free(p_cp->ppm_buffer); + p_cp->ppm_buffer = 00; + } + if + (p_cp->comment != 00) + { + opj_free(p_cp->comment); + p_cp->comment = 00; + } + if + (! p_cp->m_is_decoder) + { + if + (p_cp->m_specific_param.m_enc.m_matrice) + { + opj_free(p_cp->m_specific_param.m_enc.m_matrice); + p_cp->m_specific_param.m_enc.m_matrice = 00; + } + } +} + /* ----------------------------------------------------------------------- */ /* J2K / JPT decoder interface */ /* ----------------------------------------------------------------------- */ +/** + * Creates a J2K decompression structure. + * + * @return a handle to a J2K decompressor if successful, NULL otherwise. +*/ +opj_j2k_t* j2k_create_decompress() +{ + opj_j2k_t *l_j2k = (opj_j2k_t*) opj_malloc(sizeof(opj_j2k_t)); + if + (!l_j2k) + { + return 00; + } + memset(l_j2k,0,sizeof(opj_j2k_t)); + l_j2k->m_is_decoder = 1; + l_j2k->m_cp.m_is_decoder = 1; + l_j2k->m_specific_param.m_decoder.m_default_tcp = (opj_tcp_t*) opj_malloc(sizeof(opj_tcp_t)); + if + (!l_j2k->m_specific_param.m_decoder.m_default_tcp) + { + opj_free(l_j2k); + return 00; + } + memset(l_j2k->m_specific_param.m_decoder.m_default_tcp,0,sizeof(opj_tcp_t)); + + l_j2k->m_specific_param.m_decoder.m_header_data = (OPJ_BYTE *) opj_malloc(J2K_DEFAULT_HEADER_SIZE); + if + (! l_j2k->m_specific_param.m_decoder.m_header_data) + { + j2k_destroy(l_j2k); + return 00; + } + l_j2k->m_specific_param.m_decoder.m_header_data_size = J2K_DEFAULT_HEADER_SIZE; -opj_j2k_t* j2k_create_decompress(opj_common_ptr cinfo) { - opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t)); - if(!j2k) - return NULL; - - j2k->default_tcp = (opj_tcp_t*) opj_calloc(1, sizeof(opj_tcp_t)); - if(!j2k->default_tcp) { - opj_free(j2k); - return NULL; + // validation list creation + l_j2k->m_validation_list = opj_procedure_list_create(); + if + (! l_j2k->m_validation_list) + { + j2k_destroy(l_j2k); + return 00; } - j2k->cinfo = cinfo; - j2k->tile_data = NULL; - - return j2k; + // execution list creation + l_j2k->m_procedure_list = opj_procedure_list_create(); + if + (! l_j2k->m_procedure_list) + { + j2k_destroy(l_j2k); + return 00; + } + return l_j2k; } -void j2k_destroy_decompress(opj_j2k_t *j2k) { - int i = 0; +opj_j2k_t* j2k_create_compress() +{ + opj_j2k_t *l_j2k = (opj_j2k_t*) opj_malloc(sizeof(opj_j2k_t)); + if + (!l_j2k) + { + return 00; + } + memset(l_j2k,0,sizeof(opj_j2k_t)); + l_j2k->m_is_decoder = 0; + l_j2k->m_cp.m_is_decoder = 0; + + l_j2k->m_specific_param.m_encoder.m_header_tile_data = (OPJ_BYTE *) opj_malloc(J2K_DEFAULT_HEADER_SIZE); + if + (! l_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + j2k_destroy(l_j2k); + return 00; + } + l_j2k->m_specific_param.m_encoder.m_header_tile_data_size = J2K_DEFAULT_HEADER_SIZE; - if(j2k->tile_len != NULL) { - opj_free(j2k->tile_len); + // validation list creation + l_j2k->m_validation_list = opj_procedure_list_create(); + if + (! l_j2k->m_validation_list) + { + j2k_destroy(l_j2k); + return 00; } - if(j2k->tile_data != NULL) { - opj_free(j2k->tile_data); + + // execution list creation + l_j2k->m_procedure_list = opj_procedure_list_create(); + if + (! l_j2k->m_procedure_list) + { + j2k_destroy(l_j2k); + return 00; } - if(j2k->default_tcp != NULL) { - opj_tcp_t *default_tcp = j2k->default_tcp; - if(default_tcp->ppt_data_first != NULL) { - opj_free(default_tcp->ppt_data_first); + return l_j2k; +} + + +/** + * Destroys a jpeg2000 codec. + * + * @param p_j2k the jpeg20000 structure to destroy. + */ +void j2k_destroy (opj_j2k_t *p_j2k) +{ + if + (p_j2k == 00) + { + return; + } + + if + (p_j2k->m_is_decoder) + { + if + (p_j2k->m_specific_param.m_decoder.m_default_tcp != 00) + { + j2k_tcp_destroy(p_j2k->m_specific_param.m_decoder.m_default_tcp); + opj_free(p_j2k->m_specific_param.m_decoder.m_default_tcp); + p_j2k->m_specific_param.m_decoder.m_default_tcp = 00; } - if(j2k->default_tcp->tccps != NULL) { - opj_free(j2k->default_tcp->tccps); + if + (p_j2k->m_specific_param.m_decoder.m_header_data != 00) + { + opj_free(p_j2k->m_specific_param.m_decoder.m_header_data); + p_j2k->m_specific_param.m_decoder.m_header_data = 00; + p_j2k->m_specific_param.m_decoder.m_header_data_size = 0; } - opj_free(j2k->default_tcp); + } - if(j2k->cp != NULL) { - opj_cp_t *cp = j2k->cp; - if(cp->tcps != NULL) { - for(i = 0; i < cp->tw * cp->th; 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); + else + { + if + (p_j2k->m_specific_param.m_encoder.m_encoded_tile_data) + { + opj_free(p_j2k->m_specific_param.m_encoder.m_encoded_tile_data); + p_j2k->m_specific_param.m_encoder.m_encoded_tile_data = 00; + } + if + (p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer) + { + opj_free(p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer); + p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_buffer = 00; + p_j2k->m_specific_param.m_encoder.m_tlm_sot_offsets_current = 00; + } + if + (p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); + p_j2k->m_specific_param.m_encoder.m_header_tile_data = 00; + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; + } + } + tcd_destroy(p_j2k->m_tcd); + + j2k_cp_destroy(&(p_j2k->m_cp)); + memset(&(p_j2k->m_cp),0,sizeof(opj_cp_t)); + + opj_procedure_list_destroy(p_j2k->m_procedure_list); + p_j2k->m_procedure_list = 00; + + opj_procedure_list_destroy(p_j2k->m_validation_list); + p_j2k->m_procedure_list = 00; + + opj_free(p_j2k); +} + +/** + * Starts a compression scheme, i.e. validates the codec parameters, writes the header. + * + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream object. + * @param p_manager the user event manager. + * + * @return true if the codec is valid. + */ +bool j2k_start_compress( + opj_j2k_t *p_j2k, + opj_stream_private_t *p_stream, + opj_image_t * p_image, + opj_event_mgr_t * p_manager) +{ + // preconditions + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + p_j2k->m_image = p_image; + + + /* customization of the validation */ + j2k_setup_encoding_validation (p_j2k); + + /* validation of the parameters codec */ + if + (! j2k_exec(p_j2k,p_j2k->m_validation_list,p_stream,p_manager)) + { + return false; + } + + /* customization of the encoding */ + j2k_setup_header_writting(p_j2k); + + /* write header */ + if + (! j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) + { + return false; + } + return true; +} +/** + * Sets up the procedures to do on reading header. Developpers wanting to extend the library can add their own reading procedures. + */ +void j2k_setup_header_reading (opj_j2k_t *p_j2k) +{ + // preconditions + assert(p_j2k != 00); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_read_header_procedure); + + /* DEVELOPER CORNER, add your custom procedures */ + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_copy_default_tcp_and_create_tcd); + +} + +/** + * Sets up the procedures to do on decoding data. Developpers wanting to extend the library can add their own reading procedures. + */ +void j2k_setup_decoding (opj_j2k_t *p_j2k) +{ + // preconditions + assert(p_j2k != 00); + + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_decode_tiles); + /* DEVELOPER CORNER, add your custom procedures */ + +} + +/** + * Sets up the procedures to do on writting header. Developpers wanting to extend the library can add their own writting procedures. + */ +void j2k_setup_header_writting (opj_j2k_t *p_j2k) +{ + // preconditions + assert(p_j2k != 00); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_init_info ); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_soc ); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_siz ); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_cod ); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,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,j2k_write_image_components ); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_tlm ); + if + (p_j2k->m_cp.m_specific_param.m_enc.m_cinema == CINEMA4K_24) + { + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_poc ); + } + } + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_regions); + + if + (p_j2k->m_cp.comment != 00) + { + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_com); + } + + /* DEVELOPER CORNER, insert your custom procedures */ + if + (p_j2k->m_cp.rsiz & MCT) + { + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_mct_data_group ); + } + /* End of Developer Corner */ + + if + (p_j2k->cstr_info) + { + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_get_end_header ); + } + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_create_tcd); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_update_rates); +} + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +void j2k_setup_end_compress (opj_j2k_t *p_j2k) +{ + // preconditions + assert(p_j2k != 00); + + /* DEVELOPER CORNER, insert your custom procedures */ + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_eoc ); + if + (p_j2k->m_cp.m_specific_param.m_enc.m_cinema) + { + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_updated_tlm); + } + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_write_epc ); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_end_encoding ); + opj_procedure_list_add_procedure(p_j2k->m_procedure_list,j2k_destroy_header_memory); +} + + + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +void j2k_setup_encoding_validation (opj_j2k_t *p_j2k) +{ + // preconditions + assert(p_j2k != 00); + opj_procedure_list_add_procedure(p_j2k->m_validation_list, j2k_build_encoder); + opj_procedure_list_add_procedure(p_j2k->m_validation_list, j2k_encoding_validation); + + + /* DEVELOPER CORNER, add your custom validation procedure */ + opj_procedure_list_add_procedure(p_j2k->m_validation_list, j2k_mct_validation); +} + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +void j2k_setup_decoding_validation (opj_j2k_t *p_j2k) +{ + // preconditions + assert(p_j2k != 00); + opj_procedure_list_add_procedure(p_j2k->m_validation_list, j2k_build_decoder); + opj_procedure_list_add_procedure(p_j2k->m_validation_list, j2k_decoding_validation); + /* DEVELOPER CORNER, add your custom validation procedure */ + +} + + +/** + * Excutes the given procedures on the given codec. + * + * @param p_procedure_list the list of procedures to execute + * @param p_j2k the jpeg2000 codec to execute the procedures on. + * @param p_stream the stream to execute the procedures on. + * @param p_manager the user manager. + * + * @return true if all the procedures were successfully executed. + */ +bool j2k_exec ( + opj_j2k_t * p_j2k, + opj_procedure_list_t * p_procedure_list, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + bool (** l_procedure) (opj_j2k_t * ,opj_stream_private_t *,opj_event_mgr_t *) = 00; + bool l_result = true; + OPJ_UINT32 l_nb_proc, i; + + // preconditions + assert(p_procedure_list != 00); + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + + l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list); + l_procedure = (bool (**) (opj_j2k_t * ,opj_stream_private_t *,opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list); + for + (i=0;im_specific_param.m_decoder.m_state == J2K_DEC_STATE_NONE); + + /* POINTER validation */ + /* make sure a p_j2k codec is present */ + l_is_valid &= (p_j2k->m_procedure_list != 00); + /* make sure a validation list is present */ + l_is_valid &= (p_j2k->m_validation_list != 00); + + if + ((p_j2k->m_cp.tdx) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) + { + opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n"); + return false; + } + if + ((p_j2k->m_cp.tdy) < (OPJ_UINT32) (1 << p_j2k->m_cp.tcps->tccps->numresolutions)) + { + opj_event_msg(p_manager, EVT_ERROR, "Number of resolutions is too high in comparison to the size of tiles\n"); + return false; + } + + /* PARAMETER VALIDATION */ + return l_is_valid; +} + +/** + * The default decoding validation procedure without any extension. + * + * @param p_j2k the jpeg2000 codec to validate. + * @param p_stream the input stream to validate. + * @param p_manager the user event manager. + * + * @return true if the parameters are correct. + */ +bool j2k_decoding_validation ( + opj_j2k_t *p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + bool l_is_valid = true; + + // preconditions + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + + /* STATE checking */ + /* make sure the state is at 0 */ + l_is_valid &= (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_NONE); + + /* POINTER validation */ + /* make sure a p_j2k codec is present */ + /* make sure a procedure list is present */ + l_is_valid &= (p_j2k->m_procedure_list != 00); + /* make sure a validation list is present */ + l_is_valid &= (p_j2k->m_validation_list != 00); + + /* PARAMETER VALIDATION */ + return l_is_valid; +} + +/** + * The mct encoding validation procedure. + * + * @param p_j2k the jpeg2000 codec to validate. + * @param p_stream the input stream to validate. + * @param p_manager the user event manager. + * + * @return true if the parameters are correct. + */ +bool j2k_mct_validation ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + bool l_is_valid = true; + OPJ_UINT32 i,j; + + // preconditions + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + + if + ((p_j2k->m_cp.rsiz & 0x8200) == 0x8200) + { + OPJ_UINT32 l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; + opj_tcp_t * l_tcp = p_j2k->m_cp.tcps; + for + (i=0;imct == 2) + { + opj_tccp_t * l_tccp = l_tcp->tccps; + l_is_valid &= (l_tcp->m_mct_coding_matrix != 00); + for + (j=0;jm_image->numcomps;++j) + { + l_is_valid &= ! (l_tccp->qmfbid & 1); + ++l_tccp; } } - opj_free(cp->tcps); + ++l_tcp; } - 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(j2k); + return l_is_valid; } -void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters) { - if(j2k && parameters) { +/** + * Builds the cp decoder parameters to use to decode tile. + */ +bool j2k_build_decoder ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + // add here initialization of cp + // copy paste of setup_decoder + return true; +} + +/** + * Builds the cp encoder parameters to use to encode tile. + */ +bool j2k_build_encoder ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + // add here initialization of cp + // copy paste of setup_encoder + return true; +} + +bool j2k_copy_default_tcp_and_create_tcd + ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + opj_tcp_t * l_tcp = 00; + opj_tcp_t * l_default_tcp = 00; + OPJ_UINT32 l_nb_tiles; + OPJ_UINT32 i,j; + opj_tccp_t *l_current_tccp = 00; + OPJ_UINT32 l_tccp_size; + OPJ_UINT32 l_mct_size; + opj_image_t * l_image; + OPJ_UINT32 l_mcc_records_size,l_mct_records_size; + opj_mct_data_t * l_src_mct_rec, *l_dest_mct_rec; + opj_simple_mcc_decorrelation_data_t * l_src_mcc_rec, *l_dest_mcc_rec; + OPJ_UINT32 l_offset; + + // preconditions in debug + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + + l_image = p_j2k->m_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_default_tcp = p_j2k->m_specific_param.m_decoder.m_default_tcp; + l_mct_size = l_image->numcomps * l_image->numcomps * sizeof(OPJ_FLOAT32); + for + (i=0;itccps; + memcpy(l_tcp,l_default_tcp, sizeof(opj_tcp_t)); + l_tcp->ppt = 0; + l_tcp->ppt_data = 00; + l_tcp->tccps = l_current_tccp; + if + (l_default_tcp->m_mct_decoding_matrix) + { + l_tcp->m_mct_decoding_matrix = opj_malloc(l_mct_size); + if + (! l_tcp->m_mct_decoding_matrix ) + { + return false; + } + memcpy(l_tcp->m_mct_decoding_matrix,l_default_tcp->m_mct_decoding_matrix,l_mct_size); + } + l_mct_records_size = l_default_tcp->m_nb_max_mct_records * sizeof(opj_mct_data_t); + l_tcp->m_mct_records = opj_malloc(l_mct_records_size); + if + (! l_tcp->m_mct_records) + { + return false; + } + memcpy(l_tcp->m_mct_records, l_default_tcp->m_mct_records,l_mct_records_size); + l_src_mct_rec = l_default_tcp->m_mct_records; + l_dest_mct_rec = l_tcp->m_mct_records; + for + (j=0;jm_nb_mct_records;++j) + { + if + (l_src_mct_rec->m_data) + { + l_dest_mct_rec->m_data = opj_malloc(l_src_mct_rec->m_data_size); + if + (! l_dest_mct_rec->m_data) + { + return false; + } + memcpy(l_dest_mct_rec->m_data,l_src_mct_rec->m_data,l_src_mct_rec->m_data_size); + } + ++l_src_mct_rec; + ++l_dest_mct_rec; + } + l_mcc_records_size = l_default_tcp->m_nb_max_mcc_records * sizeof(opj_simple_mcc_decorrelation_data_t); + l_tcp->m_mcc_records = opj_malloc(l_mcc_records_size); + if + (! l_tcp->m_mcc_records) + { + return false; + } + memcpy(l_tcp->m_mcc_records,l_default_tcp->m_mcc_records,l_mcc_records_size); + l_src_mcc_rec = l_default_tcp->m_mcc_records; + l_dest_mcc_rec = l_tcp->m_mcc_records; + 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_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_dest_mcc_rec->m_offset_array = l_tcp->m_mct_records + l_offset; + } + ++l_src_mcc_rec; + ++l_dest_mcc_rec; + } + memcpy(l_current_tccp,l_default_tcp->tccps,l_tccp_size); + ++l_tcp; + } + p_j2k->m_tcd = tcd_create(true); + if + (! p_j2k->m_tcd ) + { + return false; + } + if + (! tcd_init(p_j2k->m_tcd, l_image, &(p_j2k->m_cp))) + { + tcd_destroy(p_j2k->m_tcd); + p_j2k->m_tcd = 00; + opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); + return false; + } + return true; +} + +/** + * Destroys the memory associated with the decoding of headers. + */ +bool j2k_destroy_header_memory ( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + // preconditions in debug + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + + if + (p_j2k->m_specific_param.m_encoder.m_header_tile_data) + { + opj_free(p_j2k->m_specific_param.m_encoder.m_header_tile_data); + p_j2k->m_specific_param.m_encoder.m_header_tile_data = 0; + } + p_j2k->m_specific_param.m_encoder.m_header_tile_data_size = 0; + return true; +} + +/** + * Sets up the decoder decoding parameters using user parameters. + * Decoding parameters are stored in p_j2k->m_cp. + * + * @param p_j2k J2K codec + * @param p_parameters decompression parameters + * @deprecated +*/ +void j2k_setup_decoder( + opj_j2k_t *p_j2k, + opj_dparameters_t *p_parameters + ) +{ + if + (p_j2k && p_parameters) + { /* create and initialize the coding parameters structure */ - opj_cp_t *cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t)); - cp->reduce = parameters->cp_reduce; - cp->layer = parameters->cp_layer; - cp->limit_decoding = parameters->cp_limit_decoding; + p_j2k->m_cp.m_specific_param.m_dec.m_reduce = p_parameters->cp_reduce; + p_j2k->m_cp.m_specific_param.m_dec.m_layer = p_parameters->cp_layer; + p_j2k->m_specific_param.m_decoder.m_discard_tiles = p_parameters->m_use_restrict_decode; + if + (p_parameters->m_use_restrict_decode) + { + p_j2k->m_specific_param.m_decoder.m_start_tile_x = p_parameters->m_decode_start_x; + p_j2k->m_specific_param.m_decoder.m_start_tile_y = p_parameters->m_decode_start_y; + p_j2k->m_specific_param.m_decoder.m_end_tile_x = p_parameters->m_decode_end_x; + p_j2k->m_specific_param.m_decoder.m_end_tile_y = p_parameters->m_decode_end_y; + } #ifdef USE_JPWL cp->correct = parameters->jpwl_correct; cp->exp_comps = parameters->jpwl_exp_comps; cp->max_tiles = parameters->jpwl_max_tiles; #endif /* USE_JPWL */ - - - /* keep a link to cp so that we can destroy it later in j2k_destroy_decompress */ - j2k->cp = cp; } } -opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { - opj_image_t *image = NULL; - - opj_common_ptr cinfo = j2k->cinfo; - - j2k->cio = cio; - j2k->cstr_info = cstr_info; - if (cstr_info) - memset(cstr_info, 0, sizeof(opj_codestream_info_t)); - - /* create an empty image */ - image = opj_image_create0(); - j2k->image = image; - - j2k->state = J2K_STATE_MHSOC; - - for (;;) { - opj_dec_mstabent_t *e; - int id = cio_read(cio, 2); - -#ifdef USE_JPWL - /* we try to honor JPWL correction power */ - if (j2k->cp->correct) { - - int orig_pos = cio_tell(cio); - bool status; - - /* call the corrector */ - status = jpwl_correct(j2k); - - /* go back to where you were */ - cio_seek(cio, orig_pos - 2); - - /* re-read the marker */ - id = cio_read(cio, 2); - - /* check whether it begins with ff */ - if (id >> 8 != 0xff) { - opj_event_msg(cinfo, EVT_ERROR, - "JPWL: possible bad marker %x at %d\n", - id, cio_tell(cio) - 2); - if (!JPWL_ASSUME) { - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "JPWL: giving up\n"); - return 0; - } - /* we try to correct */ - id = id | 0xff00; - cio_seek(cio, cio_tell(cio) - 2); - cio_write(cio, id, 2); - opj_event_msg(cinfo, EVT_WARNING, "- trying to adjust this\n" - "- setting marker to %x\n", - id); - } - - } -#endif /* USE_JPWL */ - - if (id >> 8 != 0xff) { - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); - return 0; - } - e = j2k_dec_mstab_lookup(id); - // Check if the marker is known - if (!(j2k->state & e->states)) { - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); - return 0; - } - // Check if the decoding is limited to the main header - if (e->id == J2K_MS_SOT && j2k->cp->limit_decoding == LIMIT_TO_MAIN_HEADER) { - opj_event_msg(cinfo, EVT_INFO, "Main Header decoded.\n"); - return image; - } - - if (e->handler) { - (*e->handler)(j2k); - } - if (j2k->state & J2K_STATE_ERR) - return NULL; - - if (j2k->state == J2K_STATE_MT) { - break; - } - if (j2k->state == J2K_STATE_NEOC) { - break; - } - } - if (j2k->state == J2K_STATE_NEOC) { - j2k_read_eoc(j2k); - } - - if (j2k->state != J2K_STATE_MT) { - opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); - } - - return image; -} - -/* -* Read a JPT-stream and decode file -* -*/ -opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { - opj_image_t *image = NULL; - opj_jpt_msg_header_t header; - int position; - - opj_common_ptr cinfo = j2k->cinfo; - - j2k->cio = cio; - - /* create an empty image */ - image = opj_image_create0(); - j2k->image = image; - - j2k->state = J2K_STATE_MHSOC; - - /* Initialize the header */ - jpt_init_msg_header(&header); - /* Read the first header of the message */ - jpt_read_msg_header(cinfo, cio, &header); - - position = cio_tell(cio); - if (header.Class_Id != 6) { /* 6 : Main header data-bin message */ - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Main header first [class_Id %d] !\n", header.Class_Id); - return 0; - } - - for (;;) { - opj_dec_mstabent_t *e = NULL; - int id; - - if (!cio_numbytesleft(cio)) { - j2k_read_eoc(j2k); - return image; - } - /* data-bin read -> need to read a new header */ - if ((unsigned int) (cio_tell(cio) - position) == header.Msg_length) { - jpt_read_msg_header(cinfo, cio, &header); - position = cio_tell(cio); - if (header.Class_Id != 4) { /* 4 : Tile data-bin message */ - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "[JPT-stream] : Expecting Tile info !\n"); - return 0; - } - } - - id = cio_read(cio, 2); - if (id >> 8 != 0xff) { - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "%.8x: expected a marker instead of %x\n", cio_tell(cio) - 2, id); - return 0; - } - e = j2k_dec_mstab_lookup(id); - if (!(j2k->state & e->states)) { - opj_image_destroy(image); - opj_event_msg(cinfo, EVT_ERROR, "%.8x: unexpected marker %x\n", cio_tell(cio) - 2, id); - return 0; - } - if (e->handler) { - (*e->handler)(j2k); - } - if (j2k->state == J2K_STATE_MT) { - break; - } - if (j2k->state == J2K_STATE_NEOC) { - break; - } - } - if (j2k->state == J2K_STATE_NEOC) { - j2k_read_eoc(j2k); - } - - if (j2k->state != J2K_STATE_MT) { - opj_event_msg(cinfo, EVT_WARNING, "Incomplete bitstream\n"); - } - - return image; -} - -/* ----------------------------------------------------------------------- */ -/* J2K encoder interface */ -/* ----------------------------------------------------------------------- */ - -opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo) { - opj_j2k_t *j2k = (opj_j2k_t*) opj_calloc(1, sizeof(opj_j2k_t)); - if(j2k) { - j2k->cinfo = cinfo; - } - return j2k; -} - -void j2k_destroy_compress(opj_j2k_t *j2k) { - int tileno; - - if(!j2k) return; - if(j2k->cp != NULL) { - opj_cp_t *cp = j2k->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(j2k); -} - -void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image) { - int i, j, tileno, numpocs_tile; - opj_cp_t *cp = NULL; - - if(!j2k || !parameters || ! image) { +void j2k_setup_encoder(opj_j2k_t *p_j2k, opj_cparameters_t *parameters, opj_image_t *image, struct opj_event_mgr * p_manager) { + OPJ_UINT32 i, j, tileno, numpocs_tile; + opj_cp_t *cp = 00; + bool l_res; + if(!p_j2k || !parameters || ! image) { return; } - - /* create and initialize the coding parameters structure */ - cp = (opj_cp_t*) opj_calloc(1, sizeof(opj_cp_t)); - + /* keep a link to cp so that we can destroy it later in j2k_destroy_compress */ - j2k->cp = cp; - + cp = &(p_j2k->m_cp); + /* set default values for cp */ cp->tw = 1; cp->th = 1; @@ -2047,18 +7762,20 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ /* copy user encoding parameters */ - cp->cinema = parameters->cp_cinema; - cp->max_comp_size = parameters->max_comp_size; + 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->rsiz = parameters->cp_rsiz; - cp->disto_alloc = parameters->cp_disto_alloc; - cp->fixed_alloc = parameters->cp_fixed_alloc; - cp->fixed_quality = parameters->cp_fixed_quality; + 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; /* mod fixed_quality */ - if(parameters->cp_matrice) { - size_t array_size = parameters->tcp_numlayers * parameters->numresolution * 3 * sizeof(int); - cp->matrice = (int *) opj_malloc(array_size); - memcpy(cp->matrice, parameters->cp_matrice, array_size); + if + (parameters->cp_matrice) + { + size_t array_size = parameters->tcp_numlayers * 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 */ @@ -2089,24 +7806,20 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ cp->tdy = image->y1 - cp->ty0; } - if(parameters->tp_on){ - cp->tp_flag = parameters->tp_flag; - cp->tp_on = 1; + if + (parameters->tp_on) + { + cp->m_specific_param.m_enc.m_tp_flag = parameters->tp_flag; + cp->m_specific_param.m_enc.m_tp_on = 1; } - cp->img_size = 0; - for(i=0;inumcomps ;i++){ - cp->img_size += (image->comps[i].w *image->comps[i].h * image->comps[i].prec); - } - - #ifdef USE_JPWL /* calculate JPWL encoding parameters */ if (parameters->jpwl_epc_on) { - int i; + OPJ_INT32 i; /* set JPWL on */ cp->epc_on = true; @@ -2160,18 +7873,24 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ /* initialize the mutiple tiles */ /* ---------------------------- */ cp->tcps = (opj_tcp_t*) opj_calloc(cp->tw * cp->th, sizeof(opj_tcp_t)); - + if + (parameters->numpocs) + { + /* initialisation of POC */ + l_res = j2k_check_poc_val(parameters->POC,parameters->numpocs, parameters->numresolution, image->numcomps, parameters->tcp_numlayers, p_manager); + // TODO + } for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { opj_tcp_t *tcp = &cp->tcps[tileno]; tcp->numlayers = parameters->tcp_numlayers; for (j = 0; j < tcp->numlayers; j++) { - if(cp->cinema){ - if (cp->fixed_quality) { + if(cp->m_specific_param.m_enc.m_cinema){ + if (cp->m_specific_param.m_enc.m_fixed_quality) { tcp->distoratio[j] = parameters->tcp_distoratio[j]; } tcp->rates[j] = parameters->tcp_rates[j]; }else{ - if (cp->fixed_quality) { /* add fixed_quality */ + if (cp->m_specific_param.m_enc.m_fixed_quality) { /* add fixed_quality */ tcp->distoratio[j] = parameters->tcp_distoratio[j]; } else { tcp->rates[j] = parameters->tcp_rates[j]; @@ -2182,12 +7901,17 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ tcp->prg = parameters->prog_order; tcp->mct = parameters->tcp_mct; + + numpocs_tile = 0; tcp->POC = 0; - if (parameters->numpocs) { + if + (parameters->numpocs) + { /* initialisation of POC */ tcp->POC = 1; - for (i = 0; i < parameters->numpocs; i++) { + // TODO + for (i = 0; i < (unsigned int) 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; @@ -2206,6 +7930,44 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ } tcp->tccps = (opj_tccp_t*) opj_calloc(image->numcomps, sizeof(opj_tccp_t)); + if + (parameters->mct_data) + { + OPJ_UINT32 lMctSize = image->numcomps * image->numcomps * sizeof(OPJ_FLOAT32); + OPJ_FLOAT32 * lTmpBuf = opj_malloc(lMctSize); + OPJ_INT32 * l_dc_shift = (OPJ_INT32 *) ((OPJ_BYTE *) parameters->mct_data + lMctSize); + tcp->mct = 2; + tcp->m_mct_coding_matrix = opj_malloc(lMctSize); + memcpy(tcp->m_mct_coding_matrix,parameters->mct_data,lMctSize); + memcpy(lTmpBuf,parameters->mct_data,lMctSize); + tcp->m_mct_decoding_matrix = opj_malloc(lMctSize); + assert(opj_matrix_inversion_f(lTmpBuf,(tcp->m_mct_decoding_matrix),image->numcomps)); + tcp->mct_norms = opj_malloc(image->numcomps * sizeof(OPJ_FLOAT64)); + opj_calculate_norms(tcp->mct_norms,image->numcomps,tcp->m_mct_decoding_matrix); + opj_free(lTmpBuf); + for + (i = 0; i < image->numcomps; i++) + { + opj_tccp_t *tccp = &tcp->tccps[i]; + tccp->m_dc_level_shift = l_dc_shift[i]; + } + j2k_setup_mct_encoding(tcp,image); + } + else + { + for + (i = 0; i < image->numcomps; i++) + { + opj_tccp_t *tccp = &tcp->tccps[i]; + opj_image_comp_t * l_comp = &(image->comps[i]); + if + (! l_comp->sgnd) + { + tccp->m_dc_level_shift = 1 << (l_comp->prec - 1); + } + } + } + for (i = 0; i < image->numcomps; i++) { opj_tccp_t *tccp = &tcp->tccps[i]; @@ -2278,227 +8040,856 @@ void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_ } } } - + dwt_calc_explicit_stepsizes(tccp, image->comps[i].prec); } } + if + (parameters->mct_data) + { + opj_free(parameters->mct_data); + parameters->mct_data = 00; + } } -bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { - int tileno, compno; - opj_cp_t *cp = NULL; +bool j2k_write_first_tile_part ( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + OPJ_UINT32 p_total_data_size, + 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; - opj_tcd_t *tcd = NULL; /* TCD component */ - - j2k->cio = cio; - j2k->image = image; - - cp = j2k->cp; - - /* j2k_dump_cp(stdout, image, cp); */ + opj_tcp_t *l_tcp = 00; + opj_tcd_t * l_tcd = 00; + opj_cp_t * l_cp = 00; + + l_tcd = p_j2k->m_tcd; + l_cp = &(p_j2k->m_cp); + l_tcp = l_cp->tcps + p_j2k->m_current_tile_number; + l_tcd->cur_pino = 0; + /*Get number of tile parts*/ + + p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0; /* INDEX >> */ - j2k->cstr_info = cstr_info; - if (cstr_info) { - int compno; - cstr_info->tile = (opj_tile_info_t *) opj_malloc(cp->tw * cp->th * sizeof(opj_tile_info_t)); - cstr_info->image_w = image->x1 - image->x0; - cstr_info->image_h = image->y1 - image->y0; - cstr_info->prog = (&cp->tcps[0])->prg; - cstr_info->tw = cp->tw; - cstr_info->th = cp->th; - cstr_info->tile_x = cp->tdx; /* new version parser */ - cstr_info->tile_y = cp->tdy; /* new version parser */ - cstr_info->tile_Ox = cp->tx0; /* new version parser */ - cstr_info->tile_Oy = cp->ty0; /* new version parser */ - cstr_info->numcomps = image->numcomps; - cstr_info->numlayers = (&cp->tcps[0])->numlayers; - cstr_info->numdecompos = (int*) opj_malloc(image->numcomps * sizeof(int)); - for (compno=0; compno < image->numcomps; compno++) { - cstr_info->numdecompos[compno] = (&cp->tcps[0])->tccps->numresolutions - 1; - } - cstr_info->D_max = 0.0; /* ADD Marcela */ - cstr_info->main_head_start = cio_tell(cio); /* position of SOC */ - cstr_info->maxmarknum = 100; - cstr_info->marker = (opj_marker_info_t *) opj_malloc(cstr_info->maxmarknum * sizeof(opj_marker_info_t)); - cstr_info->marknum = 0; - } + /* << INDEX */ + l_current_nb_bytes_written = 0; + l_begin_data = p_data; + if + (! j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) + { + return false; + } + 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; - j2k_write_soc(j2k); - j2k_write_siz(j2k); - j2k_write_cod(j2k); - j2k_write_qcd(j2k); - - if(cp->cinema){ - for (compno = 1; compno < image->numcomps; compno++) { - j2k_write_coc(j2k, compno); - j2k_write_qcc(j2k, compno); + if + (l_cp->m_specific_param.m_enc.m_cinema == 0) + { + for + (compno = 1; compno < p_j2k->m_image->numcomps; compno++) + { + l_current_nb_bytes_written = 0; + j2k_write_coc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager); + 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_current_nb_bytes_written = 0; + j2k_write_qcc_in_memory(p_j2k,compno,p_data,&l_current_nb_bytes_written,p_manager); + 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; + } + if + (l_cp->tcps[p_j2k->m_current_tile_number].numpocs) + { + l_current_nb_bytes_written = 0; + j2k_write_poc_in_memory(p_j2k,p_data,&l_current_nb_bytes_written,p_manager); + 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; } } - - for (compno = 0; compno < image->numcomps; compno++) { - opj_tcp_t *tcp = &cp->tcps[0]; - if (tcp->tccps[compno].roishift) - j2k_write_rgn(j2k, compno, 0); + l_current_nb_bytes_written = 0; + if + (! j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) + { + return false; } - if (cp->comment != NULL) { - j2k_write_com(j2k); + l_nb_bytes_written += l_current_nb_bytes_written; + * p_data_written = l_nb_bytes_written; + + /* Writing Psot in SOT marker */ + opj_write_bytes(l_begin_data + 6,l_nb_bytes_written,4); /* PSOT */ + if + (l_cp->m_specific_param.m_enc.m_cinema) + { + j2k_update_tlm(p_j2k,l_nb_bytes_written); } + return true; +} - j2k->totnum_tp = j2k_calculate_tp(cp,image->numcomps,image,j2k); - /* TLM Marker*/ - if(cp->cinema){ - j2k_write_tlm(j2k); - if (cp->cinema == CINEMA4K_24) { - j2k_write_poc(j2k); +bool j2k_write_all_tile_parts( + opj_j2k_t *p_j2k, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_data_written, + OPJ_UINT32 p_total_data_size, + opj_stream_private_t *p_stream, + struct opj_event_mgr * p_manager + ) +{ + OPJ_UINT32 tilepartno=0; + OPJ_UINT32 l_nb_bytes_written = 0; + OPJ_UINT32 l_current_nb_bytes_written; + OPJ_UINT32 l_part_tile_size; + OPJ_UINT32 tot_num_tp; + OPJ_UINT32 pino; + + OPJ_BYTE * l_begin_data; + opj_tcp_t *l_tcp = 00; + opj_tcd_t * l_tcd = 00; + opj_cp_t * l_cp = 00; + + + l_tcd = p_j2k->m_tcd; + l_cp = &(p_j2k->m_cp); + l_tcp = l_cp->tcps + p_j2k->m_current_tile_number; + + /*Get number of tile parts*/ + tot_num_tp = j2k_get_num_tp(l_cp,0,p_j2k->m_current_tile_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; + l_part_tile_size = 0; + l_begin_data = p_data; + if + (! j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) + { + return false; } + 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_current_nb_bytes_written = 0; + if + (! j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) + { + return false; + } + 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; + + /* Writing Psot in SOT marker */ + opj_write_bytes(l_begin_data + 6,l_part_tile_size,4); /* PSOT */ + + if + (l_cp->m_specific_param.m_enc.m_cinema) + { + j2k_update_tlm(p_j2k,l_part_tile_size); + } + ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number; + } + for + (pino = 1; pino <= l_tcp->numpocs; ++pino) + { + l_tcd->cur_pino = pino; + /*Get number of tile parts*/ + tot_num_tp = j2k_get_num_tp(l_cp,pino,p_j2k->m_current_tile_number); + for + (tilepartno = 0; 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; + l_part_tile_size = 0; + l_begin_data = p_data; + if + (! j2k_write_sot(p_j2k,p_data,&l_current_nb_bytes_written,p_stream,p_manager)) + { + return false; + } + 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_current_nb_bytes_written; + + l_current_nb_bytes_written = 0; + if + (! j2k_write_sod(p_j2k,l_tcd,p_data,&l_current_nb_bytes_written,p_total_data_size,p_stream,p_manager)) + { + return false; + } + 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_current_nb_bytes_written; + + /* Writing Psot in SOT marker */ + opj_write_bytes(l_begin_data + 6,l_part_tile_size,4); /* PSOT */ + + if + (l_cp->m_specific_param.m_enc.m_cinema) + { + j2k_update_tlm(p_j2k,l_part_tile_size); + } + ++p_j2k->m_specific_param.m_encoder.m_current_tile_part_number; + } + } + *p_data_written = l_nb_bytes_written; + return true; +} + + +bool j2k_pre_write_tile ( + opj_j2k_t * p_j2k, + OPJ_UINT32 p_tile_index, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + if + (p_tile_index != p_j2k->m_current_tile_number) + { + opj_event_msg(p_manager, EVT_ERROR, "The given tile index does not match." ); + return false; } - /* uncomment only for testing JPSEC marker writing */ - /* j2k_write_sec(j2k); */ + opj_event_msg(p_manager, EVT_INFO, "tile number %d / %d\n", p_j2k->m_current_tile_number + 1, p_j2k->m_cp.tw * p_j2k->m_cp.th); - /* INDEX >> */ - if(cstr_info) { - cstr_info->main_head_end = cio_tell(cio) - 1; + p_j2k->m_specific_param.m_encoder.m_current_tile_part_number = 0; + p_j2k->m_tcd->cur_totnum_tp = p_j2k->m_cp.tcps[p_tile_index].m_nb_tile_parts; + p_j2k->m_specific_param.m_encoder.m_current_poc_tile_part_number = 0; + /* initialisation before tile encoding */ + if + (! tcd_init_encode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) + { + return false; } - /* << INDEX */ - /**** Main Header ENDS here ***/ + return true; +} - /* create the tile encoder */ - tcd = tcd_create(j2k->cinfo); +/** + * Writes a tile. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool j2k_write_tile ( + opj_j2k_t * p_j2k, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + if + (! j2k_pre_write_tile(p_j2k,p_tile_index,p_stream,p_manager)) + { + return false; + } + return j2k_post_write_tile(p_j2k,p_data,p_data_size,p_stream,p_manager); +} - /* encode each tile */ - for (tileno = 0; tileno < cp->tw * cp->th; tileno++) { - int pino; - int tilepartno=0; - /* UniPG>> */ - int acc_pack_num = 0; - /* <m_specific_param.m_encoder.m_encoded_tile_data); + l_tcd = p_j2k->m_tcd; + l_cp = &(p_j2k->m_cp); + l_tcp = l_cp->tcps + p_j2k->m_current_tile_number; + + l_tile_size = p_j2k->m_specific_param.m_encoder.m_encoded_tile_size; + l_available_data = l_tile_size; + l_current_data = p_j2k->m_specific_param.m_encoder.m_encoded_tile_data; + if + (! tcd_copy_tile_data(l_tcd,p_data,p_data_size)) + { + opj_event_msg(p_manager, EVT_ERROR, "Size mismtach between tile data and sent data." ); + return false; + } + + l_nb_bytes_written = 0; + if + (! j2k_write_first_tile_part(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) + { + return false; + } + l_current_data += l_nb_bytes_written; + l_available_data -= l_nb_bytes_written; - opj_tcp_t *tcp = &cp->tcps[tileno]; - opj_event_msg(j2k->cinfo, EVT_INFO, "tile number %d / %d\n", tileno + 1, cp->tw * cp->th); + l_nb_bytes_written = 0; + if + (! j2k_write_all_tile_parts(p_j2k,l_current_data,&l_nb_bytes_written,l_available_data,p_stream,p_manager)) + { + return false; + } + + l_available_data -= l_nb_bytes_written; + l_nb_bytes_written = l_tile_size - l_available_data; + + if + (opj_stream_write_data(p_stream,p_j2k->m_specific_param.m_encoder.m_encoded_tile_data,l_nb_bytes_written,p_manager) != l_nb_bytes_written) + { + return false; + } + ++p_j2k->m_current_tile_number; + return true; +} - j2k->curtileno = tileno; - j2k->cur_tp_num = 0; - tcd->cur_totnum_tp = j2k->cur_totnum_tp[j2k->curtileno]; - /* initialisation before tile encoding */ - if (tileno == 0) { - tcd_malloc_encode(tcd, image, cp, j2k->curtileno); - } else { - tcd_init_encode(tcd, image, cp, j2k->curtileno); - } +/** + * Reads a tile header. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool j2k_read_tile_header ( + opj_j2k_t * p_j2k, + 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, + bool * p_go_on, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + OPJ_UINT32 l_current_marker = J2K_MS_SOT; + OPJ_UINT32 l_marker_size; + const opj_dec_memory_marker_handler_t * l_marker_handler = 00; + opj_tcp_t * l_tcp = 00; + OPJ_UINT32 l_nb_tiles; - /* INDEX >> */ - if(cstr_info) { - cstr_info->tile[j2k->curtileno].start_pos = cio_tell(cio) + j2k->pos_correction; - } - /* << INDEX */ - - for(pino = 0; pino <= tcp->numpocs; pino++) { - int tot_num_tp; - tcd->cur_pino=pino; - - /*Get number of tile parts*/ - tot_num_tp = j2k_get_num_tp(cp,pino,tileno); - tcd->tp_pos = cp->tp_pos; - - for(tilepartno = 0; tilepartno < tot_num_tp ; tilepartno++){ - j2k->tp_num = tilepartno; - /* INDEX >> */ - if(cstr_info) - cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pos = - cio_tell(cio) + j2k->pos_correction; - /* << INDEX */ - j2k_write_sot(j2k); - - if(j2k->cur_tp_num == 0 && cp->cinema == 0){ - for (compno = 1; compno < image->numcomps; compno++) { - j2k_write_coc(j2k, compno); - j2k_write_qcc(j2k, compno); - } - if (cp->tcps[tileno].numpocs) { - j2k_write_poc(j2k); - } + // preconditions + assert(p_stream != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + if + (p_j2k->m_specific_param.m_decoder.m_state == J2K_DEC_STATE_EOC) + { + l_current_marker = J2K_MS_EOC; + } + else if + (p_j2k->m_specific_param.m_decoder.m_state != J2K_DEC_STATE_TPHSOT) + { + return false; + } + + while + (! p_j2k->m_specific_param.m_decoder.m_can_decode && l_current_marker != J2K_MS_EOC) + { + while + (l_current_marker != J2K_MS_SOD) + { + if + (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2); + if + (p_j2k->m_specific_param.m_decoder.m_state & J2K_DEC_STATE_TPH) + { + p_j2k->m_specific_param.m_decoder.m_sot_length -= (l_marker_size + 2); + } + l_marker_size -= 2; + + l_marker_handler = j2k_get_marker_handler(l_current_marker); + // Check if the marker is known + if + (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) + { + opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n"); + return false; + } + if + (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) + { + p_j2k->m_specific_param.m_decoder.m_header_data = opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size); + if + (p_j2k->m_specific_param.m_decoder.m_header_data == 00) + { + return false; } + p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size; - /* INDEX >> */ - if(cstr_info) - cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_header = - cio_tell(cio) + j2k->pos_correction + 1; - /* << INDEX */ - - j2k_write_sod(j2k, tcd); - - /* INDEX >> */ - if(cstr_info) { - cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_end_pos = - cio_tell(cio) + j2k->pos_correction - 1; - cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_start_pack = - acc_pack_num; - cstr_info->tile[j2k->curtileno].tp[j2k->cur_tp_num].tp_numpacks = - cstr_info->packno - acc_pack_num; - acc_pack_num = cstr_info->packno; + } + if + (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager) != l_marker_size) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + if + (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n"); + return false; + } + if + (p_j2k->m_specific_param.m_decoder.m_skip_data) + { + if + (opj_stream_skip(p_stream,p_j2k->m_specific_param.m_decoder.m_sot_length,p_manager) != p_j2k->m_specific_param.m_decoder.m_sot_length) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; } - /* << INDEX */ - - j2k->cur_tp_num++; - } - } - if(cstr_info) { - cstr_info->tile[j2k->curtileno].end_pos = cio_tell(cio) + j2k->pos_correction - 1; + l_current_marker = J2K_MS_SOD; + } + else + { + if + (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2); + } } - - /* - if (tile->PPT) { // BAD PPT !!! - FILE *PPT_file; - int i; - PPT_file=fopen("PPT","rb"); - fprintf(stderr,"%c%c%c%c",255,97,tile->len_ppt/256,tile->len_ppt%256); - for (i=0;ilen_ppt;i++) { - unsigned char elmt; - fread(&elmt, 1, 1, PPT_file); - fwrite(&elmt,1,1,f); + if + (! p_j2k->m_specific_param.m_decoder.m_skip_data) + { + if + (! j2k_read_sod(p_j2k,p_stream,p_manager)) + { + return false; + } } - fclose(PPT_file); - unlink("PPT"); + else + { + p_j2k->m_specific_param.m_decoder.m_skip_data = 0; + p_j2k->m_specific_param.m_decoder.m_can_decode = 0; + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_TPHSOT; + if + (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2); + } + } + + if + (l_current_marker == J2K_MS_EOC) + { + if + (p_j2k->m_specific_param.m_decoder.m_state != J2K_DEC_STATE_EOC) + { + p_j2k->m_current_tile_number = 0; + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_EOC; + } + } + if + ( ! p_j2k->m_specific_param.m_decoder.m_can_decode) + { + l_tcp = p_j2k->m_cp.tcps + p_j2k->m_current_tile_number; + l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; + while + ( + (p_j2k->m_current_tile_number < l_nb_tiles) + && (l_tcp->m_data == 00) + ) + { + ++p_j2k->m_current_tile_number; + ++l_tcp; + } + if + (p_j2k->m_current_tile_number == l_nb_tiles) + { + *p_go_on = false; + return true; + } + } + if + (! tcd_init_decode_tile(p_j2k->m_tcd, p_j2k->m_current_tile_number)) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot decode tile, memory error\n"); + return false; + } + *p_tile_index = p_j2k->m_current_tile_number; + *p_go_on = true; + *p_data_size = tcd_get_decoded_tile_size(p_j2k->m_tcd); + * p_tile_x0 = p_j2k->m_tcd->tcd_image->tiles->x0; + * p_tile_y0 = p_j2k->m_tcd->tcd_image->tiles->y0; + * p_tile_x1 = p_j2k->m_tcd->tcd_image->tiles->x1; + * p_tile_y1 = p_j2k->m_tcd->tcd_image->tiles->y1; + * p_nb_comps = p_j2k->m_tcd->tcd_image->tiles->numcomps; + p_j2k->m_specific_param.m_decoder.m_state |= J2K_DEC_STATE_DATA; + return true; +} + +bool j2k_decode_tile ( + opj_j2k_t * p_j2k, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + OPJ_UINT32 l_current_marker; + OPJ_BYTE l_data [2]; + opj_tcp_t * l_tcp; + + // preconditions + assert(p_stream != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + if + (! (p_j2k->m_specific_param.m_decoder.m_state & J2K_DEC_STATE_DATA) || p_tile_index != p_j2k->m_current_tile_number) + { + return false; + } + l_tcp = &(p_j2k->m_cp.tcps[p_tile_index]); + if + (! l_tcp->m_data) + { + j2k_tcp_destroy(&(p_j2k->m_cp.tcps[p_tile_index])); + return false; + } + if + (! tcd_decode_tile(p_j2k->m_tcd, l_tcp->m_data, l_tcp->m_data_size, p_tile_index, p_j2k->cstr_info)) + { + j2k_tcp_destroy(l_tcp); + p_j2k->m_specific_param.m_decoder.m_state |= J2K_DEC_STATE_ERR; + return false; + } + if + (! tcd_update_tile_data(p_j2k->m_tcd,p_data,p_data_size)) + { + return false; + } + j2k_tcp_destroy(l_tcp); + p_j2k->m_tcd->tcp = 0; + + p_j2k->m_specific_param.m_decoder.m_can_decode = 0; + p_j2k->m_specific_param.m_decoder.m_state &= (~J2K_DEC_STATE_DATA); + if + (p_j2k->m_specific_param.m_decoder.m_state != J2K_DEC_STATE_EOC) + { + if + (opj_stream_read_data(p_stream,l_data,2,p_manager) != 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + opj_read_bytes(l_data,&l_current_marker,2); + if + (l_current_marker == J2K_MS_EOC) + { + p_j2k->m_current_tile_number = 0; + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_EOC; + } + else if + (l_current_marker != J2K_MS_SOT) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short, expected SOT\n"); + return false; + } + } + return true; +} + + +/** + * Ends the compression procedures and possibiliy add data to be read after the + * codestream. + */ +bool j2k_end_compress(opj_j2k_t *p_j2k, struct opj_stream_private *p_stream, struct opj_event_mgr * p_manager) +{ + /* customization of the encoding */ + j2k_setup_end_compress(p_j2k); + + if + (! j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) + { + return false; + } + return true; +} + +/** + * Reads a jpeg2000 codestream header structure. + * + * @param p_stream the stream to read data from. + * @param p_j2k the jpeg2000 codec. + * @param p_manager the user event manager. + * + * @return true if the box is valid. + */ +bool j2k_read_header( + opj_j2k_t *p_j2k, + struct opj_image ** p_image, + OPJ_INT32 * p_tile_x0, + OPJ_INT32 * p_tile_y0, + OPJ_UINT32 * p_tile_width, + OPJ_UINT32 * p_tile_height, + OPJ_UINT32 * p_nb_tiles_x, + OPJ_UINT32 * p_nb_tiles_y, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + + *p_image = 00; + /* create an empty image */ + p_j2k->m_image = opj_image_create0(); + if + (! p_j2k->m_image) + { + return false; + } + + /* customization of the validation */ + j2k_setup_decoding_validation (p_j2k); + + /* validation of the parameters codec */ + if + (! j2k_exec(p_j2k,p_j2k->m_validation_list,p_stream,p_manager)) + { + opj_image_destroy(p_j2k->m_image); + p_j2k->m_image = 00; + return false; + } + + /* customization of the encoding */ + j2k_setup_header_reading(p_j2k); + + /* read header */ + if + (! j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) + { + opj_image_destroy(p_j2k->m_image); + p_j2k->m_image = 00; + return false; + } + *p_image = p_j2k->m_image; + * p_tile_x0 = p_j2k->m_cp.tx0; + * p_tile_y0 = p_j2k->m_cp.ty0; + * p_tile_width = p_j2k->m_cp.tdx; + * p_tile_height = p_j2k->m_cp.tdy; + * p_nb_tiles_x = p_j2k->m_cp.tw; + * p_nb_tiles_y = p_j2k->m_cp.th; + return true; +} + +/** + * The read header procedure. + */ +bool j2k_read_header_procedure( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager) +{ + OPJ_UINT32 l_current_marker; + OPJ_UINT32 l_marker_size; + const opj_dec_memory_marker_handler_t * l_marker_handler = 00; + + // preconditions + assert(p_stream != 00); + assert(p_j2k != 00); + assert(p_manager != 00); + + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_MHSOC; + + if + (! j2k_read_soc(p_j2k,p_stream,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Expected a SOC marker \n"); + return false; + } + if + (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2); + + while + (l_current_marker != J2K_MS_SOT) + { + if + (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_marker_size,2); + l_marker_size -= 2; + /*if + (l_current_marker < 0xff00) + { + opj_event_msg(p_manager, EVT_ERROR, "%.8x: expected a marker instead of %x\n", opj_stream_tell(p_stream) - 2, l_current_marker); + return 0; } */ + l_marker_handler = j2k_get_marker_handler(l_current_marker); + // Check if the marker is known + if + (! (p_j2k->m_specific_param.m_decoder.m_state & l_marker_handler->states) ) + { + opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n"); + return false; + } + if + (l_marker_size > p_j2k->m_specific_param.m_decoder.m_header_data_size) + { + p_j2k->m_specific_param.m_decoder.m_header_data = opj_realloc(p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size); + if + (p_j2k->m_specific_param.m_decoder.m_header_data == 00) + { + return false; + } + p_j2k->m_specific_param.m_decoder.m_header_data_size = l_marker_size; + } + if + (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager) != l_marker_size) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + if + (! (*(l_marker_handler->handler))(p_j2k,p_j2k->m_specific_param.m_decoder.m_header_data,l_marker_size,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Marker is not compliant with its position\n"); + return false; + } + if + (opj_stream_read_data(p_stream,p_j2k->m_specific_param.m_decoder.m_header_data,2,p_manager) != 2) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream too short\n"); + return false; + } + opj_read_bytes(p_j2k->m_specific_param.m_decoder.m_header_data,&l_current_marker,2); + } + p_j2k->m_specific_param.m_decoder.m_state = J2K_DEC_STATE_TPHSOT; + return true; +} + + + +/** + * Reads the tiles. + */ +bool j2k_decode_tiles ( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager) +{ + bool l_go_on = true; + OPJ_UINT32 l_current_tile_no; + OPJ_UINT32 l_data_size,l_max_data_size; + OPJ_INT32 l_tile_x0,l_tile_y0,l_tile_x1,l_tile_y1; + OPJ_UINT32 l_nb_comps; + OPJ_BYTE * l_current_data; + + l_current_data = opj_malloc(1000); + if + (! l_current_data) + { + return false; + } + l_max_data_size = 1000; + + while + (true) + { + if + (! j2k_read_tile_header( + p_j2k,&l_current_tile_no, + &l_data_size, + &l_tile_x0, + &l_tile_y0, + &l_tile_x1, + &l_tile_y1, + &l_nb_comps, + &l_go_on, + p_stream, + p_manager)) + { + return false; + } + if + (! l_go_on) + { + break; + } + if + (l_data_size > l_max_data_size) + { + l_current_data = opj_realloc(l_current_data,l_data_size); + if + (! l_current_data) + { + return false; + } + l_max_data_size = l_data_size; + } + if + (! j2k_decode_tile(p_j2k,l_current_tile_no,l_current_data,l_data_size,p_stream,p_manager)) + { + opj_free(l_current_data); + return false; + } + if + (! j2k_update_image_data(p_j2k->m_tcd,l_current_data)) + { + opj_free(l_current_data); + return false; + } } - - /* destroy the tile encoder */ - tcd_free_encode(tcd); - tcd_destroy(tcd); - - opj_free(j2k->cur_totnum_tp); - - j2k_write_eoc(j2k); - - if(cstr_info) { - cstr_info->codestream_size = cio_tell(cio) + j2k->pos_correction; - /* 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 */ - cstr_info->codestream_size -= cstr_info->main_head_start; - /* <epc_on) { - - /* encode according to JPWL */ - jpwl_encode(j2k, cio, image); - - } -#endif /* USE_JPWL */ - + opj_free(l_current_data); return true; } @@ -2507,3 +8898,410 @@ bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestre +/** + * Decodes the tiles of the stream. + */ +opj_image_t * j2k_decode( + opj_j2k_t * p_j2k, + opj_stream_private_t * p_stream, + opj_event_mgr_t * p_manager) +{ + /* customization of the encoding */ + j2k_setup_decoding(p_j2k); + + /* write header */ + if + (! j2k_exec (p_j2k,p_j2k->m_procedure_list,p_stream,p_manager)) + { + opj_image_destroy(p_j2k->m_image); + p_j2k->m_image = 00; + } + return p_j2k->m_image; +} + +/** + * Encodes all the tiles in a row. + */ +bool j2k_encode( + opj_j2k_t * p_j2k, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + OPJ_UINT32 i; + OPJ_UINT32 l_nb_tiles; + OPJ_UINT32 l_max_tile_size, l_current_tile_size; + OPJ_BYTE * l_current_data; + + // preconditions + assert(p_j2k != 00); + assert(p_stream != 00); + assert(p_manager != 00); + + l_current_data = opj_malloc(1000); + if + (! l_current_data) + { + return false; + } + l_max_tile_size = 1000; + + l_nb_tiles = p_j2k->m_cp.th * p_j2k->m_cp.tw; + for + (i=0;im_tcd); + if + (l_current_tile_size > l_max_tile_size) + { + l_current_data = opj_realloc(l_current_data,l_current_tile_size); + if + (! l_current_data) + { + return false; + } + l_max_tile_size = l_current_tile_size; + } + j2k_get_tile_data(p_j2k->m_tcd,l_current_data); + if + (! j2k_post_write_tile (p_j2k,l_current_data,l_current_tile_size,p_stream,p_manager)) + { + return false; + } + } + opj_free(l_current_data); + return true; +} + + + +/** + * Ends the decompression procedures and possibiliy add data to be read after the + * codestream. + */ +bool j2k_end_decompress( + opj_j2k_t *p_j2k, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager) +{ + return true; +} + + + +void j2k_get_tile_data (opj_tcd_t * p_tcd, OPJ_BYTE * p_data) +{ + OPJ_UINT32 i,j,k = 0; + OPJ_UINT32 l_width,l_height,l_stride, l_offset_x,l_offset_y, l_image_width; + opj_image_comp_t * l_img_comp = 00; + opj_tcd_tilecomp_t * l_tilec = 00; + opj_image_t * l_image = 00; + OPJ_UINT32 l_size_comp, l_remaining; + OPJ_INT32 * l_src_ptr; + l_tilec = p_tcd->tcd_image->tiles->comps; + l_image = p_tcd->image; + l_img_comp = l_image->comps; + for + (i=0;iimage->numcomps;++i) + { + l_size_comp = l_img_comp->prec >> 3; /*(/ 8)*/ + l_remaining = l_img_comp->prec & 7; /* (%8) */ + if + (l_remaining) + { + ++l_size_comp; + } + if + (l_size_comp == 3) + { + l_size_comp = 4; + } + l_width = (l_tilec->x1 - l_tilec->x0); + l_height = (l_tilec->y1 - l_tilec->y0); + l_offset_x = int_ceildiv(l_image->x0, l_img_comp->dx); + l_offset_y = int_ceildiv(l_image->y0, l_img_comp->dy); + l_image_width = int_ceildiv(l_image->x1 - l_image->x0, 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; + + switch + (l_size_comp) + { + case 1: + { + OPJ_CHAR * l_dest_ptr = (OPJ_CHAR*) p_data; + if + (l_img_comp->sgnd) + { + for + (j=0;jsgnd) + { + for + (j=0;jtcd_image->tiles->comps; + l_image = p_tcd->image; + l_img_comp = l_image->comps; + for + (i=0;iimage->numcomps;++i) + { + if + (!l_img_comp->data) + { + l_img_comp->data = (OPJ_INT32*) opj_malloc(l_img_comp->w * l_img_comp->h * sizeof(OPJ_INT32)); + if + (! l_img_comp->data) + { + return false; + } + memset(l_img_comp->data,0,l_img_comp->w * l_img_comp->h * sizeof(OPJ_INT32)); + } + + 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; + + if + (l_remaining) + { + ++l_size_comp; + } + if + (l_size_comp == 3) + { + l_size_comp = 4; + } + l_width = (l_res->x1 - l_res->x0); + l_height = (l_res->y1 - l_res->y0); + l_dest_stride = (l_img_comp->w) - l_width; + l_offset_x = int_ceildivpow2(l_img_comp->x0, l_img_comp->factor); + l_offset_y = int_ceildivpow2(l_img_comp->y0, l_img_comp->factor); + l_dest_ptr = l_img_comp->data + (l_res->x0 - l_offset_x) + (l_res->y0 - l_offset_y) * l_img_comp->w; + + switch + (l_size_comp) + { + case 1: + { + OPJ_CHAR * l_src_ptr = (OPJ_CHAR*) p_data; + if + (l_img_comp->sgnd) + { + for + (j=0;jsgnd) + { + for + (j=0;jm_cp); + + if + (p_j2k->m_specific_param.m_decoder.m_state != J2K_DEC_STATE_TPHSOT) + { + return false; + } + p_j2k->m_specific_param.m_decoder.m_start_tile_x = (p_start_x - l_cp->tx0) / l_cp->tdx; + p_j2k->m_specific_param.m_decoder.m_start_tile_y = (p_start_y - l_cp->ty0) / l_cp->tdy; + p_j2k->m_specific_param.m_decoder.m_end_tile_x = int_ceildiv((p_end_x - l_cp->tx0), l_cp->tdx); + p_j2k->m_specific_param.m_decoder.m_end_tile_y = int_ceildiv((p_end_y - l_cp->ty0), l_cp->tdy); + p_j2k->m_specific_param.m_decoder.m_discard_tiles = 1; + return true; +} diff --git a/libopenjpeg/j2k.h b/libopenjpeg/j2k.h index 5599be47..c28123a5 100644 --- a/libopenjpeg/j2k.h +++ b/libopenjpeg/j2k.h @@ -6,6 +6,7 @@ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2006-2007, Parvatha Elangovan + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,6 +39,11 @@ The functions in J2K.C have for goal to read/write the several parts of the codestream: markers and data. */ +#include "openjpeg.h" + +struct opj_dparameters; +struct opj_stream_private; +struct opj_event_mgr; /** @defgroup J2K J2K - JPEG-2000 codestream reader/writer */ /*@{*/ @@ -77,6 +83,11 @@ The functions in J2K.C have for goal to read/write the several parts of the code #define J2K_MS_EPH 0xff92 /**< EPH marker value */ #define J2K_MS_CRG 0xff63 /**< CRG marker value */ #define J2K_MS_COM 0xff64 /**< COM marker value */ +#define J2K_MS_CBD 0xff78 /**< CBD marker value */ +#define J2K_MS_MCC 0xff75 /**< MCC marker value */ +#define J2K_MS_MCT 0xff74 /**< MCT marker value */ +#define J2K_MS_MCO 0xff77 /**< MCO marker value */ + /* UniPG>> */ #ifdef USE_JPWL #define J2K_MS_EPC 0xff68 /**< EPC marker value (Part 11: JPEG 2000 for Wireless) */ @@ -97,171 +108,267 @@ The functions in J2K.C have for goal to read/write the several parts of the code Values that specify the status of the decoding process when decoding the main header. These values may be combined with a | operator. */ -typedef enum J2K_STATUS { - J2K_STATE_MHSOC = 0x0001, /**< a SOC marker is expected */ - J2K_STATE_MHSIZ = 0x0002, /**< a SIZ marker is expected */ - J2K_STATE_MH = 0x0004, /**< the decoding process is in the main header */ - J2K_STATE_TPHSOT = 0x0008, /**< the decoding process is in a tile part header and expects a SOT marker */ - J2K_STATE_TPH = 0x0010, /**< the decoding process is in a tile part header */ - J2K_STATE_MT = 0x0020, /**< the EOC marker has just been read */ - J2K_STATE_NEOC = 0x0040, /**< the decoding process must not expect a EOC marker because the codestream is truncated */ - J2K_STATE_ERR = 0x0080 /**< the decoding process has encountered an error */ -} J2K_STATUS; +typedef enum +{ + J2K_DEC_STATE_NONE = 0x0000, /**< a SOC marker is expected */ + J2K_DEC_STATE_MHSOC = 0x0001, /**< a SOC marker is expected */ + J2K_DEC_STATE_MHSIZ = 0x0002, /**< a SIZ marker is expected */ + J2K_DEC_STATE_MH = 0x0004, /**< the decoding process is in the main header */ + J2K_DEC_STATE_TPHSOT = 0x0008, /**< the decoding process is in a tile part header and expects a SOT marker */ + J2K_DEC_STATE_TPH = 0x0010, /**< the decoding process is in a tile part header */ + J2K_DEC_STATE_MT = 0x0020, /**< the EOC marker has just been read */ + J2K_DEC_STATE_NEOC = 0x0040, /**< the decoding process must not expect a EOC marker because the codestream is truncated */ + J2K_DEC_STATE_DATA = 0x0080, /**< the decoding process must not expect a EOC marker because the codestream is truncated */ + J2K_DEC_STATE_ERR = 0x8000, /**< the decoding process has encountered an error */ + J2K_DEC_STATE_EOC = 0x0100 +} +J2K_DECODING_STATUS; + +/** +Values that specify the status of the decoding process when decoding the main header. +These values may be combined with a | operator. +*/ +typedef enum +{ + J2K_ENC_STATE_NONE = 0x0000, /**< a SOC marker is expected */ + J2K_ENC_STATE_ENCODE = 0x0001, /**< a SOC marker is expected */ +} +J2K_ENCODING_STATUS; + +/** + * Type of data for storing the MCT data + */ +typedef enum MCT_ELEMENT_TYPE +{ + MCT_TYPE_INT16 = 0, /** MCT data is stored as signed shorts*/ + MCT_TYPE_INT32 = 1, /** MCT data is stored as signed integers*/ + MCT_TYPE_FLOAT = 2, /** MCT data is stored as floats*/ + MCT_TYPE_DOUBLE = 3 /** MCT data is stored as doubles*/ +} J2K_MCT_ELEMENT_TYPE; + +/** + * Type of data for storing the MCT data + */ +typedef enum MCT_ARRAY_TYPE +{ + MCT_TYPE_DEPENDENCY = 0, + MCT_TYPE_DECORRELATION = 1, + MCT_TYPE_OFFSET = 2 +} J2K_MCT_ARRAY_TYPE; + /* ----------------------------------------------------------------------- */ -/** -T2 encoding mode -*/ -typedef enum T2_MODE { - THRESH_CALC = 0, /** Function called in Rate allocation process*/ - FINAL_PASS = 1 /** Function called in Tier 2 process*/ -}J2K_T2_MODE; + /** Quantization stepsize */ -typedef struct opj_stepsize { +typedef struct opj_stepsize +{ /** exponent */ - int expn; + OPJ_UINT32 expn; /** mantissa */ - int mant; -} opj_stepsize_t; + OPJ_UINT32 mant; +} +opj_stepsize_t; + +typedef struct opj_mct_data +{ + J2K_MCT_ELEMENT_TYPE m_element_type; + J2K_MCT_ARRAY_TYPE m_array_type; + OPJ_UINT32 m_index; + OPJ_BYTE * m_data; + OPJ_UINT32 m_data_size; +} +opj_mct_data_t; + +typedef struct opj_simple_mcc_decorrelation_data +{ + OPJ_UINT32 m_index; + OPJ_UINT32 m_nb_comps; + opj_mct_data_t * m_decorrelation_array; + opj_mct_data_t * m_offset_array; + OPJ_UINT32 m_is_irreversible : 1; +} +opj_simple_mcc_decorrelation_data_t; + /** Tile-component coding parameters */ -typedef struct opj_tccp { +typedef struct opj_tccp +{ /** coding style */ - int csty; + OPJ_UINT32 csty; /** number of resolutions */ - int numresolutions; + OPJ_UINT32 numresolutions; /** code-blocks width */ - int cblkw; + OPJ_UINT32 cblkw; /** code-blocks height */ - int cblkh; + OPJ_UINT32 cblkh; /** code-block coding style */ - int cblksty; + OPJ_UINT32 cblksty; /** discrete wavelet transform identifier */ - int qmfbid; + OPJ_UINT32 qmfbid; /** quantisation style */ - int qntsty; + OPJ_UINT32 qntsty; /** stepsizes used for quantization */ opj_stepsize_t stepsizes[J2K_MAXBANDS]; /** number of guard bits */ - int numgbits; + OPJ_UINT32 numgbits; /** Region Of Interest shift */ - int roishift; + OPJ_INT32 roishift; /** precinct width */ - int prcw[J2K_MAXRLVLS]; + OPJ_UINT32 prcw[J2K_MAXRLVLS]; /** precinct height */ - int prch[J2K_MAXRLVLS]; -} opj_tccp_t; + OPJ_UINT32 prch[J2K_MAXRLVLS]; + /** the dc_level_shift **/ + OPJ_INT32 m_dc_level_shift; +} +opj_tccp_t; /** Tile coding parameters : this structure is used to store 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; +typedef struct opj_tcp +{ /** coding style */ - int csty; + OPJ_UINT32 csty; /** progression order */ OPJ_PROG_ORDER prg; /** number of layers */ - int numlayers; + OPJ_UINT32 numlayers; + OPJ_UINT32 num_layers_to_decode; /** multi-component transform identifier */ - int mct; + OPJ_UINT32 mct; /** rates of layers */ - float rates[100]; + OPJ_FLOAT32 rates[100]; /** number of progression order changes */ - int numpocs; - /** indicates if a POC marker has been used O:NO, 1:YES */ - int POC; + OPJ_UINT32 numpocs; /** progression order changes */ opj_poc_t pocs[32]; /** 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; - /** ppmbug1 */ - int ppt_len; + OPJ_BYTE *ppt_data; + /** used to keep a track of the allocated memory */ + OPJ_BYTE *ppt_buffer; + /** Number of bytes stored inside ppt_data*/ + OPJ_UINT32 ppt_data_size; + /** size of ppt_data*/ + OPJ_UINT32 ppt_len; /** add fixed_quality */ - float distoratio[100]; + OPJ_FLOAT32 distoratio[100]; /** tile-component coding parameters */ opj_tccp_t *tccps; + /** number of tile parts for the tile. */ + OPJ_UINT32 m_nb_tile_parts; + /** data for the tile */ + OPJ_BYTE * m_data; + /** size of data */ + OPJ_UINT32 m_data_size; + /** encoding norms */ + OPJ_FLOAT64 * mct_norms; + /** the mct decoding matrix */ + OPJ_FLOAT32 * m_mct_decoding_matrix; + /** the mct coding matrix */ + OPJ_FLOAT32 * m_mct_coding_matrix; + /** mct records */ + opj_mct_data_t * m_mct_records; + /** the number of mct records. */ + OPJ_UINT32 m_nb_mct_records; + /** the max number of mct records. */ + OPJ_UINT32 m_nb_max_mct_records; + /** mcc records */ + opj_simple_mcc_decorrelation_data_t * m_mcc_records; + /** the number of mct records. */ + OPJ_UINT32 m_nb_mcc_records; + /** the max number of mct records. */ + OPJ_UINT32 m_nb_max_mcc_records; + + + + /***** FLAGS *******/ + /** If ppt == 1 --> there was a PPT marker for the present tile */ + OPJ_UINT32 ppt : 1; + /** indicates if a POC marker has been used O:NO, 1:YES */ + OPJ_UINT32 POC : 1; } opj_tcp_t; +typedef struct opj_encoding_param +{ + /** Digital cinema profile*/ + OPJ_CINEMA_MODE m_cinema; + /** Maximum rate for each component. If == 0, component size limitation is not considered */ + OPJ_UINT32 m_max_comp_size; + /** Position of tile part flag in progression order*/ + OPJ_INT32 m_tp_pos; + /** fixed layer */ + OPJ_INT32 *m_matrice; + /** Flag determining tile part generation*/ + OPJ_BYTE m_tp_flag; + /** allocation by rate/distortion */ + OPJ_UINT32 m_disto_alloc : 1; + /** allocation by fixed layer */ + OPJ_UINT32 m_fixed_alloc : 1; + /** add fixed_quality */ + OPJ_UINT32 m_fixed_quality : 1; + /** Enabling Tile part generation*/ + OPJ_UINT32 m_tp_on : 1; +} +opj_encoding_param_t; + +typedef struct opj_decoding_param +{ + /** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */ + OPJ_UINT32 m_reduce; + /** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ + OPJ_UINT32 m_layer; +} +opj_decoding_param_t; + /** Coding parameters */ -typedef struct opj_cp { - /** Digital cinema profile*/ - OPJ_CINEMA_MODE cinema; - /** Maximum rate for each component. If == 0, component size limitation is not considered */ - int max_comp_size; +typedef struct opj_cp +{ /** Size of the image in bits*/ - int img_size; + /*int img_size;*/ /** Rsiz*/ OPJ_RSIZ_CAPABILITIES rsiz; - /** Enabling Tile part generation*/ - char tp_on; - /** Flag determining tile part generation*/ - char tp_flag; - /** Position of tile part flag in progression order*/ - int tp_pos; - /** allocation by rate/distortion */ - int disto_alloc; - /** allocation by fixed layer */ - int fixed_alloc; - /** add fixed_quality */ - int fixed_quality; - /** if != 0, then original dimension divided by 2^(reduce); if == 0 or not used, image is decoded to the full resolution */ - int reduce; - /** if != 0, then only the first "layer" layers are decoded; if == 0 or not used, all the quality layers are decoded */ - int layer; - /** if == NO_LIMITATION, decode entire codestream; if == LIMIT_TO_MAIN_HEADER then only decode the main header */ - OPJ_LIMIT_DECODING limit_decoding; /** XTOsiz */ - int tx0; + OPJ_INT32 tx0; /** YTOsiz */ - int ty0; + OPJ_INT32 ty0; /** XTsiz */ - int tdx; + OPJ_UINT32 tdx; /** YTsiz */ - int tdy; - /** comment for coding */ - char *comment; + OPJ_UINT32 tdy; + /** comment */ + OPJ_CHAR *comment; /** number of tiles in width */ - int tw; + OPJ_UINT32 tw; /** number of tiles in heigth */ - int th; - /** ID number of the tiles present in the codestream */ - int *tileno; - /** size of the vector tileno */ - int tileno_size; + OPJ_UINT32 th; + /** packet header storage original buffer */ + OPJ_BYTE *ppm_buffer; /** 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; - /** ppmbug1 */ - int ppm_len; + OPJ_BYTE *ppm_data; + /** size of the ppm_data*/ + OPJ_UINT32 ppm_len; + /** Number of bytes actually stored inside the ppm_data */ + OPJ_UINT32 ppm_data_size; /** tile coding parameters */ opj_tcp_t *tcps; - /** fixed layer */ - int *matrice; + union + { + opj_decoding_param_t m_dec; + opj_encoding_param_t m_enc; + } + m_specific_param; + + /* UniPG>> */ #ifdef USE_JPWL /** enables writing of EPC in MH, thus activating JPWL */ @@ -305,90 +412,192 @@ typedef struct opj_cp { /** maximum number of tiles at the decoder */ int max_tiles; #endif /* USE_JPWL */ + + /******** FLAGS *********/ + /** if ppm == 1 --> there was a PPM marker*/ + OPJ_UINT32 ppm : 1; + /** tells if the parameter is a coding or decoding one */ + OPJ_UINT32 m_is_decoder : 1; /* <cp. -@param j2k J2K decompressor handle -@param parameters decompression parameters + * Starts a compression scheme, i.e. validates the codec parameters, writes the header. + * + * @param p_j2k the jpeg2000 codec. + * @param cio the stream object. + * @param p_manager the user event manager. + * + * @return true if the codec is valid. + */ +bool j2k_start_compress( + opj_j2k_t *p_j2k, + struct opj_stream_private *cio, + struct opj_image * p_image, + struct opj_event_mgr * p_manager + ); +/** + * Ends the compression procedures and possibiliy add data to be read after the + * codestream. + */ +bool j2k_end_compress(opj_j2k_t *p_j2k, struct opj_stream_private *cio, struct opj_event_mgr * p_manager); + +/** + * Sets up the decoder decoding parameters using user parameters. + * Decoding parameters are stored in j2k->cp. + * + * @param p_j2k J2K codec + * @param p_parameters decompression parameters + * @deprecated */ -void j2k_setup_decoder(opj_j2k_t *j2k, opj_dparameters_t *parameters); +void j2k_setup_decoder( + opj_j2k_t *p_j2k, + struct opj_dparameters *p_parameters + ); +/** + * Reads a jpeg2000 codestream header structure. + * + * @param cio the stream to read data from. + * @param p_j2k the jpeg2000 codec. + * @param p_manager the user event manager. + * + * @return true if the box is valid. + */ +bool j2k_read_header( + opj_j2k_t *p_j2k, + struct opj_image ** p_image, + OPJ_INT32 * p_tile_x0, + OPJ_INT32 * p_tile_y0, + OPJ_UINT32 * p_tile_width, + OPJ_UINT32 * p_tile_height, + OPJ_UINT32 * p_nb_tiles_x, + OPJ_UINT32 * p_nb_tiles_y, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); /** Decode an image from a JPEG-2000 codestream @param j2k J2K decompressor handle @@ -396,7 +605,14 @@ Decode an image from a JPEG-2000 codestream @param cstr_info Codestream information structure if required, NULL otherwise @return Returns a decoded image if successful, returns NULL otherwise */ -opj_image_t* j2k_decode(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info); +opj_image_t* j2k_decode(opj_j2k_t *j2k, struct opj_stream_private *cio, struct opj_event_mgr * p_manager); + +/** + * Ends the decompression procedures and possibiliy add data to be read after the + * codestream. + */ +bool j2k_end_decompress(opj_j2k_t *j2k, struct opj_stream_private *cio, struct opj_event_mgr * p_manager); + /** Decode an image form a JPT-stream (JPEG 2000, JPIP) @param j2k J2K decompressor handle @@ -404,18 +620,15 @@ Decode an image form a JPT-stream (JPEG 2000, JPIP) @param cstr_info Codestream information structure if required, NULL otherwise @return Returns a decoded image if successful, returns NULL otherwise */ -opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, opj_cio_t *cio, opj_codestream_info_t *cstr_info); +opj_image_t* j2k_decode_jpt_stream(opj_j2k_t *j2k, struct opj_stream_private *cio, struct opj_codestream_info *cstr_info); + /** Creates a J2K compression structure @param cinfo Codec context info @return Returns a handle to a J2K compressor if successful, returns NULL otherwise */ -opj_j2k_t* j2k_create_compress(opj_common_ptr cinfo); -/** -Destroy a J2K compressor handle -@param j2k J2K compressor handle to destroy -*/ -void j2k_destroy_compress(opj_j2k_t *j2k); +opj_j2k_t* j2k_create_compress(); + /** Setup the encoder parameters using the current image and using user parameters. Coding parameters are returned in j2k->cp. @@ -423,20 +636,97 @@ Coding parameters are returned in j2k->cp. @param parameters compression parameters @param image input filled image */ -void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image); +void j2k_setup_encoder(opj_j2k_t *j2k, opj_cparameters_t *parameters, opj_image_t *image, struct opj_event_mgr * p_manager); + /** -Converts an enum type progression order to string type -*/ -char *j2k_convert_progression_order(OPJ_PROG_ORDER prg_order); + * Writes a tile. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool j2k_write_tile ( + opj_j2k_t * p_j2k, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); + /** -Encode an image into a JPEG-2000 codestream -@param j2k J2K compressor handle -@param cio Output buffer stream -@param image Image to encode -@param cstr_info Codestream information structure if required, NULL otherwise -@return Returns true if successful, returns false otherwise -*/ -bool j2k_encode(opj_j2k_t *j2k, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); + * Converts an enum type progression order to string type. + * + * @param prg_order the progression order to get. + * + * @return the string representation of the gicen progression order. + */ +const char * j2k_convert_progression_order(OPJ_PROG_ORDER prg_order); + + +/** + * Encodes an image into a JPEG-2000 codestream + */ +bool j2k_encode( + opj_j2k_t * p_j2k, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); +bool j2k_setup_mct_encoding (opj_tcp_t * p_tcp,opj_image_t * p_image); + +/** + * Decode tile data. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool j2k_decode_tile ( + opj_j2k_t * p_j2k, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Reads a tile header. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool j2k_read_tile_header ( + opj_j2k_t * p_j2k, + 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, + bool * p_go_on, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading. + * + * @param p_j2k the jpeg2000 codec. + * @param p_start_x the left position of the rectangle to decode (in image coordinates). + * @param p_end_x the right position of the rectangle to decode (in image coordinates). + * @param p_start_y the up position of the rectangle to decode (in image coordinates). + * @param p_end_y the bottom position of the rectangle to decode (in image coordinates). + * @param p_manager the user event manager + * + * @return true if the area could be set. + */ +bool j2k_set_decode_area( + opj_j2k_t *p_j2k, + OPJ_INT32 p_start_x, + OPJ_INT32 p_start_y, + OPJ_INT32 p_end_x, + OPJ_INT32 p_end_y, + struct opj_event_mgr * p_manager + ); + /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/j2k_lib.c b/libopenjpeg/j2k_lib.c index 91aee007..3b86c728 100644 --- a/libopenjpeg/j2k_lib.c +++ b/libopenjpeg/j2k_lib.c @@ -27,13 +27,16 @@ #ifdef WIN32 #include #else -#include +/*#include #include #include +*/ #endif /* WIN32 */ -#include "opj_includes.h" +#include "j2k_lib.h" -double opj_clock(void) { + +OPJ_FLOAT64 opj_clock(void) { +#if 0 #ifdef WIN32 /* WIN32: use QueryPerformance (very accurate) */ LARGE_INTEGER freq , t ; @@ -55,5 +58,8 @@ double opj_clock(void) { /* (2b) More precisely! Get the microseconds part ! */ return ( procTime + (t.ru_utime.tv_usec + t.ru_stime.tv_usec) * 1e-6 ) ; #endif + +#endif + return 0; } diff --git a/libopenjpeg/j2k_lib.h b/libopenjpeg/j2k_lib.h index 7df4d367..c78c4f21 100644 --- a/libopenjpeg/j2k_lib.h +++ b/libopenjpeg/j2k_lib.h @@ -31,7 +31,7 @@ The functions in J2K_LIB.C are internal utilities mainly used for timing. */ - +#include "openjpeg.h" /** @defgroup MISC MISC - Miscellaneous internal functions */ /*@{*/ @@ -43,7 +43,7 @@ The functions in J2K_LIB.C are internal utilities mainly used for timing. Difference in successive opj_clock() calls tells you the elapsed time @return Returns time in seconds */ -double opj_clock(void); +OPJ_FLOAT64 opj_clock(void); /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/jp2.c b/libopenjpeg/jp2.c index b2831cfb..1bd7b4a9 100644 --- a/libopenjpeg/jp2.c +++ b/libopenjpeg/jp2.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,540 +29,2052 @@ * 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 "jp2.h" +#include "cio.h" +#include "opj_malloc.h" +#include "event.h" +#include "j2k.h" +#include "function_list.h" +#include "assert.h" /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */ /*@{*/ +#define BOX_SIZE 1024 + + + /** @name Local static functions */ /*@{*/ -/** -Read box headers -@param cinfo Codec context info -@param cio Input stream -@param box -@return Returns true if successful, returns false otherwise -*/ -static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box); -/*static void jp2_write_url(opj_cio_t *cio, char *Idx_file);*/ -/** -Read the IHDR box - Image Header box -@param jp2 JP2 handle -@param cio Input buffer stream -@return Returns true if successful, returns false otherwise -*/ -static bool jp2_read_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); -static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio); -static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); -static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio); -static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio); -static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio); -/** -Write the FTYP box - File type box -@param jp2 JP2 handle -@param cio Output buffer stream -*/ -static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); -/** -Read the FTYP box - File type box -@param jp2 JP2 handle -@param cio Input buffer stream -@return Returns true if successful, returns false otherwise -*/ -static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio); -static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); -static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset); -static void jp2_write_jp(opj_cio_t *cio); -/** -Read the JP box - JPEG 2000 signature -@param jp2 JP2 handle -@param cio Input buffer stream -@return Returns true if successful, returns false otherwise -*/ -static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio); -/** -Decode the structure of a JP2 file -@param jp2 JP2 handle -@param cio Input buffer stream -@return Returns true if successful, returns false otherwise -*/ -static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio); + +/** + * Writes the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box). + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager user event manager. + * + * @return true if writting was successful. +*/ +bool jp2_write_jp2h( + opj_jp2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); + +/** + * Skips the Jpeg2000 Codestream Header box - JP2C Header box. + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager user event manager. + * + * @return true if writting was successful. +*/ +bool jp2_skip_jp2c( + opj_jp2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); + +/** + * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box). + * + * @param p_header_data the data contained in the file header box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the file header box. + * @param p_manager the user event manager. + * + * @return true if the JP2 Header box was successfully reconized. +*/ +bool jp2_read_jp2h( + opj_jp2_t *jp2, + unsigned char * p_header_data, + unsigned int p_header_size, + struct opj_event_mgr * p_manager + ); + +/** + * Writes the Jpeg2000 codestream Header box - JP2C Header box. This function must be called AFTER the coding has been done. + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager user event manager. + * + * @return true if writting was successful. +*/ +static bool jp2_write_jp2c( + opj_jp2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure. + * + * @param cio the input stream to read data from. + * @param box the box structure to fill. + * @param p_number_bytes_read pointer to an int that will store the number of bytes read from the stream (shoul usually be 2). + * @param p_manager user event manager. + * + * @return true if the box is reconized, false otherwise +*/ +static bool jp2_read_boxhdr( + opj_jp2_box_t *box, + OPJ_UINT32 * p_number_bytes_read, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure. Data is read from a character string + * + * @param p_data the character string to read data from. + * @param box the box structure to fill. + * @param p_number_bytes_read pointer to an int that will store the number of bytes read from the stream (shoul usually be 2). + * @param p_box_max_size the maximum number of bytes in the box. + * + * @return true if the box is reconized, false otherwise +*/ +static bool jp2_read_boxhdr_char( + opj_jp2_box_t *box, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_number_bytes_read, + OPJ_UINT32 p_box_max_size, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a jpeg2000 file signature box. + * + * @param p_header_data the data contained in the signature box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the signature box. + * @param p_manager the user event manager. + * + * @return true if the file signature box is valid. + */ +static bool jp2_read_jp( + opj_jp2_t *jp2, + unsigned char * p_header_data, + unsigned int p_header_size, + struct opj_event_mgr * p_manager + ); + +/** + * Writes a jpeg2000 file signature box. + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager the user event manager. + * + * @return true if writting was successful. + */ +static bool jp2_write_jp( + opj_jp2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); + +/** + * Writes a FTYP box - File type box + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager the user event manager. + * + * @return true if writting was successful. + */ +static bool jp2_write_ftyp( + opj_jp2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a a FTYP box - File type box + * + * @param p_header_data the data contained in the FTYP box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the FTYP box. + * @param p_manager the user event manager. + * + * @return true if the FTYP box is valid. + */ +static bool jp2_read_ftyp( + opj_jp2_t *jp2, + unsigned char * p_header_data, + unsigned int p_header_size, + struct opj_event_mgr * p_manager + ); + +/** + * Reads a IHDR box - Image Header box + * + * @param p_image_header_data pointer to actual data (already read from file) + * @param jp2 the jpeg2000 file codec. + * @param p_image_header_size the size of the image header + * @param p_manager the user event manager. + * + * @return true if the image header is valid, fale else. + */ +static bool jp2_read_ihdr( + opj_jp2_t *jp2, + unsigned char * p_image_header_data, + unsigned int p_image_header_size, + struct opj_event_mgr * p_manager + ); + +/** + * Writes the Image Header box - Image Header box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +static unsigned char * jp2_write_ihdr( + opj_jp2_t *jp2, + unsigned int * p_nb_bytes_written + ); + +/** + * Reads a Bit per Component box. + * + * @param p_bpc_header_data pointer to actual data (already read from file) + * @param jp2 the jpeg2000 file codec. + * @param p_bpc_header_size the size of the bpc header + * @param p_manager the user event manager. + * + * @return true if the bpc header is valid, fale else. + */ +static bool jp2_read_bpcc( + opj_jp2_t *jp2, + unsigned char * p_bpc_header_data, + unsigned int p_bpc_header_size, + struct opj_event_mgr * p_manager + ); + + +/** + * Writes the Bit per Component box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +static unsigned char * jp2_write_bpcc( + opj_jp2_t *jp2, + unsigned int * p_nb_bytes_written + ); + +/** + * Reads the Colour Specification box. + * + * @param p_colr_header_data pointer to actual data (already read from file) + * @param jp2 the jpeg2000 file codec. + * @param p_colr_header_size the size of the color header + * @param p_manager the user event manager. + * + * @return true if the bpc header is valid, fale else. +*/ +static bool jp2_read_colr( + opj_jp2_t *jp2, + unsigned char * p_colr_header_data, + unsigned int p_colr_header_size, + struct opj_event_mgr * p_manager + ); + +/** + * Writes the Colour Specification box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +static unsigned char *jp2_write_colr( + opj_jp2_t *jp2, + unsigned int * p_nb_bytes_written + ); + + +/** + * Reads a jpeg2000 file header structure. + * + * @param cio the stream to read data from. + * @param jp2 the jpeg2000 file header structure. + * @param p_manager the user event manager. + * + * @return true if the box is valid. + */ +bool jp2_read_header_procedure( + opj_jp2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); +/** + * Excutes the given procedures on the given codec. + * + * @param p_procedure_list the list of procedures to execute + * @param jp2 the jpeg2000 file codec to execute the procedures on. + * @param cio the stream to execute the procedures on. + * @param p_manager the user manager. + * + * @return true if all the procedures were successfully executed. + */ +static bool jp2_exec ( + opj_jp2_t * jp2, + struct opj_procedure_list * p_procedure_list, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); +/** + * Finds the execution function related to the given box id. + * + * @param p_id the id of the handler to fetch. + * + * @return the given handler or NULL if it could not be found. + */ +static const opj_jp2_header_handler_t * jp2_find_handler (int p_id); + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +static void jp2_setup_encoding_validation (opj_jp2_t *jp2); + +/** + * Sets up the procedures to do on writting header. Developpers wanting to extend the library can add their own writting procedures. + */ +static void jp2_setup_header_writting (opj_jp2_t *jp2); + +/** + * The default validation procedure without any extension. + * + * @param jp2 the jpeg2000 codec to validate. + * @param cio the input stream to validate. + * @param p_manager the user event manager. + * + * @return true if the parameters are correct. + */ +bool jp2_default_validation ( + opj_jp2_t * jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); + +/** + * Finds the execution function related to the given box id. + * + * @param p_id the id of the handler to fetch. + * + * @return the given handler or NULL if it could not be found. + */ +static const opj_jp2_header_handler_t * jp2_find_handler ( + int p_id + ); + +/** + * Finds the image execution function related to the given box id. + * + * @param p_id the id of the handler to fetch. + * + * @return the given handler or NULL if it could not be found. + */ +static const opj_jp2_header_handler_t * jp2_img_find_handler ( + int p_id + ); + +/** + * Sets up the procedures to do on writting header after the codestream. + * Developpers wanting to extend the library can add their own writting procedures. + */ +static void jp2_setup_end_header_writting (opj_jp2_t *jp2); + +/** + * Sets up the procedures to do on reading header after the codestream. + * Developpers wanting to extend the library can add their own writting procedures. + */ +static void jp2_setup_end_header_reading (opj_jp2_t *jp2); + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +static void jp2_setup_decoding_validation (opj_jp2_t *jp2); + +/** + * Sets up the procedures to do on reading header. + * Developpers wanting to extend the library can add their own writting procedures. + */ +static void jp2_setup_header_reading (opj_jp2_t *jp2); /*@}*/ /*@}*/ /* ----------------------------------------------------------------------- */ +const opj_jp2_header_handler_t jp2_header [] = +{ + {JP2_JP,jp2_read_jp}, + {JP2_FTYP,jp2_read_ftyp}, + {JP2_JP2H,jp2_read_jp2h} +}; -static bool jp2_read_boxhdr(opj_common_ptr cinfo, opj_cio_t *cio, opj_jp2_box_t *box) { - box->init_pos = cio_tell(cio); - box->length = cio_read(cio, 4); - box->type = cio_read(cio, 4); - if (box->length == 1) { - if (cio_read(cio, 4) != 0) { - opj_event_msg(cinfo, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n"); - return false; +const opj_jp2_header_handler_t jp2_img_header [] = +{ + {JP2_IHDR,jp2_read_ihdr}, + {JP2_COLR,jp2_read_colr}, + {JP2_BPCC,jp2_read_bpcc} +}; +/** + * Finds the execution function related to the given box id. + * + * @param p_id the id of the handler to fetch. + * + * @return the given handler or 00 if it could not be found. + */ +const opj_jp2_header_handler_t * jp2_find_handler ( + int p_id + ) +{ + unsigned int i, l_handler_size = sizeof(jp2_header) / sizeof(opj_jp2_header_handler_t); + for + (i=0;ilength = cio_read(cio, 4); - if (box->length == 0) - box->length = cio_numbytesleft(cio) + 12; } - else if (box->length == 0) { - box->length = cio_numbytesleft(cio) + 8; + return 00; +} + +/** + * Finds the image execution function related to the given box id. + * + * @param p_id the id of the handler to fetch. + * + * @return the given handler or 00 if it could not be found. + */ +static const opj_jp2_header_handler_t * jp2_img_find_handler ( + int p_id + ) +{ + unsigned int i, l_handler_size = sizeof(jp2_img_header) / sizeof(opj_jp2_header_handler_t); + for + (i=0;icinfo; - - jp2_read_boxhdr(cinfo, cio, &box); - if (JP2_IHDR != box.type) { - opj_event_msg(cinfo, EVT_ERROR, "Expected IHDR Marker\n"); + if + (l_current_data == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle jpeg2000 file header\n"); return false; } - - jp2->h = cio_read(cio, 4); /* HEIGHT */ - jp2->w = cio_read(cio, 4); /* WIDTH */ - jp2->numcomps = cio_read(cio, 2); /* NC */ - jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t)); - - jp2->bpc = cio_read(cio, 1); /* BPC */ - - jp2->C = cio_read(cio, 1); /* C */ - jp2->UnkC = cio_read(cio, 1); /* UnkC */ - jp2->IPR = cio_read(cio, 1); /* IPR */ - - if (cio_tell(cio) - box.init_pos != box.length) { - opj_event_msg(cinfo, EVT_ERROR, "Error with IHDR Box\n"); - return false; - } - - return true; -} - -static void jp2_write_ihdr(opj_jp2_t *jp2, opj_cio_t *cio) { - opj_jp2_box_t box; - - box.init_pos = cio_tell(cio); - cio_skip(cio, 4); - cio_write(cio, JP2_IHDR, 4); /* IHDR */ - - cio_write(cio, jp2->h, 4); /* HEIGHT */ - cio_write(cio, jp2->w, 4); /* WIDTH */ - cio_write(cio, jp2->numcomps, 2); /* NC */ - - cio_write(cio, jp2->bpc, 1); /* BPC */ - - cio_write(cio, jp2->C, 1); /* C : Always 7 */ - cio_write(cio, jp2->UnkC, 1); /* UnkC, colorspace unknown */ - cio_write(cio, jp2->IPR, 1); /* IPR, no intellectual property */ - - box.length = cio_tell(cio) - box.init_pos; - cio_seek(cio, box.init_pos); - cio_write(cio, box.length, 4); /* L */ - cio_seek(cio, box.init_pos + box.length); -} - -static void jp2_write_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { - unsigned int i; - opj_jp2_box_t box; - - box.init_pos = cio_tell(cio); - cio_skip(cio, 4); - cio_write(cio, JP2_BPCC, 4); /* BPCC */ - - for (i = 0; i < jp2->numcomps; i++) { - cio_write(cio, jp2->comps[i].bpcc, 1); - } - - box.length = cio_tell(cio) - box.init_pos; - cio_seek(cio, box.init_pos); - cio_write(cio, box.length, 4); /* L */ - cio_seek(cio, box.init_pos + box.length); -} - - -static bool jp2_read_bpcc(opj_jp2_t *jp2, opj_cio_t *cio) { - unsigned int i; - opj_jp2_box_t box; - - opj_common_ptr cinfo = jp2->cinfo; - - jp2_read_boxhdr(cinfo, cio, &box); - if (JP2_BPCC != box.type) { - opj_event_msg(cinfo, EVT_ERROR, "Expected BPCC Marker\n"); - return false; - } - - for (i = 0; i < jp2->numcomps; i++) { - jp2->comps[i].bpcc = cio_read(cio, 1); - } - - if (cio_tell(cio) - box.init_pos != box.length) { - opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n"); - return false; - } - - return true; -} - -static void jp2_write_colr(opj_jp2_t *jp2, opj_cio_t *cio) { - opj_jp2_box_t box; - - box.init_pos = cio_tell(cio); - cio_skip(cio, 4); - cio_write(cio, JP2_COLR, 4); /* COLR */ - - cio_write(cio, jp2->meth, 1); /* METH */ - cio_write(cio, jp2->precedence, 1); /* PRECEDENCE */ - cio_write(cio, jp2->approx, 1); /* APPROX */ - - if (jp2->meth == 1) { - cio_write(cio, jp2->enumcs, 4); /* EnumCS */ - } else { - cio_write(cio, 0, 1); /* PROFILE (??) */ - } - - box.length = cio_tell(cio) - box.init_pos; - cio_seek(cio, box.init_pos); - cio_write(cio, box.length, 4); /* L */ - cio_seek(cio, box.init_pos + box.length); -} - -static bool jp2_read_colr(opj_jp2_t *jp2, opj_cio_t *cio) { - opj_jp2_box_t box; - int skip_len; - - opj_common_ptr cinfo = jp2->cinfo; - - jp2_read_boxhdr(cinfo, cio, &box); - do { - if (JP2_COLR != box.type) { - cio_skip(cio, box.length - 8); - jp2_read_boxhdr(cinfo, cio, &box); - } - } while(JP2_COLR != box.type); - - jp2->meth = cio_read(cio, 1); /* METH */ - jp2->precedence = cio_read(cio, 1); /* PRECEDENCE */ - jp2->approx = cio_read(cio, 1); /* APPROX */ - - if (jp2->meth == 1) { - jp2->enumcs = cio_read(cio, 4); /* EnumCS */ - } else { - /* skip PROFILE */ - skip_len = box.init_pos + box.length - cio_tell(cio); - if (skip_len < 0) { - opj_event_msg(cinfo, EVT_ERROR, "Error with JP2H box size\n"); - return false; - } - cio_skip(cio, box.init_pos + box.length - cio_tell(cio)); - } - - if (cio_tell(cio) - box.init_pos != box.length) { - opj_event_msg(cinfo, EVT_ERROR, "Error with BPCC Box\n"); - return false; - } - return true; -} - -void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { - opj_jp2_box_t box; - - box.init_pos = cio_tell(cio); - cio_skip(cio, 4); - cio_write(cio, JP2_JP2H, 4); /* JP2H */ - - jp2_write_ihdr(jp2, cio); - - if (jp2->bpc == 255) { - jp2_write_bpcc(jp2, cio); - } - jp2_write_colr(jp2, cio); - - box.length = cio_tell(cio) - box.init_pos; - cio_seek(cio, box.init_pos); - cio_write(cio, box.length, 4); /* L */ - cio_seek(cio, box.init_pos + box.length); -} - -bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio) { - opj_jp2_box_t box; - int skip_len; - - opj_common_ptr cinfo = jp2->cinfo; - - jp2_read_boxhdr(cinfo, cio, &box); - do { - if (JP2_JP2H != box.type) { - if (box.type == JP2_JP2C) { - opj_event_msg(cinfo, EVT_ERROR, "Expected JP2H Marker\n"); + memset(l_current_data, 0 , l_last_data_size); + while + (jp2_read_boxhdr(&box,&l_nb_bytes_read,cio,p_manager)) + { + // is it the codestream box ? + if + (box.type == JP2_JP2C) + { + if + (jp2->jp2_state & JP2_STATE_HEADER) + { + jp2->jp2_state |= JP2_STATE_CODESTREAM; + return true; + } + else + { + opj_event_msg(p_manager, EVT_ERROR, "bad placed jpeg codestream\n"); return false; } - cio_skip(cio, box.length - 8); - jp2_read_boxhdr(cinfo, cio, &box); } - } while(JP2_JP2H != box.type); - - if (!jp2_read_ihdr(jp2, cio)) - return false; - - if (jp2->bpc == 255) { - if (!jp2_read_bpcc(jp2, cio)) + else if + (box.length == 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n"); return false; - } - if (!jp2_read_colr(jp2, cio)) - return false; - - skip_len = box.init_pos + box.length - cio_tell(cio); - if (skip_len < 0) { - opj_event_msg(cinfo, EVT_ERROR, "Error with JP2H Box\n"); - return false; - } - cio_skip(cio, box.init_pos + box.length - cio_tell(cio)); - - return true; -} - -static void jp2_write_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { - unsigned int i; - opj_jp2_box_t box; - - box.init_pos = cio_tell(cio); - cio_skip(cio, 4); - cio_write(cio, JP2_FTYP, 4); /* FTYP */ - - cio_write(cio, jp2->brand, 4); /* BR */ - cio_write(cio, jp2->minversion, 4); /* MinV */ - - for (i = 0; i < jp2->numcl; i++) { - cio_write(cio, jp2->cl[i], 4); /* CL */ - } - - box.length = cio_tell(cio) - box.init_pos; - cio_seek(cio, box.init_pos); - cio_write(cio, box.length, 4); /* L */ - cio_seek(cio, box.init_pos + box.length); -} - -static bool jp2_read_ftyp(opj_jp2_t *jp2, opj_cio_t *cio) { - int i; - opj_jp2_box_t box; - - opj_common_ptr cinfo = jp2->cinfo; - - jp2_read_boxhdr(cinfo, cio, &box); - - if (JP2_FTYP != box.type) { - opj_event_msg(cinfo, EVT_ERROR, "Expected FTYP Marker\n"); - return false; - } - - jp2->brand = cio_read(cio, 4); /* BR */ - jp2->minversion = cio_read(cio, 4); /* MinV */ - jp2->numcl = (box.length - 16) / 4; - jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int)); - - for (i = 0; i < (int)jp2->numcl; i++) { - jp2->cl[i] = cio_read(cio, 4); /* CLi */ - } - - if (cio_tell(cio) - box.init_pos != box.length) { - opj_event_msg(cinfo, EVT_ERROR, "Error with FTYP Box\n"); - return false; - } - - return true; -} - -static int jp2_write_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { - unsigned int j2k_codestream_offset, j2k_codestream_length; - opj_jp2_box_t box; - - opj_j2k_t *j2k = jp2->j2k; - - box.init_pos = cio_tell(cio); - cio_skip(cio, 4); - cio_write(cio, JP2_JP2C, 4); /* JP2C */ - - /* J2K encoding */ - j2k_codestream_offset = cio_tell(cio); - if(!j2k_encode(j2k, cio, image, cstr_info)) { - opj_event_msg(j2k->cinfo, EVT_ERROR, "Failed to encode image\n"); - return 0; - } - j2k_codestream_length = cio_tell(cio) - j2k_codestream_offset; - - jp2->j2k_codestream_offset = j2k_codestream_offset; - jp2->j2k_codestream_length = j2k_codestream_length; - - box.length = 8 + jp2->j2k_codestream_length; - cio_seek(cio, box.init_pos); - cio_write(cio, box.length, 4); /* L */ - cio_seek(cio, box.init_pos + box.length); - - return box.length; -} - -static bool jp2_read_jp2c(opj_jp2_t *jp2, opj_cio_t *cio, unsigned int *j2k_codestream_length, unsigned int *j2k_codestream_offset) { - opj_jp2_box_t box; - - opj_common_ptr cinfo = jp2->cinfo; - - jp2_read_boxhdr(cinfo, cio, &box); - do { - if(JP2_JP2C != box.type) { - cio_skip(cio, box.length - 8); - jp2_read_boxhdr(cinfo, cio, &box); } - } while(JP2_JP2C != box.type); - *j2k_codestream_offset = cio_tell(cio); - *j2k_codestream_length = box.length - 8; + l_current_handler = jp2_find_handler(box.type); + l_current_data_size = box.length - l_nb_bytes_read; + if + (l_current_handler != 00) + { + if + (l_current_data_size > l_last_data_size) + { + l_current_data = opj_realloc(l_current_data,l_current_data_size); + l_last_data_size = l_current_data_size; + } + l_nb_bytes_read = opj_stream_read_data(cio,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"); + return false; + } + if + (! l_current_handler->handler(jp2,l_current_data,l_current_data_size,p_manager)) + { + return false; + } + } + else + { + jp2->jp2_state |= JP2_STATE_UNKNOWN; + if + (opj_stream_skip(cio,l_current_data_size,p_manager) != l_current_data_size) + { + opj_event_msg(p_manager, EVT_ERROR, "Problem with skipping JPEG2000 box, stream error\n"); + return false; + } + } + } return true; } -static void jp2_write_jp(opj_cio_t *cio) { - opj_jp2_box_t box; +/** + * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure. + * + * @param cio the input stream to read data from. + * @param box the box structure to fill. + * @param p_number_bytes_read pointer to an int that will store the number of bytes read from the stream (should usually be 8). + * @param p_manager user event manager. + * + * @return true if the box is reconized, false otherwise +*/ +bool 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) +{ + /* read header from file */ + unsigned char l_data_header [8]; - box.init_pos = cio_tell(cio); - cio_skip(cio, 4); - cio_write(cio, JP2_JP, 4); /* JP2 signature */ - cio_write(cio, 0x0d0a870a, 4); + // preconditions + assert(cio != 00); + assert(box != 00); + assert(p_number_bytes_read != 00); + assert(p_manager != 00); - box.length = cio_tell(cio) - box.init_pos; - cio_seek(cio, box.init_pos); - cio_write(cio, box.length, 4); /* L */ - cio_seek(cio, box.init_pos + box.length); -} - -static bool jp2_read_jp(opj_jp2_t *jp2, opj_cio_t *cio) { - opj_jp2_box_t box; - - opj_common_ptr cinfo = jp2->cinfo; - - jp2_read_boxhdr(cinfo, cio, &box); - if (JP2_JP != box.type) { - opj_event_msg(cinfo, EVT_ERROR, "Expected JP Marker\n"); + *p_number_bytes_read = opj_stream_read_data(cio,l_data_header,8,p_manager); + if + (*p_number_bytes_read != 8) + { return false; } - if (0x0d0a870a != cio_read(cio, 4)) { - opj_event_msg(cinfo, EVT_ERROR, "Error with JP Marker\n"); - return false; - } - if (cio_tell(cio) - box.init_pos != box.length) { - opj_event_msg(cinfo, EVT_ERROR, "Error with JP Box size\n"); - return false; - } - - return true; -} - - -static bool jp2_read_struct(opj_jp2_t *jp2, opj_cio_t *cio) { - if (!jp2_read_jp(jp2, cio)) - return false; - if (!jp2_read_ftyp(jp2, cio)) - return false; - if (!jp2_read_jp2h(jp2, cio)) - return false; - if (!jp2_read_jp2c(jp2, cio, &jp2->j2k_codestream_length, &jp2->j2k_codestream_offset)) - return false; + /* process read data */ + opj_read_bytes(l_data_header,&(box->length), 4); + opj_read_bytes(l_data_header+4,&(box->type), 4); + // 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); + if + (l_nb_bytes_read != 8) + { + if + (l_nb_bytes_read > 0) + { + *p_number_bytes_read += l_nb_bytes_read; + } + return false; + } + 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 false; + } + opj_read_bytes(l_data_header,&(box->length), 4); + } return true; } -/* ----------------------------------------------------------------------- */ -/* JP2 decoder interface */ -/* ----------------------------------------------------------------------- */ +/** + * Reads a box header. The box is the way data is packed inside a jpeg2000 file structure. Data is read from a character string + * + * @param p_data the character string to read data from. + * @param box the box structure to fill. + * @param p_number_bytes_read pointer to an int that will store the number of bytes read from the stream (shoul usually be 2). + * @param p_box_max_size the maximum number of bytes in the box. + * + * @return true if the box is reconized, false otherwise +*/ +static bool jp2_read_boxhdr_char( + opj_jp2_box_t *box, + OPJ_BYTE * p_data, + OPJ_UINT32 * p_number_bytes_read, + OPJ_UINT32 p_box_max_size, + opj_event_mgr_t * p_manager + ) +{ + // preconditions + assert(p_data != 00); + assert(box != 00); + assert(p_number_bytes_read != 00); + assert(p_manager != 00); -opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo) { - opj_jp2_t *jp2 = (opj_jp2_t*) opj_calloc(1, sizeof(opj_jp2_t)); - if(jp2) { - jp2->cinfo = cinfo; - /* create the J2K codec */ - jp2->j2k = j2k_create_decompress(cinfo); - if(jp2->j2k == NULL) { - jp2_destroy_decompress(jp2); - return NULL; - } + if + (p_box_max_size < 8) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of less than 8 bytes\n"); + return false; } - return jp2; + /* process read data */ + opj_read_bytes(p_data,&(box->length), 4); + p_data += 4; + opj_read_bytes(p_data,&(box->type), 4); + p_data += 4; + *p_number_bytes_read = 8; + + // do we have a "special very large box ?" + // read then the XLBox + if + (box->length == 1) + { + unsigned int l_xl_part_size; + if + (p_box_max_size < 16) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot handle XL box of less than 16 bytes\n"); + return false; + } + + opj_read_bytes(p_data,&l_xl_part_size, 4); + p_data += 4; + *p_number_bytes_read += 4; + if + (l_xl_part_size != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box sizes higher than 2^32\n"); + return false; + } + opj_read_bytes(p_data,&(box->length), 4); + *p_number_bytes_read += 4; + if + (box->length == 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n"); + return false; + } + + } + else if + (box->length == 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Cannot handle box of undefined sizes\n"); + return false; + } + return true; } -void jp2_destroy_decompress(opj_jp2_t *jp2) { - if(jp2) { - /* destroy the J2K codec */ - j2k_destroy_decompress(jp2->j2k); - if(jp2->comps) { - opj_free(jp2->comps); +/** + * Reads a jpeg2000 file signature box. + * + * @param p_header_data the data contained in the signature box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the signature box. + * @param p_manager the user event manager. + * + * @return true if the file signature box is valid. + */ +bool jp2_read_jp( + opj_jp2_t *jp2, + unsigned char * p_header_data, + unsigned int p_header_size, + opj_event_mgr_t * p_manager + ) +{ + unsigned int l_magic_number; + + // preconditions + assert(p_header_data != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + if + (jp2->jp2_state != JP2_STATE_NONE) + { + opj_event_msg(p_manager, EVT_ERROR, "The signature box must be the first box in the file.\n"); + return false; + } + + + /* assure length of data is correct (4 -> magic number) */ + if + (p_header_size != 4) + { + opj_event_msg(p_manager, EVT_ERROR, "Error with JP signature Box size\n"); + return false; + } + + // rearrange data + opj_read_bytes(p_header_data,&l_magic_number,4); + if + (l_magic_number != 0x0d0a870a ) + { + opj_event_msg(p_manager, EVT_ERROR, "Error with JP Signature : bad magic number\n"); + return false; + } + jp2->jp2_state |= JP2_STATE_SIGNATURE; + return true; +} + +/** + * Reads a a FTYP box - File type box + * + * @param p_header_data the data contained in the FTYP box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the FTYP box. + * @param p_manager the user event manager. + * + * @return true if the FTYP box is valid. + */ +bool jp2_read_ftyp( + opj_jp2_t *jp2, + unsigned char * p_header_data, + unsigned int p_header_size, + opj_event_mgr_t * p_manager + ) +{ + unsigned int i; + unsigned int l_remaining_bytes; + + // preconditions + assert(p_header_data != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + if + (jp2->jp2_state != JP2_STATE_SIGNATURE) + { + opj_event_msg(p_manager, EVT_ERROR, "The ftyp box must be the second box in the file.\n"); + return false; + } + + /* assure length of data is correct */ + if + (p_header_size < 8) + { + opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n"); + return false; + } + + opj_read_bytes(p_header_data,&jp2->brand,4); /* BR */ + p_header_data += 4; + + opj_read_bytes(p_header_data,&jp2->minversion,4); /* MinV */ + p_header_data += 4; + + l_remaining_bytes = p_header_size - 8; + + /* the number of remaining bytes should be a multiple of 4 */ + if + ((l_remaining_bytes & 0x3) != 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Error with FTYP signature Box size\n"); + return false; + } + /* div by 4 */ + jp2->numcl = l_remaining_bytes >> 2; + if + (jp2->numcl) + { + jp2->cl = (unsigned int *) opj_malloc(jp2->numcl * sizeof(unsigned int)); + if + (jp2->cl == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory with FTYP Box\n"); + return false; } - if(jp2->cl) { + memset(jp2->cl,0,jp2->numcl * sizeof(unsigned int)); + } + + + for + (i = 0; i < jp2->numcl; ++i) + { + opj_read_bytes(p_header_data,&jp2->cl[i],4); /* CLi */ + p_header_data += 4; + + } + jp2->jp2_state |= JP2_STATE_FILE_TYPE; + return true; +} + +/** + * Writes a jpeg2000 file signature box. + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager the user event manager. + * + * @return true if writting was successful. + */ +bool jp2_write_jp ( + opj_jp2_t *jp2, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager + ) +{ + /* 12 bytes will be read */ + unsigned char l_signature_data [12]; + + // preconditions + assert(cio != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + + /* write box length */ + opj_write_bytes(l_signature_data,12,4); + /* writes box type */ + opj_write_bytes(l_signature_data+4,JP2_JP,4); + /* writes magic number*/ + opj_write_bytes(l_signature_data+8,0x0d0a870a,4); + if + (opj_stream_write_data(cio,l_signature_data,12,p_manager) != 12) + { + return false; + } + return true; +} + + +/** + * Writes a FTYP box - File type box + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager the user event manager. + * + * @return true if writting was successful. + */ +bool jp2_write_ftyp( + opj_jp2_t *jp2, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager + ) +{ + unsigned int i; + unsigned int l_ftyp_size = 16 + 4 * jp2->numcl; + unsigned char * l_ftyp_data, * l_current_data_ptr; + bool l_result; + + // preconditions + assert(cio != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + l_ftyp_data = (unsigned char *) opj_malloc(l_ftyp_size); + + if + (l_ftyp_data == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle ftyp data\n"); + return false; + } + memset(l_ftyp_data,0,l_ftyp_size); + + l_current_data_ptr = l_ftyp_data; + + opj_write_bytes(l_current_data_ptr, l_ftyp_size,4); /* box size */ + l_current_data_ptr += 4; + + opj_write_bytes(l_current_data_ptr, JP2_FTYP,4); /* FTYP */ + l_current_data_ptr += 4; + + opj_write_bytes(l_current_data_ptr, jp2->brand,4); /* BR */ + l_current_data_ptr += 4; + + opj_write_bytes(l_current_data_ptr, jp2->minversion,4); /* MinV */ + l_current_data_ptr += 4; + + for + (i = 0; i < jp2->numcl; i++) + { + opj_write_bytes(l_current_data_ptr, jp2->cl[i],4); /* CL */ + } + + l_result = (opj_stream_write_data(cio,l_ftyp_data,l_ftyp_size,p_manager) == l_ftyp_size); + if + (! l_result) + { + opj_event_msg(p_manager, EVT_ERROR, "Error while writting ftyp data to stream\n"); + } + opj_free(l_ftyp_data); + return l_result; +} + +/** + * Writes the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box). + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager user event manager. + * + * @return true if writting was successful. +*/ +bool jp2_write_jp2h( + opj_jp2_t *jp2, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager + ) +{ + opj_jp2_img_header_writer_handler_t l_writers [3]; + opj_jp2_img_header_writer_handler_t * l_current_writer; + + int i, l_nb_pass; + /* size of data for super box*/ + int l_jp2h_size = 8; + bool l_result = true; + + /* to store the data of the super box */ + unsigned char l_jp2h_data [8]; + + // preconditions + assert(cio != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + memset(l_writers,0,sizeof(l_writers)); + + if + (jp2->bpc == 255) + { + l_nb_pass = 3; + l_writers[0].handler = jp2_write_ihdr; + l_writers[1].handler = jp2_write_bpcc; + l_writers[2].handler = jp2_write_colr; + } + else + { + l_nb_pass = 2; + l_writers[0].handler = jp2_write_ihdr; + l_writers[1].handler = jp2_write_colr; + } + + /* write box header */ + /* write JP2H type */ + opj_write_bytes(l_jp2h_data+4,JP2_JP2H,4); + + l_current_writer = l_writers; + for + (i=0;im_data = l_current_writer->handler(jp2,&(l_current_writer->m_size)); + if + (l_current_writer->m_data == 00) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to hold JP2 Header data\n"); + l_result = false; + break; + } + l_jp2h_size += l_current_writer->m_size; + ++l_current_writer; + } + + if + (! l_result) + { + l_current_writer = l_writers; + for + (i=0;im_data != 00) + { + opj_free(l_current_writer->m_data ); + } + ++l_current_writer; + } + return false; + } + + /* write super box size */ + opj_write_bytes(l_jp2h_data,l_jp2h_size,4); + + /* write super box data on stream */ + if + (opj_stream_write_data(cio,l_jp2h_data,8,p_manager) != 8) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream error while writting JP2 Header box\n"); + l_result = false; + } + + if + (l_result) + { + l_current_writer = l_writers; + for + (i=0;im_data,l_current_writer->m_size,p_manager) != l_current_writer->m_size) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream error while writting JP2 Header box\n"); + l_result = false; + break; + } + ++l_current_writer; + } + } + l_current_writer = l_writers; + /* cleanup */ + for + (i=0;im_data != 00) + { + opj_free(l_current_writer->m_data ); + } + ++l_current_writer; + } + return l_result; +} + +/** + * Reads the Jpeg2000 file Header box - JP2 Header box (warning, this is a super box). + * + * @param p_header_data the data contained in the file header box. + * @param jp2 the jpeg2000 file codec. + * @param p_header_size the size of the data contained in the file header box. + * @param p_manager the user event manager. + * + * @return true if the JP2 Header box was successfully reconized. +*/ +bool jp2_read_jp2h( + opj_jp2_t *jp2, + unsigned char * p_header_data, + unsigned int p_header_size, + opj_event_mgr_t * p_manager + ) +{ + unsigned int l_box_size=0, l_current_data_size = 0; + opj_jp2_box_t box; + const opj_jp2_header_handler_t * l_current_handler; + + // preconditions + assert(p_header_data != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + /* make sure the box is well placed */ + if + ((jp2->jp2_state & JP2_STATE_FILE_TYPE) != JP2_STATE_FILE_TYPE ) + { + opj_event_msg(p_manager, EVT_ERROR, "The box must be the first box in the file.\n"); + return false; + } + jp2->jp2_img_state = JP2_IMG_STATE_NONE; + + /* iterate while remaining data */ + while + (p_header_size > 0) + { + if + (! jp2_read_boxhdr_char(&box,p_header_data,&l_box_size,p_header_size, p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box\n"); + return false; + } + if + (box.length > p_header_size) + { + opj_event_msg(p_manager, EVT_ERROR, "Stream error while reading JP2 Header box\n"); + return false; + } + l_current_handler = jp2_img_find_handler(box.type); + + l_current_data_size = box.length - l_box_size; + p_header_data += l_box_size; + + if + (l_current_handler != 00) + { + if + (! l_current_handler->handler(jp2,p_header_data,l_current_data_size,p_manager)) + { + return false; + } + } + else + { + jp2->jp2_img_state |= JP2_IMG_STATE_UNKNOWN; + } + p_header_data += l_current_data_size; + p_header_size -= box.length; + } + jp2->jp2_state |= JP2_STATE_HEADER; + return true; +} + +/** + * Reads a IHDR box - Image Header box + * + * @param p_image_header_data pointer to actual data (already read from file) + * @param jp2 the jpeg2000 file codec. + * @param p_image_header_size the size of the image header + * @param p_image_header_max_size maximum size of the header, any size bigger than this value should result the function to output false. + * @param p_manager the user event manager. + * + * @return true if the image header is valid, fale else. + */ +bool jp2_read_ihdr( + opj_jp2_t *jp2, + unsigned char * p_image_header_data, + unsigned int p_image_header_size, + opj_event_mgr_t * p_manager + ) +{ + // preconditions + assert(p_image_header_data != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + if + (p_image_header_size != 14) + { + opj_event_msg(p_manager, EVT_ERROR, "Bad image header box (bad size)\n"); + return false; + } + opj_read_bytes(p_image_header_data,&(jp2->h),4); /* HEIGHT */ + p_image_header_data += 4; + opj_read_bytes(p_image_header_data,&(jp2->w),4); /* WIDTH */ + p_image_header_data += 4; + opj_read_bytes(p_image_header_data,&(jp2->numcomps),2); /* NC */ + p_image_header_data += 2; + + /* allocate memory for components */ + jp2->comps = (opj_jp2_comps_t*) opj_malloc(jp2->numcomps * sizeof(opj_jp2_comps_t)); + if + (jp2->comps == 0) + { + opj_event_msg(p_manager, EVT_ERROR, "Not enough memory to handle image header (ihdr)\n"); + return false; + } + memset(jp2->comps,0,jp2->numcomps * sizeof(opj_jp2_comps_t)); + + opj_read_bytes(p_image_header_data,&(jp2->bpc),1); /* BPC */ + ++ p_image_header_data; + opj_read_bytes(p_image_header_data,&(jp2->C),1); /* C */ + ++ p_image_header_data; + opj_read_bytes(p_image_header_data,&(jp2->UnkC),1); /* UnkC */ + ++ p_image_header_data; + opj_read_bytes(p_image_header_data,&(jp2->IPR),1); /* IPR */ + ++ p_image_header_data; + return true; +} + +/** + * Writes the Image Header box - Image Header box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +static unsigned char * jp2_write_ihdr( + opj_jp2_t *jp2, + unsigned int * p_nb_bytes_written + ) +{ + unsigned char * l_ihdr_data,* l_current_ihdr_ptr; + + // preconditions + assert(jp2 != 00); + assert(p_nb_bytes_written != 00); + + /* default image header is 22 bytes wide */ + l_ihdr_data = (unsigned char *) opj_malloc(22); + if + (l_ihdr_data == 00) + { + return 00; + } + memset(l_ihdr_data,0,22); + + l_current_ihdr_ptr = l_ihdr_data; + + opj_write_bytes(l_current_ihdr_ptr,22,4); /* write box size */ + l_current_ihdr_ptr+=4; + opj_write_bytes(l_current_ihdr_ptr,JP2_IHDR, 4); /* IHDR */ + l_current_ihdr_ptr+=4; + opj_write_bytes(l_current_ihdr_ptr,jp2->h, 4); /* HEIGHT */ + l_current_ihdr_ptr+=4; + opj_write_bytes(l_current_ihdr_ptr, jp2->w, 4); /* WIDTH */ + l_current_ihdr_ptr+=4; + opj_write_bytes(l_current_ihdr_ptr, jp2->numcomps, 2); /* NC */ + l_current_ihdr_ptr+=2; + opj_write_bytes(l_current_ihdr_ptr, jp2->bpc, 1); /* BPC */ + ++l_current_ihdr_ptr; + opj_write_bytes(l_current_ihdr_ptr, jp2->C, 1); /* C : Always 7 */ + ++l_current_ihdr_ptr; + opj_write_bytes(l_current_ihdr_ptr, jp2->UnkC, 1); /* UnkC, colorspace unknown */ + ++l_current_ihdr_ptr; + opj_write_bytes(l_current_ihdr_ptr, jp2->IPR, 1); /* IPR, no intellectual property */ + ++l_current_ihdr_ptr; + *p_nb_bytes_written = 22; + return l_ihdr_data; +} + +/** + * Writes the Bit per Component box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +unsigned char * jp2_write_bpcc( + opj_jp2_t *jp2, + unsigned int * p_nb_bytes_written + ) +{ + unsigned int i; + /* room for 8 bytes for box and 1 byte for each component */ + int l_bpcc_size = 8 + jp2->numcomps; + unsigned char * l_bpcc_data,* l_current_bpcc_ptr; + + // preconditions + assert(jp2 != 00); + assert(p_nb_bytes_written != 00); + + l_bpcc_data = (unsigned char *) opj_malloc(l_bpcc_size); + if + (l_bpcc_data == 00) + { + return 00; + } + memset(l_bpcc_data,0,l_bpcc_size); + + l_current_bpcc_ptr = l_bpcc_data; + + opj_write_bytes(l_current_bpcc_ptr,l_bpcc_size,4); /* write box size */ + l_current_bpcc_ptr += 4; + opj_write_bytes(l_current_bpcc_ptr,JP2_BPCC,4); /* BPCC */ + l_current_bpcc_ptr += 4; + + for + (i = 0; i < jp2->numcomps; ++i) + { + opj_write_bytes(l_current_bpcc_ptr, jp2->comps[i].bpcc, 1); /* write each component information */ + ++l_current_bpcc_ptr; + } + *p_nb_bytes_written = l_bpcc_size; + return l_bpcc_data; +} + +/** + * Reads a Bit per Component box. + * + * @param p_bpc_header_data pointer to actual data (already read from file) + * @param jp2 the jpeg2000 file codec. + * @param p_bpc_header_size pointer that will hold the size of the bpc header + * @param p_bpc_header_max_size maximum size of the header, any size bigger than this value should result the function to output false. + * @param p_manager the user event manager. + * + * @return true if the bpc header is valid, fale else. + */ +bool jp2_read_bpcc( + opj_jp2_t *jp2, + unsigned char * p_bpc_header_data, + unsigned int p_bpc_header_size, + opj_event_mgr_t * p_manager + ) +{ + unsigned int i; + + // preconditions + assert(p_bpc_header_data != 00); + assert(jp2 != 00); + assert(p_manager != 00); + + // and length is relevant + if + (p_bpc_header_size != jp2->numcomps) + { + opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n"); + return false; + } + + // read info for each component + for + (i = 0; i < jp2->numcomps; ++i) + { + opj_read_bytes(p_bpc_header_data,&jp2->comps[i].bpcc ,1); /* read each BPCC component */ + ++p_bpc_header_data; + } + return true; +} + +/** + * Writes the Colour Specification box. + * + * @param jp2 jpeg2000 file codec. + * @param p_nb_bytes_written pointer to store the nb of bytes written by the function. + * + * @return the data being copied. +*/ +unsigned char *jp2_write_colr( + opj_jp2_t *jp2, + unsigned int * p_nb_bytes_written + ) +{ + /* room for 8 bytes for box 3 for common data and variable upon profile*/ + unsigned int l_colr_size = 11; + unsigned char * l_colr_data,* l_current_colr_ptr; + + // preconditions + assert(jp2 != 00); + assert(p_nb_bytes_written != 00); + + switch + (jp2->meth) + { + case 1 : + l_colr_size += 4; + break; + case 2 : + ++l_colr_size; + break; + default : + return 00; + } + + l_colr_data = (unsigned char *) opj_malloc(l_colr_size); + if + (l_colr_data == 00) + { + return 00; + } + memset(l_colr_data,0,l_colr_size); + l_current_colr_ptr = l_colr_data; + + opj_write_bytes(l_current_colr_ptr,l_colr_size,4); /* write box size */ + l_current_colr_ptr += 4; + opj_write_bytes(l_current_colr_ptr,JP2_COLR,4); /* BPCC */ + l_current_colr_ptr += 4; + + opj_write_bytes(l_current_colr_ptr, jp2->meth,1); /* METH */ + ++l_current_colr_ptr; + opj_write_bytes(l_current_colr_ptr, jp2->precedence,1); /* PRECEDENCE */ + ++l_current_colr_ptr; + opj_write_bytes(l_current_colr_ptr, jp2->approx,1); /* APPROX */ + ++l_current_colr_ptr; + + if + (jp2->meth == 1) + { + opj_write_bytes(l_current_colr_ptr, jp2->enumcs,4); /* EnumCS */ + } + else + { + opj_write_bytes(l_current_colr_ptr, 0, 1); /* PROFILE (??) */ + } + *p_nb_bytes_written = l_colr_size; + return l_colr_data; +} + +/** + * Reads the Colour Specification box. + * + * @param p_colr_header_data pointer to actual data (already read from file) + * @param jp2 the jpeg2000 file codec. + * @param p_colr_header_size pointer that will hold the size of the color header + * @param p_colr_header_max_size maximum size of the header, any size bigger than this value should result the function to output false. + * @param p_manager the user event manager. + * + * @return true if the bpc header is valid, fale else. +*/ +bool jp2_read_colr( + opj_jp2_t * jp2, + unsigned char * p_colr_header_data, + unsigned int p_colr_header_size, + opj_event_mgr_t * p_manager + ) +{ + // preconditions + assert(jp2 != 00); + assert(p_colr_header_data != 00); + assert(p_manager != 00); + + if + (p_colr_header_size < 3) + { + opj_event_msg(p_manager, EVT_ERROR, "Bad BPCC header box (bad size)\n"); + return false; + } + + opj_read_bytes(p_colr_header_data,&jp2->meth ,1); /* METH */ + ++p_colr_header_data; + + opj_read_bytes(p_colr_header_data,&jp2->precedence ,1); /* PRECEDENCE */ + ++p_colr_header_data; + + opj_read_bytes(p_colr_header_data,&jp2->approx ,1); /* APPROX */ + ++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"); + return false; + } + opj_read_bytes(p_colr_header_data,&jp2->enumcs ,4); /* EnumCS */ + } + /*else + { + // do not care with profiles. + }*/ + return true; +} + +/** + * Writes the Jpeg2000 codestream Header box - JP2C Header box. + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager user event manager. + * + * @return true if writting was successful. +*/ +bool jp2_write_jp2c( + opj_jp2_t *jp2, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager + ) +{ + unsigned int j2k_codestream_exit; + unsigned char l_data_header [8]; + + // preconditions + assert(jp2 != 00); + assert(cio != 00); + assert(p_manager != 00); + assert(opj_stream_has_seek(cio)); + + j2k_codestream_exit = opj_stream_tell(cio); + opj_write_bytes(l_data_header,j2k_codestream_exit - jp2->j2k_codestream_offset,4); /* size of codestream */ + opj_write_bytes(l_data_header + 4,JP2_JP2C,4); /* JP2C */ + + if + (! opj_stream_seek(cio,jp2->j2k_codestream_offset,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n"); + return false; + } + + if + (opj_stream_write_data(cio,l_data_header,8,p_manager) != 8) + { + opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n"); + return false; + } + + if + (! opj_stream_seek(cio,j2k_codestream_exit,p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Failed to seek in the stream.\n"); + return false; + } + return true; +} + +/** + * Destroys a jpeg2000 file decompressor. + * + * @param jp2 a jpeg2000 file decompressor. + */ +void jp2_destroy(opj_jp2_t *jp2) +{ + if + (jp2) + { + /* destroy the J2K codec */ + j2k_destroy(jp2->j2k); + jp2->j2k = 00; + if + (jp2->comps) + { + opj_free(jp2->comps); + jp2->comps = 00; + } + if + (jp2->cl) + { opj_free(jp2->cl); + jp2->cl = 00; + } + if + (jp2->m_validation_list) + { + opj_procedure_list_destroy(jp2->m_validation_list); + jp2->m_validation_list = 00; + } + if + (jp2->m_procedure_list) + { + opj_procedure_list_destroy(jp2->m_procedure_list); + jp2->m_procedure_list = 00; } opj_free(jp2); } } -void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) { - /* setup the J2K codec */ - j2k_setup_decoder(jp2->j2k, parameters); - /* further JP2 initializations go here */ + + + + +/* ----------------------------------------------------------------------- */ +/* JP2 encoder interface */ +/* ----------------------------------------------------------------------- */ + +opj_jp2_t* jp2_create(bool p_is_decoder) +{ + opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t)); + if + (jp2) + { + memset(jp2,0,sizeof(opj_jp2_t)); + /* create the J2K codec */ + if + (! p_is_decoder) + { + jp2->j2k = j2k_create_compress(); + } + else + { + jp2->j2k = j2k_create_decompress(); + } + if + (jp2->j2k == 00) + { + jp2_destroy(jp2); + return 00; + } + // validation list creation + jp2->m_validation_list = opj_procedure_list_create(); + if + (! jp2->m_validation_list) + { + jp2_destroy(jp2); + return 00; + } + + // execution list creation + jp2->m_procedure_list = opj_procedure_list_create(); + if + (! jp2->m_procedure_list) + { + jp2_destroy(jp2); + return 00; + } + } + return jp2; } -opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { - opj_common_ptr cinfo; - opj_image_t *image = NULL; +/** + * Excutes the given procedures on the given codec. + * + * @param p_procedure_list the list of procedures to execute + * @param jp2 the jpeg2000 file codec to execute the procedures on. + * @param cio the stream to execute the procedures on. + * @param p_manager the user manager. + * + * @return true if all the procedures were successfully executed. + */ +bool jp2_exec ( + opj_jp2_t * jp2, + opj_procedure_list_t * p_procedure_list, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager + ) +{ + bool (** l_procedure) (opj_jp2_t * jp2,opj_stream_private_t *,opj_event_mgr_t *) = 00; + bool l_result = true; + unsigned int l_nb_proc, i; - if(!jp2 || !cio) { - return NULL; + // preconditions + assert(p_procedure_list != 00); + assert(jp2 != 00); + assert(cio != 00); + assert(p_manager != 00); + + l_nb_proc = opj_procedure_list_get_nb_procedures(p_procedure_list); + l_procedure = (bool (**) (opj_jp2_t * jp2,opj_stream_private_t *,opj_event_mgr_t *)) opj_procedure_list_get_first_procedure(p_procedure_list); + for + (i=0;im_validation_list,cio,p_manager)) + { + return false; } - cinfo = jp2->cinfo; + /* customization of the encoding */ + jp2_setup_header_writting(jp2); - /* JP2 decoding */ - if(!jp2_read_struct(jp2, cio)) { - opj_event_msg(cinfo, EVT_ERROR, "Failed to decode jp2 structure\n"); - return NULL; + /* write header */ + if + (! jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) + { + return false; + } + return j2k_start_compress(jp2->j2k,cio,p_image,p_manager); +} + +/** + * Reads a jpeg2000 file header structure. + * + * @param cio the stream to read data from. + * @param jp2 the jpeg2000 file header structure. + * @param p_manager the user event manager. + * + * @return true if the box is valid. + */ +bool jp2_read_header( + opj_jp2_t *jp2, + opj_image_t ** p_image, + OPJ_INT32 * p_tile_x0, + OPJ_INT32 * p_tile_y0, + OPJ_UINT32 * p_tile_width, + OPJ_UINT32 * p_tile_height, + OPJ_UINT32 * p_nb_tiles_x, + OPJ_UINT32 * p_nb_tiles_y, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(jp2 != 00); + assert(cio != 00); + assert(p_manager != 00); + + /* customization of the validation */ + jp2_setup_decoding_validation (jp2); + + /* customization of the encoding */ + jp2_setup_header_reading(jp2); + + /* validation of the parameters codec */ + if + (! jp2_exec(jp2,jp2->m_validation_list,cio,p_manager)) + { + return false; } + /* read header */ + if + (! jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) + { + return false; + } + return j2k_read_header( + jp2->j2k, + p_image, + p_tile_x0, + p_tile_y0, + p_tile_width, + p_tile_height, + p_nb_tiles_x, + p_nb_tiles_y, + cio, + p_manager); +} + +/** + * Ends the decompression procedures and possibiliy add data to be read after the + * codestream. + */ +bool jp2_end_decompress(opj_jp2_t *jp2, opj_stream_private_t *cio, opj_event_mgr_t * p_manager) +{ + // preconditions + assert(jp2 != 00); + assert(cio != 00); + assert(p_manager != 00); + + /* customization of the end encoding */ + jp2_setup_end_header_reading(jp2); + + /* write header */ + if + (! jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager)) + { + return false; + } + return j2k_end_decompress(jp2->j2k, cio, p_manager); +} + + +/** + * Ends the compression procedures and possibiliy add data to be read after the + * codestream. + */ +bool jp2_end_compress(opj_jp2_t *jp2, opj_stream_private_t *cio, opj_event_mgr_t * p_manager) +{ + // preconditions + assert(jp2 != 00); + assert(cio != 00); + assert(p_manager != 00); + + /* customization of the end encoding */ + jp2_setup_end_header_writting(jp2); + + if + (! j2k_end_compress(jp2->j2k,cio,p_manager)) + { + return false; + } + /* write header */ + return jp2_exec (jp2,jp2->m_procedure_list,cio,p_manager); +} + +/** +Encode an image into a JPEG-2000 file stream +@param jp2 JP2 compressor handle +@param cio Output buffer stream +@param image Image to encode +@param cstr_info Codestream information structure if required, NULL otherwise +@return Returns true if successful, returns false otherwise +*/ +bool jp2_encode(opj_jp2_t *jp2, struct opj_stream_private *cio, struct opj_event_mgr * p_manager) +{ + return j2k_encode(jp2->j2k,cio,p_manager); +} +/** + * Writes a tile. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool jp2_write_tile ( + opj_jp2_t *p_jp2, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ) +{ + return j2k_write_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager); +} + +/** + * Decode tile data. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool jp2_decode_tile ( + opj_jp2_t * p_jp2, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + return j2k_decode_tile (p_jp2->j2k,p_tile_index,p_data,p_data_size,p_stream,p_manager); +} +/** + * Reads a tile header. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool jp2_read_tile_header ( + opj_jp2_t * p_jp2, + 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, + bool * p_go_on, + opj_stream_private_t *p_stream, + opj_event_mgr_t * p_manager + ) +{ + return j2k_read_tile_header (p_jp2->j2k, + p_tile_index, + p_data_size, + p_tile_x0, + p_tile_y0, + p_tile_x1, + p_tile_y1, + p_nb_comps, + p_go_on, + p_stream, + p_manager); +} + +/** + * Sets up the procedures to do on writting header after the codestream. + * Developpers wanting to extend the library can add their own writting procedures. + */ +void jp2_setup_end_header_writting (opj_jp2_t *jp2) +{ + // preconditions + assert(jp2 != 00); + + opj_procedure_list_add_procedure(jp2->m_procedure_list,jp2_write_jp2c ); + /* DEVELOPER CORNER, add your custom procedures */ +} + +/** + * Sets up the procedures to do on reading header. + * Developpers wanting to extend the library can add their own writting procedures. + */ +void jp2_setup_header_reading (opj_jp2_t *jp2) +{ + // preconditions + assert(jp2 != 00); + + opj_procedure_list_add_procedure(jp2->m_procedure_list,jp2_read_header_procedure ); + /* DEVELOPER CORNER, add your custom procedures */ +} + +/** + * Sets up the procedures to do on reading header after the codestream. + * Developpers wanting to extend the library can add their own writting procedures. + */ +void jp2_setup_end_header_reading (opj_jp2_t *jp2) +{ + // preconditions + assert(jp2 != 00); + opj_procedure_list_add_procedure(jp2->m_procedure_list,jp2_read_header_procedure ); + /* DEVELOPER CORNER, add your custom procedures */ +} + + +/** + * The default validation procedure without any extension. + * + * @param jp2 the jpeg2000 codec to validate. + * @param cio the input stream to validate. + * @param p_manager the user event manager. + * + * @return true if the parameters are correct. + */ +bool jp2_default_validation ( + opj_jp2_t * jp2, + opj_stream_private_t *cio, + opj_event_mgr_t * p_manager + ) +{ + bool l_is_valid = true; + unsigned int i; + + // preconditions + assert(jp2 != 00); + assert(cio != 00); + assert(p_manager != 00); + /* JPEG2000 codec validation */ + /*TODO*/ + + /* STATE checking */ + /* make sure the state is at 0 */ + l_is_valid &= (jp2->jp2_state == JP2_STATE_NONE); + /* make sure not reading a jp2h ???? WEIRD */ + l_is_valid &= (jp2->jp2_img_state == JP2_IMG_STATE_NONE); + + /* POINTER validation */ + /* make sure a j2k codec is present */ + l_is_valid &= (jp2->j2k != 00); + /* make sure a procedure list is present */ + l_is_valid &= (jp2->m_procedure_list != 00); + /* make sure a validation list is present */ + l_is_valid &= (jp2->m_validation_list != 00); + + /* PARAMETER VALIDATION */ + /* number of components */ + l_is_valid &= (jp2->numcl > 0); + /* width */ + l_is_valid &= (jp2->h > 0); + /* height */ + l_is_valid &= (jp2->w > 0); + /* precision */ + for + (i = 0; i < jp2->numcomps; ++i) + { + l_is_valid &= (jp2->comps[i].bpcc > 0); + } + /* METH */ + l_is_valid &= ((jp2->meth > 0) && (jp2->meth < 3)); + + + + /* stream validation */ + /* back and forth is needed */ + l_is_valid &= opj_stream_has_seek(cio); + + return l_is_valid; + +} + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +void jp2_setup_encoding_validation (opj_jp2_t *jp2) +{ + // preconditions + assert(jp2 != 00); + opj_procedure_list_add_procedure(jp2->m_validation_list, jp2_default_validation); + /* DEVELOPER CORNER, add your custom validation procedure */ +} + +/** + * Sets up the validation ,i.e. adds the procedures to lauch to make sure the codec parameters + * are valid. Developpers wanting to extend the library can add their own validation procedures. + */ +void jp2_setup_decoding_validation (opj_jp2_t *jp2) +{ + // preconditions + assert(jp2 != 00); + /* DEVELOPER CORNER, add your custom validation procedure */ +} + +/** + * Sets up the procedures to do on writting header. Developpers wanting to extend the library can add their own writting procedures. + */ +void jp2_setup_header_writting (opj_jp2_t *jp2) +{ + // preconditions + assert(jp2 != 00); + opj_procedure_list_add_procedure(jp2->m_procedure_list,jp2_write_jp ); + opj_procedure_list_add_procedure(jp2->m_procedure_list,jp2_write_ftyp ); + opj_procedure_list_add_procedure(jp2->m_procedure_list,jp2_write_jp2h ); + opj_procedure_list_add_procedure(jp2->m_procedure_list,jp2_skip_jp2c ); + + /* DEVELOPER CORNER, insert your custom procedures */ + +} + + +/** + * Skips the Jpeg2000 Codestream Header box - JP2C Header box. + * + * @param cio the stream to write data to. + * @param jp2 the jpeg2000 file codec. + * @param p_manager user event manager. + * + * @return true if writting was successful. +*/ +bool jp2_skip_jp2c( + opj_jp2_t *jp2, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ) +{ + // preconditions + assert(jp2 != 00); + assert(cio != 00); + assert(p_manager != 00); + + jp2->j2k_codestream_offset = opj_stream_tell(cio); + if + (opj_stream_skip(cio,8,p_manager) != 8) + { + return false; + } + return true; +} + +struct opj_image * jp2_decode(opj_jp2_t *jp2, struct opj_stream_private *cio, struct opj_event_mgr * p_manager) +{ /* J2K decoding */ - image = j2k_decode(jp2->j2k, cio, cstr_info); - if(!image) { - opj_event_msg(cinfo, EVT_ERROR, "Failed to decode J2K image\n"); - return NULL; + struct opj_image * image = j2k_decode(jp2->j2k, cio, p_manager); + if + (!image) + { + opj_event_msg(p_manager, EVT_ERROR, "Failed to decode J2K image\n"); + return false; } /* Set Image Color Space */ @@ -573,45 +2086,12 @@ opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *c image->color_space = CLRSPC_SYCC; else image->color_space = CLRSPC_UNKNOWN; - return image; } -/* ----------------------------------------------------------------------- */ -/* JP2 encoder interface */ -/* ----------------------------------------------------------------------- */ - -opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo) { - opj_jp2_t *jp2 = (opj_jp2_t*)opj_malloc(sizeof(opj_jp2_t)); - if(jp2) { - jp2->cinfo = cinfo; - /* create the J2K codec */ - jp2->j2k = j2k_create_compress(cinfo); - if(jp2->j2k == NULL) { - jp2_destroy_compress(jp2); - return NULL; - } - } - return jp2; -} - -void jp2_destroy_compress(opj_jp2_t *jp2) { - if(jp2) { - /* destroy the J2K codec */ - j2k_destroy_compress(jp2->j2k); - - if(jp2->comps) { - opj_free(jp2->comps); - } - if(jp2->cl) { - opj_free(jp2->cl); - } - opj_free(jp2); - } -} - -void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image) { - int i; +void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image,opj_event_mgr_t * p_manager) +{ + unsigned int i; int depth_0, sign; if(!jp2 || !parameters || !image) @@ -622,11 +2102,11 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_ /* Check if number of components respects standard */ if (image->numcomps < 1 || image->numcomps > 16384) { - opj_event_msg(jp2->cinfo, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n"); + opj_event_msg(p_manager, EVT_ERROR, "Invalid number of components specified while setting up JP2 encoder\n"); return; } - j2k_setup_encoder(jp2->j2k, parameters, image); + j2k_setup_encoder(jp2->j2k, parameters, image,p_manager); /* setup the JP2 codec */ /* ------------------- */ @@ -687,25 +2167,63 @@ void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_ } -bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { +void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters) +{ + if(!jp2 || !parameters) + return; - /* JP2 encoding */ - - /* JPEG 2000 Signature box */ - jp2_write_jp(cio); - /* File Type box */ - jp2_write_ftyp(jp2, cio); - /* JP2 Header box */ - jp2_write_jp2h(jp2, cio); - - /* J2K encoding */ - - if(!jp2_write_jp2c(jp2, cio, image, cstr_info)) { - opj_event_msg(jp2->cinfo, EVT_ERROR, "Failed to encode image\n"); - return false; - } - - return true; + /* setup the J2K codec */ + /* ------------------- */ + j2k_setup_decoder(jp2->j2k, parameters); +} +/** + * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading. + * + * @param p_jp2 the jpeg2000 codec. + * @param p_end_x the right position of the rectangle to decode (in image coordinates). + * @param p_start_y the up position of the rectangle to decode (in image coordinates). + * @param p_end_y the bottom position of the rectangle to decode (in image coordinates). + * @param p_manager the user event manager + * + * @return true if the area could be set. + */ +bool jp2_set_decode_area( + opj_jp2_t *p_jp2, + OPJ_INT32 p_start_x, + OPJ_INT32 p_start_y, + OPJ_INT32 p_end_x, + OPJ_INT32 p_end_y, + struct opj_event_mgr * p_manager + ) +{ + return j2k_set_decode_area(p_jp2->j2k,p_start_x,p_start_y,p_end_x,p_end_y,p_manager); } +#if 0 + + + + +static void jp2_write_url(opj_cio_t *cio, char *Idx_file) { + unsigned int i; + opj_jp2_box_t box; + + box.init_pos = cio_tell(cio); + cio_skip(cio, 4); + cio_write(cio, JP2_URL, 4); /* DBTL */ + cio_write(cio, 0, 1); /* VERS */ + cio_write(cio, 0, 3); /* FLAG */ + + if(Idx_file) { + for (i = 0; i < strlen(Idx_file); i++) { + cio_write(cio, Idx_file[i], 1); + } + } + + box.length = cio_tell(cio) - box.init_pos; + cio_seek(cio, box.init_pos); + cio_write(cio, box.length, 4); /* L */ + cio_seek(cio, box.init_pos + box.length); +} +#endif diff --git a/libopenjpeg/jp2.h b/libopenjpeg/jp2.h index 7e363be2..e98cde39 100644 --- a/libopenjpeg/jp2.h +++ b/libopenjpeg/jp2.h @@ -3,6 +3,7 @@ * Copyright (c) 2002-2007, Professor Benoit Macq * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -33,6 +34,20 @@ @brief The JPEG-2000 file format Reader/Writer (JP2) */ +#include "openjpeg.h" + + + + +/********************************************************************************** + ********************************* FORWARD DECLARATIONS *************************** + **********************************************************************************/ +struct opj_j2k; +struct opj_procedure_list; +struct opj_event_mgr; +struct opj_stream_private; +struct opj_dparameters; +struct opj_cparameters; /** @defgroup JP2 JP2 - JPEG-2000 file format reader/writer */ /*@{*/ @@ -52,25 +67,54 @@ /* ----------------------------------------------------------------------- */ + +typedef enum +{ + JP2_STATE_NONE = 0x0, + JP2_STATE_SIGNATURE = 0x1, + JP2_STATE_FILE_TYPE = 0x2, + JP2_STATE_HEADER = 0x4, + JP2_STATE_CODESTREAM = 0x8, + JP2_STATE_END_CODESTREAM = 0x10, + JP2_STATE_UNKNOWN = 0x80000000 +} +JP2_STATE; + +typedef enum +{ + JP2_IMG_STATE_NONE = 0x0, + JP2_IMG_STATE_UNKNOWN = 0x80000000 +} +JP2_IMG_STATE; + /** JP2 component */ -typedef struct opj_jp2_comps { - int depth; +typedef struct opj_jp2_comps +{ + unsigned int depth; int sgnd; - int bpcc; -} opj_jp2_comps_t; + unsigned int bpcc; +} +opj_jp2_comps_t; /** JPEG-2000 file format reader/writer */ -typedef struct opj_jp2 { - /** codec context */ - opj_common_ptr cinfo; +typedef struct opj_jp2 +{ /** handle to the J2K codec */ - opj_j2k_t *j2k; + struct opj_j2k *j2k; + /** list of validation procedures */ + struct opj_procedure_list * m_validation_list; + /** list of execution procedures */ + struct opj_procedure_list * m_procedure_list; + + /* width of image */ unsigned int w; + /* height of image */ unsigned int h; + /* number of components in the image */ unsigned int numcomps; unsigned int bpc; unsigned int C; @@ -86,71 +130,80 @@ typedef struct opj_jp2 { unsigned int *cl; opj_jp2_comps_t *comps; unsigned int j2k_codestream_offset; - unsigned int j2k_codestream_length; -} opj_jp2_t; + unsigned int jp2_state; + unsigned int jp2_img_state; + +} +opj_jp2_t; /** JP2 Box */ -typedef struct opj_jp2_box { - int length; - int type; - int init_pos; -} opj_jp2_box_t; +typedef struct opj_jp2_box +{ + unsigned int length; + unsigned int type; +} +opj_jp2_box_t; + +typedef struct opj_jp2_header_handler +{ + /* marker value */ + int id; + /* action linked to the marker */ + bool (*handler) (opj_jp2_t *jp2,unsigned char * p_header_data, unsigned int p_header_size,struct opj_event_mgr * p_manager); +} +opj_jp2_header_handler_t; + + +typedef struct opj_jp2_img_header_writer_handler +{ + /* action to perform */ + unsigned char* (*handler) (opj_jp2_t *jp2, unsigned int * p_data_size); + /* result of the action : data */ + unsigned char * m_data; + /* size of data */ + unsigned int m_size; +} +opj_jp2_img_header_writer_handler_t; + + + + /** @name Exported functions */ /*@{*/ /* ----------------------------------------------------------------------- */ + /** -Write the JP2H box - JP2 Header box (used in MJ2) -@param jp2 JP2 handle -@param cio Output buffer stream -*/ -void jp2_write_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); -/** -Read the JP2H box - JP2 Header box (used in MJ2) -@param jp2 JP2 handle -@param cio Input buffer stream -@return Returns true if successful, returns false otherwise -*/ -bool jp2_read_jp2h(opj_jp2_t *jp2, opj_cio_t *cio); -/** -Creates a JP2 decompression structure -@param cinfo Codec context info -@return Returns a handle to a JP2 decompressor if successful, returns NULL otherwise -*/ -opj_jp2_t* jp2_create_decompress(opj_common_ptr cinfo); + * Creates a jpeg2000 file decompressor. + * + * @return an empty jpeg2000 file codec. + */ +opj_jp2_t* jp2_create (bool p_is_decoder); + /** Destroy a JP2 decompressor handle @param jp2 JP2 decompressor handle to destroy */ -void jp2_destroy_decompress(opj_jp2_t *jp2); +void jp2_destroy(opj_jp2_t *jp2); + /** Setup the decoder decoding parameters using user parameters. Decoding parameters are returned in jp2->j2k->cp. @param jp2 JP2 decompressor handle @param parameters decompression parameters */ -void jp2_setup_decoder(opj_jp2_t *jp2, opj_dparameters_t *parameters); +void jp2_setup_decoder(opj_jp2_t *jp2, struct opj_dparameters *parameters); + /** -Decode an image from a JPEG-2000 file stream -@param jp2 JP2 decompressor handle -@param cio Input buffer stream -@param cstr_info Codestream information structure if required, NULL otherwise -@return Returns a decoded image if successful, returns NULL otherwise + * Decode an image from a JPEG-2000 file stream + * @param jp2 JP2 decompressor handle + * @param cio Input buffer stream + * @param cstr_info Codestream information structure if required, NULL otherwise + * @return Returns a decoded image if successful, returns NULL otherwise */ -opj_image_t* jp2_decode(opj_jp2_t *jp2, opj_cio_t *cio, opj_codestream_info_t *cstr_info); -/** -Creates a JP2 compression structure -@param cinfo Codec context info -@return Returns a handle to a JP2 compressor if successful, returns NULL otherwise -*/ -opj_jp2_t* jp2_create_compress(opj_common_ptr cinfo); -/** -Destroy a JP2 compressor handle -@param jp2 JP2 compressor handle to destroy -*/ -void jp2_destroy_compress(opj_jp2_t *jp2); +struct opj_image* jp2_decode(opj_jp2_t *jp2, struct opj_stream_private *cio, struct opj_event_mgr * p_manager); /** Setup the encoder parameters using the current image and using user parameters. Coding parameters are returned in jp2->j2k->cp. @@ -158,7 +211,24 @@ Coding parameters are returned in jp2->j2k->cp. @param parameters compression parameters @param image input filled image */ -void jp2_setup_encoder(opj_jp2_t *jp2, opj_cparameters_t *parameters, opj_image_t *image); +void jp2_setup_encoder(opj_jp2_t *jp2, struct opj_cparameters *parameters, struct opj_image *image,struct opj_event_mgr * p_manager); + +/** + * Starts a compression scheme, i.e. validates the codec parameters, writes the header. + * + * @param jp2 the jpeg2000 file codec. + * @param cio the stream object. + * + * @return true if the codec is valid. + */ +bool jp2_start_compress(opj_jp2_t *jp2, struct opj_stream_private *cio,struct opj_image * p_image,struct opj_event_mgr * p_manager); + +/** + * Ends the compression procedures and possibiliy add data to be read after the + * codestream. + */ +bool jp2_end_compress(opj_jp2_t *jp2, struct opj_stream_private *cio, struct opj_event_mgr * p_manager); + /** Encode an image into a JPEG-2000 file stream @param jp2 JP2 compressor handle @@ -167,7 +237,102 @@ Encode an image into a JPEG-2000 file stream @param cstr_info Codestream information structure if required, NULL otherwise @return Returns true if successful, returns false otherwise */ -bool jp2_encode(opj_jp2_t *jp2, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info); +bool jp2_encode(opj_jp2_t *jp2, struct opj_stream_private *cio, struct opj_event_mgr * p_manager); + +/** + * Reads a jpeg2000 file header structure. + * + * @param cio the stream to read data from. + * @param jp2 the jpeg2000 file header structure. + * @param p_manager the user event manager. + * + * @return true if the box is valid. + */ +bool jp2_read_header( + opj_jp2_t *jp2, + struct opj_image ** p_image, + OPJ_INT32 * p_tile_x0, + OPJ_INT32 * p_tile_y0, + OPJ_UINT32 * p_tile_width, + OPJ_UINT32 * p_tile_height, + OPJ_UINT32 * p_nb_tiles_x, + OPJ_UINT32 * p_nb_tiles_y, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager + ); +/** + * Ends the decompression procedures and possibiliy add data to be read after the + * codestream. + */ +bool jp2_end_decompress(opj_jp2_t *jp2, struct opj_stream_private *cio, struct opj_event_mgr * p_manager); + +/** + * Writes a tile. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool jp2_write_tile ( + opj_jp2_t *p_jp2, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Decode tile data. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool jp2_decode_tile ( + opj_jp2_t * p_jp2, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Reads a tile header. + * @param p_j2k the jpeg2000 codec. + * @param p_stream the stream to write data to. + * @param p_manager the user event manager. + */ +bool jp2_read_tile_header ( + opj_jp2_t * p_j2k, + 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, + bool * p_go_on, + struct opj_stream_private *p_stream, + struct opj_event_mgr * p_manager + ); +/** + * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading. + * + * @param p_jp2 the jpeg2000 codec. + * @param p_end_x the right position of the rectangle to decode (in image coordinates). + * @param p_start_y the up position of the rectangle to decode (in image coordinates). + * @param p_end_y the bottom position of the rectangle to decode (in image coordinates). + * @param p_manager the user event manager + * + * @return true if the area could be set. + */ +bool jp2_set_decode_area( + opj_jp2_t *p_jp2, + OPJ_INT32 p_start_x, + OPJ_INT32 p_start_y, + OPJ_INT32 p_end_x, + OPJ_INT32 p_end_y, + struct opj_event_mgr * p_manager + ); + /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/jpt.c b/libopenjpeg/jpt.c index a2566ea8..dcbafbd9 100644 --- a/libopenjpeg/jpt.c +++ b/libopenjpeg/jpt.c @@ -3,6 +3,7 @@ * Copyright (c) 2002-2007, Professor Benoit Macq * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -27,33 +28,61 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "opj_includes.h" - +#include "jpt.h" +#include "openjpeg.h" +#include "cio.h" +#include "event.h" /* * Read the information contains in VBAS [JPP/JPT stream message header] * Store information (7 bits) in value - * + * @param p_cio the stream to read from. + * @param p_value the data to update + * @return the nb of bytes read or -1 if an io error occurred. */ -unsigned int jpt_read_VBAS_info(opj_cio_t *cio, unsigned int value) { - unsigned char elmt; +bool jpt_read_VBAS_info(opj_stream_private_t * p_cio, OPJ_UINT32 * p_nb_bytes_read, OPJ_UINT32 * p_value, opj_event_mgr_t * p_manager) +{ + OPJ_BYTE l_elmt; + OPJ_UINT32 l_nb_bytes_read = 0; + + // read data till the MSB of the current byte is 1. + // concatenate 7 bits of data, last bit is finish flag - elmt = cio_read(cio, 1); - while ((elmt >> 7) == 1) { - value = (value << 7); - value |= (elmt & 0x7f); - elmt = cio_read(cio, 1); + // read data from the stream + + if + (opj_stream_read_data(p_cio,&l_elmt,1,p_manager) != 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data.\n"); + return false; } - value = (value << 7); - value |= (elmt & 0x7f); + ++l_nb_bytes_read; - return value; + // is the MSB equal to 1 ? + while + (l_elmt & 0x80) + { + // concatenate 7 bits of data, last bit is finish flag + *p_value = (*p_value << 7) | (l_elmt & 0x7f); + if + (opj_stream_read_data(p_cio,&l_elmt,1,p_manager) != 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data.\n"); + return false; + } + ++l_nb_bytes_read; + } + // concatenate 7 bits of data, last bit is finish flag + *p_value = (*p_value << 7) | (l_elmt & 0x7f); + * p_nb_bytes_read = l_nb_bytes_read; + return true; } /* * Initialize the value of the message header structure * */ -void jpt_init_msg_header(opj_jpt_msg_header_t * header) { +void jpt_init_msg_header(opj_jpt_msg_header_t * header) +{ header->Id = 0; /* In-class Identifier */ header->last_byte = 0; /* Last byte information */ header->Class_Id = 0; /* Class Identifier */ @@ -69,7 +98,8 @@ void jpt_init_msg_header(opj_jpt_msg_header_t * header) { * Only parameters always present in message header * */ -void jpt_reinit_msg_header(opj_jpt_msg_header_t * header) { +void jpt_reinit_msg_header(opj_jpt_msg_header_t * header) +{ header->Id = 0; /* In-class Identifier */ header->last_byte = 0; /* Last byte information */ header->Msg_offset = 0; /* Message offset */ @@ -80,19 +110,31 @@ void jpt_reinit_msg_header(opj_jpt_msg_header_t * header) { * Read the message header for a JPP/JPT - stream * */ -void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header) { - unsigned char elmt, Class = 0, CSn = 0; - jpt_reinit_msg_header(header); +bool jpt_read_msg_header(opj_stream_private_t *cio, opj_jpt_msg_header_t *header, OPJ_UINT32 * p_nb_bytes_read, opj_event_mgr_t * p_manager) +{ + OPJ_BYTE elmt, Class = 0, CSn = 0; + OPJ_UINT32 l_nb_bytes_read = 0; + OPJ_UINT32 l_last_nb_bytes_read; + + jpt_reinit_msg_header(header); + /* ------------- */ /* VBAS : Bin-ID */ /* ------------- */ - elmt = cio_read(cio, 1); + if + (opj_stream_read_data(cio,&elmt,1,p_manager) != 1) + { + opj_event_msg(p_manager, EVT_ERROR, "Forbidden value encounter in message header !!\n"); + return false; + } + ++l_nb_bytes_read; /* See for Class and CSn */ - switch ((elmt >> 5) & 0x03) { + switch ((elmt >> 5) & 0x03) + { case 0: - opj_event_msg(cinfo, EVT_ERROR, "Forbidden value encounter in message header !!\n"); + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data!!!\n"); break; case 1: Class = 0; @@ -111,45 +153,97 @@ void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_heade } /* see information on bits 'c' [p 10 : A.2.1 general, ISO/IEC FCD 15444-9] */ - if (((elmt >> 4) & 0x01) == 1) + if + (((elmt >> 4) & 0x01) == 1) + { header->last_byte = 1; + } /* In-class identifier */ header->Id |= (elmt & 0x0f); - if ((elmt >> 7) == 1) - header->Id = jpt_read_VBAS_info(cio, header->Id); + if + ((elmt >> 7) == 1) + { + l_last_nb_bytes_read = 0; + if + (! jpt_read_VBAS_info(cio, &l_last_nb_bytes_read, &(header->Id), p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data!!!\n"); + return false; + } + l_nb_bytes_read += l_last_nb_bytes_read; + } /* ------------ */ /* VBAS : Class */ /* ------------ */ - if (Class == 1) { + if (Class == 1) + { header->Class_Id = 0; - header->Class_Id = jpt_read_VBAS_info(cio, header->Class_Id); + l_last_nb_bytes_read = 0; + if + (! jpt_read_VBAS_info(cio, &l_last_nb_bytes_read, &(header->Class_Id), p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data!!!\n"); + return false; + } + l_nb_bytes_read += l_last_nb_bytes_read; } /* ---------- */ /* VBAS : CSn */ /* ---------- */ - if (CSn == 1) { + if (CSn == 1) + { header->CSn_Id = 0; - header->CSn_Id = jpt_read_VBAS_info(cio, header->CSn_Id); + l_last_nb_bytes_read = 0; + if + (! jpt_read_VBAS_info(cio, &l_last_nb_bytes_read, &(header->CSn_Id), p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data!!!\n"); + return false; + } + l_nb_bytes_read += l_last_nb_bytes_read; } /* ----------------- */ /* VBAS : Msg_offset */ /* ----------------- */ - header->Msg_offset = jpt_read_VBAS_info(cio, header->Msg_offset); + l_last_nb_bytes_read = 0; + if + (! jpt_read_VBAS_info(cio, &l_last_nb_bytes_read, &(header->Msg_offset), p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data!!!\n"); + return false; + } + l_nb_bytes_read += l_last_nb_bytes_read; /* ----------------- */ /* VBAS : Msg_length */ /* ----------------- */ - header->Msg_length = jpt_read_VBAS_info(cio, header->Msg_length); + l_last_nb_bytes_read = 0; + if + (! jpt_read_VBAS_info(cio, &l_last_nb_bytes_read, &(header->Msg_length), p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data!!!\n"); + return false; + } + l_nb_bytes_read += l_last_nb_bytes_read; /* ---------- */ /* VBAS : Aux */ /* ---------- */ - if ((header->Class_Id & 0x01) == 1) { + if ((header->Class_Id & 0x01) == 1) + { header->Layer_nb = 0; - header->Layer_nb = jpt_read_VBAS_info(cio, header->Layer_nb); + if + (! jpt_read_VBAS_info(cio, &l_last_nb_bytes_read, &(header->Layer_nb), p_manager)) + { + opj_event_msg(p_manager, EVT_ERROR, "Error trying to read a byte of data!!!\n"); + return false; + } + l_nb_bytes_read += l_last_nb_bytes_read; } + * p_nb_bytes_read = l_nb_bytes_read; + return true; } diff --git a/libopenjpeg/jpt.h b/libopenjpeg/jpt.h index eb01f98e..22af2c2a 100644 --- a/libopenjpeg/jpt.h +++ b/libopenjpeg/jpt.h @@ -3,6 +3,7 @@ * Copyright (c) 2002-2007, Professor Benoit Macq * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -35,25 +36,28 @@ JPT-stream functions are implemented in J2K.C. */ - +#include "openjpeg.h" +struct opj_stream_private; +struct opj_event_mgr; /** Message Header JPT stream structure */ -typedef struct opj_jpt_msg_header { +typedef struct opj_jpt_msg_header +{ /** In-class Identifier */ - unsigned int Id; + OPJ_UINT32 Id; /** Last byte information */ - unsigned int last_byte; + OPJ_UINT32 last_byte; /** Class Identifier */ - unsigned int Class_Id; + OPJ_UINT32 Class_Id; /** CSn : index identifier */ - unsigned int CSn_Id; + OPJ_UINT32 CSn_Id; /** Message offset */ - unsigned int Msg_offset; + OPJ_UINT32 Msg_offset; /** Message length */ - unsigned int Msg_length; + OPJ_UINT32 Msg_length; /** Auxiliary for JPP case */ - unsigned int Layer_nb; + OPJ_UINT32 Layer_nb; } opj_jpt_msg_header_t; /* ----------------------------------------------------------------------- */ @@ -65,11 +69,15 @@ Initialize the value of the message header structure void jpt_init_msg_header(opj_jpt_msg_header_t * header); /** -Read the message header for a JPP/JPT - stream -@param cinfo Codec context info -@param cio CIO handle -@param header Message header structure + * Read the message header for a JPP/JPT - stream + * @param p_cio stream handle + * @param header JPT Message header structure + * @param p_manager user event manager to display nice messages. */ -void jpt_read_msg_header(opj_common_ptr cinfo, opj_cio_t *cio, opj_jpt_msg_header_t *header); +bool jpt_read_msg_header( + struct opj_stream_private * p_cio, + opj_jpt_msg_header_t * p_header, + OPJ_UINT32 * p_nb_bytes_read, + struct opj_event_mgr * p_manager); #endif diff --git a/libopenjpeg/mct.c b/libopenjpeg/mct.c index ca21744f..1c7565de 100644 --- a/libopenjpeg/mct.c +++ b/libopenjpeg/mct.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,35 +30,51 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "opj_includes.h" +#include "mct.h" +#include "fix.h" +#include "opj_malloc.h" /* */ /* This table contains the norms of the basis function of the reversible MCT. */ /* */ -static const double mct_norms[3] = { 1.732, .8292, .8292 }; +static const OPJ_FLOAT64 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 }; +static const OPJ_FLOAT64 mct_norms_real[3] = { 1.732, 1.805, 1.573 }; + + + +const OPJ_FLOAT64 * get_mct_norms () +{ + return mct_norms; +} + +const OPJ_FLOAT64 * get_mct_norms_real () +{ + return mct_norms_real; +} + + /* */ /* Foward reversible MCT. */ /* */ void mct_encode( - int* restrict c0, - int* restrict c1, - int* restrict c2, - int n) + OPJ_INT32* restrict c0, + OPJ_INT32* restrict c1, + OPJ_INT32* restrict c2, + OPJ_UINT32 n) { - int i; + OPJ_UINT32 i; for(i = 0; i < n; ++i) { - int r = c0[i]; - int g = c1[i]; - int b = c2[i]; - int y = (r + (g * 2) + b) >> 2; - int u = b - g; - int v = r - g; + OPJ_INT32 r = c0[i]; + OPJ_INT32 g = c1[i]; + OPJ_INT32 b = c2[i]; + OPJ_INT32 y = (r + (g * 2) + b) >> 2; + OPJ_INT32 u = b - g; + OPJ_INT32 v = r - g; c0[i] = y; c1[i] = u; c2[i] = v; @@ -68,19 +85,19 @@ void mct_encode( /* Inverse reversible MCT. */ /* */ void mct_decode( - int* restrict c0, - int* restrict c1, - int* restrict c2, - int n) + OPJ_INT32* restrict c0, + OPJ_INT32* restrict c1, + OPJ_INT32* restrict c2, + OPJ_UINT32 n) { - int i; + OPJ_UINT32 i; for (i = 0; i < n; ++i) { - int y = c0[i]; - int u = c1[i]; - int v = c2[i]; - int g = y - ((u + v) >> 2); - int r = v + g; - int b = u + g; + OPJ_INT32 y = c0[i]; + OPJ_INT32 u = c1[i]; + OPJ_INT32 v = c2[i]; + OPJ_INT32 g = y - ((u + v) >> 2); + OPJ_INT32 r = v + g; + OPJ_INT32 b = u + g; c0[i] = r; c1[i] = g; c2[i] = b; @@ -90,7 +107,7 @@ void mct_decode( /* */ /* Get norm of basis function of reversible MCT. */ /* */ -double mct_getnorm(int compno) { +OPJ_FLOAT64 mct_getnorm(OPJ_UINT32 compno) { return mct_norms[compno]; } @@ -98,19 +115,19 @@ double mct_getnorm(int compno) { /* Foward irreversible MCT. */ /* */ void mct_encode_real( - int* restrict c0, - int* restrict c1, - int* restrict c2, - int n) + OPJ_INT32* restrict c0, + OPJ_INT32* restrict c1, + OPJ_INT32* restrict c2, + OPJ_UINT32 n) { - int i; + OPJ_UINT32 i; for(i = 0; i < n; ++i) { - int r = c0[i]; - int g = c1[i]; - int b = c2[i]; - int y = fix_mul(r, 2449) + fix_mul(g, 4809) + fix_mul(b, 934); - int u = -fix_mul(r, 1382) - fix_mul(g, 2714) + fix_mul(b, 4096); - int v = fix_mul(r, 4096) - fix_mul(g, 3430) - fix_mul(b, 666); + OPJ_INT32 r = c0[i]; + OPJ_INT32 g = c1[i]; + OPJ_INT32 b = c2[i]; + OPJ_INT32 y = fix_mul(r, 2449) + fix_mul(g, 4809) + fix_mul(b, 934); + OPJ_INT32 u = -fix_mul(r, 1382) - fix_mul(g, 2714) + fix_mul(b, 4096); + OPJ_INT32 v = fix_mul(r, 4096) - fix_mul(g, 3430) - fix_mul(b, 666); c0[i] = y; c1[i] = u; c2[i] = v; @@ -121,19 +138,19 @@ void mct_encode_real( /* Inverse irreversible MCT. */ /* */ void mct_decode_real( - float* restrict c0, - float* restrict c1, - float* restrict c2, - int n) + OPJ_FLOAT32* restrict c0, + OPJ_FLOAT32* restrict c1, + OPJ_FLOAT32* restrict c2, + OPJ_UINT32 n) { - int i; + OPJ_UINT32 i; for(i = 0; i < n; ++i) { - float y = c0[i]; - float u = c1[i]; - float v = c2[i]; - float r = y + (v * 1.402f); - float g = y - (u * 0.34413f) - (v * (0.71414f)); - float b = y + (u * 1.772f); + OPJ_FLOAT32 y = c0[i]; + OPJ_FLOAT32 u = c1[i]; + OPJ_FLOAT32 v = c2[i]; + OPJ_FLOAT32 r = y + (v * 1.402f); + OPJ_FLOAT32 g = y - (u * 0.34413f) - (v * (0.71414f)); + OPJ_FLOAT32 b = y + (u * 1.772f); c0[i] = r; c1[i] = g; c2[i] = b; @@ -143,6 +160,145 @@ void mct_decode_real( /* */ /* Get norm of basis function of irreversible MCT. */ /* */ -double mct_getnorm_real(int compno) { +OPJ_FLOAT64 mct_getnorm_real(OPJ_UINT32 compno) { return mct_norms_real[compno]; } + +bool mct_encode_custom( + // MCT data + OPJ_BYTE * pCodingdata, + // size of components + OPJ_UINT32 n, + // components + OPJ_BYTE ** pData, + // nb of components (i.e. size of pData) + OPJ_UINT32 pNbComp, + // tells if the data is signed + OPJ_UINT32 isSigned) +{ + OPJ_FLOAT32 * lMct = (OPJ_FLOAT32 *) pCodingdata; + OPJ_UINT32 i; + OPJ_UINT32 j; + OPJ_UINT32 k; + OPJ_UINT32 lNbMatCoeff = pNbComp * pNbComp; + OPJ_INT32 * lCurrentData = 00; + OPJ_INT32 * lCurrentMatrix = 00; + OPJ_INT32 ** lData = (OPJ_INT32 **) pData; + OPJ_UINT32 lMultiplicator = 1 << 13; + OPJ_INT32 * lMctPtr; + + lCurrentData = (OPJ_INT32 *) opj_malloc((pNbComp + lNbMatCoeff) * sizeof(OPJ_INT32)); + if + (! lCurrentData) + { + return false; + } + lCurrentMatrix = lCurrentData + pNbComp; + for + (i =0;i * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,7 +39,7 @@ 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. */ - +#include "openjpeg.h" /** @defgroup MCT MCT - Implementation of a multi-component transform */ /*@{*/ @@ -52,7 +53,7 @@ Apply a reversible multi-component transform to an image @param c2 Samples blue component @param n Number of samples for each component */ -void mct_encode(int *c0, int *c1, int *c2, int n); +void mct_encode(OPJ_INT32 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 n); /** Apply a reversible multi-component inverse transform to an image @param c0 Samples for luminance component @@ -60,13 +61,13 @@ Apply a reversible multi-component inverse transform to an image @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); +void mct_decode(OPJ_INT32 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 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); +OPJ_FLOAT64 mct_getnorm(OPJ_UINT32 compno); /** Apply an irreversible multi-component transform to an image @@ -75,7 +76,7 @@ Apply an irreversible multi-component transform to an image @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); +void mct_encode_real(OPJ_INT32 *c0, OPJ_INT32 *c1, OPJ_INT32 *c2, OPJ_UINT32 n); /** Apply an irreversible multi-component inverse transform to an image @param c0 Samples for luminance component @@ -83,13 +84,44 @@ Apply an irreversible multi-component inverse transform to an image @param c2 Samples for blue chrominance component @param n Number of samples for each component */ -void mct_decode_real(float* c0, float* c1, float* c2, int n); +void mct_decode_real(OPJ_FLOAT32* c0, OPJ_FLOAT32* c1, OPJ_FLOAT32* c2, OPJ_UINT32 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); +OPJ_FLOAT64 mct_getnorm_real(OPJ_UINT32 compno); + +bool mct_encode_custom( + // MCT data + OPJ_BYTE * p_coding_data, + // size of components + OPJ_UINT32 n, + // components + OPJ_BYTE ** p_data, + // nb of components (i.e. size of p_data) + OPJ_UINT32 p_nb_comp, + // tells if the data is signed + OPJ_UINT32 is_signed); + +bool mct_decode_custom( + // MCT data + OPJ_BYTE * pDecodingData, + // size of components + OPJ_UINT32 n, + // components + OPJ_BYTE ** pData, + // nb of components (i.e. size of pData) + OPJ_UINT32 pNbComp, + // tells if the data is signed + OPJ_UINT32 isSigned); + +void opj_calculate_norms(OPJ_FLOAT64 * pNorms,OPJ_UINT32 p_nb_comps,OPJ_FLOAT32 * pMatrix); + +const OPJ_FLOAT64 * get_mct_norms (); +const OPJ_FLOAT64 * get_mct_norms_real (); + + /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/mqc.c b/libopenjpeg/mqc.c index 9aa9d2c2..e6cfd325 100644 --- a/libopenjpeg/mqc.c +++ b/libopenjpeg/mqc.c @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -29,7 +30,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#include "opj_includes.h" +#include "mqc.h" +#include "t1.h" +#include "opj_malloc.h" /** @defgroup MQC MQC - Implementation of an MQ-Coder */ /*@{*/ @@ -68,13 +71,13 @@ FIXME: documentation ??? @param mqc MQC handle @return */ -static int mqc_mpsexchange(opj_mqc_t *mqc); +static OPJ_INT32 mqc_mpsexchange(opj_mqc_t *mqc); /** FIXME: documentation ??? @param mqc MQC handle @return */ -static int mqc_lpsexchange(opj_mqc_t *mqc); +static OPJ_INT32 mqc_lpsexchange(opj_mqc_t *mqc); /** Input a byte @param mqc MQC handle @@ -264,15 +267,15 @@ static void mqc_codelps(opj_mqc_t *mqc) { } static void mqc_setbits(opj_mqc_t *mqc) { - unsigned int tempc = mqc->c + mqc->a; + OPJ_UINT32 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; +static OPJ_INT32 mqc_mpsexchange(opj_mqc_t *mqc) { + OPJ_INT32 d; if (mqc->a < (*mqc->curctx)->qeval) { d = 1 - (*mqc->curctx)->mps; *mqc->curctx = (*mqc->curctx)->nlps; @@ -284,8 +287,8 @@ static int mqc_mpsexchange(opj_mqc_t *mqc) { return d; } -static int mqc_lpsexchange(opj_mqc_t *mqc) { - int d; +static OPJ_INT32 mqc_lpsexchange(opj_mqc_t *mqc) { + OPJ_INT32 d; if (mqc->a < (*mqc->curctx)->qeval) { mqc->a = (*mqc->curctx)->qeval; d = (*mqc->curctx)->mps; @@ -301,7 +304,7 @@ static int mqc_lpsexchange(opj_mqc_t *mqc) { static void mqc_bytein(opj_mqc_t *mqc) { if (mqc->bp != mqc->end) { - unsigned int c; + OPJ_UINT32 c; if (mqc->bp + 1 != mqc->end) { c = *(mqc->bp + 1); } else { @@ -350,28 +353,31 @@ opj_mqc_t* mqc_create(void) { } void mqc_destroy(opj_mqc_t *mqc) { - if(mqc) { + if + (mqc) + { opj_free(mqc); } } -int mqc_numbytes(opj_mqc_t *mqc) { +OPJ_UINT32 mqc_numbytes(opj_mqc_t *mqc) { return mqc->bp - mqc->start; } -void mqc_init_enc(opj_mqc_t *mqc, unsigned char *bp) { +void mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp) { mqc_setcurctx(mqc, 0); mqc->a = 0x8000; mqc->c = 0; mqc->bp = bp - 1; + *(mqc->bp) = 0; mqc->ct = 12; - if (*mqc->bp == 0xff) { + /*if (*mqc->bp == 0xff) { mqc->ct = 13; - } + }*/ mqc->start = bp; } -void mqc_encode(opj_mqc_t *mqc, int d) { +void mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d) { if ((*mqc->curctx)->mps == d) { mqc_codemps(mqc); } else { @@ -399,7 +405,7 @@ void mqc_bypass_init_enc(opj_mqc_t *mqc) { } */ } -void mqc_bypass_enc(opj_mqc_t *mqc, int d) { +void mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 d) { mqc->ct--; mqc->c = mqc->c + (d << mqc->ct); if (mqc->ct == 0) { @@ -413,8 +419,8 @@ void mqc_bypass_enc(opj_mqc_t *mqc, int d) { } } -int mqc_bypass_flush_enc(opj_mqc_t *mqc) { - unsigned char bit_padding; +OPJ_UINT32 mqc_bypass_flush_enc(opj_mqc_t *mqc) { + OPJ_BYTE bit_padding; bit_padding = 0; @@ -440,11 +446,11 @@ void mqc_reset_enc(opj_mqc_t *mqc) { mqc_setstate(mqc, T1_CTXNO_ZC, 0, 4); } -int mqc_restart_enc(opj_mqc_t *mqc) { - int correction = 1; +OPJ_UINT32 mqc_restart_enc(opj_mqc_t *mqc) { + OPJ_UINT32 correction = 1; /* */ - int n = 27 - 15 - mqc->ct; + OPJ_INT32 n = 27 - 15 - mqc->ct; mqc->c <<= mqc->ct; while (n > 0) { mqc_byteout(mqc); @@ -469,7 +475,7 @@ void mqc_restart_init_enc(opj_mqc_t *mqc) { } void mqc_erterm_enc(opj_mqc_t *mqc) { - int k = 11 - mqc->ct + 1; + OPJ_INT32 k = 11 - mqc->ct + 1; while (k > 0) { mqc->c <<= mqc->ct; @@ -484,7 +490,7 @@ void mqc_erterm_enc(opj_mqc_t *mqc) { } void mqc_segmark_enc(opj_mqc_t *mqc) { - int i; + OPJ_UINT32 i; mqc_setcurctx(mqc, 18); for (i = 1; i < 5; i++) { @@ -492,7 +498,7 @@ void mqc_segmark_enc(opj_mqc_t *mqc) { } } -void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) { +void mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len) { mqc_setcurctx(mqc, 0); mqc->start = bp; mqc->end = bp + len; @@ -505,8 +511,8 @@ void mqc_init_dec(opj_mqc_t *mqc, unsigned char *bp, int len) { mqc->a = 0x8000; } -int mqc_decode(opj_mqc_t *mqc) { - int d; +OPJ_UINT32 mqc_decode(opj_mqc_t *mqc) { + OPJ_INT32 d; mqc->a -= (*mqc->curctx)->qeval; if ((mqc->c >> 16) < (*mqc->curctx)->qeval) { d = mqc_lpsexchange(mqc); @@ -521,17 +527,17 @@ int mqc_decode(opj_mqc_t *mqc) { } } - return d; + return (OPJ_UINT32)d; } void mqc_resetstates(opj_mqc_t *mqc) { - int i; + OPJ_UINT32 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) { +void mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb, OPJ_INT32 prob) { mqc->ctxs[ctxno] = &mqc_states[msb + (prob << 1)]; } diff --git a/libopenjpeg/mqc.h b/libopenjpeg/mqc.h index 8cc8c934..93d3b943 100644 --- a/libopenjpeg/mqc.h +++ b/libopenjpeg/mqc.h @@ -5,6 +5,7 @@ * Copyright (c) 2002-2003, Yannick Verschueren * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -38,7 +39,7 @@ 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. */ - +#include "openjpeg.h" /** @defgroup MQC MQC - Implementation of an MQ-Coder */ /*@{*/ @@ -47,27 +48,27 @@ 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; + OPJ_UINT32 qeval; /** the Most Probable Symbol (0 or 1) */ - int mps; + OPJ_INT32 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 19 +#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_UINT32 c; + OPJ_UINT32 a; + OPJ_UINT32 ct; + OPJ_BYTE *bp; + OPJ_BYTE *start; + OPJ_BYTE *end; opj_mqc_state_t *ctxs[MQC_NUMCTXS]; opj_mqc_state_t **curctx; } opj_mqc_t; @@ -90,7 +91,7 @@ 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); +OPJ_UINT32 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) @@ -104,25 +105,25 @@ Set the state of a particular 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); +void mqc_setstate(opj_mqc_t *mqc, OPJ_UINT32 ctxno, OPJ_UINT32 msb, OPJ_INT32 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); +void mqc_init_enc(opj_mqc_t *mqc, OPJ_BYTE *bp); /** Set the current context used for coding/decoding @param mqc MQC handle @param ctxno Number that identifies the context */ -#define mqc_setcurctx(mqc, ctxno) (mqc)->curctx = &(mqc)->ctxs[(int)(ctxno)] +#define mqc_setcurctx(mqc, ctxno) (mqc)->curctx = &(mqc)->ctxs[(OPJ_UINT32)(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); +void mqc_encode(opj_mqc_t *mqc, OPJ_UINT32 d); /** Flush the encoder, so that all remaining data is written @param mqc MQC handle @@ -142,14 +143,14 @@ JPEG 2000 p 505. @param mqc MQC handle @param d The symbol to be encoded (0 or 1) */ -void mqc_bypass_enc(opj_mqc_t *mqc, int d); +void mqc_bypass_enc(opj_mqc_t *mqc, OPJ_UINT32 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); +OPJ_UINT32 mqc_bypass_flush_enc(opj_mqc_t *mqc); /** RESET mode switch @param mqc MQC handle @@ -160,7 +161,7 @@ RESTART mode switch (TERMALL) @param mqc MQC handle @return Returns 1 (always) */ -int mqc_restart_enc(opj_mqc_t *mqc); +OPJ_UINT32 mqc_restart_enc(opj_mqc_t *mqc); /** RESTART mode switch (TERMALL) reinitialisation @param mqc MQC handle @@ -182,13 +183,13 @@ Initialize the decoder @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); +void mqc_init_dec(opj_mqc_t *mqc, OPJ_BYTE *bp, OPJ_UINT32 len); /** Decode a symbol @param mqc MQC handle @return Returns the decoded symbol (0 or 1) */ -int mqc_decode(opj_mqc_t *mqc); +OPJ_UINT32 mqc_decode(opj_mqc_t *mqc); /* ----------------------------------------------------------------------- */ /*@}*/ diff --git a/libopenjpeg/openjpeg.c b/libopenjpeg/openjpeg.c index 88d44fd0..574b5135 100644 --- a/libopenjpeg/openjpeg.c +++ b/libopenjpeg/openjpeg.c @@ -1,5 +1,6 @@ /* * Copyright (c) 2005, Hervé Drolon, FreeImage Team + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -28,7 +29,124 @@ #include #endif /* WIN32 */ -#include "opj_includes.h" +#include "openjpeg.h" +#include "opj_malloc.h" +#include "j2k.h" +#include "jp2.h" +#include "event.h" +#include "cio.h" + +typedef struct opj_decompression +{ + bool (* opj_read_header) ( + void *p_codec, + opj_image_t **, + OPJ_INT32 * p_tile_x0, + OPJ_INT32 * p_tile_y0, + OPJ_UINT32 * p_tile_width, + OPJ_UINT32 * p_tile_height, + OPJ_UINT32 * p_nb_tiles_x, + OPJ_UINT32 * p_nb_tiles_y, + struct opj_stream_private *cio, + struct opj_event_mgr * p_manager); + opj_image_t* (* opj_decode) (void * p_codec, struct opj_stream_private *p_cio, struct opj_event_mgr * p_manager); + 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, + bool * p_should_go_on, + struct opj_stream_private *p_cio, + struct opj_event_mgr * p_manager); + 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); + bool (* opj_end_decompress) (void *p_codec,struct opj_stream_private *cio,struct opj_event_mgr * p_manager); + void (* opj_destroy) (void * p_codec); + void (*opj_setup_decoder) (void * p_codec,opj_dparameters_t * p_param); + bool (*opj_set_decode_area) (void * p_codec,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); + + +}opj_decompression_t; + +typedef struct opj_compression +{ + bool (* opj_start_compress) (void *p_codec,struct opj_stream_private *cio,struct opj_image * p_image, struct opj_event_mgr * p_manager); + bool (* opj_encode) (void * p_codec, struct opj_stream_private *p_cio, struct opj_event_mgr * p_manager); + 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); + 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; + + + +typedef struct opj_codec_private +{ + union + { /* code-blocks informations */ + opj_decompression_t m_decompression; + opj_compression_t m_compression; + } m_codec_data; + void * m_codec; + opj_event_mgr_t m_event_mgr; + unsigned is_decompressor : 1; +} +opj_codec_private_t; + + + +/** + * Default callback function. + * Do nothing. + */ +void opj_default_callback (const char *msg, void *client_data) +{ +} + +void set_default_event_handler(opj_event_mgr_t * p_manager) +{ + p_manager->m_error_data = 00; + p_manager->m_warning_data = 00; + p_manager->m_info_data = 00; + p_manager->error_handler = opj_default_callback; + p_manager->info_handler = opj_default_callback; + p_manager->warning_handler = opj_default_callback; +} + +OPJ_UINT32 opj_read_from_file (void * p_buffer, OPJ_UINT32 p_nb_bytes, FILE * p_file) +{ + OPJ_UINT32 l_nb_read = fread(p_buffer,1,p_nb_bytes,p_file); + return l_nb_read ? l_nb_read : -1; +} + +OPJ_UINT32 opj_write_from_file (void * p_buffer, OPJ_UINT32 p_nb_bytes, FILE * p_file) +{ + return fwrite(p_buffer,1,p_nb_bytes,p_file); +} + +OPJ_SIZE_T opj_skip_from_file (OPJ_SIZE_T p_nb_bytes, FILE * p_user_data) +{ + if + (fseek(p_user_data,p_nb_bytes,SEEK_CUR)) + { + return -1; + } + return p_nb_bytes; +} + +bool opj_seek_from_file (OPJ_SIZE_T p_nb_bytes, FILE * p_user_data) +{ + if + (fseek(p_user_data,p_nb_bytes,SEEK_SET)) + { + return false; + } + return true; +} /* ---------------------------------------------------------------------- */ #ifdef WIN32 @@ -57,56 +175,133 @@ const char* OPJ_CALLCONV opj_version(void) { return OPENJPEG_VERSION; } -opj_dinfo_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT format) { - opj_dinfo_t *dinfo = (opj_dinfo_t*)opj_calloc(1, sizeof(opj_dinfo_t)); - if(!dinfo) return NULL; - dinfo->is_decompressor = true; - switch(format) { +opj_codec_t* OPJ_CALLCONV opj_create_decompress(OPJ_CODEC_FORMAT p_format) +{ + opj_codec_private_t *l_info = 00; + + l_info = (opj_codec_private_t*) opj_calloc(1, sizeof(opj_codec_private_t)); + if + (!l_info) + { + return 00; + } + memset(l_info, 0, sizeof(opj_codec_private_t)); + l_info->is_decompressor = 1; + switch + (p_format) + { case CODEC_J2K: - case CODEC_JPT: - /* get a J2K decoder handle */ - dinfo->j2k_handle = (void*)j2k_create_decompress((opj_common_ptr)dinfo); - if(!dinfo->j2k_handle) { - opj_free(dinfo); - return NULL; + l_info->m_codec_data.m_decompression.opj_decode = (opj_image_t* (*) (void *, struct opj_stream_private *, struct opj_event_mgr * ))j2k_decode; + l_info->m_codec_data.m_decompression.opj_end_decompress = (bool (*) (void *,struct opj_stream_private *,struct opj_event_mgr *))j2k_end_decompress; + l_info->m_codec_data.m_decompression.opj_read_header = (bool (*) ( + void *, + opj_image_t **, + OPJ_INT32 * , + OPJ_INT32 * , + OPJ_UINT32 * , + OPJ_UINT32 * , + OPJ_UINT32 * , + OPJ_UINT32 * , + struct opj_stream_private *, + struct opj_event_mgr * )) j2k_read_header; + l_info->m_codec_data.m_decompression.opj_destroy = (void (*) (void *))j2k_destroy; + l_info->m_codec_data.m_decompression.opj_setup_decoder = (void (*) (void * ,opj_dparameters_t * )) j2k_setup_decoder; + l_info->m_codec_data.m_decompression.opj_read_tile_header = (bool (*) ( + void *, + OPJ_UINT32*, + OPJ_UINT32*, + OPJ_INT32 * , + OPJ_INT32 * , + OPJ_INT32 * , + OPJ_INT32 * , + OPJ_UINT32 * , + bool *, + struct opj_stream_private *, + struct opj_event_mgr * )) j2k_read_tile_header; + l_info->m_codec_data.m_decompression.opj_decode_tile_data = (bool (*) (void *,OPJ_UINT32,OPJ_BYTE*,OPJ_UINT32,struct opj_stream_private *, struct opj_event_mgr * )) j2k_decode_tile; + l_info->m_codec_data.m_decompression.opj_set_decode_area = (bool (*) (void *,OPJ_INT32,OPJ_INT32,OPJ_INT32,OPJ_INT32, struct opj_event_mgr * )) j2k_set_decode_area; + l_info->m_codec = j2k_create_decompress(); + if + (! l_info->m_codec) + { + opj_free(l_info); + return 00; } break; + case CODEC_JP2: /* get a JP2 decoder handle */ - dinfo->jp2_handle = (void*)jp2_create_decompress((opj_common_ptr)dinfo); - if(!dinfo->jp2_handle) { - opj_free(dinfo); - return NULL; + l_info->m_codec_data.m_decompression.opj_decode = (opj_image_t* (*) (void *, struct opj_stream_private *, struct opj_event_mgr * ))jp2_decode; + l_info->m_codec_data.m_decompression.opj_end_decompress = (bool (*) (void *,struct opj_stream_private *,struct opj_event_mgr *)) jp2_end_decompress; + l_info->m_codec_data.m_decompression.opj_read_header = (bool (*) ( + void *, + opj_image_t **, + + OPJ_INT32 * , + OPJ_INT32 * , + OPJ_UINT32 * , + OPJ_UINT32 * , + OPJ_UINT32 * , + OPJ_UINT32 * , + struct opj_stream_private *, + struct opj_event_mgr * )) jp2_read_header; + + l_info->m_codec_data.m_decompression.opj_read_tile_header = ( + bool (*) ( + void *, + OPJ_UINT32*, + OPJ_UINT32*, + OPJ_INT32*, + OPJ_INT32*, + OPJ_INT32 * , + OPJ_INT32 * , + OPJ_UINT32 * , + bool *, + struct opj_stream_private *, + struct opj_event_mgr * )) jp2_read_tile_header; + + l_info->m_codec_data.m_decompression.opj_decode_tile_data = (bool (*) (void *,OPJ_UINT32,OPJ_BYTE*,OPJ_UINT32,struct opj_stream_private *, struct opj_event_mgr * )) jp2_decode_tile; + + l_info->m_codec_data.m_decompression.opj_destroy = (void (*) (void *))jp2_destroy; + l_info->m_codec_data.m_decompression.opj_setup_decoder = (void (*) (void * ,opj_dparameters_t * )) jp2_setup_decoder; + l_info->m_codec_data.m_decompression.opj_set_decode_area = (bool (*) (void *,OPJ_INT32,OPJ_INT32,OPJ_INT32,OPJ_INT32, struct opj_event_mgr * )) jp2_set_decode_area; + + + l_info->m_codec = jp2_create(true); + if + (! l_info->m_codec) + { + opj_free(l_info); + return 00; } break; case CODEC_UNKNOWN: + case CODEC_JPT: default: - opj_free(dinfo); - return NULL; + opj_free(l_info); + return 00; } - - dinfo->codec_format = format; - - return dinfo; + set_default_event_handler(&(l_info->m_event_mgr)); + return (opj_codec_t*) l_info; } -void OPJ_CALLCONV opj_destroy_decompress(opj_dinfo_t *dinfo) { - if(dinfo) { - /* destroy the codec */ - switch(dinfo->codec_format) { - case CODEC_J2K: - case CODEC_JPT: - j2k_destroy_decompress((opj_j2k_t*)dinfo->j2k_handle); - break; - case CODEC_JP2: - jp2_destroy_decompress((opj_jp2_t*)dinfo->jp2_handle); - break; - case CODEC_UNKNOWN: - default: - break; +void OPJ_CALLCONV opj_destroy_codec(opj_codec_t *p_info) +{ + if + (p_info) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_info; + if + (l_info->is_decompressor) + { + l_info->m_codec_data.m_decompression.opj_destroy(l_info->m_codec); } - /* destroy the decompressor */ - opj_free(dinfo); + else + { + l_info->m_codec_data.m_compression.opj_destroy(l_info->m_codec); + } + l_info->m_codec = 00; + opj_free(l_info); } } @@ -116,7 +311,6 @@ void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *paramete /* default decoding parameters */ parameters->cp_layer = 0; parameters->cp_reduce = 0; - parameters->cp_limit_decoding = NO_LIMITATION; parameters->decod_format = -1; parameters->cod_format = -1; @@ -130,95 +324,317 @@ void OPJ_CALLCONV opj_set_default_decoder_parameters(opj_dparameters_t *paramete } } -void OPJ_CALLCONV opj_setup_decoder(opj_dinfo_t *dinfo, opj_dparameters_t *parameters) { - if(dinfo && parameters) { - switch(dinfo->codec_format) { - case CODEC_J2K: - case CODEC_JPT: - j2k_setup_decoder((opj_j2k_t*)dinfo->j2k_handle, parameters); - break; - case CODEC_JP2: - jp2_setup_decoder((opj_jp2_t*)dinfo->jp2_handle, parameters); - break; - case CODEC_UNKNOWN: - default: - break; +bool OPJ_CALLCONV opj_setup_decoder(opj_codec_t *p_info, opj_dparameters_t *parameters) { + if + (p_info && parameters) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_info; + if + (! l_info->is_decompressor) + { + return false; } + l_info->m_codec_data.m_decompression.opj_setup_decoder(l_info->m_codec,parameters); + return true; } + return false; } -opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio) { - return opj_decode_with_info(dinfo, cio, NULL); -} - -opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *cio, opj_codestream_info_t *cstr_info) { - if(dinfo && cio) { - switch(dinfo->codec_format) { - case CODEC_J2K: - return j2k_decode((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info); - case CODEC_JPT: - return j2k_decode_jpt_stream((opj_j2k_t*)dinfo->j2k_handle, cio, cstr_info); - case CODEC_JP2: - return jp2_decode((opj_jp2_t*)dinfo->jp2_handle, cio, cstr_info); - case CODEC_UNKNOWN: - default: - break; +opj_image_t* OPJ_CALLCONV opj_decode(opj_codec_t *p_info, opj_stream_t *cio) +{ + if + (p_info && cio) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_info; + opj_stream_private_t * l_cio = (opj_stream_private_t *) cio; + if + (! l_info->is_decompressor) + { + return 00; } + return l_info->m_codec_data.m_decompression.opj_decode(l_info->m_codec,l_cio,&(l_info->m_event_mgr)); } - return NULL; + return 00; } -opj_cinfo_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format) { - opj_cinfo_t *cinfo = (opj_cinfo_t*)opj_calloc(1, sizeof(opj_cinfo_t)); - if(!cinfo) return NULL; - cinfo->is_decompressor = false; - switch(format) { +/** + * Writes a tile with the given data. + * + * @param p_compressor 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_stream the stream to write data to. + */ +bool opj_write_tile ( + opj_codec_t *p_codec, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_t *p_stream + ) +{ + if + (p_codec && p_stream && p_data) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_codec; + opj_stream_private_t * l_cio = (opj_stream_private_t *) p_stream; + if + (l_info->is_decompressor) + { + return false; + } + return l_info->m_codec_data.m_compression.opj_write_tile(l_info->m_codec,p_tile_index,p_data,p_data_size,l_cio,&(l_info->m_event_mgr)); + } + return false; +} + +/** + * Reads a tile header. This function is compulsory and allows one to know the size of the tile thta will be decoded. + * The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile. + * + * @param p_codec the jpeg2000 codec. + * @param p_tile_index pointer to a value that will hold the index of the tile being decoded, in case of success. + * @param p_data_size pointer to a value that will hold the maximum size of the decoded data, in case of success. In case + * of truncated codestreams, the actual number of bytes decoded may be lower. The computation of the size is the same + * as depicted in opj_write_tile. + * @param p_tile_x0 pointer to a value that will hold the x0 pos of the tile (in the image). + * @param p_tile_y0 pointer to a value that will hold the y0 pos of the tile (in the image). + * @param p_tile_x1 pointer to a value that will hold the x1 pos of the tile (in the image). + * @param p_tile_y1 pointer to a value that will hold the y1 pos of the tile (in the image). + * @param p_nb_comps pointer to a value that will hold the number of components in the tile. + * @param p_should_go_on pointer to a boolean that will hold the fact that the decoding should go on. In case the + * codestream is over at the time of the call, the value will be set to false. The user should then stop + * the decoding. + * @param p_stream the stream to decode. + * @return true if the tile header could be decoded. In case the decoding should end, the returned value is still true. + * returning false may be the result of a shortage of memory or an internal error. + */ +bool opj_read_tile_header( + opj_codec_t *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, + bool * p_should_go_on, + opj_stream_t * p_stream) +{ + if + (p_codec && p_stream && p_data_size && p_tile_index) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_codec; + opj_stream_private_t * l_cio = (opj_stream_private_t *) p_stream; + if + (! l_info->is_decompressor) + { + return false; + } + return l_info->m_codec_data.m_decompression.opj_read_tile_header( + l_info->m_codec, + p_tile_index, + p_data_size, + p_tile_x0, + p_tile_y0, + p_tile_x1, + p_tile_y1, + p_nb_comps, + p_should_go_on, + l_cio,&(l_info->m_event_mgr)); + } + return false; +} + +/** + * Reads a tile data. This function is compulsory and allows one to decode tile data. opj_read_tile_header should be called before. + * The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile. + * + * @param p_codec the jpeg2000 codec. + * @param p_tile_index the index of the tile being decoded, this should be the value set by opj_read_tile_header. + * @param p_data pointer to a memory block that will hold the decoded data. + * @param p_data_size size of p_data. p_data_size should be bigger or equal to the value set by opj_read_tile_header. + * @param p_stream the stream to decode. + * + * @return true if the data could be decoded. + */ +bool opj_decode_tile_data( + opj_codec_t *p_codec, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_t *p_stream + ) +{ + if + (p_codec && p_data && p_stream) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_codec; + opj_stream_private_t * l_cio = (opj_stream_private_t *) p_stream; + if + (! l_info->is_decompressor) + { + return false; + } + return l_info->m_codec_data.m_decompression.opj_decode_tile_data(l_info->m_codec,p_tile_index,p_data,p_data_size,l_cio,&(l_info->m_event_mgr)); + } + return false; +} + +bool OPJ_CALLCONV opj_read_header ( + opj_codec_t *p_codec, + opj_image_t ** p_image, + OPJ_INT32 * p_tile_x0, + OPJ_INT32 * p_tile_y0, + OPJ_UINT32 * p_tile_width, + OPJ_UINT32 * p_tile_height, + OPJ_UINT32 * p_nb_tiles_x, + OPJ_UINT32 * p_nb_tiles_y, + opj_stream_t *p_cio) +{ + if + (p_codec && p_cio) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_codec; + opj_stream_private_t * l_cio = (opj_stream_private_t *) p_cio; + if + (! l_info->is_decompressor) + { + return false; + } + return l_info->m_codec_data.m_decompression.opj_read_header( + l_info->m_codec, + p_image, + p_tile_x0, + p_tile_y0, + p_tile_width, + p_tile_height, + p_nb_tiles_x, + p_nb_tiles_y, + l_cio, + &(l_info->m_event_mgr)); + } + return false; +} + +/** + * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading. + * + * @param p_codec the jpeg2000 codec. + * @param p_start_x the left position of the rectangle to decode (in image coordinates). + * @param p_end_x the right position of the rectangle to decode (in image coordinates). + * @param p_start_y the up position of the rectangle to decode (in image coordinates). + * @param p_end_y the bottom position of the rectangle to decode (in image coordinates). + * + * @return true if the area could be set. + */ +bool opj_set_decode_area( + opj_codec_t *p_codec, + OPJ_INT32 p_start_x, + OPJ_INT32 p_start_y, + OPJ_INT32 p_end_x, + OPJ_INT32 p_end_y + ) +{ + if + (p_codec) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_codec; + if + (! l_info->is_decompressor) + { + return false; + } + return l_info->m_codec_data.m_decompression.opj_set_decode_area( + l_info->m_codec, + p_start_x, + p_start_y, + p_end_x, + p_end_y, + &(l_info->m_event_mgr)); + + } + return false; + +} + +bool OPJ_CALLCONV opj_end_decompress (opj_codec_t *p_codec,opj_stream_t *p_cio) +{ + if + (p_codec && p_cio) + { + opj_codec_private_t * l_info = (opj_codec_private_t *) p_codec; + opj_stream_private_t * l_cio = (opj_stream_private_t *) p_cio; + if + (! l_info->is_decompressor) + { + return false; + } + return l_info->m_codec_data.m_decompression.opj_end_decompress(l_info->m_codec,l_cio,&(l_info->m_event_mgr)); + } + return false; +} + + +opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT p_format) +{ + opj_codec_private_t *l_info = 00; + + l_info = (opj_codec_private_t*)opj_calloc(1, sizeof(opj_codec_private_t)); + if + (!l_info) + { + return 00; + } + memset(l_info, 0, sizeof(opj_codec_private_t)); + l_info->is_decompressor = 0; + switch + (p_format) + { case CODEC_J2K: - /* get a J2K coder handle */ - cinfo->j2k_handle = (void*)j2k_create_compress((opj_common_ptr)cinfo); - if(!cinfo->j2k_handle) { - opj_free(cinfo); - return NULL; + l_info->m_codec_data.m_compression.opj_encode = (bool (*) (void *, struct opj_stream_private *, struct opj_event_mgr * )) j2k_encode; + l_info->m_codec_data.m_compression.opj_end_compress = (bool (*) (void *, struct opj_stream_private *, struct opj_event_mgr *)) j2k_end_compress; + l_info->m_codec_data.m_compression.opj_start_compress = (bool (*) (void *,struct opj_stream_private *,struct opj_image * , struct opj_event_mgr *)) j2k_start_compress; + l_info->m_codec_data.m_compression.opj_write_tile = (bool (*) (void *,OPJ_UINT32,OPJ_BYTE*,OPJ_UINT32,struct opj_stream_private *, struct opj_event_mgr *)) j2k_write_tile; + l_info->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) j2k_destroy; + l_info->m_codec_data.m_compression.opj_setup_encoder = (void (*) (void *,opj_cparameters_t *,struct opj_image *, struct opj_event_mgr * )) j2k_setup_encoder; + + l_info->m_codec = j2k_create_compress(); + if + (! l_info->m_codec) + { + opj_free(l_info); + return 00; } break; + case CODEC_JP2: - /* get a JP2 coder handle */ - cinfo->jp2_handle = (void*)jp2_create_compress((opj_common_ptr)cinfo); - if(!cinfo->jp2_handle) { - opj_free(cinfo); - return NULL; + /* get a JP2 decoder handle */ + l_info->m_codec_data.m_compression.opj_encode = (bool (*) (void *, struct opj_stream_private *, struct opj_event_mgr * )) jp2_encode; + l_info->m_codec_data.m_compression.opj_end_compress = (bool (*) (void *, struct opj_stream_private *, struct opj_event_mgr *)) jp2_end_compress; + l_info->m_codec_data.m_compression.opj_start_compress = (bool (*) (void *,struct opj_stream_private *,struct opj_image * , struct opj_event_mgr *)) jp2_start_compress; + l_info->m_codec_data.m_compression.opj_write_tile = (bool (*) (void *,OPJ_UINT32,OPJ_BYTE*,OPJ_UINT32,struct opj_stream_private *, struct opj_event_mgr *)) jp2_write_tile; + l_info->m_codec_data.m_compression.opj_destroy = (void (*) (void *)) jp2_destroy; + l_info->m_codec_data.m_compression.opj_setup_encoder = (void (*) (void *,opj_cparameters_t *,struct opj_image *, struct opj_event_mgr * )) jp2_setup_encoder; + + l_info->m_codec = jp2_create(false); + if + (! l_info->m_codec) + { + opj_free(l_info); + return 00; } break; - case CODEC_JPT: case CODEC_UNKNOWN: + case CODEC_JPT: 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 */ - switch(cinfo->codec_format) { - case CODEC_J2K: - j2k_destroy_compress((opj_j2k_t*)cinfo->j2k_handle); - break; - case CODEC_JP2: - jp2_destroy_compress((opj_jp2_t*)cinfo->jp2_handle); - break; - case CODEC_JPT: - case CODEC_UNKNOWN: - default: - break; - } - /* destroy the decompressor */ - opj_free(cinfo); + opj_free(l_info); + return 00; } + set_default_event_handler(&(l_info->m_event_mgr)); + return (opj_codec_t*) l_info; } void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *parameters) { @@ -238,10 +654,6 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *paramete parameters->tp_on = 0; parameters->decod_format = -1; parameters->cod_format = -1; - parameters->tcp_rates[0] = 0; - parameters->tcp_numlayers = 1; - parameters->cp_disto_alloc = 1; - /* UniPG>> */ #ifdef USE_JPWL parameters->jpwl_epc_on = false; @@ -277,38 +689,153 @@ void OPJ_CALLCONV opj_set_default_encoder_parameters(opj_cparameters_t *paramete } } -void OPJ_CALLCONV opj_setup_encoder(opj_cinfo_t *cinfo, opj_cparameters_t *parameters, opj_image_t *image) { - if(cinfo && parameters && image) { - switch(cinfo->codec_format) { - case CODEC_J2K: - j2k_setup_encoder((opj_j2k_t*)cinfo->j2k_handle, parameters, image); - break; - case CODEC_JP2: - jp2_setup_encoder((opj_jp2_t*)cinfo->jp2_handle, parameters, image); - break; - case CODEC_JPT: - case CODEC_UNKNOWN: - default: - break; +/** + * Helper function. + * Sets the stream to be a file stream. The FILE must have been open previously. + * @param p_stream the stream to modify + * @param p_file handler to an already open file. +*/ +opj_stream_t* OPJ_CALLCONV opj_stream_create_default_file_stream (FILE * p_file,bool p_is_read_stream) +{ + return opj_stream_create_file_stream(p_file,J2K_STREAM_CHUNK_SIZE,p_is_read_stream); +} + +opj_stream_t* OPJ_CALLCONV opj_stream_create_file_stream (FILE * p_file,OPJ_UINT32 p_size,bool p_is_read_stream) +{ + opj_stream_t* l_stream = 00; + if + (! p_file) + { + return 00; + } + l_stream = opj_stream_create(p_size,p_is_read_stream); + if + (! l_stream) + { + return 00; + } + opj_stream_set_user_data(l_stream,p_file); + opj_stream_set_read_function(l_stream,(opj_stream_read_fn) opj_read_from_file); + opj_stream_set_write_function(l_stream, (opj_stream_write_fn) opj_write_from_file); + opj_stream_set_skip_function(l_stream, (opj_stream_skip_fn) opj_skip_from_file); + opj_stream_set_seek_function(l_stream, (opj_stream_seek_fn) opj_seek_from_file); + return l_stream; +} + + +bool OPJ_CALLCONV opj_setup_encoder(opj_codec_t *p_info, opj_cparameters_t *parameters, opj_image_t *image) +{ + if + (p_info && parameters && image) + { + opj_codec_private_t * l_codec = ((opj_codec_private_t *) p_info); + if + (! l_codec->is_decompressor) + { + l_codec->m_codec_data.m_compression.opj_setup_encoder(l_codec->m_codec,parameters,image,&(l_codec->m_event_mgr)); + return true; } } + return false; } -bool OPJ_CALLCONV opj_encode(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, char *index) { - if (index != NULL) - opj_event_msg((opj_common_ptr)cinfo, EVT_WARNING, "Set index to NULL when calling the opj_encode function.\n" - "To extract the index, use the opj_encode_with_info() function.\n" - "No index will be generated during this encoding\n"); - return opj_encode_with_info(cinfo, cio, image, NULL); +bool OPJ_CALLCONV opj_encode(opj_codec_t *p_info, opj_stream_t *cio) +{ + if + (p_info && cio) + { + opj_codec_private_t * l_codec = (opj_codec_private_t *) p_info; + opj_stream_private_t * l_cio = (opj_stream_private_t *) cio; + if + (! l_codec->is_decompressor) + { + l_codec->m_codec_data.m_compression.opj_encode(l_codec->m_codec,l_cio,&(l_codec->m_event_mgr)); + return true; + } + } + return false; + } -bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { +bool OPJ_CALLCONV opj_start_compress (opj_codec_t *p_codec,opj_image_t * p_image,opj_stream_t *p_cio) +{ + if + (p_codec && p_cio) + { + opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; + opj_stream_private_t * l_cio = (opj_stream_private_t *) p_cio; + if + (! l_codec->is_decompressor) + { + return l_codec->m_codec_data.m_compression.opj_start_compress(l_codec->m_codec,l_cio,p_image,&(l_codec->m_event_mgr)); + } + } + return false; +} + +bool OPJ_CALLCONV opj_end_compress (opj_codec_t *p_codec,opj_stream_t *p_cio) +{ + if + (p_codec && p_cio) + { + opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; + opj_stream_private_t * l_cio = (opj_stream_private_t *) p_cio; + if + (! l_codec->is_decompressor) + { + return l_codec->m_codec_data.m_compression.opj_end_compress(l_codec->m_codec,l_cio,&(l_codec->m_event_mgr)); + } + } + return false; + +} + +bool OPJ_CALLCONV opj_set_info_handler(opj_codec_t * p_codec, opj_msg_callback p_callback,void * p_user_data) +{ + opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; + if + (! l_codec) + { + return false; + } + l_codec->m_event_mgr.info_handler = p_callback; + l_codec->m_event_mgr.m_info_data = p_user_data; + return true; +} + +bool OPJ_CALLCONV opj_set_warning_handler(opj_codec_t * p_codec, opj_msg_callback p_callback,void * p_user_data) +{ + opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; + if + (! l_codec) + { + return false; + } + l_codec->m_event_mgr.warning_handler = p_callback; + l_codec->m_event_mgr.m_warning_data = p_user_data; + return true; +} + +bool OPJ_CALLCONV opj_set_error_handler(opj_codec_t * p_codec, opj_msg_callback p_callback,void * p_user_data) +{ + opj_codec_private_t * l_codec = (opj_codec_private_t *) p_codec; + if + (! l_codec) + { + return false; + } + l_codec->m_event_mgr.error_handler = p_callback; + l_codec->m_event_mgr.m_error_data = p_user_data; + return true; +} + +/*bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_stream_t *cio, opj_image_t *image, opj_codestream_info_t *cstr_info) { if(cinfo && cio && image) { switch(cinfo->codec_format) { case CODEC_J2K: - return j2k_encode((opj_j2k_t*)cinfo->j2k_handle, cio, image, cstr_info); + return j2k_encode((opj_j2k_t*)cinfo->j2k_handle, (opj_stream_private_t *) cio, image, cstr_info); case CODEC_JP2: - return jp2_encode((opj_jp2_t*)cinfo->jp2_handle, cio, image, cstr_info); + return jp2_encode((opj_jp2_t*)cinfo->jp2_handle, (opj_stream_private_t *) cio, image, cstr_info); case CODEC_JPT: case CODEC_UNKNOWN: default: @@ -316,10 +843,12 @@ bool OPJ_CALLCONV opj_encode_with_info(opj_cinfo_t *cinfo, opj_cio_t *cio, opj_i } } return false; -} +}*/ void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) { - if (cstr_info) { + if + (cstr_info) + { int tileno; for (tileno = 0; tileno < cstr_info->tw * cstr_info->th; tileno++) { opj_tile_info_t *tile_info = &cstr_info->tile[tileno]; @@ -329,6 +858,45 @@ void OPJ_CALLCONV opj_destroy_cstr_info(opj_codestream_info_t *cstr_info) { } opj_free(cstr_info->tile); opj_free(cstr_info->marker); - opj_free(cstr_info->numdecompos); } } + +bool 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_mct_total_size = l_matrix_size + l_dc_shift_size; + // add MCT capability + parameters->cp_rsiz |= 0x8100; + parameters->irreversible = 1; + // use array based MCT + parameters->tcp_mct = 2; + parameters->mct_data = opj_malloc(l_mct_total_size); + if + (! parameters->mct_data) + { + return false; + } + memcpy(parameters->mct_data,pEncodingMatrix,l_matrix_size); + memcpy(((OPJ_BYTE *) parameters->mct_data) + l_matrix_size,p_dc_shift,l_dc_shift_size); + return true; +} + +/** + * Restricts the decoding to the given image area. + * + * @param parameters the parameters to update. + * @param p_start_x the starting x position of the area to decode. + * @param p_start_y the starting y position of the area to decode. + * @param p_end_x the x end position of the area to decode. + * @param p_end_x the y end position of the area to decode. + */ +OPJ_API bool OPJ_CALLCONV opj_restrict_decoding (opj_dparameters_t *parameters,OPJ_INT32 p_start_x,OPJ_INT32 p_start_y,OPJ_INT32 p_end_x,OPJ_INT32 p_end_y) +{ + parameters->m_use_restrict_decode = 1; + parameters->m_decode_start_x = p_start_x; + parameters->m_decode_start_y = p_start_y; + parameters->m_decode_end_x = p_end_x; + parameters->m_decode_end_y = p_end_y; + return true; +} diff --git a/libopenjpeg/openjpeg.h b/libopenjpeg/openjpeg.h index ffcaacaf..48d863e1 100644 --- a/libopenjpeg/openjpeg.h +++ b/libopenjpeg/openjpeg.h @@ -6,6 +6,7 @@ * Copyright (c) 2003-2007, Francois-Olivier Devaux and Antonin Descampe * Copyright (c) 2005, Herve Drolon, FreeImage Team * Copyright (c) 2006-2007, Parvatha Elangovan + * Copyright (c) 2008, Jerome Fimes, Communications & Systemes * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -32,58 +33,59 @@ #ifndef OPENJPEG_H #define OPENJPEG_H -#define OPENJPEG_VERSION "1.3.0" +#if defined(OPJ_STATIC) || !(defined(WIN32) || defined(__WIN32__)) + #define OPJ_API + #define OPJ_CALLCONV +#else + #define OPJ_CALLCONV __stdcall + #ifdef OPJ_EXPORTS + #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) + #include + #else + #if !defined(bool) + #define bool int + #endif + #if !defined(true) + #define true 1 + #endif + #if !defined(false) + #define false 0 + #endif + #endif +#endif /* __cplusplus */ +typedef unsigned int OPJ_UINT32; +typedef int OPJ_INT32; +typedef unsigned short OPJ_UINT16; +typedef short OPJ_INT16; +typedef char OPJ_CHAR; +typedef unsigned char OPJ_BYTE; +typedef unsigned int OPJ_SIZE_T; +typedef double OPJ_FLOAT64; +typedef float OPJ_FLOAT32; +#if defined(_MSC_VER) || defined(__BORLANDC__) + typedef __int64 OPJ_INT64; +#else + typedef long long OPJ_INT64; +#endif + +#define OPENJPEG_VERSION "1.2.0" /* ========================================================== Compiler directives ========================================================== */ +#include + + -#if defined(OPJ_STATIC) || !(defined(WIN32) || defined(__WIN32__)) -#define OPJ_API -#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. -*/ -#ifdef OPJ_EXPORTS -#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 */ /* ========================================================== @@ -91,10 +93,14 @@ braindamage below. ========================================================== */ -#define OPJ_PATH_LEN 4096 /**< Maximum allowed size for filenames */ - -#define J2K_MAXRLVLS 33 /**< Number of maximum resolution level authorized */ -#define J2K_MAXBANDS (3*J2K_MAXRLVLS-2) /**< Number of maximum sub-band linked to number of resolution level */ +#define OPJ_PATH_LEN 4096 /**< Maximum allowed size for filenames */ +#define J2K_MAXRLVLS 33 /**< Number of maximum resolution level authorized */ +#define J2K_MAXBANDS (3*J2K_MAXRLVLS-2) /**< Number of maximum sub-band linked to number of resolution level */ +#define J2K_DEFAULT_NB_SEGS 10 +#define J2K_STREAM_CHUNK_SIZE 0x100000 /** 1 mega by default */ +#define J2K_DEFAULT_HEADER_SIZE 1000 +#define J2K_MCC_DEFAULT_NB_RECORDS 10 +#define J2K_MCT_DEFAULT_NB_RECORDS 10 /* UniPG>> */ #define JPWL_MAX_NO_TILESPECS 16 /**< Maximum number of tile parts expected by JPWL: increase at your will */ @@ -118,7 +124,8 @@ Rsiz Capabilities typedef enum RSIZ_CAPABILITIES { STD_RSIZ = 0, /** Standard JPEG2000 profile*/ CINEMA2K = 3, /** Profile name for a 2K image*/ - CINEMA4K = 4 /** Profile name for a 4K image*/ + CINEMA4K = 4, /** Profile name for a 4K image*/ + MCT = 0x8100 } OPJ_RSIZ_CAPABILITIES; /** @@ -163,14 +170,8 @@ typedef enum CODEC_FORMAT { CODEC_JP2 = 2 /**< JPEG-2000 file format : read/write */ } OPJ_CODEC_FORMAT; -/** -Limit decoding to certain portions of the codestream. -*/ -typedef enum LIMIT_DECODING { - NO_LIMITATION = 0, /**< No limitation for the decoding. The entire codestream will de decoded */ - LIMIT_TO_MAIN_HEADER = 1, /**< The decoding is limited to the Main Header */ - DECODE_ALL_BUT_PACKETS = 2 /**< Decode everything except the JPEG 2000 packets */ -} OPJ_LIMIT_DECODING; + + /* ========================================================== @@ -183,25 +184,9 @@ Callback function prototype for events @param msg Event message @param client_data */ -typedef void (*opj_msg_callback) (const char *msg, void *client_data); +typedef void (*opj_msg_callback) (const OPJ_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; /* @@ -213,29 +198,30 @@ typedef struct opj_event_mgr { /** Progression order changes */ -typedef struct opj_poc { +typedef struct opj_poc +{ /** Resolution num start, Component num start, given by POC */ - int resno0, compno0; + OPJ_UINT32 resno0, compno0; /** Layer num end,Resolution num end, Component num end, given by POC */ - int layno1, resno1, compno1; + OPJ_UINT32 layno1, resno1, compno1; /** Layer num start,Precinct num start, Precinct num end */ - int layno0, precno0, precno1; + OPJ_UINT32 layno0, precno0, precno1; /** Progression order enum*/ OPJ_PROG_ORDER prg1,prg; /** Progression order string*/ - char progorder[5]; + OPJ_CHAR progorder[5]; /** Tile number */ - int tile; + OPJ_UINT32 tile; /** Start and end values for Tile width and height*/ - int tx0,tx1,ty0,ty1; + OPJ_INT32 tx0,tx1,ty0,ty1; /** Start value, initialised in pi_initialise_encode*/ - int layS, resS, compS, prcS; + OPJ_UINT32 layS, resS, compS, prcS; /** End value, initialised in pi_initialise_encode */ - int layE, resE, compE, prcE; + OPJ_UINT32 layE, resE, compE, prcE; /** Start and end values of Tile width and height, initialised in pi_initialise_encode*/ - int txS,txE,tyS,tyE,dx,dy; + OPJ_UINT32 txS,txE,tyS,tyE,dx,dy; /** Temporary values for Tile parts, initialised in pi_create_encode */ - int lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t; + OPJ_UINT32 lay_t, res_t, comp_t, prc_t,tx0_t,ty0_t; } opj_poc_t; /** @@ -365,6 +351,9 @@ typedef struct opj_cparameters { char tp_flag; /** MCT (multiple component transform) */ char tcp_mct; + /** Naive implementation of MCT restricted to a single reversible array based encoding without offset concerning all the components. */ + void * mct_data; + } opj_cparameters_t; /** @@ -387,6 +376,14 @@ typedef struct opj_dparameters { */ int cp_layer; + /** + * Restrictive decoding parameters. + */ + OPJ_INT32 m_decode_start_x; + OPJ_INT32 m_decode_start_y ; + OPJ_INT32 m_decode_end_x ; + OPJ_INT32 m_decode_end_y ; + /**@name command line encoder parameters (not used inside the library) */ /*@{*/ /** input file name */ @@ -408,61 +405,19 @@ typedef struct opj_dparameters { int jpwl_exp_comps; /** maximum number of tiles */ int jpwl_max_tiles; + + /** use restrictive decoding ? */ + OPJ_UINT32 m_use_restrict_decode : 1; /*@}*/ /* <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); +OPJ_API bool OPJ_CALLCONV opj_setup_decoder(opj_codec_t *dinfo, opj_dparameters_t *parameters); +#endif + /** Decode an image from a JPEG-2000 codestream @param dinfo decompressor handle @param cio Input buffer stream @return Returns a decoded image if successful, returns NULL otherwise */ -OPJ_API opj_image_t* OPJ_CALLCONV opj_decode(opj_dinfo_t *dinfo, opj_cio_t *cio); +OPJ_API opj_image_t* OPJ_CALLCONV opj_decode(opj_codec_t *p_decompressor, opj_stream_t * cio); + +/** + * Writes a tile with the given data. + * + * @param p_compressor 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_stream the stream to write data to. + * + * @return true if the data could be written. + */ +OPJ_API bool OPJ_CALLCONV opj_write_tile ( + opj_codec_t *p_codec, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_t *p_stream + ); + +/** + * Reads a tile header. This function is compulsory and allows one to know the size of the tile thta will be decoded. + * The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile. + * + * @param p_codec the jpeg2000 codec. + * @param p_tile_index pointer to a value that will hold the index of the tile being decoded, in case of success. + * @param p_data_size pointer to a value that will hold the maximum size of the decoded data, in case of success. In case + * of truncated codestreams, the actual number of bytes decoded may be lower. The computation of the size is the same + * as depicted in opj_write_tile. + * @param p_tile_x0 pointer to a value that will hold the x0 pos of the tile (in the image). + * @param p_tile_y0 pointer to a value that will hold the y0 pos of the tile (in the image). + * @param p_tile_x1 pointer to a value that will hold the x1 pos of the tile (in the image). + * @param p_tile_y1 pointer to a value that will hold the y1 pos of the tile (in the image). + * @param p_nb_comps pointer to a value that will hold the number of components in the tile. + * @param p_should_go_on pointer to a boolean that will hold the fact that the decoding should go on. In case the + * codestream is over at the time of the call, the value will be set to false. The user should then stop + * the decoding. + * @param p_stream the stream to decode. + * @return true if the tile header could be decoded. In case the decoding should end, the returned value is still true. + * returning false may be the result of a shortage of memory or an internal error. + */ +OPJ_API bool OPJ_CALLCONV opj_read_tile_header( + opj_codec_t *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, + bool * p_should_go_on, + opj_stream_t * p_stream); + + +/** + * Reads a tile data. This function is compulsory and allows one to decode tile data. opj_read_tile_header should be called before. + * The user may need to refer to the image got by opj_read_header to understand the size being taken by the tile. + * + * @param p_codec the jpeg2000 codec. + * @param p_tile_index the index of the tile being decoded, this should be the value set by opj_read_tile_header. + * @param p_data pointer to a memory block that will hold the decoded data. + * @param p_data_size size of p_data. p_data_size should be bigger or equal to the value set by opj_read_tile_header. + * @param p_stream the stream to decode. + * + * @return true if the data could be decoded. + */ +OPJ_API bool OPJ_CALLCONV opj_decode_tile_data( + opj_codec_t *p_codec, + OPJ_UINT32 p_tile_index, + OPJ_BYTE * p_data, + OPJ_UINT32 p_data_size, + opj_stream_t *p_stream + ); + +/** + * Sets the given area to be decoded. This function should be called right after opj_read_header and before any tile header reading. + * + * @param p_codec the jpeg2000 codec. + * @param p_start_x the left position of the rectangle to decode (in image coordinates). + * @param p_end_x the right position of the rectangle to decode (in image coordinates). + * @param p_start_y the up position of the rectangle to decode (in image coordinates). + * @param p_end_y the bottom position of the rectangle to decode (in image coordinates). + * + * @return true if the area could be set. + */ +OPJ_API bool OPJ_CALLCONV opj_set_decode_area( + opj_codec_t *p_codec, + OPJ_INT32 p_start_x, + OPJ_INT32 p_start_y, + OPJ_INT32 p_end_x, + OPJ_INT32 p_end_y + ); + /** Decode an image from a JPEG-2000 codestream and extract the codestream information @@ -839,18 +927,20 @@ Decode an image from a JPEG-2000 codestream and extract the codestream informati @param cstr_info Codestream information structure if needed afterwards, NULL otherwise @return Returns a decoded image if successful, returns NULL otherwise */ -OPJ_API opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_cio_t *cio, opj_codestream_info_t *cstr_info); +//OPJ_API opj_image_t* OPJ_CALLCONV opj_decode_with_info(opj_dinfo_t *dinfo, opj_stream_t cio, opj_codestream_info_t *cstr_info); /** Creates a J2K/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); +OPJ_API opj_codec_t* OPJ_CALLCONV opj_create_compress(OPJ_CODEC_FORMAT format); + /** -Destroy a compressor handle -@param cinfo compressor handle to destroy +Destroy a decompressor handle +@param dinfo decompressor handle to destroy */ -OPJ_API void OPJ_CALLCONV opj_destroy_compress(opj_cinfo_t *cinfo); +OPJ_API void OPJ_CALLCONV opj_destroy_codec(opj_codec_t * p_codec); + /** Set encoding parameters to default values, that means :