Skip to content

Commit ff81d41

Browse files
committed
feat(formats): Add GIPL support
Also, .gz extension identification is removed in favor of .CanReadFile detection.
1 parent e9ffb6f commit ff81d41

9 files changed

Lines changed: 141 additions & 8 deletions

CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,14 @@ set(BridgeJavaScript_IOModules
1414
"ITKIOVTK"
1515
"ITKIOBMP"
1616
"ITKIOBioRad"
17+
"ITKIOGIPL"
1718
"ITKIOGE"
1819
CACHE STRING
1920
"String delimited list of ITK IO modules to support.")
2021
set(imageios_ITKIOBioRad itkBioRadImageIO)
2122
set(imageios_ITKIOBMP itkBMPImageIO)
2223
set(imageios_ITKIOGE itkGEAdwImageIO itkGE4ImageIO itkGE5ImageIO)
24+
set(imageios_ITKIOGIPL itkGiplImageIO)
2325
set(imageios_ITKIOPNG itkPNGImageIO)
2426
set(imageios_ITKIOMeta itkMetaImageIO)
2527
set(imageios_ITKIONIFTI itkNiftiImageIO)

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Supported file formats
1515
- [DICOM](http://dicom.nema.org/)
1616
- [JPEG](https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format)
1717
- [GE4,GE5,GEAdw](http://www3.gehealthcare.com)
18+
- [Gipl (Guys Image Processing Lab)](https://www.ncbi.nlm.nih.gov/pubmed/12956259)
1819
- [MetaImage](https://itk.org/Wiki/ITK/MetaIO/Documentation)
1920
- [NifTi](https://nifti.nimh.nih.gov/nifti-1)
2021
- [NRRD](http://teem.sourceforge.net/nrrd/format.html)

src/extensionToIO.js

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ extensionToIO['BMP'] = 'itkBMPImageIOJSBinding'
66
extensionToIO['dcm'] = 'itkGDCMImageIOJSBinding'
77
extensionToIO['DCM'] = 'itkGDCMImageIOJSBinding'
88

9+
extensionToIO['gipl'] = 'itkGiplImageIOJSBinding'
10+
extensionToIO['gipl.gz'] = 'itkGiplImageIOJSBinding'
11+
912
extensionToIO['jpg'] = 'itkJPEGImageIOJSBinding'
1013
extensionToIO['JPG'] = 'itkJPEGImageIOJSBinding'
1114
extensionToIO['jpeg'] = 'itkJPEGImageIOJSBinding'
@@ -16,8 +19,7 @@ extensionToIO['mhd'] = 'itkMetaImageIOJSBinding'
1619

1720
extensionToIO['nia'] = 'itkNiftiImageIOJSBinding'
1821
extensionToIO['nii'] = 'itkNiftiImageIOJSBinding'
19-
// todo: properly support .nii.gz
20-
extensionToIO['gz'] = 'itkNiftiImageIOJSBinding'
22+
extensionToIO['nii.gz'] = 'itkNiftiImageIOJSBinding'
2123
extensionToIO['hdr'] = 'itkNiftiImageIOJSBinding'
2224

2325
extensionToIO['nrrd'] = 'itkNrrdImageIOJSBinding'

src/getFileExtension.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
const getFileExtension = (filePath) => {
2-
return filePath.slice((filePath.lastIndexOf('.') - 1 >>> 0) + 2)
2+
let extension = filePath.slice((filePath.lastIndexOf('.') - 1 >>> 0) + 2)
3+
if (extension === 'gz') {
4+
const index = filePath.slice(0, -3).lastIndexOf('.')
5+
extension = filePath.slice((index - 1 >>> 0) + 2)
6+
}
7+
return extension
38
}
49

510
module.exports = getFileExtension

src/itkGiplImageIOJSBinding.cxx

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*=========================================================================
2+
*
3+
* Copyright Insight Software Consortium
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0.txt
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*
17+
*=========================================================================*/
18+
19+
#include <emscripten.h>
20+
#include <emscripten/bind.h>
21+
22+
#include "itkGiplImageIO.h"
23+
24+
#include "itkImageIOBaseJSBinding.h"
25+
26+
typedef itk::ImageIOBaseJSBinding< itk::GiplImageIO > GiplImageIOJSBindingType;
27+
28+
EMSCRIPTEN_BINDINGS(itk_biorad_image_io_js_binding) {
29+
emscripten::register_vector<double>("AxisDirectionType");
30+
emscripten::enum_<GiplImageIOJSBindingType::IOPixelType>("IOPixelType")
31+
.value("UNKNOWNPIXELTYPE", itk::ImageIOBase::UNKNOWNPIXELTYPE)
32+
.value("SCALAR", itk::ImageIOBase::SCALAR)
33+
.value("RGB", itk::ImageIOBase::RGB)
34+
.value("RGBA", itk::ImageIOBase::RGBA)
35+
.value("OFFSET", itk::ImageIOBase::OFFSET)
36+
.value("VECTOR", itk::ImageIOBase::VECTOR)
37+
.value("POINT", itk::ImageIOBase::POINT)
38+
.value("COVARIANTVECTOR", itk::ImageIOBase::COVARIANTVECTOR)
39+
.value("SYMMETRICSECONDRANKTENSOR", itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR)
40+
.value("POINT", itk::ImageIOBase::POINT)
41+
.value("COVARIANTVECTOR", itk::ImageIOBase::COVARIANTVECTOR)
42+
.value("SYMMETRICSECONDRANKTENSOR", itk::ImageIOBase::SYMMETRICSECONDRANKTENSOR)
43+
.value("DIFFUSIONTENSOR3D", itk::ImageIOBase::DIFFUSIONTENSOR3D)
44+
.value("COMPLEX", itk::ImageIOBase::COMPLEX)
45+
.value("FIXEDARRAY", itk::ImageIOBase::FIXEDARRAY)
46+
.value("MATRIX", itk::ImageIOBase::MATRIX)
47+
;
48+
emscripten::enum_<GiplImageIOJSBindingType::IOComponentType>("IOComponentType")
49+
.value("UNKNOWNCOMPONENTTYPE", itk::ImageIOBase::UNKNOWNCOMPONENTTYPE)
50+
.value("UCHAR", itk::ImageIOBase::UCHAR)
51+
.value("CHAR", itk::ImageIOBase::CHAR)
52+
.value("USHORT", itk::ImageIOBase::USHORT)
53+
.value("SHORT", itk::ImageIOBase::SHORT)
54+
.value("UINT", itk::ImageIOBase::UINT)
55+
.value("INT", itk::ImageIOBase::INT)
56+
.value("ULONG", itk::ImageIOBase::ULONG)
57+
.value("LONG", itk::ImageIOBase::LONG)
58+
.value("FLOAT", itk::ImageIOBase::FLOAT)
59+
.value("DOUBLE", itk::ImageIOBase::DOUBLE)
60+
;
61+
emscripten::class_<GiplImageIOJSBindingType>("ITKImageIO")
62+
.constructor<>()
63+
.function("SetNumberOfDimensions", &GiplImageIOJSBindingType::SetNumberOfDimensions)
64+
.function("GetNumberOfDimensions", &GiplImageIOJSBindingType::GetNumberOfDimensions)
65+
.function("SetFileName", &GiplImageIOJSBindingType::SetFileName)
66+
.function("GetFileName", &GiplImageIOJSBindingType::GetFileName)
67+
.function("CanReadFile", &GiplImageIOJSBindingType::CanReadFile)
68+
.function("ReadImageInformation", &GiplImageIOJSBindingType::ReadImageInformation)
69+
.function("SetDimensions", &GiplImageIOJSBindingType::SetDimensions)
70+
.function("GetDimensions", &GiplImageIOJSBindingType::GetDimensions)
71+
.function("SetOrigin", &GiplImageIOJSBindingType::SetOrigin)
72+
.function("GetOrigin", &GiplImageIOJSBindingType::GetOrigin)
73+
.function("SetSpacing", &GiplImageIOJSBindingType::SetSpacing)
74+
.function("GetSpacing", &GiplImageIOJSBindingType::GetSpacing)
75+
.function("SetDirection", &GiplImageIOJSBindingType::SetDirection)
76+
.function("GetDirection", &GiplImageIOJSBindingType::GetDirection)
77+
.function("GetDefaultDirection", &GiplImageIOJSBindingType::GetDefaultDirection)
78+
.function("SetPixelType", &GiplImageIOJSBindingType::SetPixelType)
79+
.function("GetPixelType", &GiplImageIOJSBindingType::GetPixelType)
80+
.function("SetComponentType", &GiplImageIOJSBindingType::SetComponentType)
81+
.function("GetComponentType", &GiplImageIOJSBindingType::GetComponentType)
82+
.class_function("GetPixelTypeAsString", &GiplImageIOJSBindingType::GetPixelTypeAsString)
83+
.class_function("GetComponentTypeAsString", &GiplImageIOJSBindingType::GetComponentTypeAsString)
84+
.function("GetImageSizeInPixels", &GiplImageIOJSBindingType::GetImageSizeInPixels)
85+
.function("GetImageSizeInBytes", &GiplImageIOJSBindingType::GetImageSizeInBytes)
86+
.function("GetImageSizeInComponents", &GiplImageIOJSBindingType::GetImageSizeInComponents)
87+
.function("SetNumberOfComponents", &GiplImageIOJSBindingType::SetNumberOfComponents)
88+
.function("GetNumberOfComponents", &GiplImageIOJSBindingType::GetNumberOfComponents)
89+
.function("Read", &GiplImageIOJSBindingType::Read)
90+
;
91+
}

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,4 +32,5 @@ ExternalData_Expand_Arguments(
3232
DATA{Input/19771.002.001}
3333
DATA{Input/113766.003.001}
3434
DATA{Input/I.001}
35+
DATA{Input/ramp.gipl}
3536
)

test/Input/ramp.gipl.md5

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
77411a7f9359b867e69dd5fa75100982

test/extensionToIOTest.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,6 @@ test('nii maps to itkNiftiImageIOJSBinding', t => {
4848
t.is(io, 'itkNiftiImageIOJSBinding')
4949
})
5050

51-
test('gz maps to itkNiftiImageIOJSBinding', t => {
52-
let io = ExtensionToIO['gz']
53-
t.is(io, 'itkNiftiImageIOJSBinding')
54-
})
55-
5651
test('hdr maps to itkNiftiImageIOJSBinding', t => {
5752
let io = ExtensionToIO['hdr']
5853
t.is(io, 'itkNiftiImageIOJSBinding')
@@ -68,6 +63,11 @@ test('nhdr maps to itkNrrdImageIOJSBinding', t => {
6863
t.is(io, 'itkNrrdImageIOJSBinding')
6964
})
7065

66+
test('gipl maps to itkGiplImageIOJSBinding', t => {
67+
let io = ExtensionToIO['gipl']
68+
t.is(io, 'itkGiplImageIOJSBinding')
69+
})
70+
7171
test('dcm maps to itkGDCMImageIOJSBinding', t => {
7272
let io = ExtensionToIO['dcm']
7373
t.is(io, 'itkGDCMImageIOJSBinding')

test/formatsTest.js

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,36 @@ test('Test reading a JPEG file', t => {
9393
})
9494
})
9595

96+
test('Test reading a GIPL file', t => {
97+
const testFilePath = path.resolve(__dirname, '..', 'build', 'ExternalData', 'test', 'Input', 'ramp.gipl')
98+
return readImageLocalFile(testFilePath).then(function (image) {
99+
t.is(image.imageType.dimension, 3, 'dimension')
100+
t.is(image.imageType.componentType, IntTypes.Int16, 'componentType')
101+
t.is(image.imageType.pixelType, PixelTypes.Scalar, 'pixelType')
102+
t.is(image.imageType.components, 1, 'components')
103+
t.is(image.origin[0], 0.0, 'origin[0]')
104+
t.is(image.origin[1], 0.0, 'origin[1]')
105+
t.is(image.origin[2], 0.0, 'origin[2]')
106+
t.is(image.spacing[0], 1.0, 'spacing[0]')
107+
t.is(image.spacing[1], 1.0, 'spacing[1]')
108+
t.is(image.spacing[2], 1.0, 'spacing[2]')
109+
t.is(image.direction.getElement(0, 0), 1.0, 'direction (0, 0)')
110+
t.is(image.direction.getElement(0, 1), 0.0, 'direction (0, 1)')
111+
t.is(image.direction.getElement(0, 2), 0.0, 'direction (0, 2)')
112+
t.is(image.direction.getElement(1, 0), 0.0, 'direction (1, 0)')
113+
t.is(image.direction.getElement(1, 1), 1.0, 'direction (1, 1)')
114+
t.is(image.direction.getElement(1, 2), 0.0, 'direction (1, 2)')
115+
t.is(image.direction.getElement(2, 0), 0.0, 'direction (2, 0)')
116+
t.is(image.direction.getElement(2, 1), 0.0, 'direction (2, 1)')
117+
t.is(image.direction.getElement(2, 2), 1.0, 'direction (2, 2)')
118+
t.is(image.size[0], 30, 'size[0]')
119+
t.is(image.size[1], 30, 'size[1]')
120+
t.is(image.size[2], 30, 'size[2]')
121+
t.is(image.buffer.length, 27000, 'buffer.length')
122+
t.is(image.buffer[2], 2, 'buffer[2]')
123+
})
124+
})
125+
96126
test('Test reading a TIFF file', t => {
97127
const testFilePath = path.resolve(__dirname, '..', 'build', 'ExternalData', 'test', 'Input', 'ShortTestImage.tiff')
98128
return readImageLocalFile(testFilePath).then(function (image) {

0 commit comments

Comments
 (0)