1
1
#pragma once
2
2
3
+ #include < pybind11/numpy.h>
4
+
5
+ #include < c/wuffs-v0.3.c>
3
6
#include < string>
4
7
#include < unordered_set>
5
8
#include < utility>
@@ -97,6 +100,18 @@ enum class PixelBlend : uint32_t {
97
100
SRC_OVER = WUFFS_BASE__PIXEL_BLEND__SRC_OVER
98
101
};
99
102
103
+ enum class PixelSubsampling : uint32_t {
104
+ NONE = WUFFS_BASE__PIXEL_SUBSAMPLING__NONE,
105
+ #define PSE (ps ) K##ps = WUFFS_BASE__PIXEL_SUBSAMPLING__##ps
106
+ PSE (444 ),
107
+ PSE (440 ),
108
+ PSE (422 ),
109
+ PSE (420 ),
110
+ PSE (411 ),
111
+ PSE (410 )
112
+ #undef PFE
113
+ };
114
+
100
115
// This struct hosts wuffs_aux::DecodeImage arguments in more user- and
101
116
// Python- friendly fashion
102
117
struct ImageDecoderConfig {
@@ -122,10 +137,10 @@ struct ImageDecoderConfig {
122
137
// input
123
138
struct MetadataEntry {
124
139
wuffs_base__more_information minfo{};
125
- std::vector <uint8_t > data;
140
+ pybind11:: array_t <uint8_t > data;
126
141
127
142
MetadataEntry (const wuffs_base__more_information& minfo,
128
- std::vector <uint8_t >&& data)
143
+ pybind11:: array_t <uint8_t >&& data)
129
144
: minfo(minfo), data(std::move(data)) {}
130
145
131
146
MetadataEntry () : minfo(wuffs_base__empty_more_information()) {}
@@ -143,33 +158,37 @@ struct MetadataEntry {
143
158
return *this ;
144
159
}
145
160
146
- MetadataEntry (const wuffs_aux_wrap::MetadataEntry& other) = default ;
147
-
148
- MetadataEntry& operator =(const wuffs_aux_wrap::MetadataEntry& other) =
149
- default ;
161
+ MetadataEntry (const wuffs_aux_wrap::MetadataEntry& other) = delete ;
162
+ MetadataEntry& operator =(const wuffs_aux_wrap::MetadataEntry& other) = delete ;
150
163
};
151
164
152
165
struct ImageDecodingResult {
153
- std::vector<uint8_t > decoded_data;
166
+ wuffs_base__pixel_config pixcfg = wuffs_base__null_pixel_config();
167
+ pybind11::array_t <uint8_t > pixbuf;
154
168
std::vector<MetadataEntry> reported_metadata;
155
169
std::string error_message;
156
170
157
171
ImageDecodingResult () = default ;
158
172
159
173
ImageDecodingResult (ImageDecodingResult&& other) noexcept {
160
- std::swap (decoded_data, other.decoded_data );
174
+ std::swap (pixcfg, other.pixcfg );
175
+ std::swap (pixbuf, other.pixbuf );
161
176
std::swap (reported_metadata, other.reported_metadata );
162
177
std::swap (error_message, other.error_message );
163
178
}
164
179
165
180
ImageDecodingResult& operator =(ImageDecodingResult&& other) noexcept {
166
181
if (this != &other) {
167
- std::swap (decoded_data, other.decoded_data );
182
+ std::swap (pixcfg, other.pixcfg );
183
+ std::swap (pixbuf, other.pixbuf );
168
184
std::swap (reported_metadata, other.reported_metadata );
169
185
std::swap (error_message, other.error_message );
170
186
}
171
187
return *this ;
172
188
}
189
+
190
+ ImageDecodingResult (ImageDecodingResult& other) = delete ;
191
+ ImageDecodingResult& operator =(ImageDecodingResult& other) = delete ;
173
192
};
174
193
175
194
struct ImageDecoderError {
@@ -182,6 +201,7 @@ struct ImageDecoderError {
182
201
static const std::string UnsupportedPixelBlend;
183
202
static const std::string UnsupportedPixelConfiguration;
184
203
static const std::string UnsupportedPixelFormat;
204
+ static const std::string FailedToOpenFile;
185
205
};
186
206
187
207
const std::string ImageDecoderError::MaxInclDimensionExceeded =
@@ -202,8 +222,10 @@ const std::string ImageDecoderError::UnsupportedPixelConfiguration =
202
222
wuffs_aux::DecodeImage_UnsupportedPixelConfiguration;
203
223
const std::string ImageDecoderError::UnsupportedPixelFormat =
204
224
wuffs_aux::DecodeImage_UnsupportedPixelFormat;
225
+ const std::string ImageDecoderError::FailedToOpenFile =
226
+ " wuffs_aux_wrap::ImageDecoder::Decode: failed to open file" ;
205
227
206
- class ImageDecoder : public wuffs_aux ::DecodeImageCallbacks {
228
+ class ImageDecoder : public wuffs_aux ::DecodeImageCallbacks {
207
229
public:
208
230
explicit ImageDecoder (const ImageDecoderConfig& config)
209
231
: quirks_vector_({config.quirks .begin (), config.quirks .end ()}),
@@ -238,8 +260,8 @@ class ImageDecoder : public wuffs_aux::DecodeImageCallbacks {
238
260
239
261
std::string HandleMetadata (const wuffs_base__more_information& minfo,
240
262
wuffs_base__slice_u8 raw) override {
241
- decoding_result_.reported_metadata .push_back (
242
- { minfo, {raw.ptr , raw.ptr + raw. len }} );
263
+ decoding_result_.reported_metadata .emplace_back (
264
+ minfo, pybind11::array ( pybind11::dtype ( " uint8 " ), {raw.len } , raw.ptr ) );
243
265
return " " ;
244
266
}
245
267
@@ -261,18 +283,18 @@ class ImageDecoder : public wuffs_aux::DecodeImageCallbacks {
261
283
if (len == 0 || SIZE_MAX < len) {
262
284
return {wuffs_aux::DecodeImage_UnsupportedPixelConfiguration};
263
285
}
264
- if (allow_uninitialized_memory) {
265
- decoding_result_. decoded_data . resize (len);
266
- } else {
267
- decoding_result_.decoded_data . resize (len, 0 );
286
+ decoding_result_. pixbuf . resize ({len});
287
+ if (!allow_uninitialized_memory) {
288
+ std::memset (decoding_result_. pixbuf . mutable_data (), 0 ,
289
+ decoding_result_.pixbuf . size () );
268
290
}
269
291
wuffs_base__pixel_buffer pixbuf;
270
292
wuffs_base__status status = pixbuf.set_from_slice (
271
293
&image_config.pixcfg ,
272
- wuffs_base__make_slice_u8 (decoding_result_.decoded_data . data (),
273
- decoding_result_.decoded_data .size ()));
294
+ wuffs_base__make_slice_u8 (decoding_result_.pixbuf . mutable_data (),
295
+ decoding_result_.pixbuf .size ()));
274
296
if (!status.is_ok ()) {
275
- decoding_result_.decoded_data . clear () ;
297
+ decoding_result_.pixbuf = {} ;
276
298
return {status.message ()};
277
299
}
278
300
return {wuffs_aux::MemOwner (nullptr , &free), pixbuf};
@@ -289,8 +311,7 @@ class ImageDecoder : public wuffs_aux::DecodeImageCallbacks {
289
311
FILE* f = fopen (path_to_file.c_str (), " rb" );
290
312
if (!f) {
291
313
ImageDecodingResult result;
292
- result.error_message =
293
- " wuffs_aux_wrap::ImageDecoder::Decode: failed to open file" ;
314
+ result.error_message = ImageDecoderError::FailedToOpenFile;
294
315
return result;
295
316
}
296
317
wuffs_aux::sync_io::FileInput input (f);
@@ -315,7 +336,16 @@ class ImageDecoder : public wuffs_aux::DecodeImageCallbacks {
315
336
decoding_result_.error_message =
316
337
std::move (decode_image_result.error_message );
317
338
if (!decode_image_result.pixbuf .pixcfg .is_valid ()) {
318
- decoding_result_.decoded_data .clear ();
339
+ decoding_result_.pixbuf = {};
340
+ decoding_result_.pixcfg = wuffs_base__null_pixel_config ();
341
+ } else {
342
+ decoding_result_.pixcfg = decode_image_result.pixbuf .pixcfg ;
343
+ decoding_result_.pixbuf =
344
+ decoding_result_.pixbuf .reshape (std::vector<size_t >{
345
+ decoding_result_.pixcfg .height (), decoding_result_.pixcfg .width (),
346
+ decoding_result_.pixcfg .pixbuf_len () /
347
+ (decoding_result_.pixcfg .width () *
348
+ decoding_result_.pixcfg .height ())});
319
349
}
320
350
return std::move (decoding_result_);
321
351
}
0 commit comments