CVB++ 15.0
detail_buffer_image.hpp
1#pragma once
2
3#include "../../global.hpp"
4
5#include "../../_decl/decl_device.hpp"
6#include "../../_decl/decl_image_plane.hpp"
7#include "../../_decl/decl_vpat.hpp"
8
9#include "../_decl/decl_buffer_image.hpp"
10
11namespace Cvb
12{
13
14 CVB_BEGIN_INLINE_NS
15
16 namespace Driver
17 {
18
19 inline std::unique_ptr<BufferImage::ImageLayout> BufferImage::ImageLayout::FromImage(const Image &image)
20 {
21 std::unique_ptr<ImageLayout> layout;
22 auto linearLayout = BufferImage::LinearLayout::TryCreate(image);
23 if (linearLayout)
24 layout.reset(linearLayout.release());
25 else
26 layout = std::make_unique<BufferImage::NonLinearLayout>();
27 return layout;
28 }
29
30 inline std::unique_ptr<BufferImage::ImageLayout> BufferImage::ImageLayout::FromIMGHandle(void *handle)
31 {
32 BufferImage::HandleImage image(handle);
33 return FromImage(image);
34 }
35
36 inline void *BufferImage::ImageLayout::CloneIMGHandle(void *handle) const
37 {
38 BufferImage::HandleImage image(handle);
39 return CloneImage(image);
40 }
41
42 inline std::unique_ptr<BufferImage> BufferImage::Create(const DevicePtr &device,
43 const BufferImage::ImageLayout &layout, double rawTimestamp)
44 {
45 HandleGuard<Image> guard(layout.CloneIMGHandle(device->Handle()));
46 return std::make_unique<BufferImage>(std::move(guard), device, rawTimestamp, PrivateTag{});
47 }
48
49 inline std::unique_ptr<BufferImage> BufferImage::Create(const DevicePtr &device, double rawTimestamp)
50 {
51 return Create(device, *ImageLayout::FromIMGHandle(device->Handle()), rawTimestamp);
52 }
53
54 inline std::unique_ptr<BufferImage::LinearLayout> BufferImage::LinearLayout::TryCreate(const Image &image) noexcept
55 {
56 try
57 {
58 if (!image.PlaneDataTypesIdentical())
59 return std::unique_ptr<LinearLayout>();
60
61 auto numPlanes = image.PlanesCount();
62 std::vector<LinearAccessData> planeData(numPlanes);
63 std::vector<PlaneIndexPair> planeBases(numPlanes);
64 for (int i = 0; i < static_cast<int>(planeData.size()); ++i)
65 {
66 if (!image.Plane(i).TryLinearAccess(planeData[i]))
67 return std::unique_ptr<LinearLayout>();
68
69 if (i > 0 && (planeData[i].XInc() != planeData[0].XInc() || planeData[i].YInc() != planeData[i].YInc()))
70 return std::unique_ptr<LinearLayout>();
71
72 planeBases[i].BasePtr = planeData[i].BasePtr();
73 planeBases[i].PlaneIndex = i;
74 }
75
76 std::intptr_t planeInc = 0;
77 if (numPlanes > 1)
78 {
79 std::sort(planeBases.begin(), planeBases.end(),
80 [](const PlaneIndexPair &a, const PlaneIndexPair &b) { return a.BasePtr < b.BasePtr; });
81 planeInc = planeBases[1].BasePtr - planeBases[0].BasePtr;
82 for (int i = 2; i < numPlanes; ++i)
83 if ((planeBases[i].BasePtr - planeBases[i - 1].BasePtr) != planeInc)
84 return std::unique_ptr<LinearLayout>();
85 }
86
87 return std::make_unique<LinearLayout>(
88 static_cast<size_t>(numPlanes) * static_cast<size_t>(image.Height()) * static_cast<size_t>(image.Width())
89 * static_cast<size_t>(image.Plane(0).DataType().BytesPerPixel()),
90 planeData[0].XInc(), planeData[0].YInc(), planeInc, planeBases, PrivateTag{});
91 }
92 catch (...)
93 {
94 return std::unique_ptr<LinearLayout>();
95 }
96 }
97
98 inline void *BufferImage::LinearLayout::CloneImage(const Image &image) const
99 {
100 LinearAccessData linearAccess;
101 image.Plane(0).TryLinearAccess(linearAccess);
102 CExports::IMG img = nullptr;
103 auto result = CVB_CALL_CAPI(CreateImageFromPointer(
104 reinterpret_cast<void *>(linearAccess.BasePtr()), memSize_, static_cast<CExports::cvbdim_t>(image.Width()),
105 static_cast<CExports::cvbdim_t>(image.Height()), static_cast<CExports::cvbdim_t>(planeOrder_.size()),
106 static_cast<CExports::cvbdatatype_t>(image.Plane(0).DataType().NativeDescriptor()), xInc_, yInc_, planeInc_,
107 const_cast<CExports::cvbval_t *>(&planeOrder_[0]), // NOLINT(cppcoreguidelines-pro-type-const-cast)
108 nullptr, nullptr, img));
109 if (result < 0)
110 Utilities::SystemInfo::ThrowLastError(result);
111
112 return img;
113 }
114
115 inline void *BufferImage::NonLinearLayout::MakeImageFromPlane(const ImagePlane &plane) const
116 {
117 auto width = plane.Parent().Width();
118 auto height = plane.Parent().Height();
119 auto dataType = plane.DataType();
120 auto memSize =
121 static_cast<size_t>(width) * static_cast<size_t>(height) * static_cast<size_t>(dataType.BytesPerPixel());
122 auto vpat = plane.Vpat();
123 CExports::IMG img = nullptr;
124
125 CVB_CALL_CAPI(CreateImageFromPointer(reinterpret_cast<void *>(vpat.BasePtr()), memSize,
126 static_cast<CExports::cvbdim_t>(width),
127 static_cast<CExports::cvbdim_t>(height), static_cast<CExports::cvbdim_t>(1),
128 static_cast<CExports::cvbdatatype_t>(dataType.NativeDescriptor()), 1, height,
129 0, nullptr, nullptr, nullptr, img));
130
131 try
132 {
133#ifdef max
134# undef max
135#endif
136 HandleImage image(img);
137 auto targetVpat = image.Plane(0).Vpat().VpatPtr();
138 auto sourceVpat = vpat.VpatPtr();
139 auto vpatSize = std::max(width, height);
140 for (int e = 0; e < vpatSize; ++e)
141 targetVpat[e] = sourceVpat[e];
142 return img;
143 }
144 catch (...)
145 {
146 std::rethrow_exception(std::current_exception());
147 }
148 }
149
150 inline void *BufferImage::NonLinearLayout::CloneImage(const Image &image) const
151 {
152 if (image.PlanesCount() == 1)
153 return MakeImageFromPlane(image.Plane(0));
154
155 std::vector<CExports::IMG> resultIMGs(image.PlanesCount());
156 std::fill(resultIMGs.begin(), resultIMGs.end(), nullptr);
157 ImageArrayGuard imageGuard(resultIMGs);
158
159 for (size_t i = 0; i < resultIMGs.size(); ++i)
160 resultIMGs[i] = MakeImageFromPlane(image.Plane(static_cast<int>(i)));
161
162 CExports::IMG concatIMG = nullptr;
163 if (!CVB_CALL_CAPI(CreateConcatenatedImage(&resultIMGs[0], resultIMGs.size(), true, concatIMG)))
164 Utilities::SystemInfo::ThrowLastError();
165 return concatIMG;
166 }
167
168 } // namespace Driver
169
170 CVB_END_INLINE_NS
171
172} // namespace Cvb
Image(Size2D< int > size, int numPlanes=1, DataType dataType=DataType::Int8BppUnsigned())
Constructs an uninitialized image with the given parameters.
Definition decl_image.hpp:197
cvbbool_t CreateConcatenatedImage(IMG *ImageArray, size_t ArrayLength, cvbbool_t ShareMemory, IMG &ImageOut)
cvbres_t CreateImageFromPointer(void *pImageMemory, size_t MemorySize, cvbdim_t Width, cvbdim_t Height, cvbdim_t NumPlanes, cvbdatatype_t DataType, intptr_t PitchX, intptr_t PitchY, intptr_t PitchPlane, const cvbval_t PlaneOrder[], PFFINALRELEASE ReleaseCallback, void *pPrivate, IMG &ImageOut)
Namespace for driver or device related operations.
Definition decl_composite.hpp:28
Root namespace for the Image Manager interface.
Definition c_bayer_to_rgb.h:17
std::shared_ptr< Device > DevicePtr
Convenience shared pointer for Device.
Definition global.hpp:98