IDS peak genericC++  v1.4.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<core::Buffer>& buffer)
38 {
39  if (buffer->HasImage())
40  {
41  assert(buffer->PixelFormatNamespace() != core::PixelFormatNamespace::IIDC
42  && buffer->PixelFormatNamespace() != core::PixelFormatNamespace::Custom);
43 
44  size_t usableHeight = buffer->Height();
45  size_t cutOff = 0;
46 
47  if (buffer->HasChunks())
48  {
49  auto chunks = buffer->Chunks();
50  for (const auto& chunk : chunks)
51  {
52  if (0x73020405 == chunk->ID())
53  {
54  uint16_t* chunkBase = static_cast<uint16_t*>(chunk->BasePtr());
55 
56  usableHeight = static_cast<size_t>(chunkBase[1]);
57  size_t usableOffsetY = static_cast<size_t>(chunkBase[3]);
58 
59  // Pitch per line
60  size_t pitch = buffer->Size() / buffer->Height();
61  cutOff = pitch * usableOffsetY;
62 
63  break;
64  }
65  }
66  }
67 
68  return peak::ipl::Image(static_cast<peak::ipl::PixelFormatName>(buffer->PixelFormat()),
69  static_cast<uint8_t*>(buffer->BasePtr()) + buffer->ImageOffset() + cutOff, buffer->Size() - buffer->ImageOffset() - cutOff,
70  buffer->Width(), usableHeight);
71  }
72  else if (buffer->PayloadType() == core::BufferPayloadType::Chunk)
73  {
74  auto remoteNodeMap = buffer->ParentDataStream()->ParentDevice()->RemoteDevice()->NodeMaps()[0];
75  remoteNodeMap->UpdateChunkNodes(buffer);
76 
77  auto chunkWidth = remoteNodeMap->FindNode<core::nodes::IntegerNode>("ChunkWidth");
78  if (chunkWidth->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
79  {
80  throw core::InvalidCastException("Buffer has no ChunkWidth.");
81  }
82  auto width = chunkWidth->Value();
83 
84  auto chunkHeight = remoteNodeMap->FindNode<core::nodes::IntegerNode>("ChunkHeight");
85  if (chunkHeight->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
86  {
87  throw core::InvalidCastException("Buffer has no ChunkHeight.");
88  }
89  auto height = chunkHeight->Value();
90 
91  auto chunkPixelFormat = remoteNodeMap->FindNode<core::nodes::EnumerationNode>("ChunkPixelFormat");
92  if (chunkPixelFormat->AccessStatus() == core::nodes::NodeAccessStatus::NotAvailable)
93  {
94  throw core::InvalidCastException("Buffer has no ChunkPixelFormat.");
95  }
96  auto pixelFormatValue = chunkPixelFormat->CurrentEntry()->NumericValue();
97  auto pixelFormat = static_cast<peak::ipl::PixelFormatName>(pixelFormatValue);
98 
99  // assume first chunks is image data
100  auto imageData = buffer->Chunks()[0];
101 
102  auto expectedDataSize = peak::ipl::PixelFormat(pixelFormat).CalculateStorageSizeOfPixels(width * height);
103  if (imageData->Size() < expectedDataSize)
104  {
105  std::stringstream msg;
106  msg << "The buffer's first chunk's size (" << imageData->Size()
107  << ") is smaller than the expected data size (" << expectedDataSize << ").";
108  throw core::InvalidCastException(msg.str());
109  }
110 
111  return peak::ipl::Image(pixelFormat, static_cast<uint8_t*>(imageData->BasePtr()), imageData->Size(),
112  static_cast<size_t>(width), static_cast<size_t>(height));
113  }
114  else
115  {
116  throw core::InvalidCastException("Buffer has no image data and no chunks.");
117  }
118 }
119 
120 } /* namespace peak */
Represents a GenAPI integer node.
Definition: peak_integer_node.hpp:35
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
Represents a GenAPI enumeration node.
Definition: peak_enumeration_node.hpp:36