1// [Blend2D]
2// 2D Vector Graphics Powered by a JIT Compiler.
3//
4// [License]
5// Zlib - See LICENSE.md file in the package.
6
7#ifndef BLEND2D_BLIMAGE_H
8#define BLEND2D_BLIMAGE_H
9
10#include "./blarray.h"
11#include "./blformat.h"
12#include "./blgeometry.h"
13#include "./blvariant.h"
14
15//! \addtogroup blend2d_api_imaging
16//! \{
17
18// ============================================================================
19// [Constants]
20// ============================================================================
21
22//! Image codec feature bits.
23BL_DEFINE_ENUM(BLImageCodecFeatures) {
24 //! Image codec supports reading images (can create BLImageDecoder).
25 BL_IMAGE_CODEC_FEATURE_READ = 0x00000001u,
26 //! Image codec supports writing images (can create BLImageEncoder).
27 BL_IMAGE_CODEC_FEATURE_WRITE = 0x00000002u,
28 //! Image codec supports lossless compression.
29 BL_IMAGE_CODEC_FEATURE_LOSSLESS = 0x00000004u,
30 //! Image codec supports loosy compression.
31 BL_IMAGE_CODEC_FEATURE_LOSSY = 0x00000008u,
32 //! Image codec supports writing multiple frames (GIF).
33 BL_IMAGE_CODEC_FEATURE_MULTI_FRAME = 0x00000010u,
34 //! Image codec supports IPTC metadata.
35 BL_IMAGE_CODEC_FEATURE_IPTC = 0x10000000u,
36 //! Image codec supports EXIF metadata.
37 BL_IMAGE_CODEC_FEATURE_EXIF = 0x20000000u,
38 //! Image codec supports XMP metadata.
39 BL_IMAGE_CODEC_FEATURE_XMP = 0x40000000u
40};
41
42//! Flags used by `BLImageInfo`.
43BL_DEFINE_ENUM(BLImageInfoFlags) {
44 //! Progressive mode.
45 BL_IMAGE_INFO_FLAG_PROGRESSIVE = 0x00000001u
46};
47
48//! Filter type used by `BLImage::scale()`.
49BL_DEFINE_ENUM(BLImageScaleFilter) {
50 //! No filter or uninitialized.
51 BL_IMAGE_SCALE_FILTER_NONE = 0,
52 //! Nearest neighbor filter (radius 1.0).
53 BL_IMAGE_SCALE_FILTER_NEAREST = 1,
54 //! Bilinear filter (radius 1.0).
55 BL_IMAGE_SCALE_FILTER_BILINEAR = 2,
56 //! Bicubic filter (radius 2.0).
57 BL_IMAGE_SCALE_FILTER_BICUBIC = 3,
58 //! Bell filter (radius 1.5).
59 BL_IMAGE_SCALE_FILTER_BELL = 4,
60 //! Gauss filter (radius 2.0).
61 BL_IMAGE_SCALE_FILTER_GAUSS = 5,
62 //! Hermite filter (radius 1.0).
63 BL_IMAGE_SCALE_FILTER_HERMITE = 6,
64 //! Hanning filter (radius 1.0).
65 BL_IMAGE_SCALE_FILTER_HANNING = 7,
66 //! Catrom filter (radius 2.0).
67 BL_IMAGE_SCALE_FILTER_CATROM = 8,
68 //! Bessel filter (radius 3.2383).
69 BL_IMAGE_SCALE_FILTER_BESSEL = 9,
70 //! Sinc filter (radius 2.0, adjustable through `BLImageScaleOptions`).
71 BL_IMAGE_SCALE_FILTER_SINC = 10,
72 //! Lanczos filter (radius 2.0, adjustable through `BLImageScaleOptions`).
73 BL_IMAGE_SCALE_FILTER_LANCZOS = 11,
74 //! Blackman filter (radius 2.0, adjustable through `BLImageScaleOptions`).
75 BL_IMAGE_SCALE_FILTER_BLACKMAN = 12,
76 //! Mitchell filter (radius 2.0, parameters 'b' and 'c' passed through `BLImageScaleOptions`).
77 BL_IMAGE_SCALE_FILTER_MITCHELL = 13,
78 //! Filter using a user-function, must be passed through `BLImageScaleOptions`.
79 BL_IMAGE_SCALE_FILTER_USER = 14,
80
81 //! Count of image-scale filters.
82 BL_IMAGE_SCALE_FILTER_COUNT = 15
83};
84
85// ============================================================================
86// [Typedefs]
87// ============================================================================
88
89//! A user function that can be used by `BLImage::scale()`.
90typedef BLResult (BL_CDECL* BLImageScaleUserFunc)(double* dst, const double* tArray, size_t n, const void* data) BL_NOEXCEPT;
91
92// ============================================================================
93// [BLImageData]
94// ============================================================================
95
96//! Data that describes a raster image. Used by `BLImage`.
97struct BLImageData {
98 void* pixelData;
99 intptr_t stride;
100 BLSizeI size;
101 uint32_t format;
102 uint32_t flags;
103
104 // --------------------------------------------------------------------------
105 #ifdef __cplusplus
106
107 BL_INLINE void reset() noexcept { memset(this, 0, sizeof(*this)); }
108
109 #endif
110 // --------------------------------------------------------------------------
111};
112
113// ============================================================================
114// [BLImageInfo]
115// ============================================================================
116
117//! Image information provided by image codecs.
118struct BLImageInfo {
119 //! Image size.
120 BLSizeI size;
121 //! Pixel density per one meter, can contain fractions.
122 BLSize density;
123
124 //! Image flags.
125 uint32_t flags;
126 //! Image depth.
127 uint16_t depth;
128 //! Number of planes.
129 uint16_t planeCount;
130 //! Number of frames (0 = unknown/unspecified).
131 uint64_t frameCount;
132
133 //! Image format (as understood by codec).
134 char format[16];
135 //! Image compression (as understood by codec).
136 char compression[16];
137
138 // --------------------------------------------------------------------------
139 #ifdef __cplusplus
140
141 BL_INLINE void reset() noexcept { memset(this, 0, sizeof(*this)); }
142
143 #endif
144 // --------------------------------------------------------------------------
145};
146
147// ============================================================================
148// [BLImageScaleOptions]
149// ============================================================================
150
151//! Options that can used to customize image scaling.
152struct BLImageScaleOptions {
153 BLImageScaleUserFunc userFunc;
154 void* userData;
155
156 double radius;
157 union {
158 double data[3];
159 struct {
160 double b, c;
161 } mitchell;
162 };
163
164 // --------------------------------------------------------------------------
165 #ifdef __cplusplus
166
167 BL_INLINE void reset() noexcept { memset(this, 0, sizeof(*this)); }
168
169 BL_INLINE void resetToDefaults() noexcept {
170 userFunc = nullptr;
171 userData = nullptr;
172 radius = 2.0;
173 mitchell.b = 1.0 / 3.0;
174 mitchell.c = 1.0 / 3.0;
175 data[2] = 0.0;
176 }
177
178 #endif
179 // --------------------------------------------------------------------------
180};
181
182// ============================================================================
183// [BLImage - Core]
184// ============================================================================
185
186//! Image [C Interface - Impl].
187struct BLImageImpl {
188 //! Pixel data.
189 void* pixelData;
190 //! Image stride.
191 intptr_t stride;
192 //! Non-null if the image has a writer.
193 volatile void* writer;
194
195 //! Reference count.
196 volatile size_t refCount;
197 //! Impl type.
198 uint8_t implType;
199 //! Impl traits.
200 uint8_t implTraits;
201 //! Memory pool data.
202 uint16_t memPoolData;
203
204 //! Image format.
205 uint8_t format;
206 //! Image flags.
207 uint8_t flags;
208 //! Image depth (in bits).
209 uint16_t depth;
210 //! Image size.
211 BLSizeI size;
212};
213
214//! Image [C Interface - Core].
215struct BLImageCore {
216 BLImageImpl* impl;
217};
218
219// ============================================================================
220// [BLImage - C++]
221// ============================================================================
222
223#ifdef __cplusplus
224//! 2D raster image [C++ API].
225class BLImage : public BLImageCore {
226public:
227 //! \cond INTERNAL
228 static constexpr const uint32_t kImplType = BL_IMPL_TYPE_IMAGE;
229 //! \endcond
230
231 //! \name Construction & Destruction
232 //! \{
233
234 BL_INLINE BLImage() noexcept { this->impl = none().impl; }
235 BL_INLINE BLImage(BLImage&& other) noexcept { blVariantInitMove(this, &other); }
236 BL_INLINE BLImage(const BLImage& other) noexcept { blVariantInitWeak(this, &other); }
237 BL_INLINE explicit BLImage(BLImageImpl* impl) noexcept { this->impl = impl; }
238 BL_INLINE BLImage(int w, int h, uint32_t format) noexcept { blImageInitAs(this, w, h, format); }
239 BL_INLINE ~BLImage() { blImageReset(this); }
240
241 //! \}
242
243 //! \name Operator Overloads
244 //! \{
245
246 BL_INLINE explicit operator bool() const noexcept { return !empty(); }
247
248 BL_INLINE BLImage& operator=(BLImage&& other) noexcept { blImageAssignMove(this, &other); return *this; }
249 BL_INLINE BLImage& operator=(const BLImage& other) noexcept { blImageAssignWeak(this, &other); return *this; }
250
251 BL_INLINE bool operator==(const BLImage& other) const noexcept { return equals(other); }
252 BL_INLINE bool operator!=(const BLImage& other) const noexcept { return !equals(other); }
253
254 //! \}
255
256 //! \name Common Functionality
257 //! \{
258
259 BL_INLINE BLResult reset() noexcept { return blImageReset(this); }
260 BL_INLINE void swap(BLImage& other) noexcept { std::swap(this->impl, other.impl); }
261
262 BL_INLINE BLResult assign(BLImage&& other) noexcept { return blImageAssignMove(this, &other); }
263 BL_INLINE BLResult assign(const BLImage& other) noexcept { return blImageAssignWeak(this, &other); }
264
265 //! Create a deep copy of the `other` image.
266 BL_INLINE BLResult assignDeep(const BLImage& other) noexcept { return blImageAssignDeep(this, &other); }
267
268 //! Tests whether the image is a built-in null instance.
269 BL_INLINE bool isNone() const noexcept { return (impl->implTraits & BL_IMPL_TRAIT_NULL) != 0; }
270 //! Tests whether the image is empty (has no size).
271 BL_INLINE bool empty() const noexcept { return impl->format == BL_FORMAT_NONE; }
272
273 BL_INLINE bool equals(const BLImage& other) const noexcept { return blImageEquals(this, &other); }
274
275 //! \}
276
277 //! \name Create Functionality
278 //! \{
279
280 //! Create a new image of a specified width `w`, height `h`, and `format`.
281 //!
282 //! \note It's important to always test whether the function succeeded as
283 //! allocating pixel-data can fail. If invalid arguments (invalid size or
284 //! format) were passed to the function a `BL_ERROR_INVALID_VALUE` result
285 //! will be returned and no data will be allocated. It's also important
286 //! to notice that `BLImage::create()` would not change anything if the
287 //! function fails (the previous image content would be kept as is).
288 BL_INLINE BLResult create(int w, int h, uint32_t format) noexcept {
289 return blImageCreate(this, w, h, format);
290 }
291
292 //! Create a new image from external data.
293 BL_INLINE BLResult createFromData(
294 int w, int h, uint32_t format,
295 void* pixelData, intptr_t stride,
296 BLDestroyImplFunc destroyFunc = nullptr,
297 void* destroyData = nullptr) noexcept { return blImageCreateFromData(this, w, h, format, pixelData, stride, destroyFunc, destroyData); }
298
299 //! \}
300
301 //! \name Image Data
302 //! \{
303
304 //! Returns image width.
305 BL_INLINE int width() const noexcept { return impl->size.w; }
306 //! Returns image height.
307 BL_INLINE int height() const noexcept { return impl->size.h; }
308 //! Returns image size.
309 BL_INLINE const BLSizeI& size() const noexcept { return impl->size; }
310 //! Returns image format, see `BLFormat`.
311 BL_INLINE uint32_t format() const noexcept { return impl->format; }
312
313 BL_INLINE BLResult getData(BLImageData* dataOut) const noexcept { return blImageGetData(this, dataOut); }
314 BL_INLINE BLResult makeMutable() noexcept { BLImageData unused; return blImageMakeMutable(this, &unused); }
315 BL_INLINE BLResult makeMutable(BLImageData* dataOut) noexcept { return blImageMakeMutable(this, dataOut); }
316
317 //! \}
318
319 //! \name Image IO
320 //! \{
321
322 BL_INLINE BLResult readFromFile(const char* fileName) noexcept {
323 return blImageReadFromFile(this, fileName, nullptr);
324 }
325
326 BL_INLINE BLResult readFromFile(const char* fileName, const BLArray<BLImageCodec>& codecs) noexcept {
327 return blImageReadFromFile(this, fileName, &codecs);
328 }
329
330 BL_INLINE BLResult readFromData(const void* data, size_t size) noexcept {
331 return blImageReadFromData(this, data, size, nullptr);
332 }
333
334 BL_INLINE BLResult readFromData(const void* data, size_t size, const BLArray<BLImageCodec>& codecs) noexcept {
335 return blImageReadFromData(this, data, size, &codecs);
336 }
337
338 BL_INLINE BLResult readFromData(const BLArray<uint8_t>& array) noexcept {
339 return blImageReadFromData(this, array.data(), array.size(), nullptr);
340 }
341
342 BL_INLINE BLResult readFromData(const BLArray<uint8_t>& array, const BLArray<BLImageCodec>& codecs) noexcept {
343 return blImageReadFromData(this, array.data(), array.size(), &codecs);
344 }
345
346 BL_INLINE BLResult readFromData(const BLArrayView<uint8_t>& view) noexcept {
347 return blImageReadFromData(this, view.data, view.size, nullptr);
348 }
349
350 BL_INLINE BLResult readFromData(const BLArrayView<uint8_t>& view, const BLArray<BLImageCodec>& codecs) noexcept {
351 return blImageReadFromData(this, view.data, view.size, &codecs);
352 }
353
354 BL_INLINE BLResult writeToFile(const char* fileName, const BLImageCodec& codec) noexcept {
355 return blImageWriteToFile(this, fileName, reinterpret_cast<const BLImageCodecCore*>(&codec));
356 }
357
358 BL_INLINE BLResult writeToData(BLArray<uint8_t>& dst, const BLImageCodec& codec) noexcept {
359 return blImageWriteToData(this, &dst, reinterpret_cast<const BLImageCodecCore*>(&codec));
360 }
361
362 //! \}
363
364 static BL_INLINE const BLImage& none() noexcept { return reinterpret_cast<const BLImage*>(blNone)[kImplType]; }
365
366 static BL_INLINE BLResult scale(BLImage& dst, const BLImage& src, const BLSizeI& size, uint32_t filter, const BLImageScaleOptions* options = nullptr) noexcept {
367 return blImageScale(&dst, &src, &size, filter, options);
368 }
369};
370#endif
371
372// ============================================================================
373// [BLImageCodec - Core]
374// ============================================================================
375
376//! Image codec [C Interface - Virtual Function Table].
377struct BLImageCodecVirt {
378 BLResult (BL_CDECL* destroy)(BLImageCodecImpl* impl) BL_NOEXCEPT;
379 uint32_t (BL_CDECL* inspectData)(const BLImageCodecImpl* impl, const uint8_t* data, size_t size) BL_NOEXCEPT;
380 BLResult (BL_CDECL* createDecoder)(const BLImageCodecImpl* impl, BLImageDecoderCore* dst) BL_NOEXCEPT;
381 BLResult (BL_CDECL* createEncoder)(const BLImageCodecImpl* impl, BLImageEncoderCore* dst) BL_NOEXCEPT;
382};
383
384//! Image codec [C Interface - Impl].
385struct BLImageCodecImpl {
386 //! Virtual function table.
387 const BLImageCodecVirt* virt;
388 //! Image codec name like "PNG", "JPEG", etc...
389 const char* name;
390 //! Image codec vendor, built-in codecs use "Blend2D".
391 const char* vendor;
392
393 //! Reference count.
394 volatile size_t refCount;
395 //! Impl type.
396 uint8_t implType;
397 //! Impl traits.
398 uint8_t implTraits;
399 //! Memory pool data.
400 uint16_t memPoolData;
401
402 //! Image codec features.
403 uint32_t features;
404 //! Mime type.
405 const char* mimeType;
406 //! Known file extensions used by this image codec separated by "|".
407 const char* extensions;
408};
409
410//! Image codec [C Interface - Core].
411struct BLImageCodecCore {
412 BLImageCodecImpl* impl;
413};
414
415// ============================================================================
416// [BLImageCodec - C++]
417// ============================================================================
418
419#ifdef __cplusplus
420//! Image codec [C++ API].
421//!
422//! Provides a unified interface for inspecting image data and creating image
423//! decoders & encoders.
424class BLImageCodec : public BLImageCodecCore {
425public:
426 //! \cond INTERNAL
427 static constexpr const uint32_t kImplType = BL_IMPL_TYPE_IMAGE_CODEC;
428 //! \endcond
429
430 //! \name Construction & Destruction
431 //! \{
432
433 BL_INLINE BLImageCodec() noexcept { this->impl = none().impl; }
434 BL_INLINE BLImageCodec(BLImageCodec&& other) noexcept { blVariantInitMove(this, &other); }
435 BL_INLINE BLImageCodec(const BLImageCodec& other) noexcept { blVariantInitWeak(this, &other); }
436 BL_INLINE explicit BLImageCodec(BLImageCodecImpl* impl) noexcept { this->impl = impl; }
437 BL_INLINE ~BLImageCodec() { blImageCodecReset(this); }
438
439 //! \}
440
441 //! \name Operator Overloads
442 //! \{
443
444 BL_INLINE explicit operator bool() const noexcept { return !isNone(); }
445
446 BL_INLINE BLImageCodec& operator=(const BLImageCodec& other) noexcept {
447 blImageCodecAssignWeak(this, &other);
448 return *this;
449 }
450
451 BL_INLINE bool operator==(const BLImageCodec& other) const noexcept { return equals(other); }
452 BL_INLINE bool operator!=(const BLImageCodec& other) const noexcept { return !equals(other); }
453
454 //! \}
455
456 //! \name Common Functionality
457 //! \{
458
459 BL_INLINE BLResult reset() noexcept { return blImageCodecReset(this); }
460 BL_INLINE void swap(BLImageCodec& other) noexcept { std::swap(this->impl, other.impl); }
461
462 BL_INLINE BLResult assign(const BLImageCodec& other) noexcept { return blImageCodecAssignWeak(this, &other); }
463
464 //! Tests whether the image codec is a built-in null instance.
465 BL_INLINE bool isNone() const noexcept { return (impl->implTraits & BL_IMPL_TRAIT_NULL) != 0; }
466
467 BL_INLINE bool equals(const BLImageCodec& other) const noexcept { return this->impl == other.impl; }
468
469 //! \}
470
471 //! \name Properties
472 //! \{
473
474 //! Returns image codec name (i.e, "PNG", "JPEG", etc...).
475 BL_INLINE const char* name() const noexcept { return impl->name; }
476 //! Returns the image codec vendor (i.e. "Blend2D" for all built-in codecs).
477 BL_INLINE const char* vendor() const noexcept { return impl->vendor; }
478 //! Returns a mime-type associated with the image codec's format.
479 BL_INLINE const char* mimeType() const noexcept { return impl->mimeType; }
480 //! Returns a list of file extensions used to store image of this codec, separated by '|' character.
481 BL_INLINE const char* extensions() const noexcept { return impl->extensions; }
482 //! Returns image codec flags, see `BLImageCodecFeatures`.
483 BL_INLINE uint32_t features() const noexcept { return impl->features; }
484 //! Tests whether the image codec has a flag `flag`.
485 BL_INLINE bool hasFeature(uint32_t feature) const noexcept { return (impl->features & feature) != 0; }
486
487 //! \}
488
489 //! \name Find Functionality
490 //! \{
491
492 BL_INLINE BLResult findByName(const char* name) noexcept {
493 return blImageCodecFindByName(this, name, SIZE_MAX, nullptr);
494 }
495
496 BL_INLINE BLResult findByName(const char* name, const BLArray<BLImageCodec>& codecs) noexcept {
497 return blImageCodecFindByName(this, name, SIZE_MAX, &codecs);
498 }
499
500 BL_INLINE BLResult findByName(const BLStringView& name) noexcept {
501 return blImageCodecFindByName(this, name.data, name.size, nullptr);
502 }
503
504 BL_INLINE BLResult findByName(const BLStringView& name, const BLArray<BLImageCodec>& codecs) noexcept {
505 return blImageCodecFindByName(this, name.data, name.size, &codecs);
506 }
507
508 BL_INLINE BLResult findByData(const void* data, size_t size) noexcept {
509 return blImageCodecFindByData(this, data, size, nullptr);
510 }
511
512 BL_INLINE BLResult findByData(const void* data, size_t size, const BLArray<BLImageCodec>& codecs) noexcept {
513 return blImageCodecFindByData(this, data, size, &codecs);
514 }
515
516 BL_INLINE BLResult findByData(const BLArrayView<uint8_t>& view) noexcept {
517 return blImageCodecFindByData(this, view.data, view.size, nullptr);
518 }
519
520 BL_INLINE BLResult findByData(const BLArrayView<uint8_t>& view, const BLArray<BLImageCodec>& codecs) noexcept {
521 return blImageCodecFindByData(this, view.data, view.size, &codecs);
522 }
523
524 BL_INLINE BLResult findByData(const BLArray<uint8_t>& buffer) noexcept {
525 return blImageCodecFindByData(this, buffer.data(), buffer.size(), nullptr);
526 }
527
528 BL_INLINE BLResult findByData(const BLArray<uint8_t>& buffer, const BLArray<BLImageCodec>& codecs) noexcept {
529 return blImageCodecFindByData(this, buffer.data(), buffer.size(), &codecs);
530 }
531
532 //! \}
533
534 //! \name Codec Functionality
535 //! \{
536
537 BL_INLINE uint32_t inspectData(const BLArray<uint8_t>& buffer) const noexcept { return inspectData(buffer.view()); }
538 BL_INLINE uint32_t inspectData(const BLArrayView<uint8_t>& view) const noexcept { return inspectData(view.data, view.size); }
539 BL_INLINE uint32_t inspectData(const void* data, size_t size) const noexcept { return blImageCodecInspectData(this, static_cast<const uint8_t*>(data), size); }
540
541 BL_INLINE BLResult createDecoder(BLImageDecoder* dst) const noexcept { return blImageCodecCreateDecoder(this, reinterpret_cast<BLImageDecoderCore*>(dst)); }
542 BL_INLINE BLResult createEncoder(BLImageEncoder* dst) const noexcept { return blImageCodecCreateEncoder(this, reinterpret_cast<BLImageEncoderCore*>(dst)); }
543
544 //! \}
545
546 //! \name Built-In Codecs
547 //! \{
548
549 static BL_INLINE BLArray<BLImageCodec> builtInCodecs() noexcept {
550 BLArray<BLImageCodec> result(nullptr);
551 blImageCodecArrayInitBuiltInCodecs(&result);
552 return result;
553 }
554
555 static BL_INLINE BLResult addToBuiltIn(const BLImageCodec& codec) noexcept {
556 return blImageCodecAddToBuiltIn(&codec);
557 }
558
559 static BL_INLINE BLResult removeFromBuiltIn(const BLImageCodec& codec) noexcept {
560 return blImageCodecRemoveFromBuiltIn(&codec);
561 }
562
563 //! \}
564
565 static BL_INLINE const BLImageCodec& none() noexcept { return reinterpret_cast<const BLImageCodec*>(blNone)[kImplType]; }
566};
567#endif
568
569// ============================================================================
570// [BLImageDecoder - Core]
571// ============================================================================
572
573//! Image decoder [C Interface - Virtual Function Table].
574struct BLImageDecoderVirt {
575 BLResult (BL_CDECL* destroy)(BLImageDecoderImpl* impl) BL_NOEXCEPT;
576 BLResult (BL_CDECL* restart)(BLImageDecoderImpl* impl) BL_NOEXCEPT;
577 BLResult (BL_CDECL* readInfo)(BLImageDecoderImpl* impl, BLImageInfo* infoOut, const uint8_t* data, size_t size) BL_NOEXCEPT;
578 BLResult (BL_CDECL* readFrame)(BLImageDecoderImpl* impl, BLImageCore* imageOut, const uint8_t* data, size_t size) BL_NOEXCEPT;
579};
580
581//! Image decoder [C Interface - Impl].
582struct BLImageDecoderImpl {
583 //! Virtual function table.
584 const BLImageDecoderVirt* virt;
585 //! Image codec that created this decoder.
586 BL_TYPED_MEMBER(BLImageCodecCore, BLImageCodec, codec);
587 //! Handle in case that this decoder wraps a thirt-party library.
588 void* handle;
589
590 //! Reference count.
591 volatile size_t refCount;
592 //! Impl type.
593 uint8_t implType;
594 //! Impl traits.
595 uint8_t implTraits;
596 //! Memory pool data.
597 uint16_t memPoolData;
598
599 //! Last faulty result (if failed).
600 BLResult lastResult;
601 //! Current frame index.
602 uint64_t frameIndex;
603 //! Position in source buffer.
604 size_t bufferIndex;
605
606 BL_HAS_TYPED_MEMBERS(BLImageDecoderImpl)
607};
608
609//! Image decoder [C Interface - Core]
610struct BLImageDecoderCore {
611 BLImageDecoderImpl* impl;
612};
613
614// ============================================================================
615// [BLImageDecoder - C++]
616// ============================================================================
617
618#ifdef __cplusplus
619//! Image decoder [C++ API].
620class BLImageDecoder : public BLImageDecoderCore {
621public:
622 //! \cond INTERNAL
623 static constexpr const uint32_t kImplType = BL_IMPL_TYPE_IMAGE_DECODER;
624 //! \endcond
625
626 //! \name Construction & Destruction
627 //! \{
628
629 BL_INLINE BLImageDecoder() noexcept { this->impl = none().impl; }
630 BL_INLINE BLImageDecoder(BLImageDecoder&& other) noexcept { blVariantInitMove(this, &other); }
631 BL_INLINE BLImageDecoder(const BLImageDecoder& other) noexcept { blVariantInitWeak(this, &other); }
632 BL_INLINE explicit BLImageDecoder(BLImageDecoderImpl* impl) noexcept { this->impl = impl; }
633 BL_INLINE ~BLImageDecoder() { blImageDecoderReset(this); }
634
635 //! \}
636
637 //! \name Operator Overloads
638 //! \{
639
640 BL_INLINE explicit operator bool() const noexcept { return !isNone(); }
641
642 BL_INLINE BLImageDecoder& operator=(BLImageDecoder&& other) noexcept { blImageDecoderAssignMove(this, &other); return *this; }
643 BL_INLINE BLImageDecoder& operator=(const BLImageDecoder& other) noexcept { blImageDecoderAssignWeak(this, &other); return *this; }
644
645 BL_INLINE bool operator==(const BLImageDecoder& other) const noexcept { return equals(other); }
646 BL_INLINE bool operator!=(const BLImageDecoder& other) const noexcept { return !equals(other); }
647
648 //! \}
649
650 //! \name Common Functionality
651 //! \{
652
653 BL_INLINE BLResult reset() noexcept { return blImageDecoderReset(this); }
654 BL_INLINE void swap(BLImageDecoder& other) noexcept { std::swap(this->impl, other.impl); }
655
656 BL_INLINE BLResult assign(BLImageDecoder&& other) noexcept { return blImageDecoderAssignMove(this, &other); }
657 BL_INLINE BLResult assign(const BLImageDecoder& other) noexcept { return blImageDecoderAssignWeak(this, &other); }
658
659 //! Tests whether the image decoder is a built-in null instance.
660 BL_INLINE bool isNone() const noexcept { return (impl->implTraits & BL_IMPL_TRAIT_NULL) != 0; }
661
662 BL_INLINE bool equals(const BLImageDecoder& other) const noexcept { return this->impl == other.impl; }
663
664 //! \}
665
666 //! \name Properties
667 //! \{
668
669 //! Returns the last decoding result.
670 BL_INLINE BLResult lastResult() const noexcept { return impl->lastResult; }
671 //! Returns the current frame index (to be decoded).
672 BL_INLINE uint64_t frameIndex() const noexcept { return impl->frameIndex; }
673 //! Returns the position in source buffer.
674 BL_INLINE size_t bufferIndex() const noexcept { return impl->bufferIndex; }
675
676 //! \}
677
678 //! \name Decoder Functionality
679 //! \{
680
681 BL_INLINE BLResult restart() noexcept { return blImageDecoderRestart(this); }
682
683 BL_INLINE BLResult readInfo(BLImageInfo& dst, const BLArray<uint8_t>& buffer) noexcept { return blImageDecoderReadInfo(this, &dst, buffer.data(), buffer.size()); }
684 BL_INLINE BLResult readInfo(BLImageInfo& dst, const BLArrayView<uint8_t>& view) noexcept { return blImageDecoderReadInfo(this, &dst, view.data, view.size); }
685 BL_INLINE BLResult readInfo(BLImageInfo& dst, const void* data, size_t size) noexcept { return blImageDecoderReadInfo(this, &dst, static_cast<const uint8_t*>(data), size); }
686
687 BL_INLINE BLResult readFrame(BLImage& dst, const BLArray<uint8_t>& buffer) noexcept { return blImageDecoderReadFrame(this, &dst, buffer.data(), buffer.size()); }
688 BL_INLINE BLResult readFrame(BLImage& dst, const BLArrayView<uint8_t>& view) noexcept { return blImageDecoderReadFrame(this, &dst, view.data, view.size); }
689 BL_INLINE BLResult readFrame(BLImage& dst, const void* data, size_t size) noexcept { return blImageDecoderReadFrame(this, &dst, static_cast<const uint8_t*>(data), size); }
690
691 //! \}
692
693 static BL_INLINE const BLImageDecoder& none() noexcept { return reinterpret_cast<const BLImageDecoder*>(blNone)[kImplType]; }
694};
695#endif
696
697// ============================================================================
698// [BLImageEncoder - Core]
699// ============================================================================
700
701//! Image encoder [C Interface - Virtual Function Table].
702struct BLImageEncoderVirt {
703 BLResult (BL_CDECL* destroy)(BLImageEncoderImpl* impl) BL_NOEXCEPT;
704 BLResult (BL_CDECL* restart)(BLImageEncoderImpl* impl) BL_NOEXCEPT;
705 BLResult (BL_CDECL* writeFrame)(BLImageEncoderImpl* impl, BLArrayCore* dst, const BLImageCore* image) BL_NOEXCEPT;
706};
707
708//! Image encoder [C Interface - Impl].
709struct BLImageEncoderImpl {
710 //! Virtual function table.
711 const BLImageEncoderVirt* virt;
712 //! Image codec that created this encoder.
713 BL_TYPED_MEMBER(BLImageCodecCore, BLImageCodec, codec);
714 //! Handle in case that this encoder wraps a thirt-party library.
715 void* handle;
716
717 //! Reference count.
718 volatile size_t refCount;
719 //! Impl type.
720 uint8_t implType;
721 //! Impl traits.
722 uint8_t implTraits;
723 //! Memory pool data.
724 uint16_t memPoolData;
725
726 //! Last faulty result (if failed).
727 BLResult lastResult;
728 //! Current frame index.
729 uint64_t frameIndex;
730 //! Position in source buffer.
731 size_t bufferIndex;
732
733 BL_HAS_TYPED_MEMBERS(BLImageEncoderImpl)
734};
735
736//! Image encoder [C Interface - Core].
737struct BLImageEncoderCore {
738 BLImageEncoderImpl* impl;
739};
740
741// ============================================================================
742// [BLImageEncoder - C++]
743// ============================================================================
744
745#ifdef __cplusplus
746//! Image encoder [C++ API].
747class BLImageEncoder : public BLImageEncoderCore {
748public:
749 //! \cond INTERNAL
750 static constexpr const uint32_t kImplType = BL_IMPL_TYPE_IMAGE_ENCODER;
751 //! \endcond
752
753 //! \name Construction & Destruction
754 //! \{
755
756 BL_INLINE BLImageEncoder() noexcept { this->impl = none().impl; }
757 BL_INLINE BLImageEncoder(BLImageEncoder&& other) noexcept { blVariantInitMove(this, &other); }
758 BL_INLINE BLImageEncoder(const BLImageEncoder& other) noexcept { blVariantInitWeak(this, &other); }
759 BL_INLINE explicit BLImageEncoder(BLImageEncoderImpl* impl) noexcept { this->impl = impl; }
760 BL_INLINE ~BLImageEncoder() { blImageEncoderReset(this); }
761
762 //! \}
763
764 //! \name Operator Overloads
765 //! \{
766
767 BL_INLINE explicit operator bool() const noexcept { return !isNone(); }
768
769 BL_INLINE BLImageEncoder& operator=(BLImageEncoder&& other) noexcept { blImageEncoderAssignMove(this, &other); return *this; }
770 BL_INLINE BLImageEncoder& operator=(const BLImageEncoder& other) noexcept { blImageEncoderAssignWeak(this, &other); return *this; }
771
772 BL_INLINE bool operator==(const BLImageEncoder& other) const noexcept { return equals(other); }
773 BL_INLINE bool operator!=(const BLImageEncoder& other) const noexcept { return !equals(other); }
774
775 //! \}
776
777 //! \name Common Functionality
778 //! \{
779
780 BL_INLINE BLResult reset() noexcept { return blImageEncoderReset(this); }
781 BL_INLINE void swap(BLImageEncoder& other) noexcept { std::swap(this->impl, other.impl); }
782
783 BL_INLINE BLResult assign(BLImageEncoder&& other) noexcept { return blImageEncoderAssignMove(this, &other); }
784 BL_INLINE BLResult assign(const BLImageEncoder& other) noexcept { return blImageEncoderAssignWeak(this, &other); }
785
786 //! Tests whether the image encoder is a built-in null instance.
787 BL_INLINE bool isNone() const noexcept { return (impl->implTraits & BL_IMPL_TRAIT_NULL) != 0; }
788
789 BL_INLINE bool equals(const BLImageEncoder& other) const noexcept { return this->impl == other.impl; }
790
791 //! \}
792
793 //! \name Properties
794 //! \{
795
796 //! Returns the last decoding result.
797 BL_INLINE BLResult lastResult() const noexcept { return impl->lastResult; }
798 //! Returns the current frame index (yet to be written).
799 BL_INLINE uint64_t frameIndex() const noexcept { return impl->frameIndex; }
800 //! Returns the position in destination buffer.
801 BL_INLINE size_t bufferIndex() const noexcept { return impl->bufferIndex; }
802
803 //! \}
804
805 //! \name Encoder Functionality
806 //! \{
807
808 BL_INLINE BLResult restart() noexcept { return blImageEncoderRestart(this); }
809
810 //! Encodes the given `image` and writes the encoded data to the destination buffer `dst`.
811 BL_INLINE BLResult writeFrame(BLArray<uint8_t>& dst, const BLImage& image) noexcept { return blImageEncoderWriteFrame(this, &dst, &image); }
812
813 //! \}
814
815 static BL_INLINE const BLImageEncoder& none() noexcept { return reinterpret_cast<const BLImageEncoder*>(blNone)[kImplType]; }
816};
817#endif
818
819//! \}
820
821#endif // BLEND2D_BLIMAGE_H
822