| #ifndef WUFFS_INCLUDE_GUARD |
| #define WUFFS_INCLUDE_GUARD |
| |
| // Wuffs ships as a "single file C library" or "header file library" as per |
| // https://github.com/nothings/stb/blob/master/docs/stb_howto.txt |
| // |
| // To use that single file as a "foo.c"-like implementation, instead of a |
| // "foo.h"-like header, #define WUFFS_IMPLEMENTATION before #include'ing or |
| // compiling it. |
| |
| // Copyright 2017 The Wuffs Authors. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // https://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| #include <stdbool.h> |
| #include <stdint.h> |
| #include <string.h> |
| |
| // GCC does not warn for unused *static inline* functions, but clang does. |
| #ifdef __clang__ |
| #pragma clang diagnostic push |
| #pragma clang diagnostic ignored "-Wunused-function" |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| // Wuffs assumes that: |
| // - converting a uint32_t to a size_t will never overflow. |
| // - converting a size_t to a uint64_t will never overflow. |
| #ifdef __WORDSIZE |
| #if (__WORDSIZE != 32) && (__WORDSIZE != 64) |
| #error "Wuffs requires a word size of either 32 or 64 bits" |
| #endif |
| #endif |
| |
| // WUFFS_VERSION is the major.minor.patch version, as per https://semver.org/, |
| // as a uint64_t. The major number is the high 32 bits. The minor number is the |
| // middle 16 bits. The patch number is the low 16 bits. The pre-release label |
| // and build metadata are part of the string representation (such as |
| // "1.2.3-beta+456.20181231") but not the uint64_t representation. |
| // |
| // WUFFS_VERSION_PRE_RELEASE_LABEL (such as "", "beta" or "rc.1") being |
| // non-empty denotes a developer preview, not a release version, and has no |
| // backwards or forwards compatibility guarantees. |
| // |
| // WUFFS_VERSION_BUILD_METADATA_XXX, if non-zero, are the number of commits and |
| // the last commit date in the repository used to build this library. Within |
| // each major.minor branch, the commit count should increase monotonically. |
| // |
| // WUFFS_VERSION was overridden by "wuffs gen -version" based on revision |
| // b36c9f019f2908639b0bb4dd5b8337bb3daf3271 committed on 2019-12-19. |
| #define WUFFS_VERSION ((uint64_t)0x0000000000020000) |
| #define WUFFS_VERSION_MAJOR ((uint64_t)0x00000000) |
| #define WUFFS_VERSION_MINOR ((uint64_t)0x0002) |
| #define WUFFS_VERSION_PATCH ((uint64_t)0x0000) |
| #define WUFFS_VERSION_PRE_RELEASE_LABEL "" |
| #define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 2078 |
| #define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20191219 |
| #define WUFFS_VERSION_STRING "0.2.0+2078.20191219" |
| |
| // Define WUFFS_CONFIG__STATIC_FUNCTIONS to make all of Wuffs' functions have |
| // static storage. The motivation is discussed in the "ALLOW STATIC |
| // IMPLEMENTATION" section of |
| // https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt |
| #ifdef WUFFS_CONFIG__STATIC_FUNCTIONS |
| #define WUFFS_BASE__MAYBE_STATIC static |
| #else |
| #define WUFFS_BASE__MAYBE_STATIC |
| #endif |
| |
| #if defined(__clang__) |
| #define WUFFS_BASE__POTENTIALLY_UNUSED_FIELD __attribute__((unused)) |
| #else |
| #define WUFFS_BASE__POTENTIALLY_UNUSED_FIELD |
| #endif |
| |
| // Clang also defines "__GNUC__". |
| #if defined(__GNUC__) |
| #define WUFFS_BASE__POTENTIALLY_UNUSED __attribute__((unused)) |
| #define WUFFS_BASE__WARN_UNUSED_RESULT __attribute__((warn_unused_result)) |
| #else |
| #define WUFFS_BASE__POTENTIALLY_UNUSED |
| #define WUFFS_BASE__WARN_UNUSED_RESULT |
| #endif |
| |
| // Flags for wuffs_foo__bar__initialize functions. |
| |
| #define WUFFS_INITIALIZE__DEFAULT_OPTIONS ((uint32_t)0x00000000) |
| |
| // WUFFS_INITIALIZE__ALREADY_ZEROED means that the "self" receiver struct value |
| // has already been set to all zeroes. |
| #define WUFFS_INITIALIZE__ALREADY_ZEROED ((uint32_t)0x00000001) |
| |
| // WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED means that, absent |
| // WUFFS_INITIALIZE__ALREADY_ZEROED, only some of the "self" receiver struct |
| // value will be set to all zeroes. Internal buffers, which tend to be a large |
| // proportion of the struct's size, will be left uninitialized. Internal means |
| // that the buffer is contained by the receiver struct, as opposed to being |
| // passed as a separately allocated "work buffer". |
| // |
| // For more detail, see: |
| // https://github.com/google/wuffs/blob/master/doc/note/initialization.md |
| #define WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED \ |
| ((uint32_t)0x00000002) |
| |
| // -------- |
| |
| // wuffs_base__empty_struct is used when a Wuffs function returns an empty |
| // struct. In C, if a function f returns void, you can't say "x = f()", but in |
| // Wuffs, if a function g returns empty, you can say "y = g()". |
| typedef struct { |
| // private_impl is a placeholder field. It isn't explicitly used, except that |
| // without it, the sizeof a struct with no fields can differ across C/C++ |
| // compilers, and it is undefined behavior in C99. For example, gcc says that |
| // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to |
| // ABI incompatibility if a Wuffs .c file is processed by one compiler and |
| // its .h file with another compiler. |
| // |
| // Instead, we explicitly insert an otherwise unused field, so that the |
| // sizeof this struct is always 1. |
| uint8_t private_impl; |
| } wuffs_base__empty_struct; |
| |
| static inline wuffs_base__empty_struct // |
| wuffs_base__make_empty_struct() { |
| wuffs_base__empty_struct ret; |
| ret.private_impl = 0; |
| return ret; |
| } |
| |
| // wuffs_base__utility is a placeholder receiver type. It enables what Java |
| // calls static methods, as opposed to regular methods. |
| typedef struct { |
| // private_impl is a placeholder field. It isn't explicitly used, except that |
| // without it, the sizeof a struct with no fields can differ across C/C++ |
| // compilers, and it is undefined behavior in C99. For example, gcc says that |
| // the sizeof an empty struct is 0, and g++ says that it is 1. This leads to |
| // ABI incompatibility if a Wuffs .c file is processed by one compiler and |
| // its .h file with another compiler. |
| // |
| // Instead, we explicitly insert an otherwise unused field, so that the |
| // sizeof this struct is always 1. |
| uint8_t private_impl; |
| } wuffs_base__utility; |
| |
| // -------- |
| |
| // See https://github.com/google/wuffs/blob/master/doc/note/statuses.md |
| typedef const char* wuffs_base__status; |
| |
| extern const char* wuffs_base__warning__end_of_data; |
| extern const char* wuffs_base__warning__metadata_reported; |
| extern const char* wuffs_base__suspension__short_read; |
| extern const char* wuffs_base__suspension__short_write; |
| extern const char* wuffs_base__error__bad_i_o_position; |
| extern const char* wuffs_base__error__bad_argument_length_too_short; |
| extern const char* wuffs_base__error__bad_argument; |
| extern const char* wuffs_base__error__bad_call_sequence; |
| extern const char* wuffs_base__error__bad_receiver; |
| extern const char* wuffs_base__error__bad_restart; |
| extern const char* wuffs_base__error__bad_sizeof_receiver; |
| extern const char* wuffs_base__error__bad_workbuf_length; |
| extern const char* wuffs_base__error__bad_wuffs_version; |
| extern const char* wuffs_base__error__cannot_return_a_suspension; |
| extern const char* wuffs_base__error__disabled_by_previous_error; |
| extern const char* wuffs_base__error__initialize_falsely_claimed_already_zeroed; |
| extern const char* wuffs_base__error__initialize_not_called; |
| extern const char* wuffs_base__error__interleaved_coroutine_calls; |
| extern const char* wuffs_base__error__not_enough_data; |
| extern const char* wuffs_base__error__unsupported_option; |
| extern const char* wuffs_base__error__too_much_data; |
| |
| static inline bool // |
| wuffs_base__status__is_complete(wuffs_base__status z) { |
| return (z == NULL) || ((*z != '$') && (*z != '#')); |
| } |
| |
| static inline bool // |
| wuffs_base__status__is_error(wuffs_base__status z) { |
| return z && (*z == '#'); |
| } |
| |
| static inline bool // |
| wuffs_base__status__is_ok(wuffs_base__status z) { |
| return z == NULL; |
| } |
| |
| static inline bool // |
| wuffs_base__status__is_suspension(wuffs_base__status z) { |
| return z && (*z == '$'); |
| } |
| |
| static inline bool // |
| wuffs_base__status__is_warning(wuffs_base__status z) { |
| return z && (*z != '$') && (*z != '#'); |
| } |
| |
| // wuffs_base__status__message strips the leading '$', '#' or '@'. |
| static inline const char* // |
| wuffs_base__status__message(wuffs_base__status z) { |
| if (z) { |
| if ((*z == '$') || (*z == '#') || (*z == '@')) { |
| return z + 1; |
| } |
| } |
| return z; |
| } |
| |
| // -------- |
| |
| // FourCC constants. |
| |
| // International Color Consortium Profile. |
| #define WUFFS_BASE__FOURCC__ICCP 0x49434350 |
| |
| // Extensible Metadata Platform. |
| #define WUFFS_BASE__FOURCC__XMP 0x584D5020 |
| |
| // -------- |
| |
| // Flicks are a unit of time. One flick (frame-tick) is 1 / 705_600_000 of a |
| // second. See https://github.com/OculusVR/Flicks |
| typedef int64_t wuffs_base__flicks; |
| |
| #define WUFFS_BASE__FLICKS_PER_SECOND ((uint64_t)705600000) |
| #define WUFFS_BASE__FLICKS_PER_MILLISECOND ((uint64_t)705600) |
| |
| // ---------------- Numeric Types |
| |
| static inline uint8_t // |
| wuffs_base__u8__min(uint8_t x, uint8_t y) { |
| return x < y ? x : y; |
| } |
| |
| static inline uint8_t // |
| wuffs_base__u8__max(uint8_t x, uint8_t y) { |
| return x > y ? x : y; |
| } |
| |
| static inline uint16_t // |
| wuffs_base__u16__min(uint16_t x, uint16_t y) { |
| return x < y ? x : y; |
| } |
| |
| static inline uint16_t // |
| wuffs_base__u16__max(uint16_t x, uint16_t y) { |
| return x > y ? x : y; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__u32__min(uint32_t x, uint32_t y) { |
| return x < y ? x : y; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__u32__max(uint32_t x, uint32_t y) { |
| return x > y ? x : y; |
| } |
| |
| static inline uint64_t // |
| wuffs_base__u64__min(uint64_t x, uint64_t y) { |
| return x < y ? x : y; |
| } |
| |
| static inline uint64_t // |
| wuffs_base__u64__max(uint64_t x, uint64_t y) { |
| return x > y ? x : y; |
| } |
| |
| // -------- |
| |
| // Saturating arithmetic (sat_add, sat_sub) branchless bit-twiddling algorithms |
| // are per https://locklessinc.com/articles/sat_arithmetic/ |
| // |
| // It is important that the underlying types are unsigned integers, as signed |
| // integer arithmetic overflow is undefined behavior in C. |
| |
| static inline uint8_t // |
| wuffs_base__u8__sat_add(uint8_t x, uint8_t y) { |
| uint8_t res = (uint8_t)(x + y); |
| res |= (uint8_t)(-(res < x)); |
| return res; |
| } |
| |
| static inline uint8_t // |
| wuffs_base__u8__sat_sub(uint8_t x, uint8_t y) { |
| uint8_t res = (uint8_t)(x - y); |
| res &= (uint8_t)(-(res <= x)); |
| return res; |
| } |
| |
| static inline uint16_t // |
| wuffs_base__u16__sat_add(uint16_t x, uint16_t y) { |
| uint16_t res = (uint16_t)(x + y); |
| res |= (uint16_t)(-(res < x)); |
| return res; |
| } |
| |
| static inline uint16_t // |
| wuffs_base__u16__sat_sub(uint16_t x, uint16_t y) { |
| uint16_t res = (uint16_t)(x - y); |
| res &= (uint16_t)(-(res <= x)); |
| return res; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__u32__sat_add(uint32_t x, uint32_t y) { |
| uint32_t res = (uint32_t)(x + y); |
| res |= (uint32_t)(-(res < x)); |
| return res; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__u32__sat_sub(uint32_t x, uint32_t y) { |
| uint32_t res = (uint32_t)(x - y); |
| res &= (uint32_t)(-(res <= x)); |
| return res; |
| } |
| |
| static inline uint64_t // |
| wuffs_base__u64__sat_add(uint64_t x, uint64_t y) { |
| uint64_t res = (uint64_t)(x + y); |
| res |= (uint64_t)(-(res < x)); |
| return res; |
| } |
| |
| static inline uint64_t // |
| wuffs_base__u64__sat_sub(uint64_t x, uint64_t y) { |
| uint64_t res = (uint64_t)(x - y); |
| res &= (uint64_t)(-(res <= x)); |
| return res; |
| } |
| |
| // ---------------- Slices and Tables |
| |
| // WUFFS_BASE__SLICE is a 1-dimensional buffer. |
| // |
| // len measures a number of elements, not necessarily a size in bytes. |
| // |
| // A value with all fields NULL or zero is a valid, empty slice. |
| #define WUFFS_BASE__SLICE(T) \ |
| struct { \ |
| T* ptr; \ |
| size_t len; \ |
| } |
| |
| // WUFFS_BASE__TABLE is a 2-dimensional buffer. |
| // |
| // width height, and stride measure a number of elements, not necessarily a |
| // size in bytes. |
| // |
| // A value with all fields NULL or zero is a valid, empty table. |
| #define WUFFS_BASE__TABLE(T) \ |
| struct { \ |
| T* ptr; \ |
| size_t width; \ |
| size_t height; \ |
| size_t stride; \ |
| } |
| |
| typedef WUFFS_BASE__SLICE(uint8_t) wuffs_base__slice_u8; |
| typedef WUFFS_BASE__SLICE(uint16_t) wuffs_base__slice_u16; |
| typedef WUFFS_BASE__SLICE(uint32_t) wuffs_base__slice_u32; |
| typedef WUFFS_BASE__SLICE(uint64_t) wuffs_base__slice_u64; |
| |
| typedef WUFFS_BASE__TABLE(uint8_t) wuffs_base__table_u8; |
| typedef WUFFS_BASE__TABLE(uint16_t) wuffs_base__table_u16; |
| typedef WUFFS_BASE__TABLE(uint32_t) wuffs_base__table_u32; |
| typedef WUFFS_BASE__TABLE(uint64_t) wuffs_base__table_u64; |
| |
| static inline wuffs_base__slice_u8 // |
| wuffs_base__make_slice_u8(uint8_t* ptr, size_t len) { |
| wuffs_base__slice_u8 ret; |
| ret.ptr = ptr; |
| ret.len = len; |
| return ret; |
| } |
| |
| static inline wuffs_base__slice_u16 // |
| wuffs_base__make_slice_u16(uint16_t* ptr, size_t len) { |
| wuffs_base__slice_u16 ret; |
| ret.ptr = ptr; |
| ret.len = len; |
| return ret; |
| } |
| |
| static inline wuffs_base__slice_u32 // |
| wuffs_base__make_slice_u32(uint32_t* ptr, size_t len) { |
| wuffs_base__slice_u32 ret; |
| ret.ptr = ptr; |
| ret.len = len; |
| return ret; |
| } |
| |
| static inline wuffs_base__slice_u64 // |
| wuffs_base__make_slice_u64(uint64_t* ptr, size_t len) { |
| wuffs_base__slice_u64 ret; |
| ret.ptr = ptr; |
| ret.len = len; |
| return ret; |
| } |
| |
| static inline wuffs_base__slice_u8 // |
| wuffs_base__empty_slice_u8() { |
| wuffs_base__slice_u8 ret; |
| ret.ptr = NULL; |
| ret.len = 0; |
| return ret; |
| } |
| |
| static inline wuffs_base__table_u8 // |
| wuffs_base__empty_table_u8() { |
| wuffs_base__table_u8 ret; |
| ret.ptr = NULL; |
| ret.width = 0; |
| ret.height = 0; |
| ret.stride = 0; |
| return ret; |
| } |
| |
| // wuffs_base__slice_u8__subslice_i returns s[i:]. |
| // |
| // It returns an empty slice if i is out of bounds. |
| static inline wuffs_base__slice_u8 // |
| wuffs_base__slice_u8__subslice_i(wuffs_base__slice_u8 s, uint64_t i) { |
| if ((i <= SIZE_MAX) && (i <= s.len)) { |
| return wuffs_base__make_slice_u8(s.ptr + i, s.len - i); |
| } |
| return wuffs_base__make_slice_u8(NULL, 0); |
| } |
| |
| // wuffs_base__slice_u8__subslice_j returns s[:j]. |
| // |
| // It returns an empty slice if j is out of bounds. |
| static inline wuffs_base__slice_u8 // |
| wuffs_base__slice_u8__subslice_j(wuffs_base__slice_u8 s, uint64_t j) { |
| if ((j <= SIZE_MAX) && (j <= s.len)) { |
| return wuffs_base__make_slice_u8(s.ptr, j); |
| } |
| return wuffs_base__make_slice_u8(NULL, 0); |
| } |
| |
| // wuffs_base__slice_u8__subslice_ij returns s[i:j]. |
| // |
| // It returns an empty slice if i or j is out of bounds. |
| static inline wuffs_base__slice_u8 // |
| wuffs_base__slice_u8__subslice_ij(wuffs_base__slice_u8 s, |
| uint64_t i, |
| uint64_t j) { |
| if ((i <= j) && (j <= SIZE_MAX) && (j <= s.len)) { |
| return wuffs_base__make_slice_u8(s.ptr + i, j - i); |
| } |
| return wuffs_base__make_slice_u8(NULL, 0); |
| } |
| |
| // ---------------- Ranges and Rects |
| |
| // See https://github.com/google/wuffs/blob/master/doc/note/ranges-and-rects.md |
| |
| typedef struct wuffs_base__range_ii_u32__struct { |
| uint32_t min_incl; |
| uint32_t max_incl; |
| |
| #ifdef __cplusplus |
| inline bool is_empty() const; |
| inline bool equals(wuffs_base__range_ii_u32__struct s) const; |
| inline wuffs_base__range_ii_u32__struct intersect( |
| wuffs_base__range_ii_u32__struct s) const; |
| inline wuffs_base__range_ii_u32__struct unite( |
| wuffs_base__range_ii_u32__struct s) const; |
| inline bool contains(uint32_t x) const; |
| inline bool contains_range(wuffs_base__range_ii_u32__struct s) const; |
| #endif // __cplusplus |
| |
| } wuffs_base__range_ii_u32; |
| |
| static inline wuffs_base__range_ii_u32 // |
| wuffs_base__make_range_ii_u32(uint32_t min_incl, uint32_t max_incl) { |
| wuffs_base__range_ii_u32 ret; |
| ret.min_incl = min_incl; |
| ret.max_incl = max_incl; |
| return ret; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ii_u32__is_empty(const wuffs_base__range_ii_u32* r) { |
| return r->min_incl > r->max_incl; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ii_u32__equals(const wuffs_base__range_ii_u32* r, |
| wuffs_base__range_ii_u32 s) { |
| return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) || |
| (wuffs_base__range_ii_u32__is_empty(r) && |
| wuffs_base__range_ii_u32__is_empty(&s)); |
| } |
| |
| static inline wuffs_base__range_ii_u32 // |
| wuffs_base__range_ii_u32__intersect(const wuffs_base__range_ii_u32* r, |
| wuffs_base__range_ii_u32 s) { |
| wuffs_base__range_ii_u32 t; |
| t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl); |
| t.max_incl = wuffs_base__u32__min(r->max_incl, s.max_incl); |
| return t; |
| } |
| |
| static inline wuffs_base__range_ii_u32 // |
| wuffs_base__range_ii_u32__unite(const wuffs_base__range_ii_u32* r, |
| wuffs_base__range_ii_u32 s) { |
| if (wuffs_base__range_ii_u32__is_empty(r)) { |
| return s; |
| } |
| if (wuffs_base__range_ii_u32__is_empty(&s)) { |
| return *r; |
| } |
| wuffs_base__range_ii_u32 t; |
| t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl); |
| t.max_incl = wuffs_base__u32__max(r->max_incl, s.max_incl); |
| return t; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ii_u32__contains(const wuffs_base__range_ii_u32* r, |
| uint32_t x) { |
| return (r->min_incl <= x) && (x <= r->max_incl); |
| } |
| |
| static inline bool // |
| wuffs_base__range_ii_u32__contains_range(const wuffs_base__range_ii_u32* r, |
| wuffs_base__range_ii_u32 s) { |
| return wuffs_base__range_ii_u32__equals( |
| &s, wuffs_base__range_ii_u32__intersect(r, s)); |
| } |
| |
| #ifdef __cplusplus |
| |
| inline bool // |
| wuffs_base__range_ii_u32::is_empty() const { |
| return wuffs_base__range_ii_u32__is_empty(this); |
| } |
| |
| inline bool // |
| wuffs_base__range_ii_u32::equals(wuffs_base__range_ii_u32 s) const { |
| return wuffs_base__range_ii_u32__equals(this, s); |
| } |
| |
| inline wuffs_base__range_ii_u32 // |
| wuffs_base__range_ii_u32::intersect(wuffs_base__range_ii_u32 s) const { |
| return wuffs_base__range_ii_u32__intersect(this, s); |
| } |
| |
| inline wuffs_base__range_ii_u32 // |
| wuffs_base__range_ii_u32::unite(wuffs_base__range_ii_u32 s) const { |
| return wuffs_base__range_ii_u32__unite(this, s); |
| } |
| |
| inline bool // |
| wuffs_base__range_ii_u32::contains(uint32_t x) const { |
| return wuffs_base__range_ii_u32__contains(this, x); |
| } |
| |
| inline bool // |
| wuffs_base__range_ii_u32::contains_range(wuffs_base__range_ii_u32 s) const { |
| return wuffs_base__range_ii_u32__contains_range(this, s); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct wuffs_base__range_ie_u32__struct { |
| uint32_t min_incl; |
| uint32_t max_excl; |
| |
| #ifdef __cplusplus |
| inline bool is_empty() const; |
| inline bool equals(wuffs_base__range_ie_u32__struct s) const; |
| inline wuffs_base__range_ie_u32__struct intersect( |
| wuffs_base__range_ie_u32__struct s) const; |
| inline wuffs_base__range_ie_u32__struct unite( |
| wuffs_base__range_ie_u32__struct s) const; |
| inline bool contains(uint32_t x) const; |
| inline bool contains_range(wuffs_base__range_ie_u32__struct s) const; |
| inline uint32_t length() const; |
| #endif // __cplusplus |
| |
| } wuffs_base__range_ie_u32; |
| |
| static inline wuffs_base__range_ie_u32 // |
| wuffs_base__make_range_ie_u32(uint32_t min_incl, uint32_t max_excl) { |
| wuffs_base__range_ie_u32 ret; |
| ret.min_incl = min_incl; |
| ret.max_excl = max_excl; |
| return ret; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ie_u32__is_empty(const wuffs_base__range_ie_u32* r) { |
| return r->min_incl >= r->max_excl; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ie_u32__equals(const wuffs_base__range_ie_u32* r, |
| wuffs_base__range_ie_u32 s) { |
| return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) || |
| (wuffs_base__range_ie_u32__is_empty(r) && |
| wuffs_base__range_ie_u32__is_empty(&s)); |
| } |
| |
| static inline wuffs_base__range_ie_u32 // |
| wuffs_base__range_ie_u32__intersect(const wuffs_base__range_ie_u32* r, |
| wuffs_base__range_ie_u32 s) { |
| wuffs_base__range_ie_u32 t; |
| t.min_incl = wuffs_base__u32__max(r->min_incl, s.min_incl); |
| t.max_excl = wuffs_base__u32__min(r->max_excl, s.max_excl); |
| return t; |
| } |
| |
| static inline wuffs_base__range_ie_u32 // |
| wuffs_base__range_ie_u32__unite(const wuffs_base__range_ie_u32* r, |
| wuffs_base__range_ie_u32 s) { |
| if (wuffs_base__range_ie_u32__is_empty(r)) { |
| return s; |
| } |
| if (wuffs_base__range_ie_u32__is_empty(&s)) { |
| return *r; |
| } |
| wuffs_base__range_ie_u32 t; |
| t.min_incl = wuffs_base__u32__min(r->min_incl, s.min_incl); |
| t.max_excl = wuffs_base__u32__max(r->max_excl, s.max_excl); |
| return t; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ie_u32__contains(const wuffs_base__range_ie_u32* r, |
| uint32_t x) { |
| return (r->min_incl <= x) && (x < r->max_excl); |
| } |
| |
| static inline bool // |
| wuffs_base__range_ie_u32__contains_range(const wuffs_base__range_ie_u32* r, |
| wuffs_base__range_ie_u32 s) { |
| return wuffs_base__range_ie_u32__equals( |
| &s, wuffs_base__range_ie_u32__intersect(r, s)); |
| } |
| |
| static inline uint32_t // |
| wuffs_base__range_ie_u32__length(const wuffs_base__range_ie_u32* r) { |
| return wuffs_base__u32__sat_sub(r->max_excl, r->min_incl); |
| } |
| |
| #ifdef __cplusplus |
| |
| inline bool // |
| wuffs_base__range_ie_u32::is_empty() const { |
| return wuffs_base__range_ie_u32__is_empty(this); |
| } |
| |
| inline bool // |
| wuffs_base__range_ie_u32::equals(wuffs_base__range_ie_u32 s) const { |
| return wuffs_base__range_ie_u32__equals(this, s); |
| } |
| |
| inline wuffs_base__range_ie_u32 // |
| wuffs_base__range_ie_u32::intersect(wuffs_base__range_ie_u32 s) const { |
| return wuffs_base__range_ie_u32__intersect(this, s); |
| } |
| |
| inline wuffs_base__range_ie_u32 // |
| wuffs_base__range_ie_u32::unite(wuffs_base__range_ie_u32 s) const { |
| return wuffs_base__range_ie_u32__unite(this, s); |
| } |
| |
| inline bool // |
| wuffs_base__range_ie_u32::contains(uint32_t x) const { |
| return wuffs_base__range_ie_u32__contains(this, x); |
| } |
| |
| inline bool // |
| wuffs_base__range_ie_u32::contains_range(wuffs_base__range_ie_u32 s) const { |
| return wuffs_base__range_ie_u32__contains_range(this, s); |
| } |
| |
| inline uint32_t // |
| wuffs_base__range_ie_u32::length() const { |
| return wuffs_base__range_ie_u32__length(this); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct wuffs_base__range_ii_u64__struct { |
| uint64_t min_incl; |
| uint64_t max_incl; |
| |
| #ifdef __cplusplus |
| inline bool is_empty() const; |
| inline bool equals(wuffs_base__range_ii_u64__struct s) const; |
| inline wuffs_base__range_ii_u64__struct intersect( |
| wuffs_base__range_ii_u64__struct s) const; |
| inline wuffs_base__range_ii_u64__struct unite( |
| wuffs_base__range_ii_u64__struct s) const; |
| inline bool contains(uint64_t x) const; |
| inline bool contains_range(wuffs_base__range_ii_u64__struct s) const; |
| #endif // __cplusplus |
| |
| } wuffs_base__range_ii_u64; |
| |
| static inline wuffs_base__range_ii_u64 // |
| wuffs_base__make_range_ii_u64(uint64_t min_incl, uint64_t max_incl) { |
| wuffs_base__range_ii_u64 ret; |
| ret.min_incl = min_incl; |
| ret.max_incl = max_incl; |
| return ret; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ii_u64__is_empty(const wuffs_base__range_ii_u64* r) { |
| return r->min_incl > r->max_incl; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ii_u64__equals(const wuffs_base__range_ii_u64* r, |
| wuffs_base__range_ii_u64 s) { |
| return (r->min_incl == s.min_incl && r->max_incl == s.max_incl) || |
| (wuffs_base__range_ii_u64__is_empty(r) && |
| wuffs_base__range_ii_u64__is_empty(&s)); |
| } |
| |
| static inline wuffs_base__range_ii_u64 // |
| wuffs_base__range_ii_u64__intersect(const wuffs_base__range_ii_u64* r, |
| wuffs_base__range_ii_u64 s) { |
| wuffs_base__range_ii_u64 t; |
| t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl); |
| t.max_incl = wuffs_base__u64__min(r->max_incl, s.max_incl); |
| return t; |
| } |
| |
| static inline wuffs_base__range_ii_u64 // |
| wuffs_base__range_ii_u64__unite(const wuffs_base__range_ii_u64* r, |
| wuffs_base__range_ii_u64 s) { |
| if (wuffs_base__range_ii_u64__is_empty(r)) { |
| return s; |
| } |
| if (wuffs_base__range_ii_u64__is_empty(&s)) { |
| return *r; |
| } |
| wuffs_base__range_ii_u64 t; |
| t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl); |
| t.max_incl = wuffs_base__u64__max(r->max_incl, s.max_incl); |
| return t; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ii_u64__contains(const wuffs_base__range_ii_u64* r, |
| uint64_t x) { |
| return (r->min_incl <= x) && (x <= r->max_incl); |
| } |
| |
| static inline bool // |
| wuffs_base__range_ii_u64__contains_range(const wuffs_base__range_ii_u64* r, |
| wuffs_base__range_ii_u64 s) { |
| return wuffs_base__range_ii_u64__equals( |
| &s, wuffs_base__range_ii_u64__intersect(r, s)); |
| } |
| |
| #ifdef __cplusplus |
| |
| inline bool // |
| wuffs_base__range_ii_u64::is_empty() const { |
| return wuffs_base__range_ii_u64__is_empty(this); |
| } |
| |
| inline bool // |
| wuffs_base__range_ii_u64::equals(wuffs_base__range_ii_u64 s) const { |
| return wuffs_base__range_ii_u64__equals(this, s); |
| } |
| |
| inline wuffs_base__range_ii_u64 // |
| wuffs_base__range_ii_u64::intersect(wuffs_base__range_ii_u64 s) const { |
| return wuffs_base__range_ii_u64__intersect(this, s); |
| } |
| |
| inline wuffs_base__range_ii_u64 // |
| wuffs_base__range_ii_u64::unite(wuffs_base__range_ii_u64 s) const { |
| return wuffs_base__range_ii_u64__unite(this, s); |
| } |
| |
| inline bool // |
| wuffs_base__range_ii_u64::contains(uint64_t x) const { |
| return wuffs_base__range_ii_u64__contains(this, x); |
| } |
| |
| inline bool // |
| wuffs_base__range_ii_u64::contains_range(wuffs_base__range_ii_u64 s) const { |
| return wuffs_base__range_ii_u64__contains_range(this, s); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct wuffs_base__range_ie_u64__struct { |
| uint64_t min_incl; |
| uint64_t max_excl; |
| |
| #ifdef __cplusplus |
| inline bool is_empty() const; |
| inline bool equals(wuffs_base__range_ie_u64__struct s) const; |
| inline wuffs_base__range_ie_u64__struct intersect( |
| wuffs_base__range_ie_u64__struct s) const; |
| inline wuffs_base__range_ie_u64__struct unite( |
| wuffs_base__range_ie_u64__struct s) const; |
| inline bool contains(uint64_t x) const; |
| inline bool contains_range(wuffs_base__range_ie_u64__struct s) const; |
| inline uint64_t length() const; |
| #endif // __cplusplus |
| |
| } wuffs_base__range_ie_u64; |
| |
| static inline wuffs_base__range_ie_u64 // |
| wuffs_base__make_range_ie_u64(uint64_t min_incl, uint64_t max_excl) { |
| wuffs_base__range_ie_u64 ret; |
| ret.min_incl = min_incl; |
| ret.max_excl = max_excl; |
| return ret; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ie_u64__is_empty(const wuffs_base__range_ie_u64* r) { |
| return r->min_incl >= r->max_excl; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ie_u64__equals(const wuffs_base__range_ie_u64* r, |
| wuffs_base__range_ie_u64 s) { |
| return (r->min_incl == s.min_incl && r->max_excl == s.max_excl) || |
| (wuffs_base__range_ie_u64__is_empty(r) && |
| wuffs_base__range_ie_u64__is_empty(&s)); |
| } |
| |
| static inline wuffs_base__range_ie_u64 // |
| wuffs_base__range_ie_u64__intersect(const wuffs_base__range_ie_u64* r, |
| wuffs_base__range_ie_u64 s) { |
| wuffs_base__range_ie_u64 t; |
| t.min_incl = wuffs_base__u64__max(r->min_incl, s.min_incl); |
| t.max_excl = wuffs_base__u64__min(r->max_excl, s.max_excl); |
| return t; |
| } |
| |
| static inline wuffs_base__range_ie_u64 // |
| wuffs_base__range_ie_u64__unite(const wuffs_base__range_ie_u64* r, |
| wuffs_base__range_ie_u64 s) { |
| if (wuffs_base__range_ie_u64__is_empty(r)) { |
| return s; |
| } |
| if (wuffs_base__range_ie_u64__is_empty(&s)) { |
| return *r; |
| } |
| wuffs_base__range_ie_u64 t; |
| t.min_incl = wuffs_base__u64__min(r->min_incl, s.min_incl); |
| t.max_excl = wuffs_base__u64__max(r->max_excl, s.max_excl); |
| return t; |
| } |
| |
| static inline bool // |
| wuffs_base__range_ie_u64__contains(const wuffs_base__range_ie_u64* r, |
| uint64_t x) { |
| return (r->min_incl <= x) && (x < r->max_excl); |
| } |
| |
| static inline bool // |
| wuffs_base__range_ie_u64__contains_range(const wuffs_base__range_ie_u64* r, |
| wuffs_base__range_ie_u64 s) { |
| return wuffs_base__range_ie_u64__equals( |
| &s, wuffs_base__range_ie_u64__intersect(r, s)); |
| } |
| |
| static inline uint64_t // |
| wuffs_base__range_ie_u64__length(const wuffs_base__range_ie_u64* r) { |
| return wuffs_base__u64__sat_sub(r->max_excl, r->min_incl); |
| } |
| |
| #ifdef __cplusplus |
| |
| inline bool // |
| wuffs_base__range_ie_u64::is_empty() const { |
| return wuffs_base__range_ie_u64__is_empty(this); |
| } |
| |
| inline bool // |
| wuffs_base__range_ie_u64::equals(wuffs_base__range_ie_u64 s) const { |
| return wuffs_base__range_ie_u64__equals(this, s); |
| } |
| |
| inline wuffs_base__range_ie_u64 // |
| wuffs_base__range_ie_u64::intersect(wuffs_base__range_ie_u64 s) const { |
| return wuffs_base__range_ie_u64__intersect(this, s); |
| } |
| |
| inline wuffs_base__range_ie_u64 // |
| wuffs_base__range_ie_u64::unite(wuffs_base__range_ie_u64 s) const { |
| return wuffs_base__range_ie_u64__unite(this, s); |
| } |
| |
| inline bool // |
| wuffs_base__range_ie_u64::contains(uint64_t x) const { |
| return wuffs_base__range_ie_u64__contains(this, x); |
| } |
| |
| inline bool // |
| wuffs_base__range_ie_u64::contains_range(wuffs_base__range_ie_u64 s) const { |
| return wuffs_base__range_ie_u64__contains_range(this, s); |
| } |
| |
| inline uint64_t // |
| wuffs_base__range_ie_u64::length() const { |
| return wuffs_base__range_ie_u64__length(this); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct wuffs_base__rect_ii_u32__struct { |
| uint32_t min_incl_x; |
| uint32_t min_incl_y; |
| uint32_t max_incl_x; |
| uint32_t max_incl_y; |
| |
| #ifdef __cplusplus |
| inline bool is_empty() const; |
| inline bool equals(wuffs_base__rect_ii_u32__struct s) const; |
| inline wuffs_base__rect_ii_u32__struct intersect( |
| wuffs_base__rect_ii_u32__struct s) const; |
| inline wuffs_base__rect_ii_u32__struct unite( |
| wuffs_base__rect_ii_u32__struct s) const; |
| inline bool contains(uint32_t x, uint32_t y) const; |
| inline bool contains_rect(wuffs_base__rect_ii_u32__struct s) const; |
| #endif // __cplusplus |
| |
| } wuffs_base__rect_ii_u32; |
| |
| static inline wuffs_base__rect_ii_u32 // |
| wuffs_base__make_rect_ii_u32(uint32_t min_incl_x, |
| uint32_t min_incl_y, |
| uint32_t max_incl_x, |
| uint32_t max_incl_y) { |
| wuffs_base__rect_ii_u32 ret; |
| ret.min_incl_x = min_incl_x; |
| ret.min_incl_y = min_incl_y; |
| ret.max_incl_x = max_incl_x; |
| ret.max_incl_y = max_incl_y; |
| return ret; |
| } |
| |
| static inline bool // |
| wuffs_base__rect_ii_u32__is_empty(const wuffs_base__rect_ii_u32* r) { |
| return (r->min_incl_x > r->max_incl_x) || (r->min_incl_y > r->max_incl_y); |
| } |
| |
| static inline bool // |
| wuffs_base__rect_ii_u32__equals(const wuffs_base__rect_ii_u32* r, |
| wuffs_base__rect_ii_u32 s) { |
| return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y && |
| r->max_incl_x == s.max_incl_x && r->max_incl_y == s.max_incl_y) || |
| (wuffs_base__rect_ii_u32__is_empty(r) && |
| wuffs_base__rect_ii_u32__is_empty(&s)); |
| } |
| |
| static inline wuffs_base__rect_ii_u32 // |
| wuffs_base__rect_ii_u32__intersect(const wuffs_base__rect_ii_u32* r, |
| wuffs_base__rect_ii_u32 s) { |
| wuffs_base__rect_ii_u32 t; |
| t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x); |
| t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y); |
| t.max_incl_x = wuffs_base__u32__min(r->max_incl_x, s.max_incl_x); |
| t.max_incl_y = wuffs_base__u32__min(r->max_incl_y, s.max_incl_y); |
| return t; |
| } |
| |
| static inline wuffs_base__rect_ii_u32 // |
| wuffs_base__rect_ii_u32__unite(const wuffs_base__rect_ii_u32* r, |
| wuffs_base__rect_ii_u32 s) { |
| if (wuffs_base__rect_ii_u32__is_empty(r)) { |
| return s; |
| } |
| if (wuffs_base__rect_ii_u32__is_empty(&s)) { |
| return *r; |
| } |
| wuffs_base__rect_ii_u32 t; |
| t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x); |
| t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y); |
| t.max_incl_x = wuffs_base__u32__max(r->max_incl_x, s.max_incl_x); |
| t.max_incl_y = wuffs_base__u32__max(r->max_incl_y, s.max_incl_y); |
| return t; |
| } |
| |
| static inline bool // |
| wuffs_base__rect_ii_u32__contains(const wuffs_base__rect_ii_u32* r, |
| uint32_t x, |
| uint32_t y) { |
| return (r->min_incl_x <= x) && (x <= r->max_incl_x) && (r->min_incl_y <= y) && |
| (y <= r->max_incl_y); |
| } |
| |
| static inline bool // |
| wuffs_base__rect_ii_u32__contains_rect(const wuffs_base__rect_ii_u32* r, |
| wuffs_base__rect_ii_u32 s) { |
| return wuffs_base__rect_ii_u32__equals( |
| &s, wuffs_base__rect_ii_u32__intersect(r, s)); |
| } |
| |
| #ifdef __cplusplus |
| |
| inline bool // |
| wuffs_base__rect_ii_u32::is_empty() const { |
| return wuffs_base__rect_ii_u32__is_empty(this); |
| } |
| |
| inline bool // |
| wuffs_base__rect_ii_u32::equals(wuffs_base__rect_ii_u32 s) const { |
| return wuffs_base__rect_ii_u32__equals(this, s); |
| } |
| |
| inline wuffs_base__rect_ii_u32 // |
| wuffs_base__rect_ii_u32::intersect(wuffs_base__rect_ii_u32 s) const { |
| return wuffs_base__rect_ii_u32__intersect(this, s); |
| } |
| |
| inline wuffs_base__rect_ii_u32 // |
| wuffs_base__rect_ii_u32::unite(wuffs_base__rect_ii_u32 s) const { |
| return wuffs_base__rect_ii_u32__unite(this, s); |
| } |
| |
| inline bool // |
| wuffs_base__rect_ii_u32::contains(uint32_t x, uint32_t y) const { |
| return wuffs_base__rect_ii_u32__contains(this, x, y); |
| } |
| |
| inline bool // |
| wuffs_base__rect_ii_u32::contains_rect(wuffs_base__rect_ii_u32 s) const { |
| return wuffs_base__rect_ii_u32__contains_rect(this, s); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct wuffs_base__rect_ie_u32__struct { |
| uint32_t min_incl_x; |
| uint32_t min_incl_y; |
| uint32_t max_excl_x; |
| uint32_t max_excl_y; |
| |
| #ifdef __cplusplus |
| inline bool is_empty() const; |
| inline bool equals(wuffs_base__rect_ie_u32__struct s) const; |
| inline wuffs_base__rect_ie_u32__struct intersect( |
| wuffs_base__rect_ie_u32__struct s) const; |
| inline wuffs_base__rect_ie_u32__struct unite( |
| wuffs_base__rect_ie_u32__struct s) const; |
| inline bool contains(uint32_t x, uint32_t y) const; |
| inline bool contains_rect(wuffs_base__rect_ie_u32__struct s) const; |
| inline uint32_t width() const; |
| inline uint32_t height() const; |
| #endif // __cplusplus |
| |
| } wuffs_base__rect_ie_u32; |
| |
| static inline wuffs_base__rect_ie_u32 // |
| wuffs_base__make_rect_ie_u32(uint32_t min_incl_x, |
| uint32_t min_incl_y, |
| uint32_t max_excl_x, |
| uint32_t max_excl_y) { |
| wuffs_base__rect_ie_u32 ret; |
| ret.min_incl_x = min_incl_x; |
| ret.min_incl_y = min_incl_y; |
| ret.max_excl_x = max_excl_x; |
| ret.max_excl_y = max_excl_y; |
| return ret; |
| } |
| |
| static inline bool // |
| wuffs_base__rect_ie_u32__is_empty(const wuffs_base__rect_ie_u32* r) { |
| return (r->min_incl_x >= r->max_excl_x) || (r->min_incl_y >= r->max_excl_y); |
| } |
| |
| static inline bool // |
| wuffs_base__rect_ie_u32__equals(const wuffs_base__rect_ie_u32* r, |
| wuffs_base__rect_ie_u32 s) { |
| return (r->min_incl_x == s.min_incl_x && r->min_incl_y == s.min_incl_y && |
| r->max_excl_x == s.max_excl_x && r->max_excl_y == s.max_excl_y) || |
| (wuffs_base__rect_ie_u32__is_empty(r) && |
| wuffs_base__rect_ie_u32__is_empty(&s)); |
| } |
| |
| static inline wuffs_base__rect_ie_u32 // |
| wuffs_base__rect_ie_u32__intersect(const wuffs_base__rect_ie_u32* r, |
| wuffs_base__rect_ie_u32 s) { |
| wuffs_base__rect_ie_u32 t; |
| t.min_incl_x = wuffs_base__u32__max(r->min_incl_x, s.min_incl_x); |
| t.min_incl_y = wuffs_base__u32__max(r->min_incl_y, s.min_incl_y); |
| t.max_excl_x = wuffs_base__u32__min(r->max_excl_x, s.max_excl_x); |
| t.max_excl_y = wuffs_base__u32__min(r->max_excl_y, s.max_excl_y); |
| return t; |
| } |
| |
| static inline wuffs_base__rect_ie_u32 // |
| wuffs_base__rect_ie_u32__unite(const wuffs_base__rect_ie_u32* r, |
| wuffs_base__rect_ie_u32 s) { |
| if (wuffs_base__rect_ie_u32__is_empty(r)) { |
| return s; |
| } |
| if (wuffs_base__rect_ie_u32__is_empty(&s)) { |
| return *r; |
| } |
| wuffs_base__rect_ie_u32 t; |
| t.min_incl_x = wuffs_base__u32__min(r->min_incl_x, s.min_incl_x); |
| t.min_incl_y = wuffs_base__u32__min(r->min_incl_y, s.min_incl_y); |
| t.max_excl_x = wuffs_base__u32__max(r->max_excl_x, s.max_excl_x); |
| t.max_excl_y = wuffs_base__u32__max(r->max_excl_y, s.max_excl_y); |
| return t; |
| } |
| |
| static inline bool // |
| wuffs_base__rect_ie_u32__contains(const wuffs_base__rect_ie_u32* r, |
| uint32_t x, |
| uint32_t y) { |
| return (r->min_incl_x <= x) && (x < r->max_excl_x) && (r->min_incl_y <= y) && |
| (y < r->max_excl_y); |
| } |
| |
| static inline bool // |
| wuffs_base__rect_ie_u32__contains_rect(const wuffs_base__rect_ie_u32* r, |
| wuffs_base__rect_ie_u32 s) { |
| return wuffs_base__rect_ie_u32__equals( |
| &s, wuffs_base__rect_ie_u32__intersect(r, s)); |
| } |
| |
| static inline uint32_t // |
| wuffs_base__rect_ie_u32__width(const wuffs_base__rect_ie_u32* r) { |
| return wuffs_base__u32__sat_sub(r->max_excl_x, r->min_incl_x); |
| } |
| |
| static inline uint32_t // |
| wuffs_base__rect_ie_u32__height(const wuffs_base__rect_ie_u32* r) { |
| return wuffs_base__u32__sat_sub(r->max_excl_y, r->min_incl_y); |
| } |
| |
| #ifdef __cplusplus |
| |
| inline bool // |
| wuffs_base__rect_ie_u32::is_empty() const { |
| return wuffs_base__rect_ie_u32__is_empty(this); |
| } |
| |
| inline bool // |
| wuffs_base__rect_ie_u32::equals(wuffs_base__rect_ie_u32 s) const { |
| return wuffs_base__rect_ie_u32__equals(this, s); |
| } |
| |
| inline wuffs_base__rect_ie_u32 // |
| wuffs_base__rect_ie_u32::intersect(wuffs_base__rect_ie_u32 s) const { |
| return wuffs_base__rect_ie_u32__intersect(this, s); |
| } |
| |
| inline wuffs_base__rect_ie_u32 // |
| wuffs_base__rect_ie_u32::unite(wuffs_base__rect_ie_u32 s) const { |
| return wuffs_base__rect_ie_u32__unite(this, s); |
| } |
| |
| inline bool // |
| wuffs_base__rect_ie_u32::contains(uint32_t x, uint32_t y) const { |
| return wuffs_base__rect_ie_u32__contains(this, x, y); |
| } |
| |
| inline bool // |
| wuffs_base__rect_ie_u32::contains_rect(wuffs_base__rect_ie_u32 s) const { |
| return wuffs_base__rect_ie_u32__contains_rect(this, s); |
| } |
| |
| inline uint32_t // |
| wuffs_base__rect_ie_u32::width() const { |
| return wuffs_base__rect_ie_u32__width(this); |
| } |
| |
| inline uint32_t // |
| wuffs_base__rect_ie_u32::height() const { |
| return wuffs_base__rect_ie_u32__height(this); |
| } |
| |
| #endif // __cplusplus |
| |
| // ---------------- I/O |
| // |
| // See (/doc/note/io-input-output.md). |
| |
| // wuffs_base__io_buffer_meta is the metadata for a wuffs_base__io_buffer's |
| // data. |
| typedef struct { |
| size_t wi; // Write index. Invariant: wi <= len. |
| size_t ri; // Read index. Invariant: ri <= wi. |
| uint64_t pos; // Position of the buffer start relative to the stream start. |
| bool closed; // No further writes are expected. |
| } wuffs_base__io_buffer_meta; |
| |
| // wuffs_base__io_buffer is a 1-dimensional buffer (a pointer and length) plus |
| // additional metadata. |
| // |
| // A value with all fields zero is a valid, empty buffer. |
| typedef struct { |
| wuffs_base__slice_u8 data; |
| wuffs_base__io_buffer_meta meta; |
| |
| #ifdef __cplusplus |
| inline void compact(); |
| inline uint64_t reader_available() const; |
| inline uint64_t reader_io_position() const; |
| inline uint64_t writer_available() const; |
| inline uint64_t writer_io_position() const; |
| #endif // __cplusplus |
| |
| } wuffs_base__io_buffer; |
| |
| static inline wuffs_base__io_buffer // |
| wuffs_base__make_io_buffer(wuffs_base__slice_u8 data, |
| wuffs_base__io_buffer_meta meta) { |
| wuffs_base__io_buffer ret; |
| ret.data = data; |
| ret.meta = meta; |
| return ret; |
| } |
| |
| static inline wuffs_base__io_buffer_meta // |
| wuffs_base__make_io_buffer_meta(size_t wi, |
| size_t ri, |
| uint64_t pos, |
| bool closed) { |
| wuffs_base__io_buffer_meta ret; |
| ret.wi = wi; |
| ret.ri = ri; |
| ret.pos = pos; |
| ret.closed = closed; |
| return ret; |
| } |
| |
| static inline wuffs_base__io_buffer // |
| wuffs_base__empty_io_buffer() { |
| wuffs_base__io_buffer ret; |
| ret.data.ptr = NULL; |
| ret.data.len = 0; |
| ret.meta.wi = 0; |
| ret.meta.ri = 0; |
| ret.meta.pos = 0; |
| ret.meta.closed = false; |
| return ret; |
| } |
| |
| static inline wuffs_base__io_buffer_meta // |
| wuffs_base__empty_io_buffer_meta() { |
| wuffs_base__io_buffer_meta ret; |
| ret.wi = 0; |
| ret.ri = 0; |
| ret.pos = 0; |
| ret.closed = false; |
| return ret; |
| } |
| |
| // wuffs_base__io_buffer__compact moves any written but unread bytes to the |
| // start of the buffer. |
| static inline void // |
| wuffs_base__io_buffer__compact(wuffs_base__io_buffer* buf) { |
| if (!buf || (buf->meta.ri == 0)) { |
| return; |
| } |
| buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri); |
| size_t n = buf->meta.wi - buf->meta.ri; |
| if (n != 0) { |
| memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, n); |
| } |
| buf->meta.wi = n; |
| buf->meta.ri = 0; |
| } |
| |
| static inline uint64_t // |
| wuffs_base__io_buffer__reader_available(const wuffs_base__io_buffer* buf) { |
| return buf ? buf->meta.wi - buf->meta.ri : 0; |
| } |
| |
| static inline uint64_t // |
| wuffs_base__io_buffer__reader_io_position(const wuffs_base__io_buffer* buf) { |
| return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0; |
| } |
| |
| static inline uint64_t // |
| wuffs_base__io_buffer__writer_available(const wuffs_base__io_buffer* buf) { |
| return buf ? buf->data.len - buf->meta.wi : 0; |
| } |
| |
| static inline uint64_t // |
| wuffs_base__io_buffer__writer_io_position(const wuffs_base__io_buffer* buf) { |
| return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0; |
| } |
| |
| #ifdef __cplusplus |
| |
| inline void // |
| wuffs_base__io_buffer::compact() { |
| wuffs_base__io_buffer__compact(this); |
| } |
| |
| inline uint64_t // |
| wuffs_base__io_buffer::reader_available() const { |
| return wuffs_base__io_buffer__reader_available(this); |
| } |
| |
| inline uint64_t // |
| wuffs_base__io_buffer::reader_io_position() const { |
| return wuffs_base__io_buffer__reader_io_position(this); |
| } |
| |
| inline uint64_t // |
| wuffs_base__io_buffer::writer_available() const { |
| return wuffs_base__io_buffer__writer_available(this); |
| } |
| |
| inline uint64_t // |
| wuffs_base__io_buffer::writer_io_position() const { |
| return wuffs_base__io_buffer__writer_io_position(this); |
| } |
| |
| #endif // __cplusplus |
| |
| // ---------------- Memory Allocation |
| |
| // The memory allocation related functions in this section aren't used by Wuffs |
| // per se, but they may be helpful to the code that uses Wuffs. |
| |
| // wuffs_base__malloc_slice_uxx wraps calling a malloc-like function, except |
| // that it takes a uint64_t number of elements instead of a size_t size in |
| // bytes, and it returns a slice (a pointer and a length) instead of just a |
| // pointer. |
| // |
| // You can pass the C stdlib's malloc as the malloc_func. |
| // |
| // It returns an empty slice (containing a NULL ptr field) if (num_uxx * |
| // sizeof(uintxx_t)) would overflow SIZE_MAX. |
| |
| static inline wuffs_base__slice_u8 // |
| wuffs_base__malloc_slice_u8(void* (*malloc_func)(size_t), uint64_t num_u8) { |
| if (malloc_func && (num_u8 <= (SIZE_MAX / sizeof(uint8_t)))) { |
| void* p = (*malloc_func)(num_u8 * sizeof(uint8_t)); |
| if (p) { |
| return wuffs_base__make_slice_u8((uint8_t*)(p), num_u8); |
| } |
| } |
| return wuffs_base__make_slice_u8(NULL, 0); |
| } |
| |
| static inline wuffs_base__slice_u16 // |
| wuffs_base__malloc_slice_u16(void* (*malloc_func)(size_t), uint64_t num_u16) { |
| if (malloc_func && (num_u16 <= (SIZE_MAX / sizeof(uint16_t)))) { |
| void* p = (*malloc_func)(num_u16 * sizeof(uint16_t)); |
| if (p) { |
| return wuffs_base__make_slice_u16((uint16_t*)(p), num_u16); |
| } |
| } |
| return wuffs_base__make_slice_u16(NULL, 0); |
| } |
| |
| static inline wuffs_base__slice_u32 // |
| wuffs_base__malloc_slice_u32(void* (*malloc_func)(size_t), uint64_t num_u32) { |
| if (malloc_func && (num_u32 <= (SIZE_MAX / sizeof(uint32_t)))) { |
| void* p = (*malloc_func)(num_u32 * sizeof(uint32_t)); |
| if (p) { |
| return wuffs_base__make_slice_u32((uint32_t*)(p), num_u32); |
| } |
| } |
| return wuffs_base__make_slice_u32(NULL, 0); |
| } |
| |
| static inline wuffs_base__slice_u64 // |
| wuffs_base__malloc_slice_u64(void* (*malloc_func)(size_t), uint64_t num_u64) { |
| if (malloc_func && (num_u64 <= (SIZE_MAX / sizeof(uint64_t)))) { |
| void* p = (*malloc_func)(num_u64 * sizeof(uint64_t)); |
| if (p) { |
| return wuffs_base__make_slice_u64((uint64_t*)(p), num_u64); |
| } |
| } |
| return wuffs_base__make_slice_u64(NULL, 0); |
| } |
| |
| // ---------------- Images |
| |
| // wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied |
| // Alpha, Red, Green, Blue color, as a uint32_t value. It is in word order, not |
| // byte order: its value is always 0xAARRGGBB, regardless of endianness. |
| typedef uint32_t wuffs_base__color_u32_argb_premul; |
| |
| // -------- |
| |
| // wuffs_base__pixel_format encodes the format of the bytes that constitute an |
| // image frame's pixel data. |
| // |
| // See https://github.com/google/wuffs/blob/master/doc/note/pixel-formats.md |
| // |
| // Do not manipulate its bits directly; they are private implementation |
| // details. Use methods such as wuffs_base__pixel_format__num_planes instead. |
| typedef uint32_t wuffs_base__pixel_format; |
| |
| // Common 8-bit-depth pixel formats. This list is not exhaustive; not all valid |
| // wuffs_base__pixel_format values are present. |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__INVALID ((wuffs_base__pixel_format)0x00000000) |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__A ((wuffs_base__pixel_format)0x02000008) |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__Y ((wuffs_base__pixel_format)0x10000008) |
| #define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL \ |
| ((wuffs_base__pixel_format)0x15000008) |
| #define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL \ |
| ((wuffs_base__pixel_format)0x16000008) |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__YCBCR ((wuffs_base__pixel_format)0x20020888) |
| #define WUFFS_BASE__PIXEL_FORMAT__YCBCRK ((wuffs_base__pixel_format)0x21038888) |
| #define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL \ |
| ((wuffs_base__pixel_format)0x25038888) |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__YCOCG ((wuffs_base__pixel_format)0x30020888) |
| #define WUFFS_BASE__PIXEL_FORMAT__YCOCGK ((wuffs_base__pixel_format)0x31038888) |
| #define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL \ |
| ((wuffs_base__pixel_format)0x35038888) |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL \ |
| ((wuffs_base__pixel_format)0x45040008) |
| #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL \ |
| ((wuffs_base__pixel_format)0x46040008) |
| #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY \ |
| ((wuffs_base__pixel_format)0x47040008) |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__BGR ((wuffs_base__pixel_format)0x40000888) |
| #define WUFFS_BASE__PIXEL_FORMAT__BGRX ((wuffs_base__pixel_format)0x41008888) |
| #define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL \ |
| ((wuffs_base__pixel_format)0x45008888) |
| #define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL \ |
| ((wuffs_base__pixel_format)0x46008888) |
| #define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY \ |
| ((wuffs_base__pixel_format)0x47008888) |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__RGB ((wuffs_base__pixel_format)0x50000888) |
| #define WUFFS_BASE__PIXEL_FORMAT__RGBX ((wuffs_base__pixel_format)0x51008888) |
| #define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL \ |
| ((wuffs_base__pixel_format)0x55008888) |
| #define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL \ |
| ((wuffs_base__pixel_format)0x56008888) |
| #define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY \ |
| ((wuffs_base__pixel_format)0x57008888) |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__CMY ((wuffs_base__pixel_format)0x60020888) |
| #define WUFFS_BASE__PIXEL_FORMAT__CMYK ((wuffs_base__pixel_format)0x61038888) |
| |
| extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16]; |
| |
| static inline bool // |
| wuffs_base__pixel_format__is_valid(wuffs_base__pixel_format f) { |
| return f != 0; |
| } |
| |
| // wuffs_base__pixel_format__bits_per_pixel returns the number of bits per |
| // pixel for interleaved pixel formats, and returns 0 for planar pixel formats. |
| static inline uint32_t // |
| wuffs_base__pixel_format__bits_per_pixel(wuffs_base__pixel_format f) { |
| if (((f >> 16) & 0x03) != 0) { |
| return 0; |
| } |
| return wuffs_base__pixel_format__bits_per_channel[0x0F & (f >> 0)] + |
| wuffs_base__pixel_format__bits_per_channel[0x0F & (f >> 4)] + |
| wuffs_base__pixel_format__bits_per_channel[0x0F & (f >> 8)] + |
| wuffs_base__pixel_format__bits_per_channel[0x0F & (f >> 12)]; |
| } |
| |
| static inline bool // |
| wuffs_base__pixel_format__is_indexed(wuffs_base__pixel_format f) { |
| return (f >> 18) & 0x01; |
| } |
| |
| static inline bool // |
| wuffs_base__pixel_format__is_interleaved(wuffs_base__pixel_format f) { |
| return ((f >> 16) & 0x03) == 0; |
| } |
| |
| static inline bool // |
| wuffs_base__pixel_format__is_planar(wuffs_base__pixel_format f) { |
| return ((f >> 16) & 0x03) != 0; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__pixel_format__num_planes(wuffs_base__pixel_format f) { |
| return ((f >> 16) & 0x03) + 1; |
| } |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4 |
| |
| #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0 |
| #define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3 |
| |
| // -------- |
| |
| // wuffs_base__pixel_subsampling encodes whether sample values cover one pixel |
| // or cover multiple pixels. |
| // |
| // See https://github.com/google/wuffs/blob/master/doc/note/pixel-subsampling.md |
| // |
| // Do not manipulate its bits directly; they are private implementation |
| // details. Use methods such as wuffs_base__pixel_subsampling__bias_x instead. |
| typedef uint32_t wuffs_base__pixel_subsampling; |
| |
| #define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE ((wuffs_base__pixel_subsampling)0) |
| |
| #define WUFFS_BASE__PIXEL_SUBSAMPLING__444 \ |
| ((wuffs_base__pixel_subsampling)0x000000) |
| #define WUFFS_BASE__PIXEL_SUBSAMPLING__440 \ |
| ((wuffs_base__pixel_subsampling)0x010100) |
| #define WUFFS_BASE__PIXEL_SUBSAMPLING__422 \ |
| ((wuffs_base__pixel_subsampling)0x101000) |
| #define WUFFS_BASE__PIXEL_SUBSAMPLING__420 \ |
| ((wuffs_base__pixel_subsampling)0x111100) |
| #define WUFFS_BASE__PIXEL_SUBSAMPLING__411 \ |
| ((wuffs_base__pixel_subsampling)0x303000) |
| #define WUFFS_BASE__PIXEL_SUBSAMPLING__410 \ |
| ((wuffs_base__pixel_subsampling)0x313100) |
| |
| static inline uint32_t // |
| wuffs_base__pixel_subsampling__bias_x(wuffs_base__pixel_subsampling s, |
| uint32_t plane) { |
| uint32_t shift = ((plane & 0x03) * 8) + 6; |
| return (s >> shift) & 0x03; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__pixel_subsampling__denominator_x(wuffs_base__pixel_subsampling s, |
| uint32_t plane) { |
| uint32_t shift = ((plane & 0x03) * 8) + 4; |
| return ((s >> shift) & 0x03) + 1; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__pixel_subsampling__bias_y(wuffs_base__pixel_subsampling s, |
| uint32_t plane) { |
| uint32_t shift = ((plane & 0x03) * 8) + 2; |
| return (s >> shift) & 0x03; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__pixel_subsampling__denominator_y(wuffs_base__pixel_subsampling s, |
| uint32_t plane) { |
| uint32_t shift = ((plane & 0x03) * 8) + 0; |
| return ((s >> shift) & 0x03) + 1; |
| } |
| |
| // -------- |
| |
| typedef struct { |
| // Do not access the private_impl's fields directly. There is no API/ABI |
| // compatibility or safety guarantee if you do so. |
| struct { |
| wuffs_base__pixel_format pixfmt; |
| wuffs_base__pixel_subsampling pixsub; |
| uint32_t width; |
| uint32_t height; |
| } private_impl; |
| |
| #ifdef __cplusplus |
| inline void set(wuffs_base__pixel_format pixfmt, |
| wuffs_base__pixel_subsampling pixsub, |
| uint32_t width, |
| uint32_t height); |
| inline void invalidate(); |
| inline bool is_valid() const; |
| inline wuffs_base__pixel_format pixel_format() const; |
| inline wuffs_base__pixel_subsampling pixel_subsampling() const; |
| inline wuffs_base__rect_ie_u32 bounds() const; |
| inline uint32_t width() const; |
| inline uint32_t height() const; |
| inline uint64_t pixbuf_len() const; |
| #endif // __cplusplus |
| |
| } wuffs_base__pixel_config; |
| |
| static inline wuffs_base__pixel_config // |
| wuffs_base__null_pixel_config() { |
| wuffs_base__pixel_config ret; |
| ret.private_impl.pixfmt = 0; |
| ret.private_impl.pixsub = 0; |
| ret.private_impl.width = 0; |
| ret.private_impl.height = 0; |
| return ret; |
| } |
| |
| // TODO: Should this function return bool? An error type? |
| static inline void // |
| wuffs_base__pixel_config__set(wuffs_base__pixel_config* c, |
| wuffs_base__pixel_format pixfmt, |
| wuffs_base__pixel_subsampling pixsub, |
| uint32_t width, |
| uint32_t height) { |
| if (!c) { |
| return; |
| } |
| if (pixfmt) { |
| uint64_t wh = ((uint64_t)width) * ((uint64_t)height); |
| // TODO: handle things other than 1 byte per pixel. |
| if (wh <= ((uint64_t)SIZE_MAX)) { |
| c->private_impl.pixfmt = pixfmt; |
| c->private_impl.pixsub = pixsub; |
| c->private_impl.width = width; |
| c->private_impl.height = height; |
| return; |
| } |
| } |
| |
| c->private_impl.pixfmt = 0; |
| c->private_impl.pixsub = 0; |
| c->private_impl.width = 0; |
| c->private_impl.height = 0; |
| } |
| |
| static inline void // |
| wuffs_base__pixel_config__invalidate(wuffs_base__pixel_config* c) { |
| if (c) { |
| c->private_impl.pixfmt = 0; |
| c->private_impl.pixsub = 0; |
| c->private_impl.width = 0; |
| c->private_impl.height = 0; |
| } |
| } |
| |
| static inline bool // |
| wuffs_base__pixel_config__is_valid(const wuffs_base__pixel_config* c) { |
| return c && c->private_impl.pixfmt; |
| } |
| |
| static inline wuffs_base__pixel_format // |
| wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) { |
| return c ? c->private_impl.pixfmt : 0; |
| } |
| |
| static inline wuffs_base__pixel_subsampling // |
| wuffs_base__pixel_config__pixel_subsampling(const wuffs_base__pixel_config* c) { |
| return c ? c->private_impl.pixsub : 0; |
| } |
| |
| static inline wuffs_base__rect_ie_u32 // |
| wuffs_base__pixel_config__bounds(const wuffs_base__pixel_config* c) { |
| if (c) { |
| wuffs_base__rect_ie_u32 ret; |
| ret.min_incl_x = 0; |
| ret.min_incl_y = 0; |
| ret.max_excl_x = c->private_impl.width; |
| ret.max_excl_y = c->private_impl.height; |
| return ret; |
| } |
| |
| wuffs_base__rect_ie_u32 ret; |
| ret.min_incl_x = 0; |
| ret.min_incl_y = 0; |
| ret.max_excl_x = 0; |
| ret.max_excl_y = 0; |
| return ret; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__pixel_config__width(const wuffs_base__pixel_config* c) { |
| return c ? c->private_impl.width : 0; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__pixel_config__height(const wuffs_base__pixel_config* c) { |
| return c ? c->private_impl.height : 0; |
| } |
| |
| // TODO: this is the right API for planar (not interleaved) pixbufs? Should it |
| // allow decoding into a color model different from the format's intrinsic one? |
| // For example, decoding a JPEG image straight to RGBA instead of to YCbCr? |
| static inline uint64_t // |
| wuffs_base__pixel_config__pixbuf_len(const wuffs_base__pixel_config* c) { |
| if (!c) { |
| return 0; |
| } |
| if (wuffs_base__pixel_format__is_planar(c->private_impl.pixfmt)) { |
| // TODO: support planar pixel formats, concious of pixel subsampling. |
| return 0; |
| } |
| uint32_t bits_per_pixel = |
| wuffs_base__pixel_format__bits_per_pixel(c->private_impl.pixfmt); |
| if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) { |
| // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel? |
| return 0; |
| } |
| uint64_t bytes_per_pixel = bits_per_pixel / 8; |
| |
| uint64_t n = |
| ((uint64_t)c->private_impl.width) * ((uint64_t)c->private_impl.height); |
| if (n > (UINT64_MAX / bytes_per_pixel)) { |
| return 0; |
| } |
| n *= bytes_per_pixel; |
| |
| if (wuffs_base__pixel_format__is_indexed(c->private_impl.pixfmt)) { |
| if (n > (UINT64_MAX - 1024)) { |
| return 0; |
| } |
| n += 1024; |
| } |
| |
| return n; |
| } |
| |
| #ifdef __cplusplus |
| |
| inline void // |
| wuffs_base__pixel_config::set(wuffs_base__pixel_format pixfmt, |
| wuffs_base__pixel_subsampling pixsub, |
| uint32_t width, |
| uint32_t height) { |
| wuffs_base__pixel_config__set(this, pixfmt, pixsub, width, height); |
| } |
| |
| inline void // |
| wuffs_base__pixel_config::invalidate() { |
| wuffs_base__pixel_config__invalidate(this); |
| } |
| |
| inline bool // |
| wuffs_base__pixel_config::is_valid() const { |
| return wuffs_base__pixel_config__is_valid(this); |
| } |
| |
| inline wuffs_base__pixel_format // |
| wuffs_base__pixel_config::pixel_format() const { |
| return wuffs_base__pixel_config__pixel_format(this); |
| } |
| |
| inline wuffs_base__pixel_subsampling // |
| wuffs_base__pixel_config::pixel_subsampling() const { |
| return wuffs_base__pixel_config__pixel_subsampling(this); |
| } |
| |
| inline wuffs_base__rect_ie_u32 // |
| wuffs_base__pixel_config::bounds() const { |
| return wuffs_base__pixel_config__bounds(this); |
| } |
| |
| inline uint32_t // |
| wuffs_base__pixel_config::width() const { |
| return wuffs_base__pixel_config__width(this); |
| } |
| |
| inline uint32_t // |
| wuffs_base__pixel_config::height() const { |
| return wuffs_base__pixel_config__height(this); |
| } |
| |
| inline uint64_t // |
| wuffs_base__pixel_config::pixbuf_len() const { |
| return wuffs_base__pixel_config__pixbuf_len(this); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct { |
| wuffs_base__pixel_config pixcfg; |
| |
| // Do not access the private_impl's fields directly. There is no API/ABI |
| // compatibility or safety guarantee if you do so. |
| struct { |
| uint64_t first_frame_io_position; |
| bool first_frame_is_opaque; |
| } private_impl; |
| |
| #ifdef __cplusplus |
| inline void set(wuffs_base__pixel_format pixfmt, |
| wuffs_base__pixel_subsampling pixsub, |
| uint32_t width, |
| uint32_t height, |
| uint64_t first_frame_io_position, |
| bool first_frame_is_opaque); |
| inline void invalidate(); |
| inline bool is_valid() const; |
| inline uint64_t first_frame_io_position() const; |
| inline bool first_frame_is_opaque() const; |
| #endif // __cplusplus |
| |
| } wuffs_base__image_config; |
| |
| static inline wuffs_base__image_config // |
| wuffs_base__null_image_config() { |
| wuffs_base__image_config ret; |
| ret.pixcfg = wuffs_base__null_pixel_config(); |
| ret.private_impl.first_frame_io_position = 0; |
| ret.private_impl.first_frame_is_opaque = false; |
| return ret; |
| } |
| |
| // TODO: Should this function return bool? An error type? |
| static inline void // |
| wuffs_base__image_config__set(wuffs_base__image_config* c, |
| wuffs_base__pixel_format pixfmt, |
| wuffs_base__pixel_subsampling pixsub, |
| uint32_t width, |
| uint32_t height, |
| uint64_t first_frame_io_position, |
| bool first_frame_is_opaque) { |
| if (!c) { |
| return; |
| } |
| if (wuffs_base__pixel_format__is_valid(pixfmt)) { |
| c->pixcfg.private_impl.pixfmt = pixfmt; |
| c->pixcfg.private_impl.pixsub = pixsub; |
| c->pixcfg.private_impl.width = width; |
| c->pixcfg.private_impl.height = height; |
| c->private_impl.first_frame_io_position = first_frame_io_position; |
| c->private_impl.first_frame_is_opaque = first_frame_is_opaque; |
| return; |
| } |
| |
| c->pixcfg.private_impl.pixfmt = 0; |
| c->pixcfg.private_impl.pixsub = 0; |
| c->pixcfg.private_impl.width = 0; |
| c->pixcfg.private_impl.height = 0; |
| c->private_impl.first_frame_io_position = 0; |
| c->private_impl.first_frame_is_opaque = 0; |
| } |
| |
| static inline void // |
| wuffs_base__image_config__invalidate(wuffs_base__image_config* c) { |
| if (c) { |
| c->pixcfg.private_impl.pixfmt = 0; |
| c->pixcfg.private_impl.pixsub = 0; |
| c->pixcfg.private_impl.width = 0; |
| c->pixcfg.private_impl.height = 0; |
| c->private_impl.first_frame_io_position = 0; |
| c->private_impl.first_frame_is_opaque = 0; |
| } |
| } |
| |
| static inline bool // |
| wuffs_base__image_config__is_valid(const wuffs_base__image_config* c) { |
| return c && wuffs_base__pixel_config__is_valid(&(c->pixcfg)); |
| } |
| |
| static inline uint64_t // |
| wuffs_base__image_config__first_frame_io_position( |
| const wuffs_base__image_config* c) { |
| return c ? c->private_impl.first_frame_io_position : 0; |
| } |
| |
| static inline bool // |
| wuffs_base__image_config__first_frame_is_opaque( |
| const wuffs_base__image_config* c) { |
| return c ? c->private_impl.first_frame_is_opaque : false; |
| } |
| |
| #ifdef __cplusplus |
| |
| inline void // |
| wuffs_base__image_config::set(wuffs_base__pixel_format pixfmt, |
| wuffs_base__pixel_subsampling pixsub, |
| uint32_t width, |
| uint32_t height, |
| uint64_t first_frame_io_position, |
| bool first_frame_is_opaque) { |
| wuffs_base__image_config__set(this, pixfmt, pixsub, width, height, |
| first_frame_io_position, first_frame_is_opaque); |
| } |
| |
| inline void // |
| wuffs_base__image_config::invalidate() { |
| wuffs_base__image_config__invalidate(this); |
| } |
| |
| inline bool // |
| wuffs_base__image_config::is_valid() const { |
| return wuffs_base__image_config__is_valid(this); |
| } |
| |
| inline uint64_t // |
| wuffs_base__image_config::first_frame_io_position() const { |
| return wuffs_base__image_config__first_frame_io_position(this); |
| } |
| |
| inline bool // |
| wuffs_base__image_config::first_frame_is_opaque() const { |
| return wuffs_base__image_config__first_frame_is_opaque(this); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| // wuffs_base__animation_blend encodes, for an animated image, how to blend the |
| // transparent pixels of this frame with the existing canvas. In Porter-Duff |
| // compositing operator terminology: |
| // - 0 means the frame may be transparent, and should be blended "src over |
| // dst", also known as just "over". |
| // - 1 means the frame may be transparent, and should be blended "src". |
| // - 2 means the frame is completely opaque, so that "src over dst" and "src" |
| // are equivalent. |
| // |
| // These semantics are conservative. It is valid for a completely opaque frame |
| // to have a blend value other than 2. |
| typedef uint8_t wuffs_base__animation_blend; |
| |
| #define WUFFS_BASE__ANIMATION_BLEND__SRC_OVER_DST \ |
| ((wuffs_base__animation_blend)0) |
| #define WUFFS_BASE__ANIMATION_BLEND__SRC ((wuffs_base__animation_blend)1) |
| #define WUFFS_BASE__ANIMATION_BLEND__OPAQUE ((wuffs_base__animation_blend)2) |
| |
| // -------- |
| |
| // wuffs_base__animation_disposal encodes, for an animated image, how to |
| // dispose of a frame after displaying it: |
| // - None means to draw the next frame on top of this one. |
| // - Restore Background means to clear the frame's dirty rectangle to "the |
| // background color" (in practice, this means transparent black) before |
| // drawing the next frame. |
| // - Restore Previous means to undo the current frame, so that the next frame |
| // is drawn on top of the previous one. |
| typedef uint8_t wuffs_base__animation_disposal; |
| |
| #define WUFFS_BASE__ANIMATION_DISPOSAL__NONE ((wuffs_base__animation_disposal)0) |
| #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_BACKGROUND \ |
| ((wuffs_base__animation_disposal)1) |
| #define WUFFS_BASE__ANIMATION_DISPOSAL__RESTORE_PREVIOUS \ |
| ((wuffs_base__animation_disposal)2) |
| |
| // -------- |
| |
| typedef struct { |
| // Do not access the private_impl's fields directly. There is no API/ABI |
| // compatibility or safety guarantee if you do so. |
| struct { |
| wuffs_base__rect_ie_u32 bounds; |
| wuffs_base__flicks duration; |
| uint64_t index; |
| uint64_t io_position; |
| wuffs_base__animation_blend blend; |
| wuffs_base__animation_disposal disposal; |
| wuffs_base__color_u32_argb_premul background_color; |
| } private_impl; |
| |
| #ifdef __cplusplus |
| inline void update(wuffs_base__rect_ie_u32 bounds, |
| wuffs_base__flicks duration, |
| uint64_t index, |
| uint64_t io_position, |
| wuffs_base__animation_blend blend, |
| wuffs_base__animation_disposal disposal, |
| wuffs_base__color_u32_argb_premul background_color); |
| inline wuffs_base__rect_ie_u32 bounds() const; |
| inline uint32_t width() const; |
| inline uint32_t height() const; |
| inline wuffs_base__flicks duration() const; |
| inline uint64_t index() const; |
| inline uint64_t io_position() const; |
| inline wuffs_base__animation_blend blend() const; |
| inline wuffs_base__animation_disposal disposal() const; |
| inline wuffs_base__color_u32_argb_premul background_color() const; |
| #endif // __cplusplus |
| |
| } wuffs_base__frame_config; |
| |
| static inline wuffs_base__frame_config // |
| wuffs_base__null_frame_config() { |
| wuffs_base__frame_config ret; |
| ret.private_impl.bounds = wuffs_base__make_rect_ie_u32(0, 0, 0, 0); |
| ret.private_impl.duration = 0; |
| ret.private_impl.index = 0; |
| ret.private_impl.io_position = 0; |
| ret.private_impl.blend = 0; |
| ret.private_impl.disposal = 0; |
| return ret; |
| } |
| |
| static inline void // |
| wuffs_base__frame_config__update( |
| wuffs_base__frame_config* c, |
| wuffs_base__rect_ie_u32 bounds, |
| wuffs_base__flicks duration, |
| uint64_t index, |
| uint64_t io_position, |
| wuffs_base__animation_blend blend, |
| wuffs_base__animation_disposal disposal, |
| wuffs_base__color_u32_argb_premul background_color) { |
| if (!c) { |
| return; |
| } |
| |
| c->private_impl.bounds = bounds; |
| c->private_impl.duration = duration; |
| c->private_impl.index = index; |
| c->private_impl.io_position = io_position; |
| c->private_impl.blend = blend; |
| c->private_impl.disposal = disposal; |
| c->private_impl.background_color = background_color; |
| } |
| |
| static inline wuffs_base__rect_ie_u32 // |
| wuffs_base__frame_config__bounds(const wuffs_base__frame_config* c) { |
| if (c) { |
| return c->private_impl.bounds; |
| } |
| |
| wuffs_base__rect_ie_u32 ret; |
| ret.min_incl_x = 0; |
| ret.min_incl_y = 0; |
| ret.max_excl_x = 0; |
| ret.max_excl_y = 0; |
| return ret; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__frame_config__width(const wuffs_base__frame_config* c) { |
| return c ? wuffs_base__rect_ie_u32__width(&c->private_impl.bounds) : 0; |
| } |
| |
| static inline uint32_t // |
| wuffs_base__frame_config__height(const wuffs_base__frame_config* c) { |
| return c ? wuffs_base__rect_ie_u32__height(&c->private_impl.bounds) : 0; |
| } |
| |
| // wuffs_base__frame_config__duration returns the amount of time to display |
| // this frame. Zero means to display forever - a still (non-animated) image. |
| static inline wuffs_base__flicks // |
| wuffs_base__frame_config__duration(const wuffs_base__frame_config* c) { |
| return c ? c->private_impl.duration : 0; |
| } |
| |
| // wuffs_base__frame_config__index returns the index of this frame. The first |
| // frame in an image has index 0, the second frame has index 1, and so on. |
| static inline uint64_t // |
| wuffs_base__frame_config__index(const wuffs_base__frame_config* c) { |
| return c ? c->private_impl.index : 0; |
| } |
| |
| // wuffs_base__frame_config__io_position returns the I/O stream position before |
| // the frame config. |
| static inline uint64_t // |
| wuffs_base__frame_config__io_position(const wuffs_base__frame_config* c) { |
| return c ? c->private_impl.io_position : 0; |
| } |
| |
| // wuffs_base__frame_config__blend returns, for an animated image, how to blend |
| // the transparent pixels of this frame with the existing canvas. |
| static inline wuffs_base__animation_blend // |
| wuffs_base__frame_config__blend(const wuffs_base__frame_config* c) { |
| return c ? c->private_impl.blend : 0; |
| } |
| |
| // wuffs_base__frame_config__disposal returns, for an animated image, how to |
| // dispose of this frame after displaying it. |
| static inline wuffs_base__animation_disposal // |
| wuffs_base__frame_config__disposal(const wuffs_base__frame_config* c) { |
| return c ? c->private_impl.disposal : 0; |
| } |
| |
| static inline wuffs_base__color_u32_argb_premul // |
| wuffs_base__frame_config__background_color(const wuffs_base__frame_config* c) { |
| return c ? c->private_impl.background_color : 0; |
| } |
| |
| #ifdef __cplusplus |
| |
| inline void // |
| wuffs_base__frame_config::update( |
| wuffs_base__rect_ie_u32 bounds, |
| wuffs_base__flicks duration, |
| uint64_t index, |
| uint64_t io_position, |
| wuffs_base__animation_blend blend, |
| wuffs_base__animation_disposal disposal, |
| wuffs_base__color_u32_argb_premul background_color) { |
| wuffs_base__frame_config__update(this, bounds, duration, index, io_position, |
| blend, disposal, background_color); |
| } |
| |
| inline wuffs_base__rect_ie_u32 // |
| wuffs_base__frame_config::bounds() const { |
| return wuffs_base__frame_config__bounds(this); |
| } |
| |
| inline uint32_t // |
| wuffs_base__frame_config::width() const { |
| return wuffs_base__frame_config__width(this); |
| } |
| |
| inline uint32_t // |
| wuffs_base__frame_config::height() const { |
| return wuffs_base__frame_config__height(this); |
| } |
| |
| inline wuffs_base__flicks // |
| wuffs_base__frame_config::duration() const { |
| return wuffs_base__frame_config__duration(this); |
| } |
| |
| inline uint64_t // |
| wuffs_base__frame_config::index() const { |
| return wuffs_base__frame_config__index(this); |
| } |
| |
| inline uint64_t // |
| wuffs_base__frame_config::io_position() const { |
| return wuffs_base__frame_config__io_position(this); |
| } |
| |
| inline wuffs_base__animation_blend // |
| wuffs_base__frame_config::blend() const { |
| return wuffs_base__frame_config__blend(this); |
| } |
| |
| inline wuffs_base__animation_disposal // |
| wuffs_base__frame_config::disposal() const { |
| return wuffs_base__frame_config__disposal(this); |
| } |
| |
| inline wuffs_base__color_u32_argb_premul // |
| wuffs_base__frame_config::background_color() const { |
| return wuffs_base__frame_config__background_color(this); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct { |
| wuffs_base__pixel_config pixcfg; |
| |
| // Do not access the private_impl's fields directly. There is no API/ABI |
| // compatibility or safety guarantee if you do so. |
| struct { |
| wuffs_base__table_u8 planes[WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX]; |
| // TODO: color spaces. |
| } private_impl; |
| |
| #ifdef __cplusplus |
| inline wuffs_base__status set_from_slice( |
| const wuffs_base__pixel_config* pixcfg, |
| wuffs_base__slice_u8 pixbuf_memory); |
| inline wuffs_base__status set_from_table( |
| const wuffs_base__pixel_config* pixcfg, |
| wuffs_base__table_u8 pixbuf_memory); |
| inline wuffs_base__slice_u8 palette(); |
| inline wuffs_base__pixel_format pixel_format() const; |
| inline wuffs_base__table_u8 plane(uint32_t p); |
| #endif // __cplusplus |
| |
| } wuffs_base__pixel_buffer; |
| |
| static inline wuffs_base__pixel_buffer // |
| wuffs_base__null_pixel_buffer() { |
| wuffs_base__pixel_buffer ret; |
| ret.pixcfg = wuffs_base__null_pixel_config(); |
| ret.private_impl.planes[0] = wuffs_base__empty_table_u8(); |
| ret.private_impl.planes[1] = wuffs_base__empty_table_u8(); |
| ret.private_impl.planes[2] = wuffs_base__empty_table_u8(); |
| ret.private_impl.planes[3] = wuffs_base__empty_table_u8(); |
| return ret; |
| } |
| |
| static inline wuffs_base__status // |
| wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* b, |
| const wuffs_base__pixel_config* pixcfg, |
| wuffs_base__slice_u8 pixbuf_memory) { |
| if (!b) { |
| return wuffs_base__error__bad_receiver; |
| } |
| memset(b, 0, sizeof(*b)); |
| if (!pixcfg) { |
| return wuffs_base__error__bad_argument; |
| } |
| if (wuffs_base__pixel_format__is_planar(pixcfg->private_impl.pixfmt)) { |
| // TODO: support planar pixel formats, concious of pixel subsampling. |
| return wuffs_base__error__unsupported_option; |
| } |
| uint32_t bits_per_pixel = |
| wuffs_base__pixel_format__bits_per_pixel(pixcfg->private_impl.pixfmt); |
| if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) { |
| // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel? |
| return wuffs_base__error__unsupported_option; |
| } |
| uint64_t bytes_per_pixel = bits_per_pixel / 8; |
| |
| uint8_t* ptr = pixbuf_memory.ptr; |
| uint64_t len = pixbuf_memory.len; |
| if (wuffs_base__pixel_format__is_indexed(pixcfg->private_impl.pixfmt)) { |
| // Split a 1024 byte chunk (256 palette entries × 4 bytes per entry) from |
| // the start of pixbuf_memory. We split from the start, not the end, so |
| // that the both chunks' pointers have the same alignment as the original |
| // pointer, up to an alignment of 1024. |
| if (len < 1024) { |
| return wuffs_base__error__bad_argument_length_too_short; |
| } |
| wuffs_base__table_u8* tab = |
| &b->private_impl.planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE]; |
| tab->ptr = ptr; |
| tab->width = 1024; |
| tab->height = 1; |
| tab->stride = 1024; |
| ptr += 1024; |
| len -= 1024; |
| } |
| |
| uint64_t wh = ((uint64_t)pixcfg->private_impl.width) * |
| ((uint64_t)pixcfg->private_impl.height); |
| size_t width = (size_t)(pixcfg->private_impl.width); |
| if ((wh > (UINT64_MAX / bytes_per_pixel)) || |
| (width > (SIZE_MAX / bytes_per_pixel))) { |
| return wuffs_base__error__bad_argument; |
| } |
| wh *= bytes_per_pixel; |
| width *= bytes_per_pixel; |
| if (wh > len) { |
| return wuffs_base__error__bad_argument_length_too_short; |
| } |
| |
| b->pixcfg = *pixcfg; |
| wuffs_base__table_u8* tab = &b->private_impl.planes[0]; |
| tab->ptr = ptr; |
| tab->width = width; |
| tab->height = pixcfg->private_impl.height; |
| tab->stride = width; |
| return NULL; |
| } |
| |
| static inline wuffs_base__status // |
| wuffs_base__pixel_buffer__set_from_table(wuffs_base__pixel_buffer* b, |
| const wuffs_base__pixel_config* pixcfg, |
| wuffs_base__table_u8 pixbuf_memory) { |
| if (!b) { |
| return wuffs_base__error__bad_receiver; |
| } |
| memset(b, 0, sizeof(*b)); |
| if (!pixcfg || |
| wuffs_base__pixel_format__is_planar(pixcfg->private_impl.pixfmt)) { |
| return wuffs_base__error__bad_argument; |
| } |
| uint32_t bits_per_pixel = |
| wuffs_base__pixel_format__bits_per_pixel(pixcfg->private_impl.pixfmt); |
| if ((bits_per_pixel == 0) || ((bits_per_pixel % 8) != 0)) { |
| // TODO: support fraction-of-byte pixels, e.g. 1 bit per pixel? |
| return wuffs_base__error__unsupported_option; |
| } |
| uint64_t bytes_per_pixel = bits_per_pixel / 8; |
| |
| uint64_t width_in_bytes = |
| ((uint64_t)pixcfg->private_impl.width) * bytes_per_pixel; |
| if ((width_in_bytes > pixbuf_memory.width) || |
| (pixcfg->private_impl.height > pixbuf_memory.height)) { |
| return wuffs_base__error__bad_argument; |
| } |
| |
| b->pixcfg = *pixcfg; |
| b->private_impl.planes[0] = pixbuf_memory; |
| return NULL; |
| } |
| |
| // wuffs_base__pixel_buffer__palette returns the palette color data. If |
| // non-empty, it will have length 1024. |
| static inline wuffs_base__slice_u8 // |
| wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* b) { |
| if (b && |
| wuffs_base__pixel_format__is_indexed(b->pixcfg.private_impl.pixfmt)) { |
| wuffs_base__table_u8* tab = |
| &b->private_impl.planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE]; |
| if ((tab->width == 1024) && (tab->height == 1)) { |
| return wuffs_base__make_slice_u8(tab->ptr, 1024); |
| } |
| } |
| return wuffs_base__make_slice_u8(NULL, 0); |
| } |
| |
| static inline wuffs_base__pixel_format // |
| wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* b) { |
| if (b) { |
| return b->pixcfg.private_impl.pixfmt; |
| } |
| return WUFFS_BASE__PIXEL_FORMAT__INVALID; |
| } |
| |
| static inline wuffs_base__table_u8 // |
| wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* b, uint32_t p) { |
| if (b && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX)) { |
| return b->private_impl.planes[p]; |
| } |
| |
| wuffs_base__table_u8 ret; |
| ret.ptr = NULL; |
| ret.width = 0; |
| ret.height = 0; |
| ret.stride = 0; |
| return ret; |
| } |
| |
| #ifdef __cplusplus |
| |
| inline wuffs_base__status // |
| wuffs_base__pixel_buffer::set_from_slice(const wuffs_base__pixel_config* pixcfg, |
| wuffs_base__slice_u8 pixbuf_memory) { |
| return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg, pixbuf_memory); |
| } |
| |
| inline wuffs_base__status // |
| wuffs_base__pixel_buffer::set_from_table(const wuffs_base__pixel_config* pixcfg, |
| wuffs_base__table_u8 pixbuf_memory) { |
| return wuffs_base__pixel_buffer__set_from_table(this, pixcfg, pixbuf_memory); |
| } |
| |
| inline wuffs_base__slice_u8 // |
| wuffs_base__pixel_buffer::palette() { |
| return wuffs_base__pixel_buffer__palette(this); |
| } |
| |
| inline wuffs_base__pixel_format // |
| wuffs_base__pixel_buffer::pixel_format() const { |
| return wuffs_base__pixel_buffer__pixel_format(this); |
| } |
| |
| inline wuffs_base__table_u8 // |
| wuffs_base__pixel_buffer::plane(uint32_t p) { |
| return wuffs_base__pixel_buffer__plane(this, p); |
| } |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct { |
| // Do not access the private_impl's fields directly. There is no API/ABI |
| // compatibility or safety guarantee if you do so. |
| struct { |
| uint8_t TODO; |
| } private_impl; |
| |
| #ifdef __cplusplus |
| #endif // __cplusplus |
| |
| } wuffs_base__decode_frame_options; |
| |
| #ifdef __cplusplus |
| |
| #endif // __cplusplus |
| |
| // -------- |
| |
| typedef struct { |
| // Do not access the private_impl's fields directly. There is no API/ABI |
| // compatibility or safety guarantee if you do so. |
| struct { |
| // TODO: should the func type take restrict pointers? |
| uint64_t (*func)(wuffs_base__slice_u8 dst, |
| wuffs_base__slice_u8 dst_palette, |
| wuffs_base__slice_u8 src); |
| } private_impl; |
| |
| #ifdef __cplusplus |
| inline wuffs_base__status prepare(wuffs_base__pixel_format dst_format, |
| wuffs_base__slice_u8 dst_palette, |
| wuffs_base__pixel_format src_format, |
| wuffs_base__slice_u8 src_palette); |
| inline uint64_t swizzle_interleaved(wuffs_base__slice_u8 dst, |
| wuffs_base__slice_u8 dst_palette, |
| wuffs_base__slice_u8 src) const; |
| #endif // __cplusplus |
| |
| } wuffs_base__pixel_swizzler; |
| |
| wuffs_base__status // |
| wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p, |
| wuffs_base__pixel_format dst_format, |
| wuffs_base__slice_u8 dst_palette, |
| wuffs_base__pixel_format src_format, |
| wuffs_base__slice_u8 src_palette); |
| |
| uint64_t // |
| wuffs_base__pixel_swizzler__swizzle_interleaved( |
| const wuffs_base__pixel_swizzler* p, |
| wuffs_base__slice_u8 dst, |
| wuffs_base__slice_u8 dst_palette, |
| wuffs_base__slice_u8 src); |
| |
| #ifdef __cplusplus |
| |
| inline wuffs_base__status // |
| wuffs_base__pixel_swizzler::prepare(wuffs_base__pixel_format dst_format, |
| wuffs_base__slice_u8 dst_palette, |
| wuffs_base__pixel_format src_format, |
| wuffs_base__slice_u8 src_palette) { |
| return wuffs_base__pixel_swizzler__prepare(this, dst_format, dst_palette, |
| src_format, src_palette); |
| } |
| |
| uint64_t // |
| wuffs_base__pixel_swizzler::swizzle_interleaved( |
| wuffs_base__slice_u8 dst, |
| wuffs_base__slice_u8 dst_palette, |
| wuffs_base__slice_u8 src) const { |
| return wuffs_base__pixel_swizzler__swizzle_interleaved(this, dst, dst_palette, |
| src); |
| } |
| |
| #endif // __cplusplus |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #ifdef __clang__ |
| #pragma clang diagnostic pop |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| // ---------------- Status Codes |
| |
| // ---------------- Public Consts |
| |
| // ---------------- Struct Declarations |
| |
| typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher; |
| |
| // ---------------- Public Initializer Prototypes |
| |
| // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, |
| // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". |
| // |
| // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. |
| // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags. |
| |
| wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| wuffs_adler32__hasher__initialize(wuffs_adler32__hasher* self, |
| size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags); |
| |
| size_t // |
| sizeof__wuffs_adler32__hasher(); |
| |
| // ---------------- Public Function Prototypes |
| |
| WUFFS_BASE__MAYBE_STATIC uint32_t // |
| wuffs_adler32__hasher__update_u32(wuffs_adler32__hasher* self, |
| wuffs_base__slice_u8 a_x); |
| |
| // ---------------- Struct Definitions |
| |
| // These structs' fields, and the sizeof them, are private implementation |
| // details that aren't guaranteed to be stable across Wuffs versions. |
| // |
| // See https://en.wikipedia.org/wiki/Opaque_pointer#C |
| |
| #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| struct wuffs_adler32__hasher__struct { |
| #ifdef WUFFS_IMPLEMENTATION |
| |
| // Do not access the private_impl's or private_data's fields directly. There |
| // is no API/ABI compatibility or safety guarantee if you do so. Instead, use |
| // the wuffs_foo__bar__baz functions. |
| // |
| // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct |
| // can be stack allocated when WUFFS_IMPLEMENTATION is defined. |
| |
| struct { |
| uint32_t magic; |
| uint32_t active_coroutine; |
| |
| uint32_t f_state; |
| bool f_started; |
| |
| } private_impl; |
| |
| #else // WUFFS_IMPLEMENTATION |
| |
| // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is |
| // large enough to discourage trying to allocate one on the stack. The sizeof |
| // the real private_impl (and the sizeof the real outermost wuffs_foo__bar |
| // struct) is not part of the public, stable, memory-safe API. Call |
| // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their |
| // first argument) instead of fiddling with bar.private_impl.qux fields. |
| // |
| // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still |
| // defines C++ convenience methods. These methods forward on "this", so that |
| // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". |
| private: |
| union { |
| uint32_t align_as_per_magic_field; |
| uint8_t placeholder[1073741824]; // 1 GiB. |
| } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD; |
| |
| public: |
| |
| #endif // WUFFS_IMPLEMENTATION |
| |
| #ifdef __cplusplus |
| |
| inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| initialize(size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags) { |
| return wuffs_adler32__hasher__initialize(this, sizeof_star_self, |
| wuffs_version, initialize_flags); |
| } |
| |
| inline uint32_t // |
| update_u32(wuffs_base__slice_u8 a_x) { |
| return wuffs_adler32__hasher__update_u32(this, a_x); |
| } |
| |
| #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION) |
| // Disallow copy and assign. |
| wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete; |
| wuffs_adler32__hasher__struct& operator=( |
| const wuffs_adler32__hasher__struct&) = delete; |
| #endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION) |
| |
| #endif // __cplusplus |
| |
| }; // struct wuffs_adler32__hasher__struct |
| |
| #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| // ---------------- Status Codes |
| |
| // ---------------- Public Consts |
| |
| // ---------------- Struct Declarations |
| |
| typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher; |
| |
| // ---------------- Public Initializer Prototypes |
| |
| // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, |
| // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". |
| // |
| // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. |
| // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags. |
| |
| wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| wuffs_crc32__ieee_hasher__initialize(wuffs_crc32__ieee_hasher* self, |
| size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags); |
| |
| size_t // |
| sizeof__wuffs_crc32__ieee_hasher(); |
| |
| // ---------------- Public Function Prototypes |
| |
| WUFFS_BASE__MAYBE_STATIC uint32_t // |
| wuffs_crc32__ieee_hasher__update_u32(wuffs_crc32__ieee_hasher* self, |
| wuffs_base__slice_u8 a_x); |
| |
| // ---------------- Struct Definitions |
| |
| // These structs' fields, and the sizeof them, are private implementation |
| // details that aren't guaranteed to be stable across Wuffs versions. |
| // |
| // See https://en.wikipedia.org/wiki/Opaque_pointer#C |
| |
| #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| struct wuffs_crc32__ieee_hasher__struct { |
| #ifdef WUFFS_IMPLEMENTATION |
| |
| // Do not access the private_impl's or private_data's fields directly. There |
| // is no API/ABI compatibility or safety guarantee if you do so. Instead, use |
| // the wuffs_foo__bar__baz functions. |
| // |
| // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct |
| // can be stack allocated when WUFFS_IMPLEMENTATION is defined. |
| |
| struct { |
| uint32_t magic; |
| uint32_t active_coroutine; |
| |
| uint32_t f_state; |
| |
| } private_impl; |
| |
| #else // WUFFS_IMPLEMENTATION |
| |
| // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is |
| // large enough to discourage trying to allocate one on the stack. The sizeof |
| // the real private_impl (and the sizeof the real outermost wuffs_foo__bar |
| // struct) is not part of the public, stable, memory-safe API. Call |
| // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their |
| // first argument) instead of fiddling with bar.private_impl.qux fields. |
| // |
| // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still |
| // defines C++ convenience methods. These methods forward on "this", so that |
| // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". |
| private: |
| union { |
| uint32_t align_as_per_magic_field; |
| uint8_t placeholder[1073741824]; // 1 GiB. |
| } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD; |
| |
| public: |
| |
| #endif // WUFFS_IMPLEMENTATION |
| |
| #ifdef __cplusplus |
| |
| inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| initialize(size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags) { |
| return wuffs_crc32__ieee_hasher__initialize( |
| this, sizeof_star_self, wuffs_version, initialize_flags); |
| } |
| |
| inline uint32_t // |
| update_u32(wuffs_base__slice_u8 a_x) { |
| return wuffs_crc32__ieee_hasher__update_u32(this, a_x); |
| } |
| |
| #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION) |
| // Disallow copy and assign. |
| wuffs_crc32__ieee_hasher__struct(const wuffs_crc32__ieee_hasher__struct&) = |
| delete; |
| wuffs_crc32__ieee_hasher__struct& operator=( |
| const wuffs_crc32__ieee_hasher__struct&) = delete; |
| #endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION) |
| |
| #endif // __cplusplus |
| |
| }; // struct wuffs_crc32__ieee_hasher__struct |
| |
| #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| // ---------------- Status Codes |
| |
| extern const char* wuffs_deflate__error__bad_huffman_code_over_subscribed; |
| extern const char* wuffs_deflate__error__bad_huffman_code_under_subscribed; |
| extern const char* wuffs_deflate__error__bad_huffman_code_length_count; |
| extern const char* wuffs_deflate__error__bad_huffman_code_length_repetition; |
| extern const char* wuffs_deflate__error__bad_huffman_code; |
| extern const char* wuffs_deflate__error__bad_huffman_minimum_code_length; |
| extern const char* wuffs_deflate__error__bad_block; |
| extern const char* wuffs_deflate__error__bad_distance; |
| extern const char* wuffs_deflate__error__bad_distance_code_count; |
| extern const char* wuffs_deflate__error__bad_literal_length_code_count; |
| extern const char* wuffs_deflate__error__inconsistent_stored_block_length; |
| extern const char* wuffs_deflate__error__missing_end_of_block_code; |
| extern const char* wuffs_deflate__error__no_huffman_codes; |
| |
| // ---------------- Public Consts |
| |
| #define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1 |
| |
| // ---------------- Struct Declarations |
| |
| typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder; |
| |
| // ---------------- Public Initializer Prototypes |
| |
| // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, |
| // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". |
| // |
| // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. |
| // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags. |
| |
| wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| wuffs_deflate__decoder__initialize(wuffs_deflate__decoder* self, |
| size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags); |
| |
| size_t // |
| sizeof__wuffs_deflate__decoder(); |
| |
| // ---------------- Public Function Prototypes |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct // |
| wuffs_deflate__decoder__add_history(wuffs_deflate__decoder* self, |
| wuffs_base__slice_u8 a_hist); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 // |
| wuffs_deflate__decoder__workbuf_len(const wuffs_deflate__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__status // |
| wuffs_deflate__decoder__decode_io_writer(wuffs_deflate__decoder* self, |
| wuffs_base__io_buffer* a_dst, |
| wuffs_base__io_buffer* a_src, |
| wuffs_base__slice_u8 a_workbuf); |
| |
| // ---------------- Struct Definitions |
| |
| // These structs' fields, and the sizeof them, are private implementation |
| // details that aren't guaranteed to be stable across Wuffs versions. |
| // |
| // See https://en.wikipedia.org/wiki/Opaque_pointer#C |
| |
| #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| struct wuffs_deflate__decoder__struct { |
| #ifdef WUFFS_IMPLEMENTATION |
| |
| // Do not access the private_impl's or private_data's fields directly. There |
| // is no API/ABI compatibility or safety guarantee if you do so. Instead, use |
| // the wuffs_foo__bar__baz functions. |
| // |
| // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct |
| // can be stack allocated when WUFFS_IMPLEMENTATION is defined. |
| |
| struct { |
| uint32_t magic; |
| uint32_t active_coroutine; |
| |
| uint32_t f_bits; |
| uint32_t f_n_bits; |
| uint32_t f_history_index; |
| uint32_t f_n_huffs_bits[2]; |
| bool f_end_of_block; |
| |
| uint32_t p_decode_io_writer[1]; |
| uint32_t p_decode_blocks[1]; |
| uint32_t p_decode_uncompressed[1]; |
| uint32_t p_init_dynamic_huffman[1]; |
| uint32_t p_decode_huffman_slow[1]; |
| } private_impl; |
| |
| struct { |
| uint32_t f_huffs[2][1024]; |
| uint8_t f_history[32768]; |
| uint8_t f_code_lengths[320]; |
| |
| struct { |
| uint32_t v_final; |
| } s_decode_blocks[1]; |
| struct { |
| uint32_t v_length; |
| uint64_t scratch; |
| } s_decode_uncompressed[1]; |
| struct { |
| uint32_t v_bits; |
| uint32_t v_n_bits; |
| uint32_t v_n_lit; |
| uint32_t v_n_dist; |
| uint32_t v_n_clen; |
| uint32_t v_i; |
| uint32_t v_mask; |
| uint32_t v_table_entry; |
| uint32_t v_n_extra_bits; |
| uint8_t v_rep_symbol; |
| uint32_t v_rep_count; |
| } s_init_dynamic_huffman[1]; |
| struct { |
| uint32_t v_bits; |
| uint32_t v_n_bits; |
| uint32_t v_table_entry; |
| uint32_t v_table_entry_n_bits; |
| uint32_t v_lmask; |
| uint32_t v_dmask; |
| uint32_t v_redir_top; |
| uint32_t v_redir_mask; |
| uint32_t v_length; |
| uint32_t v_dist_minus_1; |
| uint32_t v_hlen; |
| uint32_t v_hdist; |
| } s_decode_huffman_slow[1]; |
| } private_data; |
| |
| #else // WUFFS_IMPLEMENTATION |
| |
| // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is |
| // large enough to discourage trying to allocate one on the stack. The sizeof |
| // the real private_impl (and the sizeof the real outermost wuffs_foo__bar |
| // struct) is not part of the public, stable, memory-safe API. Call |
| // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their |
| // first argument) instead of fiddling with bar.private_impl.qux fields. |
| // |
| // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still |
| // defines C++ convenience methods. These methods forward on "this", so that |
| // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". |
| private: |
| union { |
| uint32_t align_as_per_magic_field; |
| uint8_t placeholder[1073741824]; // 1 GiB. |
| } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD; |
| |
| public: |
| |
| #endif // WUFFS_IMPLEMENTATION |
| |
| #ifdef __cplusplus |
| |
| inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| initialize(size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags) { |
| return wuffs_deflate__decoder__initialize(this, sizeof_star_self, |
| wuffs_version, initialize_flags); |
| } |
| |
| inline wuffs_base__empty_struct // |
| add_history(wuffs_base__slice_u8 a_hist) { |
| return wuffs_deflate__decoder__add_history(this, a_hist); |
| } |
| |
| inline wuffs_base__range_ii_u64 // |
| workbuf_len() const { |
| return wuffs_deflate__decoder__workbuf_len(this); |
| } |
| |
| inline wuffs_base__status // |
| decode_io_writer(wuffs_base__io_buffer* a_dst, |
| wuffs_base__io_buffer* a_src, |
| wuffs_base__slice_u8 a_workbuf) { |
| return wuffs_deflate__decoder__decode_io_writer(this, a_dst, a_src, |
| a_workbuf); |
| } |
| |
| #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION) |
| // Disallow copy and assign. |
| wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) = |
| delete; |
| wuffs_deflate__decoder__struct& operator=( |
| const wuffs_deflate__decoder__struct&) = delete; |
| #endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION) |
| |
| #endif // __cplusplus |
| |
| }; // struct wuffs_deflate__decoder__struct |
| |
| #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| // ---------------- Status Codes |
| |
| extern const char* wuffs_lzw__error__bad_code; |
| |
| // ---------------- Public Consts |
| |
| #define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0 |
| |
| // ---------------- Struct Declarations |
| |
| typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder; |
| |
| // ---------------- Public Initializer Prototypes |
| |
| // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, |
| // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". |
| // |
| // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. |
| // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags. |
| |
| wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| wuffs_lzw__decoder__initialize(wuffs_lzw__decoder* self, |
| size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags); |
| |
| size_t // |
| sizeof__wuffs_lzw__decoder(); |
| |
| // ---------------- Public Function Prototypes |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct // |
| wuffs_lzw__decoder__set_literal_width(wuffs_lzw__decoder* self, uint32_t a_lw); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 // |
| wuffs_lzw__decoder__workbuf_len(const wuffs_lzw__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__status // |
| wuffs_lzw__decoder__decode_io_writer(wuffs_lzw__decoder* self, |
| wuffs_base__io_buffer* a_dst, |
| wuffs_base__io_buffer* a_src, |
| wuffs_base__slice_u8 a_workbuf); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8 // |
| wuffs_lzw__decoder__flush(wuffs_lzw__decoder* self); |
| |
| // ---------------- Struct Definitions |
| |
| // These structs' fields, and the sizeof them, are private implementation |
| // details that aren't guaranteed to be stable across Wuffs versions. |
| // |
| // See https://en.wikipedia.org/wiki/Opaque_pointer#C |
| |
| #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| struct wuffs_lzw__decoder__struct { |
| #ifdef WUFFS_IMPLEMENTATION |
| |
| // Do not access the private_impl's or private_data's fields directly. There |
| // is no API/ABI compatibility or safety guarantee if you do so. Instead, use |
| // the wuffs_foo__bar__baz functions. |
| // |
| // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct |
| // can be stack allocated when WUFFS_IMPLEMENTATION is defined. |
| |
| struct { |
| uint32_t magic; |
| uint32_t active_coroutine; |
| |
| uint32_t f_set_literal_width_arg; |
| uint32_t f_literal_width; |
| uint32_t f_clear_code; |
| uint32_t f_end_code; |
| uint32_t f_save_code; |
| uint32_t f_prev_code; |
| uint32_t f_width; |
| uint32_t f_bits; |
| uint32_t f_n_bits; |
| uint32_t f_output_ri; |
| uint32_t f_output_wi; |
| uint32_t f_read_from_return_value; |
| uint16_t f_prefixes[4096]; |
| |
| uint32_t p_decode_io_writer[1]; |
| uint32_t p_write_to[1]; |
| } private_impl; |
| |
| struct { |
| uint8_t f_suffixes[4096][8]; |
| uint16_t f_lm1s[4096]; |
| uint8_t f_output[8199]; |
| |
| } private_data; |
| |
| #else // WUFFS_IMPLEMENTATION |
| |
| // When WUFFS_IMPLEMENTATION is not defined, this placeholder private_impl is |
| // large enough to discourage trying to allocate one on the stack. The sizeof |
| // the real private_impl (and the sizeof the real outermost wuffs_foo__bar |
| // struct) is not part of the public, stable, memory-safe API. Call |
| // wuffs_foo__bar__baz methods (which all take a "this"-like pointer as their |
| // first argument) instead of fiddling with bar.private_impl.qux fields. |
| // |
| // Even when WUFFS_IMPLEMENTATION is not defined, the outermost struct still |
| // defines C++ convenience methods. These methods forward on "this", so that |
| // you can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)". |
| private: |
| union { |
| uint32_t align_as_per_magic_field; |
| uint8_t placeholder[1073741824]; // 1 GiB. |
| } private_impl WUFFS_BASE__POTENTIALLY_UNUSED_FIELD; |
| |
| public: |
| |
| #endif // WUFFS_IMPLEMENTATION |
| |
| #ifdef __cplusplus |
| |
| inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| initialize(size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags) { |
| return wuffs_lzw__decoder__initialize(this, sizeof_star_self, wuffs_version, |
| initialize_flags); |
| } |
| |
| inline wuffs_base__empty_struct // |
| set_literal_width(uint32_t a_lw) { |
| return wuffs_lzw__decoder__set_literal_width(this, a_lw); |
| } |
| |
| inline wuffs_base__range_ii_u64 // |
| workbuf_len() const { |
| return wuffs_lzw__decoder__workbuf_len(this); |
| } |
| |
| inline wuffs_base__status // |
| decode_io_writer(wuffs_base__io_buffer* a_dst, |
| wuffs_base__io_buffer* a_src, |
| wuffs_base__slice_u8 a_workbuf) { |
| return wuffs_lzw__decoder__decode_io_writer(this, a_dst, a_src, a_workbuf); |
| } |
| |
| inline wuffs_base__slice_u8 // |
| flush() { |
| return wuffs_lzw__decoder__flush(this); |
| } |
| |
| #if (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION) |
| // Disallow copy and assign. |
| wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete; |
| wuffs_lzw__decoder__struct& operator=(const wuffs_lzw__decoder__struct&) = |
| delete; |
| #endif // (__cplusplus >= 201103L) && !defined(WUFFS_IMPLEMENTATION) |
| |
| #endif // __cplusplus |
| |
| }; // struct wuffs_lzw__decoder__struct |
| |
| #endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| #ifdef __cplusplus |
| } // extern "C" |
| #endif |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| // ---------------- Status Codes |
| |
| extern const char* wuffs_gif__error__bad_block; |
| extern const char* wuffs_gif__error__bad_extension_label; |
| extern const char* wuffs_gif__error__bad_frame_size; |
| extern const char* wuffs_gif__error__bad_graphic_control; |
| extern const char* wuffs_gif__error__bad_header; |
| extern const char* wuffs_gif__error__bad_literal_width; |
| extern const char* wuffs_gif__error__bad_palette; |
| |
| // ---------------- Public Consts |
| |
| #define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1 |
| |
| #define WUFFS_GIF__QUIRK_DELAY_NUM_DECODED_FRAMES 1041635328 |
| |
| #define WUFFS_GIF__QUIRK_FIRST_FRAME_LOCAL_PALETTE_MEANS_BLACK_BACKGROUND \ |
| 1041635329 |
| |
| #define WUFFS_GIF__QUIRK_HONOR_BACKGROUND_COLOR 1041635330 |
| |
| #define WUFFS_GIF__QUIRK_IGNORE_TOO_MUCH_PIXEL_DATA 1041635331 |
| |
| #define WUFFS_GIF__QUIRK_IMAGE_BOUNDS_ARE_STRICT 1041635332 |
| |
| #define WUFFS_GIF__QUIRK_REJECT_EMPTY_FRAME 1041635333 |
| |
| #define WUFFS_GIF__QUIRK_REJECT_EMPTY_PALETTE 1041635334 |
| |
| // ---------------- Struct Declarations |
| |
| typedef struct wuffs_gif__decoder__struct wuffs_gif__decoder; |
| |
| // ---------------- Public Initializer Prototypes |
| |
| // For any given "wuffs_foo__bar* self", "wuffs_foo__bar__initialize(self, |
| // etc)" should be called before any other "wuffs_foo__bar__xxx(self, etc)". |
| // |
| // Pass sizeof(*self) and WUFFS_VERSION for sizeof_star_self and wuffs_version. |
| // Pass 0 (or some combination of WUFFS_INITIALIZE__XXX) for initialize_flags. |
| |
| wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT // |
| wuffs_gif__decoder__initialize(wuffs_gif__decoder* self, |
| size_t sizeof_star_self, |
| uint64_t wuffs_version, |
| uint32_t initialize_flags); |
| |
| size_t // |
| sizeof__wuffs_gif__decoder(); |
| |
| // ---------------- Public Function Prototypes |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct // |
| wuffs_gif__decoder__set_quirk_enabled(wuffs_gif__decoder* self, |
| uint32_t a_quirk, |
| bool a_enabled); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__status // |
| wuffs_gif__decoder__decode_image_config(wuffs_gif__decoder* self, |
| wuffs_base__image_config* a_dst, |
| wuffs_base__io_buffer* a_src); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct // |
| wuffs_gif__decoder__set_report_metadata(wuffs_gif__decoder* self, |
| uint32_t a_fourcc, |
| bool a_report); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__status // |
| wuffs_gif__decoder__ack_metadata_chunk(wuffs_gif__decoder* self, |
| wuffs_base__io_buffer* a_src); |
| |
| WUFFS_BASE__MAYBE_STATIC uint32_t // |
| wuffs_gif__decoder__metadata_fourcc(const wuffs_gif__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC uint64_t // |
| wuffs_gif__decoder__metadata_chunk_length(const wuffs_gif__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC uint32_t // |
| wuffs_gif__decoder__num_animation_loops(const wuffs_gif__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC uint64_t // |
| wuffs_gif__decoder__num_decoded_frame_configs(const wuffs_gif__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC uint64_t // |
| wuffs_gif__decoder__num_decoded_frames(const wuffs_gif__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32 // |
| wuffs_gif__decoder__frame_dirty_rect(const wuffs_gif__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64 // |
| wuffs_gif__decoder__workbuf_len(const wuffs_gif__decoder* self); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__status // |
| wuffs_gif__decoder__restart_frame(wuffs_gif__decoder* self, |
| uint64_t a_index, |
| uint64_t a_io_position); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__status // |
| wuffs_gif__decoder__decode_frame_config(wuffs_gif__decoder* self, |
| wuffs_base__frame_config* a_dst, |
| wuffs_base__io_buffer* a_src); |
| |
| WUFFS_BASE__MAYBE_STATIC wuffs_base__status // |
| wuffs_gif__decoder__decode_frame(wuffs_gif__decoder* self, |
| wuffs_base__pixel_buffer* a_dst, |
| wuffs_base__io_buffer* a_src, |
| wuffs_base__slice_u8 a_workbuf, |
| wuffs_base__decode_frame_options* a_opts); |
| |
| // ---------------- Struct Definitions |
| |
| // These structs' fields, and the sizeof them, are private implementation |
| // details that aren't guaranteed to be stable across Wuffs versions. |
| // |
| // See https://en.wikipedia.org/wiki/Opaque_pointer#C |
| |
| #if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION) |
| |
| struct wuffs_gif__decoder__struct { |
| #ifdef WUFFS_IMPLEMENTATION |
| |
| // Do not access the private_impl's or private_data's fields directly. There |
| // is no API/ABI compatibility or safety guarantee if you do so. Instead, use |
| // the wuffs_foo__bar__baz functions. |
| // |
| // It is a struct, not a struct*, so that the outermost wuffs_foo__bar struct |
| // can be stack allocated when WUFFS_IMPLEMENTATION is defined. |
| |
| struct { |
| uint32_t magic; |
| uint32_t active_coroutine; |
| |
| uint32_t f_width; |
| uint32_t f_height; |
| uint8_t f_call_sequence; |
| bool f_ignore_metadata; |
| bool f_report_metadata_iccp; |
| bool f_report_metadata_xmp; |
| uint32_t f_metadata_fourcc_value; |
| uint64_t f_metadata_chunk_length_value; |
| uint64_t f_metadata_io_position; |
| bool f_quirk_enabled_delay_num_decoded_frames; |
| bool f_quirk_enabled_first_frame_local_palette_means_black_background; |
| bool f_quirk_enabled_honor_background_color; |
| bool f_quirk_enabled_ignore_too_much_pixel_data; |
| bool f_quirk_enabled_image_bounds_are_strict; |
| bool f_quirk_enabled_reject_empty_frame; |
| bool f_quirk_enabled_reject_empty_palette; |
| bool f_delayed_num_decoded_frames; |
| bool f_end_of_data; |
| bool f_restarted; |
| bool f_previous_lzw_decode_ended_abruptly; |
| bool f_has_global_palette; |
| uint8_t f_interlace; |
| bool f_seen_num_loops; |
| uint32_t f_num_loops; |
| uint32_t f_background_color_u32_argb_premul; |
| uint32_t f_black_color_u32_argb_premul; |
| bool f_gc_has_transparent_index; |
| uint8_t f_gc_transparent_index |