Skip to content

Commit 6cc2576

Browse files
committed
feat(transform-io): package C++ addition
1 parent eeb4947 commit 6cc2576

20 files changed

+1329
-42
lines changed

ITKKWStyleOverwrite.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ itkSupportInputMeshTypesTest\.cxx Namespace Disable
66
itkSupportInputMeshTypesMemoryIOTest\.cxx Namespace Disable
77
itkSupportInputPolyDataTypesTest\.cxx Namespace Disable
88
itkFloatTypesJSON\.h Namespace Disable
9+
itkOutputTransformIO\.h Namespace Disable

include/itkInputTransformIO.h

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
/*=========================================================================
2+
*
3+
* Copyright NumFOCUS
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+
* https://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+
#ifndef itkInputTransformIO_h
19+
#define itkInputTransformIO_h
20+
21+
#include "itkPipeline.h"
22+
#include "itkWasmTransformIOBase.h"
23+
#include "itkWasmTransformIO.h"
24+
25+
#ifndef ITK_WASM_NO_MEMORY_IO
26+
#include "itkWasmExports.h"
27+
#endif
28+
#ifndef ITK_WASM_NO_FILESYSTEM_IO
29+
#endif
30+
31+
namespace itk
32+
{
33+
namespace wasm
34+
{
35+
36+
/**
37+
*\class InputTransformIO
38+
* \brief Input transform for an itk::wasm::Pipeline from an itk::TransformIOBase
39+
*
40+
* This transform is read from the filesystem or memory when ITK_WASM_PARSE_ARGS is called.
41+
*
42+
* This class is for the WriteTransform ITK-Wasm pipeline. Most pipelines will use itk::wasm::InputTransform.
43+
*
44+
* \ingroup WebAssemblyInterface
45+
*/
46+
template <typename TParametersValueType>
47+
class InputTransformIO
48+
{
49+
public:
50+
using ParametersValueType = TParametersValueType;
51+
using WasmTransformIOBaseType = WasmTransformIOBase<ParametersValueType>;
52+
53+
void Set(const WasmTransformIOBaseType * transformIO) {
54+
this->m_WasmTransformIOBase = transformIO;
55+
}
56+
57+
const WasmTransformIOBaseType * Get() const {
58+
return this->m_WasmTransformIOBase.GetPointer();
59+
}
60+
61+
InputTransformIO() = default;
62+
~InputTransformIO() = default;
63+
protected:
64+
typename WasmTransformIOBaseType::ConstPointer m_WasmTransformIOBase;
65+
};
66+
67+
68+
template <typename TParametersValueType>
69+
bool lexical_cast(const std::string &input, InputTransformIO<TParametersValueType> &inputTransformIO)
70+
{
71+
using ParametersValueType = TParametersValueType;
72+
using WasmTransformIOType = itk::WasmTransformIOTemplate<ParametersValueType>;
73+
using WasmTransformIOBaseType = WasmTransformIOBase<ParametersValueType>;
74+
using FixedParametersType = typename WasmTransformIOType::FixedParametersType;
75+
76+
if (input.empty())
77+
{
78+
return false;
79+
}
80+
81+
if (wasm::Pipeline::get_use_memory_io())
82+
{
83+
#ifndef ITK_WASM_NO_MEMORY_IO
84+
const unsigned int index = std::stoi(input);
85+
auto json = getMemoryStoreInputJSON(0, index);
86+
auto deserializedAttempt = glz::read_json<itk::TransformListJSON>(json);
87+
if (!deserializedAttempt)
88+
{
89+
const std::string descriptiveError = glz::format_error(deserializedAttempt, json);
90+
throw std::runtime_error("Failed to deserialize TransformJSON: " + descriptiveError);
91+
}
92+
auto transformListJSON = deserializedAttempt.value();
93+
if (transformListJSON.size() < 1)
94+
{
95+
throw std::runtime_error("Expected at least one transform in the list");
96+
}
97+
98+
auto wasmTransformIO = WasmTransformIOType::New();
99+
wasmTransformIO->SetJSON(transformListJSON);
100+
101+
auto wasmTransformIOBase = WasmTransformIOBaseType::New();
102+
wasmTransformIOBase->SetTransformIO(wasmTransformIO, false);
103+
wasmTransformIOBase->SetJSON(json);
104+
105+
inputTransformIO.Set(wasmTransformIOBase);
106+
#else
107+
return false;
108+
#endif
109+
}
110+
else
111+
{
112+
#ifndef ITK_WASM_NO_FILESYSTEM_IO
113+
auto wasmTransformIO = WasmTransformIOType::New();
114+
wasmTransformIO->SetFileName(input);
115+
wasmTransformIO->Read();
116+
117+
auto wasmTransformIOBase = WasmTransformIOBaseType::New();
118+
wasmTransformIOBase->SetTransformIO(wasmTransformIO);
119+
120+
inputTransformIO.Set(wasmTransformIOBase);
121+
#else
122+
return false;
123+
#endif
124+
}
125+
return true;
126+
}
127+
128+
} // end namespace wasm
129+
} // end namespace itk
130+
131+
#endif

include/itkOutputTransformIO.h

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*=========================================================================
2+
*
3+
* Copyright NumFOCUS
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+
* https://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+
#ifndef itkOutputTransformIO_h
19+
#define itkOutputTransformIO_h
20+
21+
#include "itkTransformBase.h"
22+
23+
#include "itkPipeline.h"
24+
25+
#include "itkTransformIOBase.h"
26+
#include "itkWasmTransformIOBase.h"
27+
#include "itkWasmTransformIO.h"
28+
#include "itkTransformJSON.h"
29+
#ifndef ITK_WASM_NO_MEMORY_IO
30+
#include "itkWasmExports.h"
31+
#endif
32+
#ifndef ITK_WASM_NO_FILESYSTEM_IO
33+
#endif
34+
35+
namespace
36+
{
37+
38+
template <typename TParametersValueType>
39+
void
40+
addTransformBuffersToMemoryStore(const itk::TransformListJSON & transformListJSON, size_t index)
41+
{
42+
using ParametersValueType = TParametersValueType;
43+
44+
using TransformBaseType = itk::TransformBaseTemplate<ParametersValueType>;
45+
46+
using FixedParametersValueType = typename TransformBaseType::FixedParametersValueType;
47+
48+
unsigned int dataCount = 0;
49+
// iterate through the transform list and store each transfrom's fixed parameters and parameters
50+
for (const auto & transformJSON: transformListJSON)
51+
{
52+
if (transformJSON.transformType.transformParameterization == itk::JSONTransformParameterizationEnum::Composite)
53+
{
54+
continue;
55+
}
56+
const auto fixedParamsAddress = static_cast< size_t >( std::strtoull(transformJSON.fixedParameters.substr(35).c_str(), nullptr, 10) );
57+
const auto fixedParamsSize = transformJSON.numberOfFixedParameters * sizeof(FixedParametersValueType);
58+
itk::wasm::setMemoryStoreOutputArray(0, index, dataCount, fixedParamsAddress, fixedParamsSize);
59+
++dataCount;
60+
61+
const auto paramsAddress = static_cast< size_t >( std::strtoull(transformJSON.parameters.substr(35).c_str(), nullptr, 10) );
62+
const auto paramsSize = transformJSON.numberOfParameters * sizeof(ParametersValueType);
63+
itk::wasm::setMemoryStoreOutputArray(0, index, dataCount, paramsAddress, paramsSize);
64+
++dataCount;
65+
}
66+
}
67+
68+
} // end anonymous namespace
69+
70+
namespace itk
71+
{
72+
namespace wasm
73+
{
74+
/**
75+
*\class OutputTransformIO
76+
* \brief Output transform for an itk::wasm::Pipeline from an itk::TransformIOBaseTemplate
77+
*
78+
* This transform is written to the filesystem or memory when it goes out of scope.
79+
*
80+
* This class is for the ReadTransform ITK-Wasm pipeline. Most pipelines will use itk::wasm::OutputTransform.
81+
*
82+
* \ingroup WebAssemblyInterface
83+
*/
84+
template <typename TParametersValueType>
85+
class OutputTransformIO
86+
{
87+
public:
88+
using ParametersValueType = TParametersValueType;
89+
using TransformIOBaseType = itk::TransformIOBaseTemplate<ParametersValueType>;
90+
91+
void Set(TransformIOBaseType * transformIO) {
92+
this->m_TransformIO = transformIO;
93+
}
94+
95+
TransformIOBaseType * Get() const {
96+
return this->m_TransformIO.GetPointer();
97+
}
98+
99+
/** FileName or output index. */
100+
void SetIdentifier(const std::string & identifier)
101+
{
102+
this->m_Identifier = identifier;
103+
}
104+
const std::string & GetIdentifier() const
105+
{
106+
return this->m_Identifier;
107+
}
108+
109+
OutputTransformIO() = default;
110+
~OutputTransformIO() {
111+
if(wasm::Pipeline::get_use_memory_io())
112+
{
113+
#ifndef ITK_WASM_NO_MEMORY_IO
114+
if (!this->m_TransformIO.IsNull() && !this->m_Identifier.empty())
115+
{
116+
const auto index = std::stoi(this->m_Identifier);
117+
auto wasmTransformIOBase = WasmTransformIOBase<ParametersValueType>::New();
118+
wasmTransformIOBase->SetTransformIO(this->m_TransformIO);
119+
setMemoryStoreOutputDataObject(0, index, wasmTransformIOBase);
120+
121+
const auto transformListJSON = wasmTransformIOBase->GetTransformListJSON();
122+
123+
if (transformListJSON.size() > 0)
124+
{
125+
addTransformBuffersToMemoryStore<ParametersValueType>(transformListJSON, index);
126+
}
127+
}
128+
#else
129+
std::cerr << "Memory IO not supported" << std::endl;
130+
abort();
131+
#endif
132+
}
133+
else
134+
{
135+
#ifndef ITK_WASM_NO_FILESYSTEM_IO
136+
if (!this->m_TransformIO.IsNull() && !this->m_Identifier.empty())
137+
{
138+
this->m_TransformIO->Read();
139+
140+
using WasmTransformIOType = itk::WasmTransformIOTemplate<ParametersValueType>;
141+
auto wasmTransformIO = WasmTransformIOType::New();
142+
143+
wasmTransformIO->SetTransformList(*(reinterpret_cast<typename WasmTransformIOType::ConstTransformListType *>(&(this->m_TransformIO->GetTransformList()))));
144+
wasmTransformIO->SetFileName(this->m_Identifier);
145+
wasmTransformIO->Write();
146+
}
147+
#else
148+
std::cerr << "Filesystem IO not supported" << std::endl;
149+
abort();
150+
#endif
151+
}
152+
}
153+
protected:
154+
typename TransformIOBaseType::Pointer m_TransformIO;
155+
156+
std::string m_Identifier;
157+
};
158+
159+
template<typename TParametersValueType>
160+
bool lexical_cast(const std::string &input, OutputTransformIO<TParametersValueType> &outputTransformIO)
161+
{
162+
outputTransformIO.SetIdentifier(input);
163+
return true;
164+
}
165+
166+
} // namespace wasm
167+
} // namespace itk
168+
169+
#endif

include/itkWasmMeshIO.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,11 @@ namespace itk
3232
* \brief Read and write the an itk::Mesh in a format for interfacing in WebAssembly (Wasm).
3333
*
3434
* This format is intended to facilitate data exchange in itk-wasm.
35-
* It reads and writes an itk-wasm Mesh object where TypedArrays are
35+
* It reads and writes an ITK-Wasm Mesh object where TypedArrays are
3636
* replaced by binary files on the filesystem or in a CBOR file.
3737
*
3838
* The file extensions used are .iwm and .iwm.cbor.
39-
*
39+
*
4040
* \ingroup IOFilters
4141
* \ingroup WebAssemblyInterface
4242
*/

include/itkWasmTransformIO.h

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class ITK_TEMPLATE_EXPORT WasmTransformIOTemplate : public TransformIOBaseTempla
8686
#if !defined(ITK_WRAPPING_PARSER)
8787
/** Get the JSON representation of the mesh information. */
8888
auto
89-
GetJSON() -> TransformListJSON;
89+
GetJSON(bool inMemory=false) -> TransformListJSON;
9090
#endif
9191

9292
protected:
@@ -95,7 +95,7 @@ class ITK_TEMPLATE_EXPORT WasmTransformIOTemplate : public TransformIOBaseTempla
9595
void
9696
PrintSelf(std::ostream & os, Indent indent) const override;
9797

98-
auto
98+
virtual auto
9999
ReadTransformInformation() -> const TransformListJSON;
100100
void
101101
ReadFixedParameters(const TransformListJSON & json);
@@ -109,12 +109,8 @@ class ITK_TEMPLATE_EXPORT WasmTransformIOTemplate : public TransformIOBaseTempla
109109
void
110110
WriteParameters();
111111

112-
/** Reads in the transform information and populates the related buffers. */
113-
void
114-
ReadCBOR();
115-
/** Writes the buffers into the CBOR item and the buffer out to disk. */
116-
void
117-
WriteCBOR();
112+
void ReadCBOR(void * buffer = nullptr, unsigned char * cborBuffer = nullptr, size_t cborBufferLength = 0);
113+
size_t WriteCBOR(const void * buffer = nullptr, unsigned char ** cborBuffer = nullptr, bool allocateCBORBuffer = false);
118114

119115
cbor_item_t * m_CBORRoot{ nullptr };
120116

0 commit comments

Comments
 (0)