1
+ /*
2
+ * SPDX-FileCopyrightText: 2024-2024 Istituto Italiano di Tecnologia (IIT)
3
+ * SPDX-License-Identifier: BSD-3-Clause
4
+ */
5
+
6
+ #include < yarp/sig/Image.h>
7
+ #include < yarp/sig/ImageNetworkHeader.h>
8
+
9
+ #include < yarp/os/Bottle.h>
10
+ #include < yarp/os/ConnectionReader.h>
11
+ #include < yarp/os/ConnectionWriter.h>
12
+ #include < yarp/os/Log.h>
13
+ #include < yarp/os/Time.h>
14
+ #include < yarp/os/Vocab.h>
15
+ #include < yarp/os/LogStream.h>
16
+
17
+ #include < yarp/sig/LayeredImage.h>
18
+ #include < yarp/sig/ImageUtils.h>
19
+
20
+ #include < cstdio>
21
+ #include < cstring>
22
+ #include < string>
23
+ #include < utility>
24
+
25
+ #include < opencv2/opencv.hpp>
26
+
27
+ using namespace yarp ::sig;
28
+ using namespace yarp ::os;
29
+
30
+ inline void writeToConnection (const Image& img, ConnectionWriter& connection)
31
+ {
32
+ ImageNetworkHeader imghdr;
33
+
34
+ imghdr.setFromImage (img);
35
+ size_t hdrsize = sizeof (imghdr);
36
+ connection.appendInt32 (BOTTLE_TAG_BLOB);
37
+ connection.appendInt32 (hdrsize);
38
+ connection.appendBlock ((char *)(&imghdr), hdrsize);
39
+
40
+ size_t imgsize = img.getRawImageSize ();
41
+ connection.appendInt32 (BOTTLE_TAG_BLOB);
42
+ connection.appendInt32 (imgsize);
43
+ connection.appendBlock ((char *)(img.getRawImage ()), imgsize);
44
+
45
+ return ;
46
+ }
47
+
48
+ inline bool readFromConnection (FlexImage& dest, ConnectionReader& connection)
49
+ {
50
+ bool ok = true ;
51
+ ImageNetworkHeader imghdr;
52
+
53
+ connection.expectInt32 ();
54
+ size_t sizeData = connection.expectInt32 ();
55
+ ok &= connection.expectBlock ((char *)(&imghdr), sizeData);
56
+ if (!ok) { return false ; }
57
+ imghdr.setToImage (dest);
58
+
59
+ connection.expectInt32 ();
60
+ size_t sizeImg = connection.expectInt32 ();
61
+ size_t psizeImg = dest.getRawImageSize ();
62
+ if (sizeImg != psizeImg)
63
+ {
64
+ return false ;
65
+ }
66
+ unsigned char * pImg = dest.getRawImage ();
67
+ ok &= connection.expectBlock ((char *)pImg, sizeImg);
68
+
69
+ return ok;
70
+ }
71
+
72
+ LayeredImage::LayeredImage ()
73
+ {
74
+ }
75
+
76
+
77
+ LayeredImage::~LayeredImage ()
78
+ {
79
+ }
80
+
81
+
82
+ void LayeredImage::clear ()
83
+ {
84
+ background.zero ();
85
+ layers.clear ();
86
+ }
87
+
88
+ bool LayeredImage::read (yarp::os::ConnectionReader& connection)
89
+ {
90
+ bool ok = true ;
91
+
92
+ connection.convertTextMode ();
93
+
94
+ // LIST OF ELEMENTS
95
+ connection.expectInt32 ();
96
+ size_t elems = connection.expectInt32 ();
97
+
98
+ // ELEMENT 1
99
+ connection.expectInt32 ();
100
+ size_t layersNum = connection.expectInt32 ();
101
+ if (elems != 1 + (1 * 2 ) + (layersNum*10 ))
102
+ {
103
+ return false ;
104
+ }
105
+
106
+ // ELEMENT 2-3
107
+ ok &= readFromConnection (background, connection);
108
+
109
+ // ELEMENT 4-...
110
+ // each layer contains 8+2 elems
111
+ layers.clear ();
112
+ for (size_t i = 0 ; i < layersNum; i++)
113
+ {
114
+ yarp::sig::ImageLayer::colorkey_s colorkey = yarp::sig::ImageLayer::colorkey_s {};
115
+ yarp::sig::ImageLayer::alpha_s alpha = yarp::sig::ImageLayer::alpha_s {};
116
+
117
+ connection.expectInt32 ();
118
+ int32_t enable_val = connection.expectInt8 (); // 1
119
+ connection.expectInt32 ();
120
+ colorkey.enable = connection.expectInt8 (); // 2
121
+ connection.expectInt32 ();
122
+ colorkey.value = connection.expectInt32 (); // 3
123
+ connection.expectInt32 ();
124
+ alpha.enable = connection.expectInt8 (); // 4
125
+ connection.expectInt32 ();
126
+ alpha.value = connection.expectFloat32 (); // 5
127
+ connection.expectInt32 ();
128
+ bool can_be_compressed = connection.expectInt8 (); // 6
129
+ connection.expectInt32 ();
130
+ int32_t offset_x = connection.expectInt32 (); // 7
131
+ connection.expectInt32 ();
132
+ int32_t offset_y = connection.expectInt32 (); // 8
133
+
134
+ FlexImage fleximg;
135
+ ok &= readFromConnection (fleximg, connection); // 9-10
136
+ yarp::sig::ImageLayer oneLayer (fleximg, enable_val, colorkey, alpha, can_be_compressed, offset_x, offset_y);
137
+ layers.emplace_back (oneLayer);
138
+ }
139
+
140
+ return true ;
141
+ }
142
+
143
+
144
+ bool LayeredImage::write (yarp::os::ConnectionWriter& connection) const
145
+ {
146
+ bool ok = true ;
147
+ size_t layers_num = layers.size ();
148
+
149
+ // LIST OF ELEMENTS
150
+ connection.appendInt32 (BOTTLE_TAG_LIST);
151
+ connection.appendInt32 (1 +(1 *2 )+(layers_num*10 ));
152
+
153
+ // ELEMENT 1
154
+ connection.appendInt32 (BOTTLE_TAG_INT32);
155
+ connection.appendInt32 (layers_num);
156
+
157
+ // ELEMENT 2-3
158
+ writeToConnection (background, connection);
159
+
160
+ // ELEMENT 4-...
161
+ // each layer contains 8+2 elems
162
+ for (size_t i = 0 ; i < layers_num; i++)
163
+ {
164
+ connection.appendInt32 (BOTTLE_TAG_INT8); // 1
165
+ connection.appendInt8 (layers[i].enable );
166
+ connection.appendInt32 (BOTTLE_TAG_INT8); // 2
167
+ connection.appendInt8 (layers[i].colorkey .enable );
168
+ connection.appendInt32 (BOTTLE_TAG_INT32); // 3
169
+ connection.appendInt32 (layers[i].colorkey .value );
170
+ connection.appendInt32 (BOTTLE_TAG_INT8); // 4
171
+ connection.appendInt8 (layers[i].alpha .enable );
172
+ connection.appendInt32 (BOTTLE_TAG_FLOAT32); // 5
173
+ connection.appendFloat32 (layers[i].alpha .value );
174
+ connection.appendInt32 (BOTTLE_TAG_INT8); // 6
175
+ connection.appendInt8 (layers[i].can_be_compressed );
176
+ connection.appendInt32 (BOTTLE_TAG_INT32); // 7
177
+ connection.appendInt32 (layers[i].offset_x );
178
+ connection.appendInt32 (BOTTLE_TAG_INT32); // 8
179
+ connection.appendInt32 (layers[i].offset_y );
180
+ writeToConnection (layers[i].layer , connection); // 9-10
181
+ }
182
+
183
+ connection.convertTextMode ();
184
+ return !connection.isError ();
185
+ }
186
+
187
+
188
+ LayeredImage::LayeredImage (const LayeredImage& alt) :
189
+ Portable()
190
+ {
191
+ background = alt.background ;
192
+ this ->layers = alt.layers ;
193
+ }
194
+
195
+ LayeredImage::LayeredImage (LayeredImage&& other) noexcept
196
+ {
197
+ }
198
+
199
+ LayeredImage& LayeredImage::operator =(const LayeredImage& alt)
200
+ {
201
+ background = alt.background ;
202
+ this ->layers = alt.layers ;
203
+ return *this ;
204
+ }
205
+
206
+ bool LayeredImage::operator ==(const LayeredImage& alt) const
207
+ {
208
+ size_t l1 = this ->layers .size ();
209
+ size_t l2 = alt.layers .size ();
210
+
211
+ if (l1 != l2)
212
+ {
213
+ return false ;
214
+ }
215
+
216
+ if (background != alt.background )
217
+ {
218
+ return false ;
219
+ }
220
+
221
+ for (size_t i = 0 ; i < l1; i++)
222
+ {
223
+ if ((this ->layers [i].enable != alt.layers [i].enable ) ||
224
+ (this ->layers [i].colorkey .enable != alt.layers [i].colorkey .enable ) ||
225
+ (this ->layers [i].colorkey .value != alt.layers [i].colorkey .value ) ||
226
+ (this ->layers [i].alpha .enable != alt.layers [i].alpha .enable ) ||
227
+ (fabs (this ->layers [i].alpha .value - alt.layers [i].alpha .value ) > 0.001 ) ||
228
+ (this ->layers [i].layer != alt.layers [i].layer ) ||
229
+ (this ->layers [i].can_be_compressed != alt.layers [i].can_be_compressed ) ||
230
+ (this ->layers [i].offset_x != alt.layers [i].offset_x ) ||
231
+ (this ->layers [i].offset_y != alt.layers [i].offset_y ))
232
+ {
233
+ return false ;
234
+ }
235
+ }
236
+
237
+ return true ;
238
+ }
239
+
240
+ yarp::sig::FlexImage LayeredImage::convert_to_flexImage ()
241
+ {
242
+ yarp::sig::FlexImage outimg = background;
243
+
244
+ bool ret = true ;
245
+ for (size_t i = 0 ; i < this ->layers .size (); i++)
246
+ {
247
+ if (layers[i].enable == false )
248
+ {
249
+ continue ;
250
+ }
251
+
252
+ ret &= yarp::sig::utils::sum (outimg, layers[i].layer , layers[i].colorkey .enable , layers[i].colorkey .value , layers[i].alpha .enable , layers[i].alpha .value , layers[i].offset_x , layers[i].offset_y );
253
+ }
254
+
255
+ return outimg;
256
+ }
257
+
258
+ LayeredImage::operator yarp::sig::FlexImage ()
259
+ {
260
+ return convert_to_flexImage ();
261
+ }
0 commit comments