dicube 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dicube-0.1.4/.cursor/rules/error-handling.mdc +39 -0
- dicube-0.1.4/.cursor/rules/file-formats.mdc +26 -0
- dicube-0.1.4/.cursor/rules/key-classes.mdc +52 -0
- dicube-0.1.4/.cursor/rules/project-structure.mdc +33 -0
- dicube-0.1.4/.cursor/rules/python-style.mdc +46 -0
- dicube-0.1.4/.github/actions/setup-python-env/action.yml +39 -0
- dicube-0.1.4/.github/workflows/build-wheels.yml +101 -0
- dicube-0.1.4/.github/workflows/release.yml +86 -0
- dicube-0.1.4/.github/workflows/test.yml +43 -0
- dicube-0.1.4/.gitignore +65 -0
- dicube-0.1.4/.gitmodules +6 -0
- dicube-0.1.4/CMakeLists.txt +141 -0
- dicube-0.1.4/PKG-INFO +271 -0
- dicube-0.1.4/README.md +226 -0
- dicube-0.1.4/build_scripts/build_local.py +191 -0
- dicube-0.1.4/build_scripts/check_wheels.py +237 -0
- dicube-0.1.4/dicube/__init__.py +140 -0
- dicube-0.1.4/dicube/codecs/__init__.py +152 -0
- dicube-0.1.4/dicube/codecs/jph/__init__.py +15 -0
- dicube-0.1.4/dicube/codecs/jph/codec.py +161 -0
- dicube-0.1.4/dicube/codecs/jph/decode_complete.cpp +191 -0
- dicube-0.1.4/dicube/codecs/jph/encode_complete.cpp +220 -0
- dicube-0.1.4/dicube/core/__init__.py +21 -0
- dicube-0.1.4/dicube/core/image.py +349 -0
- dicube-0.1.4/dicube/core/io.py +354 -0
- dicube-0.1.4/dicube/core/pixel_header.py +117 -0
- dicube-0.1.4/dicube/dicom/__init__.py +13 -0
- dicube-0.1.4/dicube/dicom/dcb_streaming.py +250 -0
- dicube-0.1.4/dicube/dicom/dicom_io.py +153 -0
- dicube-0.1.4/dicube/dicom/dicom_meta.py +740 -0
- dicube-0.1.4/dicube/dicom/dicom_status.py +259 -0
- dicube-0.1.4/dicube/dicom/dicom_tags.py +121 -0
- dicube-0.1.4/dicube/dicom/merge_utils.py +283 -0
- dicube-0.1.4/dicube/dicom/space_from_meta.py +70 -0
- dicube-0.1.4/dicube/exceptions.py +189 -0
- dicube-0.1.4/dicube/storage/__init__.py +17 -0
- dicube-0.1.4/dicube/storage/dcb_file.py +805 -0
- dicube-0.1.4/dicube/storage/pixel_utils.py +141 -0
- dicube-0.1.4/dicube/utils/__init__.py +6 -0
- dicube-0.1.4/dicube/validation.py +380 -0
- dicube-0.1.4/example/example.ipynb +442 -0
- dicube-0.1.4/pyproject.toml +114 -0
- dicube-0.1.4/source/OpenJPH/.devcontainer/Dockerfile +42 -0
- dicube-0.1.4/source/OpenJPH/.devcontainer/devcontainer.json +29 -0
- dicube-0.1.4/source/OpenJPH/.github/FUNDING.yml +13 -0
- dicube-0.1.4/source/OpenJPH/.github/workflows/ccp-workflow.yml +348 -0
- dicube-0.1.4/source/OpenJPH/.github/workflows/codeql.yml +82 -0
- dicube-0.1.4/source/OpenJPH/.github/workflows/emcc.yml +47 -0
- dicube-0.1.4/source/OpenJPH/.gitignore +7 -0
- dicube-0.1.4/source/OpenJPH/CMakeLists.txt +232 -0
- dicube-0.1.4/source/OpenJPH/Dockerfile +32 -0
- dicube-0.1.4/source/OpenJPH/LICENSE +27 -0
- dicube-0.1.4/source/OpenJPH/README.md +24 -0
- dicube-0.1.4/source/OpenJPH/_config.yml +1 -0
- dicube-0.1.4/source/OpenJPH/docs/.gitignore +2 -0
- dicube-0.1.4/source/OpenJPH/docs/Doxyfile +2494 -0
- dicube-0.1.4/source/OpenJPH/docs/OpenJPH_docs.css +6 -0
- dicube-0.1.4/source/OpenJPH/docs/compiling.md +116 -0
- dicube-0.1.4/source/OpenJPH/docs/docker.md +16 -0
- dicube-0.1.4/source/OpenJPH/docs/doxygen_style.md +47 -0
- dicube-0.1.4/source/OpenJPH/docs/status.md +9 -0
- dicube-0.1.4/source/OpenJPH/docs/usage_examples.md +19 -0
- dicube-0.1.4/source/OpenJPH/docs/web_demos.md +5 -0
- dicube-0.1.4/source/OpenJPH/ojph_version.cmake +29 -0
- dicube-0.1.4/source/OpenJPH/src/apps/CMakeLists.txt +29 -0
- dicube-0.1.4/source/OpenJPH/src/apps/common/ojph_img_io.h +819 -0
- dicube-0.1.4/source/OpenJPH/src/apps/common/ojph_sockets.h +236 -0
- dicube-0.1.4/source/OpenJPH/src/apps/common/ojph_threads.h +155 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_compress/CMakeLists.txt +58 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_compress/ojph_compress.cpp +1178 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_expand/CMakeLists.txt +58 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_expand/ojph_expand.cpp +438 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_stream_expand/CMakeLists.txt +26 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_stream_expand/ojph_stream_expand.cpp +373 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_stream_expand/stream_expand_support.cpp +464 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_stream_expand/stream_expand_support.h +554 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_stream_expand/threaded_frame_processors.cpp +64 -0
- dicube-0.1.4/source/OpenJPH/src/apps/ojph_stream_expand/threaded_frame_processors.h +107 -0
- dicube-0.1.4/source/OpenJPH/src/apps/others/ojph_img_io.cpp +2125 -0
- dicube-0.1.4/source/OpenJPH/src/apps/others/ojph_img_io_avx2.cpp +358 -0
- dicube-0.1.4/source/OpenJPH/src/apps/others/ojph_img_io_sse41.cpp +513 -0
- dicube-0.1.4/source/OpenJPH/src/apps/others/ojph_sockets.cpp +202 -0
- dicube-0.1.4/source/OpenJPH/src/apps/others/ojph_threads.cpp +108 -0
- dicube-0.1.4/source/OpenJPH/src/core/CMakeLists.txt +154 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_bitbuffer_read.h +226 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_bitbuffer_write.h +147 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codeblock.cpp +264 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codeblock.h +130 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codeblock_fun.cpp +286 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codeblock_fun.h +123 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream.cpp +208 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream_avx.cpp +58 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream_avx2.cpp +278 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream_gen.cpp +171 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream_local.cpp +1232 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream_local.h +177 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream_sse.cpp +58 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream_sse2.cpp +295 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_codestream_wasm.cpp +289 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_params.cpp +2498 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_params_local.h +1049 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_precinct.cpp +559 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_precinct.h +82 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_resolution.cpp +1049 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_resolution.h +133 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_subband.cpp +382 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_subband.h +124 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_tile.cpp +897 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_tile.h +112 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_tile_comp.cpp +200 -0
- dicube-0.1.4/source/OpenJPH/src/core/codestream/ojph_tile_comp.h +104 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_common.cpp +345 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_common.h +49 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_decoder.h +83 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_decoder32.cpp +1616 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_decoder64.cpp +1663 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_decoder_avx2.cpp +2044 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_decoder_ssse3.cpp +2070 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_decoder_wasm.cpp +2118 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_encoder.cpp +1523 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_encoder.h +88 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_encoder_avx2.cpp +1229 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/ojph_block_encoder_avx512.cpp +1218 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/table0.h +444 -0
- dicube-0.1.4/source/OpenJPH/src/core/coding/table1.h +358 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_arch.h +317 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_arg.h +272 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_base.h +72 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_codestream.h +370 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_defs.h +83 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_file.h +294 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_mem.h +241 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_message.h +291 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_params.h +306 -0
- dicube-0.1.4/source/OpenJPH/src/core/common/ojph_version.h +38 -0
- dicube-0.1.4/source/OpenJPH/src/core/others/ojph_arch.cpp +250 -0
- dicube-0.1.4/source/OpenJPH/src/core/others/ojph_file.cpp +336 -0
- dicube-0.1.4/source/OpenJPH/src/core/others/ojph_mem.cpp +120 -0
- dicube-0.1.4/source/OpenJPH/src/core/others/ojph_message.cpp +181 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_colour.cpp +558 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_colour.h +109 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_colour_avx.cpp +103 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_colour_avx2.cpp +623 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_colour_local.h +320 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_colour_sse.cpp +102 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_colour_sse2.cpp +662 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_colour_wasm.cpp +678 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform.cpp +844 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform.h +101 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform_avx.cpp +291 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform_avx2.cpp +1079 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform_avx512.cpp +1429 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform_local.h +318 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform_sse.cpp +287 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform_sse2.cpp +1006 -0
- dicube-0.1.4/source/OpenJPH/src/core/transform/ojph_transform_wasm.cpp +1310 -0
- dicube-0.1.4/source/OpenJPH/src/openjph-config.cmake.in +5 -0
- dicube-0.1.4/source/OpenJPH/src/openjph.pc.in +9 -0
- dicube-0.1.4/source/OpenJPH/subprojects/.gitignore +2 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/.gitignore +4 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/CMakeLists.txt +27 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/emscripten-docker.sh +2 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/html/.gitignore +2 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/html/index.html +252 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/html/libopenjph.js +16 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/html/libopenjph.wasm +0 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/html/libopenjph_simd.js +16 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/html/libopenjph_simd.wasm +0 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/html/test.j2c +0 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/src/ojph_wrapper.cpp +248 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/standalone/README.md +52 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/standalone/com_decom.sh +72 -0
- dicube-0.1.4/source/OpenJPH/subprojects/js/standalone/com_decom_yuv.sh +77 -0
- dicube-0.1.4/source/OpenJPH/target_arch.cmake +68 -0
- dicube-0.1.4/source/OpenJPH/tests/CMakeLists.txt +83 -0
- dicube-0.1.4/source/OpenJPH/tests/compare_files.cpp +96 -0
- dicube-0.1.4/source/OpenJPH/tests/mse_pae.cmake +50 -0
- dicube-0.1.4/source/OpenJPH/tests/mse_pae.cpp +706 -0
- dicube-0.1.4/source/OpenJPH/tests/test_executables.cpp +1469 -0
- dicube-0.1.4/source/OpenJPH/tests/test_helpers/Readme.md +20 -0
- dicube-0.1.4/source/OpenJPH/tests/test_helpers/convert_mse_pae_to_tests.cpp +567 -0
- dicube-0.1.4/source/OpenJPH/tests/test_helpers/ht_cmdlines.txt +102 -0
- dicube-0.1.4/tests/conftest.py +93 -0
- dicube-0.1.4/tests/test_codec_integration.py +195 -0
- dicube-0.1.4/tests/test_codec_system.py +142 -0
- dicube-0.1.4/tests/test_dcb_streaming.py +240 -0
- dicube-0.1.4/tests/test_dicom_meta.py +149 -0
- dicube-0.1.4/tests/test_dicom_status.py +457 -0
- dicube-0.1.4/tests/test_dicom_tags.py +119 -0
- dicube-0.1.4/tests/test_exceptions.py +229 -0
- dicube-0.1.4/tests/test_image.py +407 -0
- dicube-0.1.4/tests/test_image_exceptions.py +217 -0
- dicube-0.1.4/tests/test_integration_exceptions.py +301 -0
- dicube-0.1.4/tests/test_validation.py +360 -0
@@ -0,0 +1,39 @@
|
|
1
|
+
---
|
2
|
+
description: Guidelines for error handling in DiCube
|
3
|
+
---
|
4
|
+
# Error Handling in DiCube
|
5
|
+
|
6
|
+
DiCube provides a hierarchy of exception classes in [dicube/exceptions.py](mdc:dicube/exceptions.py)
|
7
|
+
|
8
|
+
## Key Exceptions
|
9
|
+
|
10
|
+
```python
|
11
|
+
from dicube.exceptions import (
|
12
|
+
DicomCubeError, # Base exception for all DiCube errors
|
13
|
+
InvalidCubeFileError, # Invalid file format or corrupted file
|
14
|
+
CodecError, # Compression/decompression failures
|
15
|
+
MetaDataError, # Missing or invalid metadata
|
16
|
+
DataConsistencyError # Inconsistent data structure
|
17
|
+
)
|
18
|
+
```
|
19
|
+
|
20
|
+
## Best Practices
|
21
|
+
|
22
|
+
1. **Use specific exceptions** rather than generic ones
|
23
|
+
2. **Include descriptive error messages** to aid debugging
|
24
|
+
3. **Chain exceptions** when re-raising to preserve context
|
25
|
+
4. **Validate early** to catch errors before processing begins
|
26
|
+
5. **Clean up resources** in finally blocks or context managers
|
27
|
+
|
28
|
+
## Example Usage
|
29
|
+
|
30
|
+
```python
|
31
|
+
try:
|
32
|
+
image = dicube.load(\"corrupted.dcbs\")
|
33
|
+
except InvalidCubeFileError as e:
|
34
|
+
print(f\"Not a valid DiCube file: {e}\")
|
35
|
+
except CodecError as e:
|
36
|
+
print(f\"Compression/decompression failed: {e}\")
|
37
|
+
except MetaDataError as e:
|
38
|
+
print(f\"Missing or invalid metadata: {e}\")
|
39
|
+
```
|
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
description: Information about DiCube file formats and specifications
|
3
|
+
---
|
4
|
+
# DiCube File Formats
|
5
|
+
|
6
|
+
DiCube defines three file format specifications:
|
7
|
+
|
8
|
+
## Currently Implemented
|
9
|
+
|
10
|
+
### .dcbs (Speed Format)
|
11
|
+
- **Magic**: `DCMCUBES`
|
12
|
+
- **Target**: I/O speed suitable for deep learning training with high compression ratio
|
13
|
+
- **Codec**: High Throughput JPEG 2000 (HTJ2K)
|
14
|
+
- **Implementation**: [storage/dcb_file.py](mdc:dicube/storage/dcb_file.py) and [codecs/jph/](mdc:dicube/codecs/jph/)
|
15
|
+
|
16
|
+
## Placeholder Formats (Future Implementation)
|
17
|
+
|
18
|
+
### .dcba (Archive Format)
|
19
|
+
- **Magic**: `DCMCUBEA`
|
20
|
+
- **Target**: 20% better compression ratio than dcbs
|
21
|
+
- **Use case**: Long-term storage and archiving
|
22
|
+
|
23
|
+
### .dcbl (Lossy Format)
|
24
|
+
- **Magic**: `DCMCUBEL`
|
25
|
+
- **Target**: 60%+ compression ratio with imperceptible quality loss
|
26
|
+
- **Use case**: High-compression scenarios where minor quality trade-offs are acceptable
|
@@ -0,0 +1,52 @@
|
|
1
|
+
---
|
2
|
+
description: Key classes and interfaces in the DiCube library
|
3
|
+
---
|
4
|
+
# Key Classes and Interfaces
|
5
|
+
|
6
|
+
## DicomCubeImage
|
7
|
+
Main interface for medical image handling, defined in [dicube/core/image.py](mdc:dicube/core/image.py)
|
8
|
+
|
9
|
+
```python
|
10
|
+
import dicube
|
11
|
+
|
12
|
+
# Create from DICOM directory
|
13
|
+
image = dicube.load_from_dicom_folder(\"path/to/dicom/\")
|
14
|
+
|
15
|
+
# Save to compressed format
|
16
|
+
dicube.save(image, \"output.dcbs\", file_type=\"s\") # HTJ2K (Speed format)
|
17
|
+
|
18
|
+
# Load from file
|
19
|
+
loaded_image = dicube.load(\"output.dcbs\")
|
20
|
+
|
21
|
+
# Get pixel data
|
22
|
+
pixel_data = image.get_fdata() # Returns float array
|
23
|
+
raw_data = image.raw_image # Returns original dtype
|
24
|
+
```
|
25
|
+
|
26
|
+
## DicomMeta
|
27
|
+
DICOM metadata container with efficient shared/non-shared value handling:
|
28
|
+
Defined in [dicube/dicom/dicom_meta.py](mdc:dicube/dicom/dicom_meta.py)
|
29
|
+
|
30
|
+
```python
|
31
|
+
from dicube import DicomMeta, read_dicom_dir
|
32
|
+
|
33
|
+
# Read DICOM directory
|
34
|
+
meta = read_dicom_dir(\"dicom_folder/\")
|
35
|
+
|
36
|
+
# Access shared values (same across all slices)
|
37
|
+
patient_name = meta.get(\"PatientName\") # Returns single value
|
38
|
+
|
39
|
+
# Access non-shared values (different per slice)
|
40
|
+
positions = meta.get(\"ImagePositionPatient\") # Returns list
|
41
|
+
```
|
42
|
+
|
43
|
+
## DicomStatus
|
44
|
+
DICOM consistency checking provided in [dicube/dicom/dicom_status.py](mdc:dicube/dicom/dicom_status.py)
|
45
|
+
|
46
|
+
```python
|
47
|
+
from dicube import DicomStatus, get_dicom_status
|
48
|
+
|
49
|
+
status = get_dicom_status(meta)
|
50
|
+
```
|
51
|
+
|
52
|
+
Common status values include: `CONSISTENT`, `MISSING_SERIES_UID`, `DUPLICATE_INSTANCE_NUMBERS`, `NON_UNIFORM_SPACING`, etc.
|
@@ -0,0 +1,33 @@
|
|
1
|
+
---
|
2
|
+
alwaysApply: true
|
3
|
+
---
|
4
|
+
|
5
|
+
# DiCube Project Structure
|
6
|
+
|
7
|
+
DiCube is a Python library for efficient storage and processing of 3D medical images with complete DICOM metadata preservation.
|
8
|
+
|
9
|
+
## Project Organization
|
10
|
+
|
11
|
+
- **Core modules** in [dicube/core/](mdc:dicube/core/)
|
12
|
+
- [image.py](mdc:dicube/core/image.py): DicomCubeImage (main interface)
|
13
|
+
- [io.py](mdc:dicube/core/io.py): DicomCubeImageIO (file format I/O)
|
14
|
+
- [pixel_header.py](mdc:dicube/core/pixel_header.py): PixelDataHeader (image metadata)
|
15
|
+
|
16
|
+
- **DICOM handling** in [dicube/dicom/](mdc:dicube/dicom/)
|
17
|
+
- [dicom_meta.py](mdc:dicube/dicom/dicom_meta.py): DicomMeta (metadata container)
|
18
|
+
- [dicom_status.py](mdc:dicube/dicom/dicom_status.py): DICOM consistency checking
|
19
|
+
- [dicom_tags.py](mdc:dicube/dicom/dicom_tags.py): DICOM tag definitions
|
20
|
+
- [dicom_io.py](mdc:dicube/dicom/dicom_io.py): DICOM file I/O
|
21
|
+
- [merge_utils.py](mdc:dicube/dicom/merge_utils.py): Metadata merging utilities
|
22
|
+
|
23
|
+
- **Storage formats** in [dicube/storage/](mdc:dicube/storage/)
|
24
|
+
- [dcb_file.py](mdc:dicube/storage/dcb_file.py): DCB file format implementations
|
25
|
+
- [pixel_utils.py](mdc:dicube/storage/pixel_utils.py): Pixel processing utilities
|
26
|
+
|
27
|
+
- **Compression codecs** in [dicube/codecs/](mdc:dicube/codecs/)
|
28
|
+
- [jph/](mdc:dicube/codecs/jph/): HTJ2K codec implementation
|
29
|
+
|
30
|
+
- **Entry point**: [dicube/__init__.py](mdc:dicube/__init__.py)
|
31
|
+
- **Exceptions**: [dicube/exceptions.py](mdc:dicube/exceptions.py)
|
32
|
+
|
33
|
+
This library works alongside `spacetransformer` (for 3D spatial transformations) and `medmask` (for medical image segmentation).
|
@@ -0,0 +1,46 @@
|
|
1
|
+
---
|
2
|
+
globs: *.py
|
3
|
+
---
|
4
|
+
# Python Code Style Guide
|
5
|
+
|
6
|
+
When writing or modifying Python code in this project, follow these guidelines:
|
7
|
+
|
8
|
+
1. Use **type annotations** wherever possible for improved code clarity and IDE support.
|
9
|
+
2. Import order should be:
|
10
|
+
- Standard library imports
|
11
|
+
- Third-party imports
|
12
|
+
- Local imports (from dicube)
|
13
|
+
3. Use **Google style docstrings** for all functions, classes, and modules:
|
14
|
+
|
15
|
+
```python
|
16
|
+
def function_example(param1, param2):
|
17
|
+
"""Short description of function purpose.
|
18
|
+
|
19
|
+
Args:
|
20
|
+
param1 (type): Description of parameter.
|
21
|
+
param2 (type): Description of parameter.
|
22
|
+
|
23
|
+
Returns:
|
24
|
+
type: Description of return value.
|
25
|
+
|
26
|
+
Raises:
|
27
|
+
ExceptionType: When and why this exception is raised.
|
28
|
+
|
29
|
+
Example:
|
30
|
+
>>> result = function_example(1, 2)
|
31
|
+
>>> print(result)
|
32
|
+
3
|
33
|
+
"""
|
34
|
+
```
|
35
|
+
|
36
|
+
4. Keep functions **focused** and **single-purpose**.
|
37
|
+
5. For error handling:
|
38
|
+
- Use specific exceptions from [dicube/exceptions.py](mdc:dicube/exceptions.py)
|
39
|
+
- Validate input parameters early
|
40
|
+
- Add clear error messages
|
41
|
+
6. For complex operations, add comments explaining the algorithm or approach.
|
42
|
+
7. Use constants for magic values and define them at the module level.
|
43
|
+
8. Performance matters - use numpy vectorized operations where possible.
|
44
|
+
9. Method naming follows standard Python conventions:
|
45
|
+
- Methods that modify state: `set_`, `update_`, etc.
|
46
|
+
- Methods that return new objects without modifying state: `get_`, `compute_`, etc.
|
@@ -0,0 +1,39 @@
|
|
1
|
+
name: 'Setup Python Environment'
|
2
|
+
description: 'Setup Python with common dependencies'
|
3
|
+
inputs:
|
4
|
+
python-version:
|
5
|
+
description: 'Python version to use'
|
6
|
+
required: true
|
7
|
+
default: '3.9'
|
8
|
+
install-dev:
|
9
|
+
description: 'Install development dependencies'
|
10
|
+
required: false
|
11
|
+
default: 'false'
|
12
|
+
|
13
|
+
runs:
|
14
|
+
using: 'composite'
|
15
|
+
steps:
|
16
|
+
- name: Set up Python
|
17
|
+
uses: actions/setup-python@v4
|
18
|
+
with:
|
19
|
+
python-version: ${{ inputs.python-version }}
|
20
|
+
|
21
|
+
- name: Cache pip
|
22
|
+
uses: actions/cache@v3
|
23
|
+
with:
|
24
|
+
path: ~/.cache/pip
|
25
|
+
key: ${{ runner.os }}-pip-${{ inputs.python-version }}-${{ hashFiles('**/pyproject.toml') }}
|
26
|
+
restore-keys: |
|
27
|
+
${{ runner.os }}-pip-${{ inputs.python-version }}-
|
28
|
+
|
29
|
+
- name: Install base dependencies
|
30
|
+
shell: bash
|
31
|
+
run: |
|
32
|
+
python -m pip install --upgrade pip
|
33
|
+
pip install wheel setuptools
|
34
|
+
|
35
|
+
- name: Install dev dependencies
|
36
|
+
if: inputs.install-dev == 'true'
|
37
|
+
shell: bash
|
38
|
+
run: |
|
39
|
+
pip install ruff black mypy pytest pytest-cov
|
@@ -0,0 +1,101 @@
|
|
1
|
+
name: Build Wheels
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
tags: ['v*']
|
6
|
+
branches: ['feat/test_build']
|
7
|
+
pull_request:
|
8
|
+
branches: [main, master]
|
9
|
+
workflow_dispatch:
|
10
|
+
workflow_call:
|
11
|
+
|
12
|
+
jobs:
|
13
|
+
build_wheels:
|
14
|
+
name: Build wheels on ${{ matrix.os }}
|
15
|
+
runs-on: ${{ matrix.os }}
|
16
|
+
strategy:
|
17
|
+
matrix:
|
18
|
+
os: [ubuntu-latest, windows-latest, macos-latest]
|
19
|
+
|
20
|
+
steps:
|
21
|
+
- uses: actions/checkout@v4
|
22
|
+
with:
|
23
|
+
submodules: recursive
|
24
|
+
ref: ${{ github.ref }}
|
25
|
+
# Ensure full history to prevent setuptools_scm issues
|
26
|
+
fetch-depth: 0
|
27
|
+
|
28
|
+
# For Windows, we need to manually install pip
|
29
|
+
- name: Set up Windows environment
|
30
|
+
if: runner.os == 'Windows'
|
31
|
+
run: |
|
32
|
+
python -m pip install --upgrade pip
|
33
|
+
|
34
|
+
- name: Build wheels
|
35
|
+
# Using explicit command to avoid empty parameter issues on Windows
|
36
|
+
run: |
|
37
|
+
python -m pip install cibuildwheel==2.16.2
|
38
|
+
python -m cibuildwheel
|
39
|
+
env:
|
40
|
+
CIBW_BUILD: cp38-* cp39-* cp310-* cp311-* cp312-*
|
41
|
+
CIBW_SKIP: pp* *-musllinux*
|
42
|
+
CIBW_ARCHS_LINUX: auto
|
43
|
+
CIBW_ARCHS_MACOS: x86_64 arm64
|
44
|
+
CIBW_ARCHS_WINDOWS: auto
|
45
|
+
|
46
|
+
# 更健壮的依赖安装方式
|
47
|
+
CIBW_BEFORE_ALL_LINUX: |
|
48
|
+
if command -v yum &>/dev/null; then
|
49
|
+
# Try multiple times with increasing timeouts (network issues)
|
50
|
+
for i in 1 2 3; do
|
51
|
+
echo "Attempt $i: Installing dependencies with yum..."
|
52
|
+
yum install -y cmake gcc-c++ && break || sleep 5
|
53
|
+
done
|
54
|
+
elif command -v apt-get &>/dev/null; then
|
55
|
+
echo "Installing dependencies with apt..."
|
56
|
+
apt-get update -y && apt-get install -y cmake g++
|
57
|
+
elif command -v apk &>/dev/null; then
|
58
|
+
echo "Installing dependencies with apk..."
|
59
|
+
apk add --no-cache cmake g++
|
60
|
+
else
|
61
|
+
echo "No supported package manager found!"
|
62
|
+
exit 1
|
63
|
+
fi
|
64
|
+
CIBW_BEFORE_ALL_MACOS: |
|
65
|
+
brew install cmake
|
66
|
+
CIBW_BEFORE_ALL_WINDOWS: |
|
67
|
+
choco install cmake
|
68
|
+
|
69
|
+
# 简单的测试
|
70
|
+
CIBW_TEST_COMMAND: |
|
71
|
+
python -c "from dicube.codecs.jph import JphCodec; print('Import test passed successfully')"
|
72
|
+
|
73
|
+
- uses: actions/upload-artifact@v4
|
74
|
+
with:
|
75
|
+
name: wheels-${{ matrix.os }}
|
76
|
+
path: wheelhouse/*.whl
|
77
|
+
|
78
|
+
build_sdist:
|
79
|
+
name: Build source distribution
|
80
|
+
runs-on: ubuntu-latest
|
81
|
+
steps:
|
82
|
+
- uses: actions/checkout@v4
|
83
|
+
with:
|
84
|
+
submodules: recursive
|
85
|
+
ref: ${{ github.ref }}
|
86
|
+
# Ensure full history to prevent setuptools_scm issues
|
87
|
+
fetch-depth: 0
|
88
|
+
|
89
|
+
- uses: ./.github/actions/setup-python-env
|
90
|
+
with:
|
91
|
+
python-version: '3.9'
|
92
|
+
|
93
|
+
- name: Build sdist
|
94
|
+
run: |
|
95
|
+
pip install build setuptools_scm
|
96
|
+
python -m build --sdist
|
97
|
+
|
98
|
+
- uses: actions/upload-artifact@v4
|
99
|
+
with:
|
100
|
+
name: sdist
|
101
|
+
path: dist/*.tar.gz
|
@@ -0,0 +1,86 @@
|
|
1
|
+
name: Release
|
2
|
+
|
3
|
+
on:
|
4
|
+
release:
|
5
|
+
types: [published]
|
6
|
+
workflow_dispatch:
|
7
|
+
inputs:
|
8
|
+
tag:
|
9
|
+
description: 'Release tag (for manual dispatch)'
|
10
|
+
required: false
|
11
|
+
default: ''
|
12
|
+
type: string
|
13
|
+
|
14
|
+
jobs:
|
15
|
+
# 构建 wheels 和 sdist
|
16
|
+
build:
|
17
|
+
uses: ./.github/workflows/build-wheels.yml
|
18
|
+
|
19
|
+
# 发布到 GitHub Release
|
20
|
+
github-release:
|
21
|
+
runs-on: ubuntu-latest
|
22
|
+
needs: build
|
23
|
+
if: github.event_name == 'release'
|
24
|
+
permissions:
|
25
|
+
contents: write
|
26
|
+
steps:
|
27
|
+
- name: Download all artifacts
|
28
|
+
uses: actions/download-artifact@v4
|
29
|
+
with:
|
30
|
+
path: dist
|
31
|
+
merge-multiple: true
|
32
|
+
|
33
|
+
- name: List release assets
|
34
|
+
run: |
|
35
|
+
echo "📦 Release assets:"
|
36
|
+
ls -la dist/
|
37
|
+
echo "Total wheels: $(ls dist/*.whl 2>/dev/null | wc -l)"
|
38
|
+
echo "Source dist: $(ls dist/*.tar.gz 2>/dev/null | wc -l)"
|
39
|
+
|
40
|
+
- name: Upload to GitHub Release
|
41
|
+
uses: softprops/action-gh-release@v1
|
42
|
+
with:
|
43
|
+
files: dist/*
|
44
|
+
fail_on_unmatched_files: true
|
45
|
+
generate_release_notes: true
|
46
|
+
|
47
|
+
# 发布到 PyPI
|
48
|
+
pypi-release:
|
49
|
+
runs-on: ubuntu-latest
|
50
|
+
needs: build
|
51
|
+
if: github.event_name == 'release'
|
52
|
+
environment: pypi
|
53
|
+
permissions:
|
54
|
+
id-token: write
|
55
|
+
steps:
|
56
|
+
- name: Download all artifacts
|
57
|
+
uses: actions/download-artifact@v4
|
58
|
+
with:
|
59
|
+
path: dist
|
60
|
+
merge-multiple: true
|
61
|
+
|
62
|
+
- name: Publish to PyPI
|
63
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
64
|
+
with:
|
65
|
+
packages-dir: dist/
|
66
|
+
verbose: true
|
67
|
+
|
68
|
+
# 发布总结
|
69
|
+
release-summary:
|
70
|
+
runs-on: ubuntu-latest
|
71
|
+
needs: [github-release, pypi-release]
|
72
|
+
if: always()
|
73
|
+
steps:
|
74
|
+
- name: Release Summary
|
75
|
+
run: |
|
76
|
+
echo "## 🚀 Release Summary" >> $GITHUB_STEP_SUMMARY
|
77
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
78
|
+
echo "- GitHub Release: ${{ needs.github-release.result == 'success' && '✅ Success' || '❌ Failed' }}" >> $GITHUB_STEP_SUMMARY
|
79
|
+
echo "- PyPI Release: ${{ needs.pypi-release.result == 'success' && '✅ Success' || '❌ Failed' }}" >> $GITHUB_STEP_SUMMARY
|
80
|
+
echo "" >> $GITHUB_STEP_SUMMARY
|
81
|
+
|
82
|
+
if [[ "${{ needs.github-release.result }}" == "success" && "${{ needs.pypi-release.result }}" == "success" ]]; then
|
83
|
+
echo "✅ Release completed successfully!" >> $GITHUB_STEP_SUMMARY
|
84
|
+
else
|
85
|
+
echo "❌ Release encountered issues" >> $GITHUB_STEP_SUMMARY
|
86
|
+
fi
|
@@ -0,0 +1,43 @@
|
|
1
|
+
name: Test
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches: [main, master]
|
6
|
+
pull_request:
|
7
|
+
branches: [main, master]
|
8
|
+
workflow_dispatch:
|
9
|
+
|
10
|
+
jobs:
|
11
|
+
test:
|
12
|
+
strategy:
|
13
|
+
matrix:
|
14
|
+
os: [ubuntu-latest]
|
15
|
+
python-version: ['3.8', '3.12'] # 只测试最低和最高版本
|
16
|
+
|
17
|
+
runs-on: ${{ matrix.os }}
|
18
|
+
|
19
|
+
steps:
|
20
|
+
- uses: actions/checkout@v4
|
21
|
+
with:
|
22
|
+
submodules: recursive
|
23
|
+
|
24
|
+
- uses: ./.github/actions/setup-python-env
|
25
|
+
with:
|
26
|
+
python-version: ${{ matrix.python-version }}
|
27
|
+
install-dev: 'true'
|
28
|
+
|
29
|
+
# 安装和测试
|
30
|
+
- name: Install package
|
31
|
+
run: |
|
32
|
+
pip install -e .[dev]
|
33
|
+
|
34
|
+
- name: Run tests
|
35
|
+
run: |
|
36
|
+
pytest tests/ -v --tb=short
|
37
|
+
|
38
|
+
# 基本导入测试
|
39
|
+
python -c "
|
40
|
+
import dicube
|
41
|
+
from dicube.codecs.jph import JphCodec
|
42
|
+
print(f'dicube version: {dicube.__version__} - Import successful')
|
43
|
+
"
|
dicube-0.1.4/.gitignore
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
.kiro
|
2
|
+
trash
|
3
|
+
dicube/_version.py
|
4
|
+
*.mska
|
5
|
+
*.msk
|
6
|
+
*.nii
|
7
|
+
*.nii.gz
|
8
|
+
|
9
|
+
# Byte-compiled / optimized / DLL files
|
10
|
+
__pycache__/
|
11
|
+
*.py[cod]
|
12
|
+
*$py.class
|
13
|
+
|
14
|
+
# C extensions
|
15
|
+
*.so
|
16
|
+
|
17
|
+
# Distribution / packaging
|
18
|
+
.Python
|
19
|
+
build/
|
20
|
+
dist/
|
21
|
+
*.egg-info/
|
22
|
+
.eggs/
|
23
|
+
|
24
|
+
# Installer logs
|
25
|
+
pip-log.txt
|
26
|
+
pip-delete-this-directory.txt
|
27
|
+
|
28
|
+
# Unit test / coverage reports
|
29
|
+
htmlcov/
|
30
|
+
.tox/
|
31
|
+
.nox/
|
32
|
+
.coverage
|
33
|
+
.coverage.*
|
34
|
+
.cache
|
35
|
+
pytest_cache/
|
36
|
+
|
37
|
+
# MyPy / Pyright / Pyre type checker
|
38
|
+
.mypy_cache/
|
39
|
+
.pyre/
|
40
|
+
.pytype/
|
41
|
+
|
42
|
+
# VS Code
|
43
|
+
.vscode/
|
44
|
+
|
45
|
+
# IDEs
|
46
|
+
.idea/
|
47
|
+
|
48
|
+
# Environments
|
49
|
+
.env
|
50
|
+
.venv
|
51
|
+
venv/
|
52
|
+
ENV/
|
53
|
+
|
54
|
+
# Jupyter Notebook checkpoints
|
55
|
+
.ipynb_checkpoints/
|
56
|
+
|
57
|
+
# Mac / Linux
|
58
|
+
.DS_Store
|
59
|
+
*.swp
|
60
|
+
|
61
|
+
# Logs
|
62
|
+
*.log
|
63
|
+
|
64
|
+
# uv local cache
|
65
|
+
.uv/
|
dicube-0.1.4/.gitmodules
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
cmake_minimum_required(VERSION 3.15.0)
|
2
|
+
|
3
|
+
project(dicube-openjph
|
4
|
+
VERSION 0.1.0
|
5
|
+
DESCRIPTION "DiCube with statically linked OpenJPH"
|
6
|
+
LANGUAGES CXX
|
7
|
+
)
|
8
|
+
|
9
|
+
# 设置 C++ 标准
|
10
|
+
set(CMAKE_CXX_STANDARD 14)
|
11
|
+
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
12
|
+
|
13
|
+
# 构建类型
|
14
|
+
if(NOT CMAKE_BUILD_TYPE)
|
15
|
+
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "Build type" FORCE)
|
16
|
+
endif()
|
17
|
+
|
18
|
+
# 设置输出目录
|
19
|
+
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
|
20
|
+
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
21
|
+
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
|
22
|
+
|
23
|
+
# ================================================================================================
|
24
|
+
# 选项配置
|
25
|
+
# ================================================================================================
|
26
|
+
|
27
|
+
option(DICUBE_BUILD_PYTHON_EXTENSIONS "Build Python extensions" ON)
|
28
|
+
|
29
|
+
# ================================================================================================
|
30
|
+
# 编译器设置
|
31
|
+
# ================================================================================================
|
32
|
+
|
33
|
+
if(MSVC)
|
34
|
+
# Windows MSVC 设置
|
35
|
+
add_compile_definitions(_CRT_SECURE_NO_WARNINGS)
|
36
|
+
add_compile_options(/W3 /EHsc)
|
37
|
+
# 静态链接 CRT
|
38
|
+
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>")
|
39
|
+
else()
|
40
|
+
# GCC/Clang 设置
|
41
|
+
add_compile_options(-fexceptions -Wall -Wextra -fPIC)
|
42
|
+
if(CMAKE_BUILD_TYPE STREQUAL "Release")
|
43
|
+
add_compile_options(-O3 -DNDEBUG)
|
44
|
+
endif()
|
45
|
+
endif()
|
46
|
+
|
47
|
+
# ================================================================================================
|
48
|
+
# OpenJPH 构建
|
49
|
+
# ================================================================================================
|
50
|
+
|
51
|
+
# 检查 OpenJPH 源码
|
52
|
+
set(OPENJPH_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/source/OpenJPH")
|
53
|
+
if(NOT EXISTS "${OPENJPH_SOURCE_DIR}/CMakeLists.txt")
|
54
|
+
message(FATAL_ERROR
|
55
|
+
"OpenJPH source not found. Please run: git submodule update --init --recursive"
|
56
|
+
)
|
57
|
+
endif()
|
58
|
+
|
59
|
+
# OpenJPH 构建选项
|
60
|
+
set(BUILD_SHARED_LIBS OFF CACHE BOOL "" FORCE)
|
61
|
+
set(OJPH_ENABLE_TIFF_SUPPORT OFF CACHE BOOL "" FORCE)
|
62
|
+
set(OJPH_BUILD_TESTS OFF CACHE BOOL "" FORCE)
|
63
|
+
set(OJPH_BUILD_EXECUTABLES OFF CACHE BOOL "" FORCE)
|
64
|
+
set(OJPH_BUILD_STREAM_EXPAND OFF CACHE BOOL "" FORCE)
|
65
|
+
set(OJPH_DISABLE_SIMD OFF CACHE BOOL "" FORCE) # 启用 SIMD 优化
|
66
|
+
|
67
|
+
# 添加 OpenJPH
|
68
|
+
add_subdirectory(${OPENJPH_SOURCE_DIR} openjph EXCLUDE_FROM_ALL)
|
69
|
+
|
70
|
+
# 设置 OpenJPH 目标和头文件
|
71
|
+
set(OPENJPH_TARGET openjph)
|
72
|
+
set(OPENJPH_INCLUDE_DIRS
|
73
|
+
"${OPENJPH_SOURCE_DIR}/src/core/common"
|
74
|
+
"${CMAKE_BINARY_DIR}/openjph/src/core/common" # 生成的配置文件
|
75
|
+
)
|
76
|
+
|
77
|
+
# ================================================================================================
|
78
|
+
# Python 扩展构建
|
79
|
+
# ================================================================================================
|
80
|
+
|
81
|
+
if(DICUBE_BUILD_PYTHON_EXTENSIONS)
|
82
|
+
# 查找 Python 和 pybind11
|
83
|
+
find_package(Python REQUIRED COMPONENTS Interpreter Development.Module)
|
84
|
+
find_package(pybind11 REQUIRED)
|
85
|
+
|
86
|
+
# 查找 NumPy
|
87
|
+
execute_process(
|
88
|
+
COMMAND ${Python_EXECUTABLE} -c "import numpy; print(numpy.get_include())"
|
89
|
+
OUTPUT_VARIABLE NUMPY_INCLUDE_DIR
|
90
|
+
OUTPUT_STRIP_TRAILING_WHITESPACE
|
91
|
+
)
|
92
|
+
|
93
|
+
if(NOT NUMPY_INCLUDE_DIR)
|
94
|
+
message(FATAL_ERROR "NumPy not found")
|
95
|
+
endif()
|
96
|
+
|
97
|
+
# 构建 Python 扩展
|
98
|
+
pybind11_add_module(ojph_complete dicube/codecs/jph/encode_complete.cpp)
|
99
|
+
pybind11_add_module(ojph_decode_complete dicube/codecs/jph/decode_complete.cpp)
|
100
|
+
|
101
|
+
# 设置包含目录和链接
|
102
|
+
foreach(target ojph_complete ojph_decode_complete)
|
103
|
+
target_include_directories(${target} PRIVATE
|
104
|
+
${OPENJPH_INCLUDE_DIRS}
|
105
|
+
${NUMPY_INCLUDE_DIR}
|
106
|
+
)
|
107
|
+
target_link_libraries(${target} PRIVATE ${OPENJPH_TARGET})
|
108
|
+
|
109
|
+
# 确保 .pyd/.so 文件直接放在正确的目录,不带 Release 子目录
|
110
|
+
if(MSVC)
|
111
|
+
# Windows特殊处理,防止产生 Release 子目录
|
112
|
+
set_target_properties(${target} PROPERTIES
|
113
|
+
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dicube/codecs/jph
|
114
|
+
RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/dicube/codecs/jph
|
115
|
+
RUNTIME_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/dicube/codecs/jph
|
116
|
+
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dicube/codecs/jph
|
117
|
+
LIBRARY_OUTPUT_DIRECTORY_RELEASE ${CMAKE_CURRENT_SOURCE_DIR}/dicube/codecs/jph
|
118
|
+
LIBRARY_OUTPUT_DIRECTORY_DEBUG ${CMAKE_CURRENT_SOURCE_DIR}/dicube/codecs/jph
|
119
|
+
)
|
120
|
+
else()
|
121
|
+
# Linux/macOS
|
122
|
+
set_target_properties(${target} PROPERTIES
|
123
|
+
LIBRARY_OUTPUT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/dicube/codecs/jph
|
124
|
+
)
|
125
|
+
endif()
|
126
|
+
endforeach()
|
127
|
+
|
128
|
+
message(STATUS "Python extensions configured (Python ${Python_VERSION})")
|
129
|
+
endif()
|
130
|
+
|
131
|
+
# ================================================================================================
|
132
|
+
# 构建摘要
|
133
|
+
# ================================================================================================
|
134
|
+
|
135
|
+
message(STATUS "=== Build Configuration ===")
|
136
|
+
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
|
137
|
+
message(STATUS "Python extensions: ${DICUBE_BUILD_PYTHON_EXTENSIONS}")
|
138
|
+
if(DICUBE_BUILD_PYTHON_EXTENSIONS)
|
139
|
+
message(STATUS "Python: ${Python_VERSION}")
|
140
|
+
endif()
|
141
|
+
message(STATUS "===========================")
|