IDS peak genericC++ v1.13.0
Loading...
Searching...
No Matches
peak_image_view_impl.hpp
Go to the documentation of this file.
1
10
11#pragma once
12
13#include "peak_image_view.hpp"
14
17
24
25#include <memory>
26
27namespace peak
28{
29namespace core
30{
31
32namespace detail
33{
34
35inline ExtractedPayload ExtractPayloadTypeImage(const std::shared_ptr<peak::core::Buffer>& buffer)
36{
37 assert(buffer->PixelFormatNamespace() != core::PixelFormatNamespace::IIDC
38 && buffer->PixelFormatNamespace() != core::PixelFormatNamespace::Custom);
39
40 auto usableHeight = static_cast<uint32_t>(buffer->Height());
41 const auto usableWidth = static_cast<uint32_t>(buffer->Width());
42 const auto pixelFormatInfo = peak::common::PixelFormatInfo(static_cast<peak::common::PixelFormat>(buffer->PixelFormat()));
43 const auto imageSizeWithPadding = buffer->Size() - buffer->ImageOffset();
44 auto usableBytes = pixelFormatInfo.GetSizeInBytes({usableWidth, usableHeight});
45
46 if (usableBytes > imageSizeWithPadding)
47 {
48 throw InternalErrorException("Buffer is not large enough to fit the expected image size!");
49 }
50 auto* firstPixelPtr = static_cast<uint8_t*>(buffer->BasePtr()) + buffer->ImageOffset();
51
52 if (buffer->HasChunks())
53 {
54 auto chunks = buffer->Chunks();
55
56 if (chunks.empty())
57 {
58 throw core::InternalErrorException("Buffer has no chunks.");
59 }
60
61 const auto imageSizeWithPaddingWithoutChunks = chunks[0]->Size();
62
63 for (const auto& chunk : chunks)
64 {
65 if (0x73020405 == chunk->ID())
66 {
67 const auto* chunkBase = static_cast<uint16_t*>(chunk->BasePtr());
68
69 usableHeight = static_cast<uint32_t>(chunkBase[1]);
70 const auto usableOffsetX = static_cast<size_t>(chunkBase[2]);
71 if (usableOffsetX != 0)
72 {
74 "Buffer has a non-zero 'UsableOffsetX', which is not supported!");
75 }
76 const auto usableOffsetY = static_cast<size_t>(chunkBase[3]);
77
78
79 const auto pitch = imageSizeWithPaddingWithoutChunks / buffer->Height();
80 const auto cutOffTop = pitch * usableOffsetY;
81
82 firstPixelPtr += cutOffTop;
83 // NOTE: The chunk size may contain padding bytes, so we need
84 // to calculate the usable bytes from the width, height,
85 // and pixel format.
86 usableBytes = pixelFormatInfo.GetSizeInBytes({ usableWidth, usableHeight });
87 if (usableBytes > imageSizeWithPaddingWithoutChunks)
88 {
89 throw InternalErrorException("Chunk size is not large enough to fit the expected image size!");
90 }
91
92 break;
93 }
94 }
95 }
96
97 return { { usableWidth, usableHeight }, static_cast<peak::common::PixelFormat>(buffer->PixelFormat()),
98 static_cast<void*>(firstPixelPtr), usableBytes };
99}
100
101inline ExtractedPayload ExtractPayloadTypeChunk(const std::shared_ptr<peak::core::Buffer>& buffer)
102{
103 const auto remoteNodeMap = buffer->ParentDataStream()->ParentDevice()->RemoteDevice()->NodeMaps().at(0);
104 remoteNodeMap->UpdateChunkNodes(buffer);
105
106 const auto chunkWidth = remoteNodeMap->FindNode<core::nodes::IntegerNode>("ChunkWidth");
107 if (chunkWidth->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
108 {
109 throw core::InvalidCastException("Buffer has no ChunkWidth.");
110 }
111
112 const auto chunkHeight = remoteNodeMap->FindNode<core::nodes::IntegerNode>("ChunkHeight");
113 if (chunkHeight->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
114 {
115 throw core::InvalidCastException("Buffer has no ChunkHeight.");
116 }
117
118 const peak::common::Size size(
119 static_cast<uint32_t>(chunkWidth->Value()), static_cast<uint32_t>(chunkHeight->Value()));
120
121 const auto chunkPixelFormat = remoteNodeMap->FindNode<core::nodes::EnumerationNode>("ChunkPixelFormat");
122 if (chunkPixelFormat->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
123 {
124 throw core::InvalidCastException("Buffer has no ChunkPixelFormat.");
125 }
126
127 const auto pixelFormat = static_cast<peak::common::PixelFormat>(
128 chunkPixelFormat->CurrentEntry()->NumericValue());
129
130 // assume first chunks is image data
131 const auto imageData = buffer->Chunks().at(0);
132 const auto rawData = imageData->BasePtr();
133 const auto sizeInBytes = imageData->Size();
134
135 const auto pixelFormatInfo = peak::common::PixelFormatInfo(pixelFormat);
136 const auto expectedDataSize = pixelFormatInfo.GetSizeInBytes(size);
137 if (sizeInBytes < expectedDataSize)
138 {
139 std::stringstream msg;
140 msg << "The buffer's first chunk's size (" << imageData->Size() << ") is smaller than the expected data size ("
141 << expectedDataSize << ").";
142 throw core::InvalidCastException(msg.str());
143 }
144
145 return { size, pixelFormat, rawData, sizeInBytes };
146}
147
148inline ExtractedPayload ExtractPayloadFromBufferPart(const std::shared_ptr<core::BufferPart>& part)
149{
150 if (part == nullptr)
151 {
152 throw core::InvalidArgumentException("The given part is a nullptr!");
153 }
154
155 const auto partType = part->Type();
156
158 && partType != core::BufferPartType::Image3D)
159 {
160 throw core::InvalidCastException("BufferPart has no image data.");
161 }
162
163 assert(part->FormatNamespace() != static_cast<uint64_t>(core::PixelFormatNamespace::IIDC)
164 && part->FormatNamespace() != static_cast<uint64_t>(core::PixelFormatNamespace::Custom));
165
166 return { peak::common::Size{ static_cast<uint32_t>(part->Width()), static_cast<uint32_t>(part->Height()) },
167 static_cast<peak::common::PixelFormat>(part->Format()), part->BasePtr(), part->Size() };
168}
169
170inline ExtractedPayload ExtractPayloadFromBuffer(const std::shared_ptr<peak::core::Buffer>& buffer)
171{
172 if (buffer == nullptr)
173 {
174 throw core::InvalidArgumentException("The given buffer is a nullptr!");
175 }
176
177 if (buffer->HasImage())
178 {
179 return ExtractPayloadTypeImage(buffer);
180 }
181
182 if (buffer->PayloadType() == core::BufferPayloadType::Chunk)
183 {
184 return ExtractPayloadTypeChunk(buffer);
185 }
186
187 throw core::InvalidCastException("Buffer has no image data and no chunks.");
188}
189
190inline std::shared_ptr<peak::common::Metadata> ExtractMetadataFromBuffer(const std::shared_ptr<core::Buffer>& buffer)
191{
192 if (buffer == nullptr)
193 {
194 throw core::InvalidArgumentException("The given buffer is a nullptr!");
195 }
196
197 auto metadata = std::make_shared<peak::common::Metadata>();
198
199 // NOTE: We need to try, as the timestamp might not be supported by the TL.
200 try
201 {
202 metadata->SetValueByKey<peak::common::MetadataKey::DeviceFrameID>(buffer->FrameID());
203 metadata->SetValueByKey<peak::common::MetadataKey::DeviceTimestamp>(buffer->Timestamp_ns());
204 }
206 {}
208 {}
209
210 return metadata;
211}
212
213} // namespace detail
214
215inline ImageView::ImageView(const detail::ExtractedPayload& payload, std::shared_ptr<peak::common::Metadata> metadata)
216 : m_metadata{ std::move(metadata) }
217 , m_payload{ payload }
218{}
219
220inline ImageView::ImageView(const std::shared_ptr<peak::core::Buffer>& buffer)
221 : ImageView(detail::ExtractPayloadFromBuffer(buffer), detail::ExtractMetadataFromBuffer(buffer))
222{
223 m_parentBuffer = buffer;
224}
225
226inline ImageView::ImageView(const std::shared_ptr<core::BufferPart>& part)
227 : ImageView(detail::ExtractPayloadFromBufferPart(part), detail::ExtractMetadataFromBuffer(part->ParentBuffer()))
228{
229 m_parentBuffer = part->ParentBuffer();
230}
231
232inline const uint8_t* ImageView::GetData() const
233{
234 return static_cast<uint8_t*>(m_payload.dataPtr);
235}
236
237inline uint8_t* ImageView::GetData()
238{
239 return static_cast<uint8_t*>(m_payload.dataPtr);
240}
241
242inline std::size_t ImageView::GetSizeInBytes() const
243{
244 return m_payload.dataSize;
245}
246
248{
249 return m_payload.pixelFormat;
250}
251
253{
254 return peak::common::PixelFormatInfo(m_payload.pixelFormat);
255}
256
258{
259 return m_payload.size;
260}
261
262inline uint32_t ImageView::GetWidth() const
263{
264 return m_payload.size.GetWidth();
265}
266
267inline uint32_t ImageView::GetHeight() const
268{
269 return m_payload.size.GetHeight();
270}
271
272inline size_t ImageView::GetBitsPerPixel() const
273{
274 return peak::common::PixelFormatInfo(m_payload.pixelFormat).GetAllocatedBitsPerPixel();
275}
276
277inline size_t ImageView::GetBytesPerLine() const
278{
279 const auto pixelformatInfo = peak::common::PixelFormatInfo(m_payload.pixelFormat);
280
281 return pixelformatInfo.GetSizeInBytes(m_payload.size) / m_payload.size.GetHeight();
282}
283
284inline std::shared_ptr<peak::common::Metadata> ImageView::GetMetadata()
285{
286 return m_metadata;
287}
288
289inline std::shared_ptr<const peak::common::Metadata> ImageView::GetMetadata() const
290{
291 return m_metadata;
292}
293
294inline std::shared_ptr<peak::core::Buffer> ImageView::GetParentBuffer() const
295{
296 return LockOrThrow(m_parentBuffer);
297}
298
299} // namespace core
300} // namespace peak
Provides information and utility functions for pixel formats.
Definition peak_common_pixel_format.hpp:140
PEAK_COMMON_NO_DISCARD size_t GetAllocatedBitsPerPixel() const
Returns the number of allocated bits per pixel.
Definition peak_common_pixel_format.hpp:2596
PEAK_COMMON_NO_DISCARD constexpr T GetWidth() const
Returns the width.
Definition peak_common_size.hpp:119
PEAK_COMMON_NO_DISCARD uint32_t GetHeight() const override
Height of the image in pixels.
Definition peak_image_view_impl.hpp:267
PEAK_COMMON_NO_DISCARD std::size_t GetSizeInBytes() const override
Size of the image in bytes.
Definition peak_image_view_impl.hpp:242
PEAK_COMMON_NO_DISCARD size_t GetBytesPerLine() const override
The amount of bytes per line.
Definition peak_image_view_impl.hpp:277
PEAK_COMMON_NO_DISCARD peak::common::PixelFormatInfo GetPixelFormatInfo() const override
Information object for the PixelFormat of the contained image.
Definition peak_image_view_impl.hpp:252
PEAK_COMMON_NO_DISCARD size_t GetBitsPerPixel() const override
The amount of bits in one pixel.
Definition peak_image_view_impl.hpp:272
PEAK_COMMON_NO_DISCARD std::shared_ptr< peak::core::Buffer > GetParentBuffer() const
The parent buffer object, the image view was created from.
Definition peak_image_view_impl.hpp:294
PEAK_COMMON_NO_DISCARD uint32_t GetWidth() const override
Width of the image in pixels.
Definition peak_image_view_impl.hpp:262
PEAK_COMMON_NO_DISCARD const uint8_t * GetData() const override
Get pointer to the first byte of the image (read-only).
Definition peak_image_view_impl.hpp:232
ImageView(const std::shared_ptr< Buffer > &buffer)
Construct an ImageView from a Buffer.
Definition peak_image_view_impl.hpp:220
PEAK_COMMON_NO_DISCARD peak::common::PixelFormat GetPixelFormat() const override
PixelFormat of the contained image.
Definition peak_image_view_impl.hpp:247
PEAK_COMMON_NO_DISCARD peak::common::Size GetSize() const override
Get the dimensions of the image. I.e. Width, Height, etc.
Definition peak_image_view_impl.hpp:257
PEAK_COMMON_NO_DISCARD std::shared_ptr< peak::common::Metadata > GetMetadata() override
The metadata object belonging to the image.
Definition peak_image_view_impl.hpp:284
The exception thrown for internal errors.
Definition peak_exception.hpp:81
The exception thrown for passing an invalid argument to a function.
Definition peak_exception.hpp:116
The exception thrown for trying to apply an invalid cast.
Definition peak_exception.hpp:142
The exception thrown for signaling that a feature is not available in the device.
Definition peak_exception.hpp:177
The exception thrown for signaling a feature is not implemented.
Definition peak_exception.hpp:195
Represents a GenAPI enumeration node.
Definition peak_enumeration_node.hpp:40
Represents a GenAPI integer node.
Definition peak_integer_node.hpp:38
@ Image3D
Definition peak_buffer_part.hpp:42
@ ConfidenceMap
Definition peak_buffer_part.hpp:46
@ Image2D
Definition peak_buffer_part.hpp:38
@ Chunk
Definition peak_buffer.hpp:48
@ Custom
Definition peak_buffer.hpp:72
@ IIDC
Definition peak_buffer.hpp:68
detail::SizeT< uint32_t > Size
Size with unsigned 32-bit integer dimensions.
Definition peak_common_size.hpp:273
PixelFormat
Enum listing all supported pixel formats and their internal IDs.
Definition peak_common_pixel_format.hpp:44
@ NotAvailable
Definition peak_node.hpp:48
@ DeviceTimestamp
Device-provided image acquisition timestamp in nanoseconds.
Definition peak_common_metadata_key.hpp:44
@ DeviceFrameID
A sequentially incremented identifier for the frame.
Definition peak_common_metadata_key.hpp:57
Definition peak_image_view.hpp:31
std::shared_ptr< peak::common::Metadata > ExtractMetadataFromBuffer(const std::shared_ptr< core::Buffer > &buffer)
Definition peak_image_view_impl.hpp:190
ExtractedPayload ExtractPayloadFromBuffer(const std::shared_ptr< peak::core::Buffer > &buffer)
Definition peak_image_view_impl.hpp:170
ExtractedPayload ExtractPayloadTypeChunk(const std::shared_ptr< peak::core::Buffer > &buffer)
Definition peak_image_view_impl.hpp:101
ExtractedPayload ExtractPayloadFromBufferPart(const std::shared_ptr< core::BufferPart > &part)
Definition peak_image_view_impl.hpp:148
ExtractedPayload ExtractPayloadTypeImage(const std::shared_ptr< peak::core::Buffer > &buffer)
Definition peak_image_view_impl.hpp:35
The "core" namespace contains the direct GenAPI and GenTL wrapper.
Definition peak_buffer.hpp:34
The "peak" namespace directly contains convenience functionality like the DeviceManager as well as th...
Definition peak_dynamic_loader.h:33
Definition peak_image_view.hpp:33