IDS peak genericC++  v1.7.0
peak_buffer_converter_ipl.hpp
Go to the documentation of this file.
1 
11 #pragma once
12 
13 
14 #include <peak_ipl/peak_ipl.hpp>
18 
19 #include <cassert>
20 
21 
22 namespace peak
23 {
24 
36 template <>
37 inline peak::ipl::Image BufferTo<peak::ipl::Image>(const std::shared_ptr<peak::core::Buffer>& buffer)
38 {
39  if (buffer == nullptr)
40  {
41  throw core::InvalidArgumentException("The given buffer is a nullptr!");
42  }
43 
44  if (buffer->HasImage())
45  {
46  assert(buffer->PixelFormatNamespace() != core::PixelFormatNamespace::IIDC
47  && buffer->PixelFormatNamespace() != core::PixelFormatNamespace::Custom);
48 
49  size_t usableHeight = buffer->Height();
50  const size_t usableWidth = buffer->Width();
51  size_t usableBytes = buffer->Size() - buffer->ImageOffset();
52  uint8_t* firstPixelPtr = static_cast<uint8_t*>(buffer->BasePtr()) + buffer->ImageOffset();
53 
54  if (buffer->HasChunks())
55  {
56  auto chunks = buffer->Chunks();
57 
58  if (chunks.empty())
59  {
60  throw core::InternalErrorException("Buffer has no chunks.");
61  }
62 
63  const auto imageSizeWithoutChunks = chunks[0]->Size();
64 
65  for (const auto& chunk : chunks)
66  {
67  if (0x73020405 == chunk->ID())
68  {
69  uint16_t* chunkBase = static_cast<uint16_t*>(chunk->BasePtr());
70 
71  usableHeight = static_cast<size_t>(chunkBase[1]);
72  const auto usableOffsetY = static_cast<size_t>(chunkBase[3]);
73 
74  // Pitch per line
75  const auto pitch = imageSizeWithoutChunks / buffer->Height();
76  const auto cutOffTop = pitch * usableOffsetY;
77  const auto cutOff = (buffer->Height() - usableHeight) * pitch;
78 
79  firstPixelPtr += cutOffTop;
80  usableBytes = imageSizeWithoutChunks - cutOff;
81 
82  break;
83  }
84  }
85  }
86 
87  return peak::ipl::Image(static_cast<peak::ipl::PixelFormatName>(buffer->PixelFormat()),
88  firstPixelPtr, usableBytes, usableWidth, usableHeight, buffer->Timestamp_ns());
89  }
90  else if (buffer->PayloadType() == core::BufferPayloadType::Chunk)
91  {
92  auto remoteNodeMap = buffer->ParentDataStream()->ParentDevice()->RemoteDevice()->NodeMaps()[0];
93  remoteNodeMap->UpdateChunkNodes(buffer);
94 
95  auto chunkWidth = remoteNodeMap->FindNode<core::nodes::IntegerNode>("ChunkWidth");
96  if (chunkWidth->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
97  {
98  throw core::InvalidCastException("Buffer has no ChunkWidth.");
99  }
100  auto width = chunkWidth->Value();
101 
102  auto chunkHeight = remoteNodeMap->FindNode<core::nodes::IntegerNode>("ChunkHeight");
103  if (chunkHeight->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
104  {
105  throw core::InvalidCastException("Buffer has no ChunkHeight.");
106  }
107  auto height = chunkHeight->Value();
108 
109  auto chunkPixelFormat = remoteNodeMap->FindNode<core::nodes::EnumerationNode>("ChunkPixelFormat");
110  if (chunkPixelFormat->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
111  {
112  throw core::InvalidCastException("Buffer has no ChunkPixelFormat.");
113  }
114  auto pixelFormatValue = chunkPixelFormat->CurrentEntry()->NumericValue();
115  auto pixelFormat = static_cast<peak::ipl::PixelFormatName>(pixelFormatValue);
116 
117  // assume first chunks is image data
118  auto imageData = buffer->Chunks()[0];
119 
120  auto expectedDataSize = peak::ipl::PixelFormat(pixelFormat).CalculateStorageSizeOfPixels(static_cast<uint64_t>(width * height));
121  if (imageData->Size() < expectedDataSize)
122  {
123  std::stringstream msg;
124  msg << "The buffer's first chunk's size (" << imageData->Size()
125  << ") is smaller than the expected data size (" << expectedDataSize << ").";
126  throw core::InvalidCastException(msg.str());
127  }
128 
129  return peak::ipl::Image(pixelFormat, static_cast<uint8_t*>(imageData->BasePtr()), imageData->Size(),
130  static_cast<size_t>(width), static_cast<size_t>(height), buffer->Timestamp_ns());
131  }
132  else
133  {
134  throw core::InvalidCastException("Buffer has no image data and no chunks.");
135  }
136 }
137 
138 } /* namespace peak */
Represents a GenAPI integer node.
Definition: peak_integer_node.hpp:35
The exception thrown for pass an invalid argument to a function.
Definition: peak_exception.hpp:73
The "peak" namespace directly contains convenience functionality like the DeviceManager as well as th...
Definition: peak_dynamic_loader.h:32
The exception thrown for trying to apply an invalid cast.
Definition: peak_exception.hpp:81
The exception thrown for internal errors.
Definition: peak_exception.hpp:57
Represents a GenAPI enumeration node.
Definition: peak_enumeration_node.hpp:36