Skip to content

Commit 476ea2d

Browse files
committed
feat(WASMZstdImageIO): Add support for .iwi.cbor.zstd
Fast, high compression ratio binary storage for Image's.
1 parent 0230331 commit 476ea2d

File tree

14 files changed

+409
-60
lines changed

14 files changed

+409
-60
lines changed

CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ FetchContent_Declare(
7373
)
7474
set(WITH_TESTS OFF CACHE BOOL "Build libcbor tests")
7575
set(WITH_EXAMPLES OFF CACHE BOOL "Build libcbor examples")
76+
set(SANITIZE OFF CACHE BOOL "Enable sanitizers in Debug mode in libcbor")
7677

7778
list(APPEND CMAKE_MODULE_PATH ${libcbor_SOURCE_DIR}/CMakeModules)
7879
FetchContent_MakeAvailable(rapidjson_lib cli11 rang libcbor)

include/itkWASMImageIO.h

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,13 @@ namespace itk
2727
{
2828
/** \class WASMImageIO
2929
*
30-
* \brief Read and write the an itk::Image in format.
30+
* \brief Read and write an itk::Image in a web-friendly format.
3131
*
32-
* This format is intended to facilitage data exchange in itk-wasm.
33-
* It reads and writes an itk-wasm Image object where TypedArrays are
34-
* replaced by binary files on the file system or in a ZIP file.
32+
* This format is intended to facilitate data exchange in itk-wasm.
33+
* It reads and writes an itk-wasm Image object in a CbOR file on the
34+
* filesystem with JSON files and binary files for TypedArrays.
35+
*
36+
* The file extensions used are .iwi and .iwi.cbor.
3537
*
3638
* \ingroup IOFilters
3739
* \ingroup WebAssemblyInterface
@@ -94,8 +96,8 @@ class WebAssemblyInterface_EXPORT WASMImageIO: public StreamingImageIOBase
9496
return 0;
9597
}
9698

97-
void ReadCBOR(void * buffer = nullptr);
98-
void WriteCBOR(const void * buffer = nullptr);
99+
void ReadCBOR(void * buffer = nullptr, unsigned char * cborBuffer = nullptr, size_t cborBufferLength = 0);
100+
size_t WriteCBOR(const void * buffer = nullptr, unsigned char ** cborBuffer = nullptr, bool allocateCBORBuffer = false);
99101

100102
private:
101103
ITK_DISALLOW_COPY_AND_ASSIGN(WASMImageIO);

src/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ if(BUILD_ITK_WASM_IO_MODULES)
2929
set(common_link_flags " -s ALLOW_MEMORY_GROWTH=1 -s FORCE_FILESYSTEM=1 -s MODULARIZE=1 -s WASM=1 -lnodefs.js -s EXIT_RUNTIME=0 -s INVOKE_RUN=1 --post-js ${CMAKE_CURRENT_SOURCE_DIR}/emscripten-module/itkJSPost.js")
3030
set(esm_link_flags " -s EXPORT_ES6=1 -s USE_ES6_IMPORT_META=0")
3131

32+
include(${CMAKE_CURRENT_SOURCE_DIR}/io/internal/pipelines/common/CompressStringify/BuildZstd.cmake)
3233
add_subdirectory(io/internal/pipelines/common/CompressStringify)
3334
add_subdirectory(io/internal/pipelines/image/ConvertImage)
3435
add_subdirectory(io/internal/pipelines/image/ReadDICOM)

src/io/getFileExtension.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ function getFileExtension (filePath: string): string {
66
} else if (extension.toLowerCase() === 'cbor') {
77
const index = filePath.slice(0, -5).lastIndexOf('.')
88
extension = filePath.slice((index - 1 >>> 0) + 2)
9+
} else if (extension.toLowerCase() === 'zstd') {
10+
// .iwi.cbor.zstd
11+
const index = filePath.slice(0, -10).lastIndexOf('.')
12+
extension = filePath.slice((index - 1 >>> 0) + 2)
913
} else if (extension.toLowerCase() === 'zip') {
1014
const index = filePath.slice(0, -4).lastIndexOf('.')
1115
extension = filePath.slice((index - 1 >>> 0) + 2)

src/io/internal/extensionToImageIO.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ const extensionToIO = new Map([
1717

1818
['iwi', 'itkWASMImageIO'],
1919
['iwi.cbor', 'itkWASMImageIO'],
20+
['iwi.cbor.zstd', 'itkWASMZstdImageIO'],
2021

2122
['lsm', 'itkLSMImageIO'],
2223

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
include(FetchContent)
2+
option(ZSTD_BUILD_CONTRIB "BUILD_CONTRIB" OFF)
3+
option(ZSTD_BUILD_PROGRAMS "BUILD_PROGRAMS" OFF)
4+
option(ZSTD_BUILD_SHARED "BUILD_SHARED" OFF)
5+
option(ZSTD_BUILD_STATIC "BUILD_STATIC" ON)
6+
option(ZSTD_BUILD_TESTS "BUILD_TESTS" OFF)
7+
option(ZSTD_BUILD_LEGACY_SUPPORT "BUILD_LEGACY_SUPPORT" OFF)
8+
option(ZSTD_MULTITHREAD_SUPPORT "BUILD_MULTITHREAD_SUPPORT" OFF)
9+
option(ZSTD_BUILD_PROGRAMS_LINK_SHARED "BUILD_PROGRAMS_LINK_SHARED" OFF)
10+
option(ZSTD_BUILD_LZ4 "BUILD_LZ4" OFF)
11+
option(ZSTD_BUILD_LZMA "BUILD_LZMA" OFF)
12+
option(ZSTD_BUILD_ZLIB "BUILD_ZLIB" OFF)
13+
set(zstd_GIT_REPOSITORY "https://github.com/facebook/zstd.git")
14+
# v1.5.2
15+
set(zstd_GIT_TAG c9c7be85f49f45a581ec00c309afda5c62ba9ef2)
16+
FetchContent_Declare(
17+
zstd_lib
18+
GIT_REPOSITORY ${zstd_GIT_REPOSITORY}
19+
GIT_TAG ${zstd_GIT_TAG}
20+
)
21+
22+
FetchContent_MakeAvailable(zstd_lib)
23+
set(zstd_lib_INCLUDE_DIR "${zstd_lib_SOURCE_DIR}/lib")
24+
include_directories(${zstd_lib_INCLUDE_DIR})
25+
add_subdirectory("${zstd_lib_SOURCE_DIR}/build/cmake" "${zstd_lib_BINARY_DIR}")

src/io/internal/pipelines/common/CompressStringify/CMakeLists.txt

Lines changed: 4 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -4,25 +4,9 @@ project(CompressStringify)
44
set(CMAKE_CXX_STANDARD 17)
55

66
include(FetchContent)
7-
option(ZSTD_BUILD_CONTRIB "BUILD_CONTRIB" OFF)
8-
option(ZSTD_BUILD_PROGRAMS "BUILD_PROGRAMS" OFF)
9-
option(ZSTD_BUILD_SHARED "BUILD_SHARED" OFF)
10-
option(ZSTD_BUILD_STATIC "BUILD_STATIC" ON)
11-
option(ZSTD_BUILD_TESTS "BUILD_TESTS" OFF)
12-
option(ZSTD_BUILD_LEGACY_SUPPORT "BUILD_LEGACY_SUPPORT" OFF)
13-
option(ZSTD_MULTITHREAD_SUPPORT "BUILD_MULTITHREAD_SUPPORT" OFF)
14-
option(ZSTD_BUILD_PROGRAMS_LINK_SHARED "BUILD_PROGRAMS_LINK_SHARED" OFF)
15-
option(ZSTD_BUILD_LZ4 "BUILD_LZ4" OFF)
16-
option(ZSTD_BUILD_LZMA "BUILD_LZMA" OFF)
17-
option(ZSTD_BUILD_ZLIB "BUILD_ZLIB" OFF)
18-
set(zstd_GIT_REPOSITORY "https://github.com/facebook/zstd.git")
19-
# v1.5.2
20-
set(zstd_GIT_TAG c9c7be85f49f45a581ec00c309afda5c62ba9ef2)
21-
FetchContent_Declare(
22-
zstd_lib
23-
GIT_REPOSITORY ${zstd_GIT_REPOSITORY}
24-
GIT_TAG ${zstd_GIT_TAG}
25-
)
7+
if (NOT TARGET libzstd_static)
8+
include(${CMAKE_CURRENT_SOURCE_DIR}/BuildZstd.cmake)
9+
endif()
2610

2711
set(cpp_base64_GIT_REPOSITORY "https://github.com/thewtex/cpp-base64.git")
2812
set(cpp_base64_GET_TAG 9144cd53be930b37235ae552a92b5d2aa51e9325)
@@ -32,11 +16,7 @@ FetchContent_Declare(
3216
GIT_TAG ${cpp_base64_GIT_TAG}
3317
)
3418

35-
FetchContent_MakeAvailable(zstd_lib cpp_base64)
36-
set(zstd_lib_INCLUDE_DIR "${zstd_lib_SOURCE_DIR}/lib")
37-
include_directories(${zstd_lib_INCLUDE_DIR})
38-
# message(FATAL_ERROR "${zstd_lib_INCLUDE_DIR}")
39-
add_subdirectory("${zstd_lib_SOURCE_DIR}/build/cmake" "${zstd_lib_BINARY_DIR}")
19+
FetchContent_MakeAvailable(cpp_base64)
4020

4121
find_package(ITK REQUIRED COMPONENTS WebAssemblyInterface)
4222
include(${ITK_USE_FILE})

src/io/internal/pipelines/image/ConvertImage/CMakeLists.txt

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ project(ConvertImage)
33

44
set(CMAKE_CXX_STANDARD 17)
55

6+
if (NOT TARGET libzstd_static)
7+
include(${CMAKE_CURRENT_SOURCE_DIR}/../../common/CompressStringify/BuildZstd.cmake)
8+
endif()
9+
610
# This list should be ordered from approximately most commonly to least
711
# commonly used modules.
812
set(WebAssemblyInterface_ImageIOModules
@@ -86,8 +90,9 @@ set(imageio_id_itkScancoImageIO 19)
8690
set(imageios_IOFDF itkFDFImageIO)
8791
set(imageio_id_itkFDFImageIO 20)
8892

89-
set(imageios_WebAssemblyInterface itkWASMImageIO)
93+
set(imageios_WebAssemblyInterface itkWASMImageIO itkWASMZstdImageIO)
9094
set(imageio_id_itkWASMImageIO 21)
95+
set(imageio_id_itkWASMZstdImageIO 22)
9196

9297
set(ITK_NO_IO_FACTORY_REGISTER_MANAGER 1)
9398
set(ImageIOIndex_ARRAY "")
@@ -97,6 +102,7 @@ foreach(io_module ${WebAssemblyInterface_ImageIOModules} WebAssemblyInterface)
97102
find_package(ITK REQUIRED COMPONENTS ITKIOImageBase)
98103
include(${ITK_USE_FILE})
99104
include_directories(${WebAssemblyInterface_INCLUDE_DIRS})
105+
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
100106
list(APPEND ITK_LIBRARIES ${WebAssemblyInterface_LIBRARIES})
101107
else()
102108
find_package(ITK REQUIRED COMPONENTS ${io_module} WebAssemblyInterface)
@@ -112,11 +118,16 @@ foreach(io_module ${WebAssemblyInterface_ImageIOModules} WebAssemblyInterface)
112118
endif()
113119
foreach(imageio ${imageios_${io_module}})
114120
set(ImageIOIndex_ARRAY "${ImageIOIndex_ARRAY}'${imageio}', ")
121+
set(extra_srcs)
122+
if(${imageio} STREQUAL "itkWASMZstdImageIO")
123+
list(APPEND ITK_LIBRARIES libzstd_static)
124+
list(APPEND extra_srcs itkWASMZstdImageIO.cxx)
125+
endif()
115126

116-
add_executable(${imageio}ReadImage ReadImage.cxx)
127+
add_executable(${imageio}ReadImage ReadImage.cxx ${extra_srcs})
117128
target_link_libraries(${imageio}ReadImage PUBLIC ${ITK_LIBRARIES})
118129
target_compile_definitions(${imageio}ReadImage PUBLIC -DIMAGE_IO_CLASS=${imageio_id_${imageio}})
119-
add_executable(${imageio}WriteImage WriteImage.cxx)
130+
add_executable(${imageio}WriteImage WriteImage.cxx ${extra_srcs})
120131
target_link_libraries(${imageio}WriteImage PUBLIC ${ITK_LIBRARIES})
121132
target_compile_definitions(${imageio}WriteImage PUBLIC -DIMAGE_IO_CLASS=${imageio_id_${imageio}})
122133
if (EMSCRIPTEN AND DEFINED WebAssemblyInterface_BINARY_DIR)

src/io/internal/pipelines/image/ConvertImage/ReadImage.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@
8787
#elif IMAGE_IO_CLASS == 20
8888
#include "itkFDFImageIO.h"
8989
#elif IMAGE_IO_CLASS == 21
90+
#elif IMAGE_IO_CLASS == 22
91+
#include "itkWASMZstdImageIO.h"
9092
#else
9193
#error "Unsupported IMAGE_IO_CLASS"
9294
#endif
@@ -176,6 +178,8 @@ int main (int argc, char * argv[])
176178
return readImage<itk::FDFImageIO>(inputFileName, outputImageIO, quiet);
177179
#elif IMAGE_IO_CLASS == 21
178180
return readImage<itk::WASMImageIO>(inputFileName, outputImageIO, quiet);
181+
#elif IMAGE_IO_CLASS == 22
182+
return readImage<itk::WASMZstdImageIO>(inputFileName, outputImageIO, quiet);
179183
#else
180184
#error "Unsupported IMAGE_IO_CLASS"
181185
#endif

src/io/internal/pipelines/image/ConvertImage/WriteImage.cxx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,8 @@
8787
#elif IMAGE_IO_CLASS == 20
8888
#include "itkFDFImageIO.h"
8989
#elif IMAGE_IO_CLASS == 21
90+
#elif IMAGE_IO_CLASS == 22
91+
#include "itkWASMZstdImageIO.h"
9092
#else
9193
#error "Unsupported IMAGE_IO_CLASS"
9294
#endif
@@ -212,6 +214,8 @@ int main (int argc, char * argv[])
212214
return writeImage<itk::FDFImageIO>(inputImageIO, outputFileName, quiet, useCompression);
213215
#elif IMAGE_IO_CLASS == 21
214216
return writeImage<itk::WASMImageIO>(inputImageIO, outputFileName, quiet, useCompression);
217+
#elif IMAGE_IO_CLASS == 22
218+
return writeImage<itk::WASMZstdImageIO>(inputImageIO, outputFileName, quiet, useCompression);
215219
#else
216220
#error "Unsupported IMAGE_IO_CLASS"
217221
#endif

0 commit comments

Comments
 (0)