summaryrefslogtreecommitdiff
path: root/src/vendorcode
diff options
context:
space:
mode:
authorPatrick Georgi <patrick@coreboot.org>2023-10-06 20:19:15 +0200
committerFelix Held <felix-coreboot@felixheld.de>2023-12-13 16:17:34 +0000
commit1d029b40c9deca792ccc5820293d3bc8f8b8a2a4 (patch)
tree8936e4f3aeb4d8c0beed486bb3d7de62d858a373 /src/vendorcode
parent54662610197d7304b48d8e85a5b13263db3357f2 (diff)
lib/jpeg: Replace decoder with Wuffs' implementation
To quote its repo[0]: Wuffs is a memory-safe programming language (and a standard library written in that language) for Wrangling Untrusted File Formats Safely. Wrangling includes parsing, decoding and encoding. It compiles its library, written in its own language, to a C/C++ source file that can then be used independently without needing support for the language. That library is now imported to src/vendorcode/wuffs/. This change modifies our linters to ignore that directory because it's supposed to contain the wuffs compiler's result verbatim. Nigel Tao provided an initial wrapper around wuffs' jpeg decoder that implements our JPEG API. I further changed it a bit regarding data placement, dropped stuff from our API that wasn't ever used, or isn't used anymore, and generally made it fit coreboot a bit better. Features are Nigel's, bugs are mine. This commit also adapts our jpeg fuzz test to work with the modified API. After limiting it to deal only with approximately screen sized inputs, it fuzzed for 25 hours CPU time without a single hang or crash. This is a notable improvement over running the test with our old decoder which crashes within a minute. Finally, I tried the new parser with a pretty-much-random JPEG file I got from the internet, and it just showed it (once the resolution matched), which is also a notable improvement over the old decoder which is very particular about the subset of JPEG it supports. In terms of code size, a QEmu build's ramstage increases from 128060 bytes decompressed (64121 bytes after LZMA) to 172304 bytes decompressed (82734 bytes after LZMA). [0] https://github.com/google/wuffs Change-Id: If8fa7da69da1ad412f27c2c5e882393c7739bc82 Signed-off-by: Patrick Georgi <patrick@coreboot.org> Based-on-work-by: Nigel Tao <nigeltao@golang.org> Reviewed-on: https://review.coreboot.org/c/coreboot/+/78271 Reviewed-by: Paul Menzel <paulepanter@mailbox.org> Reviewed-by: Martin L Roth <gaumless@gmail.com> Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Diffstat (limited to 'src/vendorcode')
-rw-r--r--src/vendorcode/wuffs/wuffs-v0.4.c64187
1 files changed, 64187 insertions, 0 deletions
diff --git a/src/vendorcode/wuffs/wuffs-v0.4.c b/src/vendorcode/wuffs/wuffs-v0.4.c
new file mode 100644
index 0000000000..bce9eb9798
--- /dev/null
+++ b/src/vendorcode/wuffs/wuffs-v0.4.c
@@ -0,0 +1,64187 @@
+#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.
+
+// Wuffs' C code is generated automatically, not hand-written. These warnings'
+// costs outweigh the benefits.
+//
+// The "elif defined(__clang__)" isn't redundant. While vanilla clang defines
+// __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wimplicit-fallthrough"
+#pragma GCC diagnostic ignored "-Wmissing-field-initializers"
+#pragma GCC diagnostic ignored "-Wunreachable-code"
+#pragma GCC diagnostic ignored "-Wunused-function"
+#pragma GCC diagnostic ignored "-Wunused-parameter"
+#if defined(__cplusplus)
+#pragma GCC diagnostic ignored "-Wold-style-cast"
+#endif
+#elif defined(__clang__)
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wimplicit-fallthrough"
+#pragma clang diagnostic ignored "-Wmissing-field-initializers"
+#pragma clang diagnostic ignored "-Wunreachable-code"
+#pragma clang diagnostic ignored "-Wunused-function"
+#pragma clang diagnostic ignored "-Wunused-parameter"
+#if defined(__cplusplus)
+#pragma clang diagnostic ignored "-Wold-style-cast"
+#endif
+#endif
+
+// Copyright 2017 The Wuffs Authors.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+//
+// SPDX-License-Identifier: Apache-2.0 OR MIT
+
+#include <stdbool.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef __cplusplus
+#if (__cplusplus >= 201103L) || defined(_MSC_VER)
+#include <memory>
+#define WUFFS_BASE__HAVE_EQ_DELETE
+#define WUFFS_BASE__HAVE_UNIQUE_PTR
+// The "defined(__clang__)" isn't redundant. While vanilla clang defines
+// __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
+#elif defined(__GNUC__) || defined(__clang__)
+#warning "Wuffs' C++ code expects -std=c++11 or later"
+#endif
+
+extern "C" {
+#endif
+
+// ---------------- Version
+
+// 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
+// ae8531f7f846fbbe3a7340bf88499ad294a1367b committed on 2023-10-07.
+#define WUFFS_VERSION 0x000040000
+#define WUFFS_VERSION_MAJOR 0
+#define WUFFS_VERSION_MINOR 4
+#define WUFFS_VERSION_PATCH 0
+#define WUFFS_VERSION_PRE_RELEASE_LABEL "alpha.2"
+#define WUFFS_VERSION_BUILD_METADATA_COMMIT_COUNT 3603
+#define WUFFS_VERSION_BUILD_METADATA_COMMIT_DATE 20231007
+#define WUFFS_VERSION_STRING "0.4.0-alpha.2+3603.20231007"
+
+// ---------------- Configuration
+
+// Define WUFFS_CONFIG__AVOID_CPU_ARCH to avoid any code tied to a specific CPU
+// architecture, such as SSE SIMD for the x86 CPU family.
+#if defined(WUFFS_CONFIG__AVOID_CPU_ARCH) // (#if-chain ref AVOID_CPU_ARCH_0)
+// No-op.
+#else // (#if-chain ref AVOID_CPU_ARCH_0)
+
+// The "defined(__clang__)" isn't redundant. While vanilla clang defines
+// __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
+#if defined(__GNUC__) || defined(__clang__)
+#define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg) __attribute__((target(arg)))
+#else
+#define WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET(arg)
+#endif // defined(__GNUC__) || defined(__clang__)
+
+#if defined(__GNUC__) // (#if-chain ref AVOID_CPU_ARCH_1)
+
+// To simplify Wuffs code, "cpu_arch >= arm_xxx" requires xxx but also
+// unaligned little-endian load/stores.
+#if defined(__ARM_FEATURE_UNALIGNED) && !defined(__native_client__) && \
+ defined(__BYTE_ORDER__) && (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
+// Not all gcc versions define __ARM_ACLE, even if they support crc32
+// intrinsics. Look for __ARM_FEATURE_CRC32 instead.
+#if defined(__ARM_FEATURE_CRC32)
+#include <arm_acle.h>
+#define WUFFS_BASE__CPU_ARCH__ARM_CRC32
+#endif // defined(__ARM_FEATURE_CRC32)
+#if defined(__ARM_NEON)
+#include <arm_neon.h>
+#define WUFFS_BASE__CPU_ARCH__ARM_NEON
+#endif // defined(__ARM_NEON)
+#endif // defined(__ARM_FEATURE_UNALIGNED) etc
+
+// Similarly, "cpu_arch >= x86_sse42" requires SSE4.2 but also PCLMUL and
+// POPCNT. This is checked at runtime via cpuid, not at compile time.
+//
+// Likewise, "cpu_arch >= x86_avx2" also requires PCLMUL, POPCNT and SSE4.2.
+#if defined(__i386__) || defined(__x86_64__)
+#if !defined(__native_client__)
+#include <cpuid.h>
+#include <x86intrin.h>
+// X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously).
+#define WUFFS_BASE__CPU_ARCH__X86_FAMILY
+#if defined(__x86_64__)
+#define WUFFS_BASE__CPU_ARCH__X86_64
+#endif // defined(__x86_64__)
+#endif // !defined(__native_client__)
+#endif // defined(__i386__) || defined(__x86_64__)
+
+#elif defined(_MSC_VER) // (#if-chain ref AVOID_CPU_ARCH_1)
+
+#if defined(_M_IX86) || defined(_M_X64)
+#if defined(__AVX__) || defined(__clang__)
+
+// We need <intrin.h> for the __cpuid function.
+#include <intrin.h>
+// That's not enough for X64 SIMD, with clang-cl, if we want to use
+// "__attribute__((target(arg)))" without e.g. "/arch:AVX".
+//
+// Some web pages suggest that <immintrin.h> is all you need, as it pulls in
+// the earlier SIMD families like SSE4.2, but that doesn't seem to work in
+// practice, possibly for the same reason that just <intrin.h> doesn't work.
+#include <immintrin.h> // AVX, AVX2, FMA, POPCNT
+#include <nmmintrin.h> // SSE4.2
+#include <wmmintrin.h> // AES, PCLMUL
+// X86_FAMILY means X86 (32-bit) or X86_64 (64-bit, obviously).
+#define WUFFS_BASE__CPU_ARCH__X86_FAMILY
+#if defined(_M_X64)
+#define WUFFS_BASE__CPU_ARCH__X86_64
+#endif // defined(_M_X64)
+
+#else // defined(__AVX__) || defined(__clang__)
+
+// clang-cl (which defines both __clang__ and _MSC_VER) supports
+// "__attribute__((target(arg)))".
+//
+// For MSVC's cl.exe (unlike clang or gcc), SIMD capability is a compile-time
+// property of the source file (e.g. a /arch:AVX or -mavx compiler flag), not
+// of individual functions (that can be conditionally selected at runtime).
+#pragma message("Wuffs with MSVC+IX86/X64 needs /arch:AVX for best performance")
+
+#endif // defined(__AVX__) || defined(__clang__)
+#endif // defined(_M_IX86) || defined(_M_X64)
+
+#endif // (#if-chain ref AVOID_CPU_ARCH_1)
+#endif // (#if-chain ref AVOID_CPU_ARCH_0)
+
+// --------
+
+// Define WUFFS_CONFIG__STATIC_FUNCTIONS (combined with WUFFS_IMPLEMENTATION)
+// to make all of Wuffs' functions have static storage.
+//
+// This can help the compiler ignore or discard unused code, which can produce
+// faster compiles and smaller binaries. Other motivations are discussed in the
+// "ALLOW STATIC IMPLEMENTATION" section of
+// https://raw.githubusercontent.com/nothings/stb/master/docs/stb_howto.txt
+#if defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
+#define WUFFS_BASE__MAYBE_STATIC static
+#else
+#define WUFFS_BASE__MAYBE_STATIC
+#endif // defined(WUFFS_CONFIG__STATIC_FUNCTIONS)
+
+// ---------------- CPU Architecture
+
+static inline bool //
+wuffs_base__cpu_arch__have_arm_crc32(void) {
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
+ return true;
+#else
+ return false;
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
+}
+
+static inline bool //
+wuffs_base__cpu_arch__have_arm_neon(void) {
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+ return true;
+#else
+ return false;
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+}
+
+static inline bool //
+wuffs_base__cpu_arch__have_x86_avx2(void) {
+#if defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) && \
+ defined(__AVX2__)
+ return true;
+#else
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+ // GCC defines these macros but MSVC does not.
+ // - bit_AVX2 = (1 << 5)
+ const unsigned int avx2_ebx7 = 0x00000020;
+ // GCC defines these macros but MSVC does not.
+ // - bit_PCLMUL = (1 << 1)
+ // - bit_POPCNT = (1 << 23)
+ // - bit_SSE4_2 = (1 << 20)
+ const unsigned int avx2_ecx1 = 0x00900002;
+
+ // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
+#if defined(__GNUC__)
+ unsigned int eax7 = 0;
+ unsigned int ebx7 = 0;
+ unsigned int ecx7 = 0;
+ unsigned int edx7 = 0;
+ if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
+ ((ebx7 & avx2_ebx7) == avx2_ebx7)) {
+ unsigned int eax1 = 0;
+ unsigned int ebx1 = 0;
+ unsigned int ecx1 = 0;
+ unsigned int edx1 = 0;
+ if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
+ ((ecx1 & avx2_ecx1) == avx2_ecx1)) {
+ return true;
+ }
+ }
+#elif defined(_MSC_VER) // defined(__GNUC__)
+ int x7[4];
+ __cpuidex(x7, 7, 0);
+ if ((((unsigned int)(x7[1])) & avx2_ebx7) == avx2_ebx7) {
+ int x1[4];
+ __cpuid(x1, 1);
+ if ((((unsigned int)(x1[2])) & avx2_ecx1) == avx2_ecx1) {
+ return true;
+ }
+ }
+#else
+#error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
+#endif // defined(__GNUC__); defined(_MSC_VER)
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64)
+ return false;
+#endif // defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__) &&
+ // defined(__AVX2__)
+}
+
+static inline bool //
+wuffs_base__cpu_arch__have_x86_bmi2(void) {
+#if defined(__BMI2__)
+ return true;
+#else
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ // GCC defines these macros but MSVC does not.
+ // - bit_BMI2 = (1 << 8)
+ const unsigned int bmi2_ebx7 = 0x00000100;
+
+ // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
+#if defined(__GNUC__)
+ unsigned int eax7 = 0;
+ unsigned int ebx7 = 0;
+ unsigned int ecx7 = 0;
+ unsigned int edx7 = 0;
+ if (__get_cpuid_count(7, 0, &eax7, &ebx7, &ecx7, &edx7) &&
+ ((ebx7 & bmi2_ebx7) == bmi2_ebx7)) {
+ return true;
+ }
+#elif defined(_MSC_VER) // defined(__GNUC__)
+ int x7[4];
+ __cpuidex(x7, 7, 0);
+ if ((((unsigned int)(x7[1])) & bmi2_ebx7) == bmi2_ebx7) {
+ return true;
+ }
+#else
+#error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
+#endif // defined(__GNUC__); defined(_MSC_VER)
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ return false;
+#endif // defined(__BMI2__)
+}
+
+static inline bool //
+wuffs_base__cpu_arch__have_x86_sse42(void) {
+#if defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__)
+ return true;
+#else
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ // GCC defines these macros but MSVC does not.
+ // - bit_PCLMUL = (1 << 1)
+ // - bit_POPCNT = (1 << 23)
+ // - bit_SSE4_2 = (1 << 20)
+ const unsigned int sse42_ecx1 = 0x00900002;
+
+ // clang defines __GNUC__ and clang-cl defines _MSC_VER (but not __GNUC__).
+#if defined(__GNUC__)
+ unsigned int eax1 = 0;
+ unsigned int ebx1 = 0;
+ unsigned int ecx1 = 0;
+ unsigned int edx1 = 0;
+ if (__get_cpuid(1, &eax1, &ebx1, &ecx1, &edx1) &&
+ ((ecx1 & sse42_ecx1) == sse42_ecx1)) {
+ return true;
+ }
+#elif defined(_MSC_VER) // defined(__GNUC__)
+ int x1[4];
+ __cpuid(x1, 1);
+ if ((((unsigned int)(x1[2])) & sse42_ecx1) == sse42_ecx1) {
+ return true;
+ }
+#else
+#error "WUFFS_BASE__CPU_ARCH__ETC combined with an unsupported compiler"
+#endif // defined(__GNUC__); defined(_MSC_VER)
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ return false;
+#endif // defined(__PCLMUL__) && defined(__POPCNT__) && defined(__SSE4_2__)
+}
+
+// ---------------- Fundamentals
+
+// 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.
+#if defined(__WORDSIZE)
+#if (__WORDSIZE != 32) && (__WORDSIZE != 64)
+#error "Wuffs requires a word size of either 32 or 64 bits"
+#endif
+#endif
+
+// The "defined(__clang__)" isn't redundant. While vanilla clang defines
+// __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
+#if defined(__GNUC__) || defined(__clang__)
+#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
+
+// Clang's "-fsanitize=integer" checks for "unsigned-integer-overflow" even
+// though, for *unsigned* integers, it is *not* undefined behavior. The check
+// is still made because unsigned integer overflow "is often unintentional".
+// https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html
+//
+// However, for Wuffs' generated C code, unsigned overflow is intentional. The
+// programmer has to use "~mod+" instead of a plain "+" operator in Wuffs code.
+// Further runtime checks for unsigned integer overflow can add performance
+// overhead (fuzzers can then time out) and can raise false negatives, without
+// generating much benefits. We disable the "unsigned-integer-overflow" check.
+#if defined(__has_feature)
+#if __has_feature(undefined_behavior_sanitizer)
+#define WUFFS_BASE__GENERATED_C_CODE \
+ __attribute__((no_sanitize("unsigned-integer-overflow")))
+#endif
+#endif
+#if !defined(WUFFS_BASE__GENERATED_C_CODE)
+#define WUFFS_BASE__GENERATED_C_CODE
+#endif
+
+// --------
+
+// Options (bitwise or'ed together) 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/main/doc/note/initialization.md
+#define WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED \
+ ((uint32_t)0x00000002)
+
+// --------
+
+#ifdef __cplusplus
+// Wuffs structs are just data, not resources (in the RAII sense). They don't
+// subclass anything. They don't have virtual destructors. They don't contain
+// pointers to dynamically allocated memory. They don't contain file
+// descriptors. And so on. Destroying such a struct (e.g. via a
+// wuffs_foo__bar::unique_ptr) can just call free, especially as
+// sizeof(wuffs_foo__bar) isn't supposed to be part of the public (stable) API.
+struct wuffs_unique_ptr_deleter {
+ void operator()(void* p) { free(p); }
+};
+#endif // __cplusplus
+
+// --------
+
+// 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 wuffs_base__empty_struct__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(void) {
+ 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 wuffs_base__utility__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;
+
+typedef struct wuffs_base__vtable__struct {
+ const char* vtable_name;
+ const void* function_pointers;
+} wuffs_base__vtable;
+
+// --------
+
+// See https://github.com/google/wuffs/blob/main/doc/note/statuses.md
+typedef struct wuffs_base__status__struct {
+ const char* repr;
+
+#ifdef __cplusplus
+ inline bool is_complete() const;
+ inline bool is_error() const;
+ inline bool is_note() const;
+ inline bool is_ok() const;
+ inline bool is_suspension() const;
+ inline bool is_truncated_input_error() const;
+ inline const char* message() const;
+#endif // __cplusplus
+
+} wuffs_base__status;
+
+extern const char wuffs_base__note__i_o_redirect[];
+extern const char wuffs_base__note__end_of_data[];
+extern const char wuffs_base__note__metadata_reported[];
+extern const char wuffs_base__suspension__even_more_information[];
+extern const char wuffs_base__suspension__mispositioned_read[];
+extern const char wuffs_base__suspension__mispositioned_write[];
+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_data[];
+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_vtable[];
+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__no_more_information[];
+extern const char wuffs_base__error__not_enough_data[];
+extern const char wuffs_base__error__out_of_bounds[];
+extern const char wuffs_base__error__unsupported_image_dimension[];
+extern const char wuffs_base__error__unsupported_method[];
+extern const char wuffs_base__error__unsupported_option[];
+extern const char wuffs_base__error__unsupported_pixel_swizzler_option[];
+extern const char wuffs_base__error__too_much_data[];
+
+static inline wuffs_base__status //
+wuffs_base__make_status(const char* repr) {
+ wuffs_base__status z;
+ z.repr = repr;
+ return z;
+}
+
+static inline bool //
+wuffs_base__status__is_complete(const wuffs_base__status* z) {
+ return (z->repr == NULL) || ((*z->repr != '$') && (*z->repr != '#'));
+}
+
+static inline bool //
+wuffs_base__status__is_error(const wuffs_base__status* z) {
+ return z->repr && (*z->repr == '#');
+}
+
+static inline bool //
+wuffs_base__status__is_note(const wuffs_base__status* z) {
+ return z->repr && (*z->repr != '$') && (*z->repr != '#');
+}
+
+static inline bool //
+wuffs_base__status__is_ok(const wuffs_base__status* z) {
+ return z->repr == NULL;
+}
+
+static inline bool //
+wuffs_base__status__is_suspension(const wuffs_base__status* z) {
+ return z->repr && (*z->repr == '$');
+}
+
+static inline bool //
+wuffs_base__status__is_truncated_input_error(const wuffs_base__status* z) {
+ const char* p = z->repr;
+ if (!p || (*p != '#')) {
+ return false;
+ }
+ p++;
+ while (1) {
+ if (*p == 0) {
+ return false;
+ } else if (*p++ == ':') {
+ break;
+ }
+ }
+ return strcmp(p, " truncated input") == 0;
+}
+
+// wuffs_base__status__message strips the leading '$', '#' or '@'.
+static inline const char* //
+wuffs_base__status__message(const wuffs_base__status* z) {
+ if (z->repr) {
+ if ((*z->repr == '$') || (*z->repr == '#') || (*z->repr == '@')) {
+ return z->repr + 1;
+ }
+ }
+ return z->repr;
+}
+
+#ifdef __cplusplus
+
+inline bool //
+wuffs_base__status::is_complete() const {
+ return wuffs_base__status__is_complete(this);
+}
+
+inline bool //
+wuffs_base__status::is_error() const {
+ return wuffs_base__status__is_error(this);
+}
+
+inline bool //
+wuffs_base__status::is_note() const {
+ return wuffs_base__status__is_note(this);
+}
+
+inline bool //
+wuffs_base__status::is_ok() const {
+ return wuffs_base__status__is_ok(this);
+}
+
+inline bool //
+wuffs_base__status::is_suspension() const {
+ return wuffs_base__status__is_suspension(this);
+}
+
+inline bool //
+wuffs_base__status::is_truncated_input_error() const {
+ return wuffs_base__status__is_truncated_input_error(this);
+}
+
+inline const char* //
+wuffs_base__status::message() const {
+ return wuffs_base__status__message(this);
+}
+
+#endif // __cplusplus
+
+// --------
+
+// WUFFS_BASE__RESULT is a result type: either a status (an error) or a value.
+//
+// A result with all fields NULL or zero is as valid as a zero-valued T.
+#define WUFFS_BASE__RESULT(T) \
+ struct { \
+ wuffs_base__status status; \
+ T value; \
+ }
+
+typedef WUFFS_BASE__RESULT(double) wuffs_base__result_f64;
+typedef WUFFS_BASE__RESULT(int64_t) wuffs_base__result_i64;
+typedef WUFFS_BASE__RESULT(uint64_t) wuffs_base__result_u64;
+
+// --------
+
+// wuffs_base__transform__output is the result of transforming from a src slice
+// to a dst slice.
+typedef struct wuffs_base__transform__output__struct {
+ wuffs_base__status status;
+ size_t num_dst;
+ size_t num_src;
+} wuffs_base__transform__output;
+
+// --------
+
+// FourCC constants. Four Character Codes are literally four ASCII characters
+// (sometimes padded with ' ' spaces) that pack neatly into a signed or
+// unsigned 32-bit integer. ASCII letters are conventionally upper case.
+//
+// They are often used to identify video codecs (e.g. "H265") and pixel formats
+// (e.g. "YV12"). Wuffs uses them for that but also generally for naming
+// various things: compression formats (e.g. "BZ2 "), image metadata (e.g.
+// "EXIF"), file formats (e.g. "HTML"), etc.
+//
+// Wuffs' u32 values are big-endian ("JPEG" is 0x4A504547 not 0x4745504A) to
+// preserve ordering: "JPEG" < "MP3 " and 0x4A504547 < 0x4D503320.
+
+// Background Color.
+#define WUFFS_BASE__FOURCC__BGCL 0x4247434C
+
+// Bitmap.
+#define WUFFS_BASE__FOURCC__BMP 0x424D5020
+
+// Brotli.
+#define WUFFS_BASE__FOURCC__BRTL 0x4252544C
+
+// Bzip2.
+#define WUFFS_BASE__FOURCC__BZ2 0x425A3220
+
+// Concise Binary Object Representation.
+#define WUFFS_BASE__FOURCC__CBOR 0x43424F52
+
+// Primary Chromaticities and White Point.
+#define WUFFS_BASE__FOURCC__CHRM 0x4348524D
+
+// Cascading Style Sheets.
+#define WUFFS_BASE__FOURCC__CSS 0x43535320
+
+// Encapsulated PostScript.
+#define WUFFS_BASE__FOURCC__EPS 0x45505320
+
+// Exchangeable Image File Format.
+#define WUFFS_BASE__FOURCC__EXIF 0x45584946
+
+// Free Lossless Audio Codec.
+#define WUFFS_BASE__FOURCC__FLAC 0x464C4143
+
+// Gamma Correction.
+#define WUFFS_BASE__FOURCC__GAMA 0x47414D41
+
+// Graphics Interchange Format.
+#define WUFFS_BASE__FOURCC__GIF 0x47494620
+
+// GNU Zip.
+#define WUFFS_BASE__FOURCC__GZ 0x475A2020
+
+// High Efficiency Image File.
+#define WUFFS_BASE__FOURCC__HEIF 0x48454946
+
+// Hypertext Markup Language.
+#define WUFFS_BASE__FOURCC__HTML 0x48544D4C
+
+// International Color Consortium Profile.
+#define WUFFS_BASE__FOURCC__ICCP 0x49434350
+
+// Icon.
+#define WUFFS_BASE__FOURCC__ICO 0x49434F20
+
+// Icon Vector Graphics.
+#define WUFFS_BASE__FOURCC__ICVG 0x49435647
+
+// Initialization.
+#define WUFFS_BASE__FOURCC__INI 0x494E4920
+
+// Joint Photographic Experts Group.
+#define WUFFS_BASE__FOURCC__JPEG 0x4A504547
+
+// JavaScript.
+#define WUFFS_BASE__FOURCC__JS 0x4A532020
+
+// JavaScript Object Notation.
+#define WUFFS_BASE__FOURCC__JSON 0x4A534F4E
+
+// JSON With Commas and Comments.
+#define WUFFS_BASE__FOURCC__JWCC 0x4A574343
+
+// Key-Value Pair.
+#define WUFFS_BASE__FOURCC__KVP 0x4B565020
+
+// Key-Value Pair (Key).
+#define WUFFS_BASE__FOURCC__KVPK 0x4B56504B
+
+// Key-Value Pair (Value).
+#define WUFFS_BASE__FOURCC__KVPV 0x4B565056
+
+// Lempel–Ziv 4.
+#define WUFFS_BASE__FOURCC__LZ4 0x4C5A3420
+
+// Lempel–Ziv Markov-chain Algorithm.
+#define WUFFS_BASE__FOURCC__LZMA 0x4C5A4D41
+
+// Markdown.
+#define WUFFS_BASE__FOURCC__MD 0x4D442020
+
+// Modification Time.
+#define WUFFS_BASE__FOURCC__MTIM 0x4D54494D
+
+// MPEG-1 Audio Layer III.
+#define WUFFS_BASE__FOURCC__MP3 0x4D503320
+
+// Naive Image.
+#define WUFFS_BASE__FOURCC__NIE 0x4E494520
+
+// Netpbm (Portable Anymap).
+#define WUFFS_BASE__FOURCC__NPBM 0x4E50424D
+
+// Offset (2-Dimensional).
+#define WUFFS_BASE__FOURCC__OFS2 0x4F465332
+
+// Open Type Format.
+#define WUFFS_BASE__FOURCC__OTF 0x4F544620
+
+// Portable Document Format.
+#define WUFFS_BASE__FOURCC__PDF 0x50444620
+
+// Physical Dimensions.
+#define WUFFS_BASE__FOURCC__PHYD 0x50485944
+
+// Portable Network Graphics.
+#define WUFFS_BASE__FOURCC__PNG 0x504E4720
+
+// PostScript.
+#define WUFFS_BASE__FOURCC__PS 0x50532020
+
+// Quite OK Image.
+#define WUFFS_BASE__FOURCC__QOI 0x514F4920
+
+// Random Access Compression.
+#define WUFFS_BASE__FOURCC__RAC 0x52414320
+
+// Raw.
+#define WUFFS_BASE__FOURCC__RAW 0x52415720
+
+// Resource Interchange File Format.
+#define WUFFS_BASE__FOURCC__RIFF 0x52494646
+
+// Riegeli Records.
+#define WUFFS_BASE__FOURCC__RIGL 0x5249474C
+
+// Snappy.
+#define WUFFS_BASE__FOURCC__SNPY 0x534E5059
+
+// Standard Red Green Blue (Rendering Intent).
+#define WUFFS_BASE__FOURCC__SRGB 0x53524742
+
+// Scalable Vector Graphics.
+#define WUFFS_BASE__FOURCC__SVG 0x53564720
+
+// Tape Archive.
+#define WUFFS_BASE__FOURCC__TAR 0x54415220
+
+// Text.
+#define WUFFS_BASE__FOURCC__TEXT 0x54455854
+
+// Truevision Advanced Raster Graphics Adapter.
+#define WUFFS_BASE__FOURCC__TGA 0x54474120
+
+// Tagged Image File Format.
+#define WUFFS_BASE__FOURCC__TIFF 0x54494646
+
+// Tom's Obvious Minimal Language.
+#define WUFFS_BASE__FOURCC__TOML 0x544F4D4C
+
+// Waveform.
+#define WUFFS_BASE__FOURCC__WAVE 0x57415645
+
+// Wireless Bitmap.
+#define WUFFS_BASE__FOURCC__WBMP 0x57424D50
+
+// Web Picture.
+#define WUFFS_BASE__FOURCC__WEBP 0x57454250
+
+// Web Open Font Format.
+#define WUFFS_BASE__FOURCC__WOFF 0x574F4646
+
+// Extensible Markup Language.
+#define WUFFS_BASE__FOURCC__XML 0x584D4C20
+
+// Extensible Metadata Platform.
+#define WUFFS_BASE__FOURCC__XMP 0x584D5020
+
+// Xz.
+#define WUFFS_BASE__FOURCC__XZ 0x585A2020
+
+// Zip.
+#define WUFFS_BASE__FOURCC__ZIP 0x5A495020
+
+// Zlib.
+#define WUFFS_BASE__FOURCC__ZLIB 0x5A4C4942
+
+// Zstandard.
+#define WUFFS_BASE__FOURCC__ZSTD 0x5A535444
+
+// --------
+
+// Quirks.
+
+#define WUFFS_BASE__QUIRK_IGNORE_CHECKSUM 1
+
+// --------
+
+// 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
+
+// The helpers below are functions, instead of macros, because their arguments
+// can be an expression that we shouldn't evaluate more than once.
+//
+// They are static, so that linking multiple wuffs .o files won't complain about
+// duplicate function definitions.
+//
+// They are explicitly marked inline, even if modern compilers don't use the
+// inline attribute to guide optimizations such as inlining, to avoid the
+// -Wunused-function warning, and we like to compile with -Wall -Werror.
+
+static inline int8_t //
+wuffs_base__i8__min(int8_t x, int8_t y) {
+ return x < y ? x : y;
+}
+
+static inline int8_t //
+wuffs_base__i8__max(int8_t x, int8_t y) {
+ return x > y ? x : y;
+}
+
+static inline int16_t //
+wuffs_base__i16__min(int16_t x, int16_t y) {
+ return x < y ? x : y;
+}
+
+static inline int16_t //
+wuffs_base__i16__max(int16_t x, int16_t y) {
+ return x > y ? x : y;
+}
+
+static inline int32_t //
+wuffs_base__i32__min(int32_t x, int32_t y) {
+ return x < y ? x : y;
+}
+
+static inline int32_t //
+wuffs_base__i32__max(int32_t x, int32_t y) {
+ return x > y ? x : y;
+}
+
+static inline int64_t //
+wuffs_base__i64__min(int64_t x, int64_t y) {
+ return x < y ? x : y;
+}
+
+static inline int64_t //
+wuffs_base__i64__max(int64_t x, int64_t y) {
+ return x > y ? x : y;
+}
+
+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;
+}
+
+// --------
+
+static inline uint8_t //
+wuffs_base__u8__rotate_left(uint8_t x, uint32_t n) {
+ n &= 7;
+ return ((uint8_t)(x << n)) | ((uint8_t)(x >> (8 - n)));
+}
+
+static inline uint8_t //
+wuffs_base__u8__rotate_right(uint8_t x, uint32_t n) {
+ n &= 7;
+ return ((uint8_t)(x >> n)) | ((uint8_t)(x << (8 - n)));
+}
+
+static inline uint16_t //
+wuffs_base__u16__rotate_left(uint16_t x, uint32_t n) {
+ n &= 15;
+ return ((uint16_t)(x << n)) | ((uint16_t)(x >> (16 - n)));
+}
+
+static inline uint16_t //
+wuffs_base__u16__rotate_right(uint16_t x, uint32_t n) {
+ n &= 15;
+ return ((uint16_t)(x >> n)) | ((uint16_t)(x << (16 - n)));
+}
+
+static inline uint32_t //
+wuffs_base__u32__rotate_left(uint32_t x, uint32_t n) {
+ n &= 31;
+ return ((uint32_t)(x << n)) | ((uint32_t)(x >> (32 - n)));
+}
+
+static inline uint32_t //
+wuffs_base__u32__rotate_right(uint32_t x, uint32_t n) {
+ n &= 31;
+ return ((uint32_t)(x >> n)) | ((uint32_t)(x << (32 - n)));
+}
+
+static inline uint64_t //
+wuffs_base__u64__rotate_left(uint64_t x, uint32_t n) {
+ n &= 63;
+ return ((uint64_t)(x << n)) | ((uint64_t)(x >> (64 - n)));
+}
+
+static inline uint64_t //
+wuffs_base__u64__rotate_right(uint64_t x, uint32_t n) {
+ n &= 63;
+ return ((uint64_t)(x >> n)) | ((uint64_t)(x << (64 - n)));
+}
+
+// --------
+
+// 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;
+}
+
+// --------
+
+typedef struct wuffs_base__multiply_u64__output__struct {
+ uint64_t lo;
+ uint64_t hi;
+} wuffs_base__multiply_u64__output;
+
+// wuffs_base__multiply_u64 returns x*y as a 128-bit value.
+//
+// The maximum inclusive output hi_lo is 0xFFFFFFFFFFFFFFFE_0000000000000001.
+static inline wuffs_base__multiply_u64__output //
+wuffs_base__multiply_u64(uint64_t x, uint64_t y) {
+#if defined(__SIZEOF_INT128__)
+ __uint128_t z = ((__uint128_t)x) * ((__uint128_t)y);
+ wuffs_base__multiply_u64__output o;
+ o.lo = ((uint64_t)(z));
+ o.hi = ((uint64_t)(z >> 64));
+ return o;
+#else
+ // TODO: consider using the _mul128 intrinsic if defined(_MSC_VER).
+ uint64_t x0 = x & 0xFFFFFFFF;
+ uint64_t x1 = x >> 32;
+ uint64_t y0 = y & 0xFFFFFFFF;
+ uint64_t y1 = y >> 32;
+ uint64_t w0 = x0 * y0;
+ uint64_t t = (x1 * y0) + (w0 >> 32);
+ uint64_t w1 = t & 0xFFFFFFFF;
+ uint64_t w2 = t >> 32;
+ w1 += x0 * y1;
+ wuffs_base__multiply_u64__output o;
+ o.lo = x * y;
+ o.hi = (x1 * y1) + w2 + (w1 >> 32);
+ return o;
+#endif
+}
+
+// --------
+
+// The "defined(__clang__)" isn't redundant. While vanilla clang defines
+// __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
+#if (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
+
+static inline uint32_t //
+wuffs_base__count_leading_zeroes_u64(uint64_t u) {
+ return u ? ((uint32_t)(__builtin_clzl(u))) : 64u;
+}
+
+#else
+// TODO: consider using the _BitScanReverse intrinsic if defined(_MSC_VER).
+
+static inline uint32_t //
+wuffs_base__count_leading_zeroes_u64(uint64_t u) {
+ if (u == 0) {
+ return 64;
+ }
+
+ uint32_t n = 0;
+ if ((u >> 32) == 0) {
+ n |= 32;
+ u <<= 32;
+ }
+ if ((u >> 48) == 0) {
+ n |= 16;
+ u <<= 16;
+ }
+ if ((u >> 56) == 0) {
+ n |= 8;
+ u <<= 8;
+ }
+ if ((u >> 60) == 0) {
+ n |= 4;
+ u <<= 4;
+ }
+ if ((u >> 62) == 0) {
+ n |= 2;
+ u <<= 2;
+ }
+ if ((u >> 63) == 0) {
+ n |= 1;
+ u <<= 1;
+ }
+ return n;
+}
+
+#endif // (defined(__GNUC__) || defined(__clang__)) && (__SIZEOF_LONG__ == 8)
+
+// --------
+
+// Normally, the wuffs_base__peek_etc and wuffs_base__poke_etc implementations
+// are both (1) correct regardless of CPU endianness and (2) very fast (e.g. an
+// inlined wuffs_base__peek_u32le__no_bounds_check call, in an optimized clang
+// or gcc build, is a single MOV instruction on x86_64).
+//
+// However, the endian-agnostic implementations are slow on Microsoft's C
+// compiler (MSC). Alternative memcpy-based implementations restore speed, but
+// they are only correct on little-endian CPU architectures. Defining
+// WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE opts in to these implementations.
+//
+// https://godbolt.org/z/q4MfjzTPh
+#if defined(_MSC_VER) && !defined(__clang__) && \
+ (defined(_M_ARM64) || defined(_M_X64))
+#define WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE
+#endif
+
+#define wuffs_base__peek_u8be__no_bounds_check \
+ wuffs_base__peek_u8__no_bounds_check
+#define wuffs_base__peek_u8le__no_bounds_check \
+ wuffs_base__peek_u8__no_bounds_check
+
+static inline uint8_t //
+wuffs_base__peek_u8__no_bounds_check(const uint8_t* p) {
+ return p[0];
+}
+
+static inline uint16_t //
+wuffs_base__peek_u16be__no_bounds_check(const uint8_t* p) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
+ uint16_t x;
+ memcpy(&x, p, 2);
+ return _byteswap_ushort(x);
+#else
+ return (uint16_t)(((uint16_t)(p[0]) << 8) | ((uint16_t)(p[1]) << 0));
+#endif
+}
+
+static inline uint16_t //
+wuffs_base__peek_u16le__no_bounds_check(const uint8_t* p) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
+ uint16_t x;
+ memcpy(&x, p, 2);
+ return x;
+#else
+ return (uint16_t)(((uint16_t)(p[0]) << 0) | ((uint16_t)(p[1]) << 8));
+#endif
+}
+
+static inline uint32_t //
+wuffs_base__peek_u24be__no_bounds_check(const uint8_t* p) {
+ return ((uint32_t)(p[0]) << 16) | ((uint32_t)(p[1]) << 8) |
+ ((uint32_t)(p[2]) << 0);
+}
+
+static inline uint32_t //
+wuffs_base__peek_u24le__no_bounds_check(const uint8_t* p) {
+ return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
+ ((uint32_t)(p[2]) << 16);
+}
+
+static inline uint32_t //
+wuffs_base__peek_u32be__no_bounds_check(const uint8_t* p) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
+ uint32_t x;
+ memcpy(&x, p, 4);
+ return _byteswap_ulong(x);
+#else
+ return ((uint32_t)(p[0]) << 24) | ((uint32_t)(p[1]) << 16) |
+ ((uint32_t)(p[2]) << 8) | ((uint32_t)(p[3]) << 0);
+#endif
+}
+
+static inline uint32_t //
+wuffs_base__peek_u32le__no_bounds_check(const uint8_t* p) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
+ uint32_t x;
+ memcpy(&x, p, 4);
+ return x;
+#else
+ return ((uint32_t)(p[0]) << 0) | ((uint32_t)(p[1]) << 8) |
+ ((uint32_t)(p[2]) << 16) | ((uint32_t)(p[3]) << 24);
+#endif
+}
+
+static inline uint64_t //
+wuffs_base__peek_u40be__no_bounds_check(const uint8_t* p) {
+ return ((uint64_t)(p[0]) << 32) | ((uint64_t)(p[1]) << 24) |
+ ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 8) |
+ ((uint64_t)(p[4]) << 0);
+}
+
+static inline uint64_t //
+wuffs_base__peek_u40le__no_bounds_check(const uint8_t* p) {
+ return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
+ ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
+ ((uint64_t)(p[4]) << 32);
+}
+
+static inline uint64_t //
+wuffs_base__peek_u48be__no_bounds_check(const uint8_t* p) {
+ return ((uint64_t)(p[0]) << 40) | ((uint64_t)(p[1]) << 32) |
+ ((uint64_t)(p[2]) << 24) | ((uint64_t)(p[3]) << 16) |
+ ((uint64_t)(p[4]) << 8) | ((uint64_t)(p[5]) << 0);
+}
+
+static inline uint64_t //
+wuffs_base__peek_u48le__no_bounds_check(const uint8_t* p) {
+ return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
+ ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
+ ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40);
+}
+
+static inline uint64_t //
+wuffs_base__peek_u56be__no_bounds_check(const uint8_t* p) {
+ return ((uint64_t)(p[0]) << 48) | ((uint64_t)(p[1]) << 40) |
+ ((uint64_t)(p[2]) << 32) | ((uint64_t)(p[3]) << 24) |
+ ((uint64_t)(p[4]) << 16) | ((uint64_t)(p[5]) << 8) |
+ ((uint64_t)(p[6]) << 0);
+}
+
+static inline uint64_t //
+wuffs_base__peek_u56le__no_bounds_check(const uint8_t* p) {
+ return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
+ ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
+ ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
+ ((uint64_t)(p[6]) << 48);
+}
+
+static inline uint64_t //
+wuffs_base__peek_u64be__no_bounds_check(const uint8_t* p) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
+ uint64_t x;
+ memcpy(&x, p, 8);
+ return _byteswap_uint64(x);
+#else
+ return ((uint64_t)(p[0]) << 56) | ((uint64_t)(p[1]) << 48) |
+ ((uint64_t)(p[2]) << 40) | ((uint64_t)(p[3]) << 32) |
+ ((uint64_t)(p[4]) << 24) | ((uint64_t)(p[5]) << 16) |
+ ((uint64_t)(p[6]) << 8) | ((uint64_t)(p[7]) << 0);
+#endif
+}
+
+static inline uint64_t //
+wuffs_base__peek_u64le__no_bounds_check(const uint8_t* p) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE)
+ uint64_t x;
+ memcpy(&x, p, 8);
+ return x;
+#else
+ return ((uint64_t)(p[0]) << 0) | ((uint64_t)(p[1]) << 8) |
+ ((uint64_t)(p[2]) << 16) | ((uint64_t)(p[3]) << 24) |
+ ((uint64_t)(p[4]) << 32) | ((uint64_t)(p[5]) << 40) |
+ ((uint64_t)(p[6]) << 48) | ((uint64_t)(p[7]) << 56);
+#endif
+}
+
+// --------
+
+#define wuffs_base__poke_u8be__no_bounds_check \
+ wuffs_base__poke_u8__no_bounds_check
+#define wuffs_base__poke_u8le__no_bounds_check \
+ wuffs_base__poke_u8__no_bounds_check
+
+static inline void //
+wuffs_base__poke_u8__no_bounds_check(uint8_t* p, uint8_t x) {
+ p[0] = x;
+}
+
+static inline void //
+wuffs_base__poke_u16be__no_bounds_check(uint8_t* p, uint16_t x) {
+ p[0] = (uint8_t)(x >> 8);
+ p[1] = (uint8_t)(x >> 0);
+}
+
+static inline void //
+wuffs_base__poke_u16le__no_bounds_check(uint8_t* p, uint16_t x) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
+ (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
+ // This seems to perform better on gcc 10 (but not clang 9). Clang also
+ // defines "__GNUC__".
+ memcpy(p, &x, 2);
+#else
+ p[0] = (uint8_t)(x >> 0);
+ p[1] = (uint8_t)(x >> 8);
+#endif
+}
+
+static inline void //
+wuffs_base__poke_u24be__no_bounds_check(uint8_t* p, uint32_t x) {
+ p[0] = (uint8_t)(x >> 16);
+ p[1] = (uint8_t)(x >> 8);
+ p[2] = (uint8_t)(x >> 0);
+}
+
+static inline void //
+wuffs_base__poke_u24le__no_bounds_check(uint8_t* p, uint32_t x) {
+ p[0] = (uint8_t)(x >> 0);
+ p[1] = (uint8_t)(x >> 8);
+ p[2] = (uint8_t)(x >> 16);
+}
+
+static inline void //
+wuffs_base__poke_u32be__no_bounds_check(uint8_t* p, uint32_t x) {
+ p[0] = (uint8_t)(x >> 24);
+ p[1] = (uint8_t)(x >> 16);
+ p[2] = (uint8_t)(x >> 8);
+ p[3] = (uint8_t)(x >> 0);
+}
+
+static inline void //
+wuffs_base__poke_u32le__no_bounds_check(uint8_t* p, uint32_t x) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
+ (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
+ // This seems to perform better on gcc 10 (but not clang 9). Clang also
+ // defines "__GNUC__".
+ memcpy(p, &x, 4);
+#else
+ p[0] = (uint8_t)(x >> 0);
+ p[1] = (uint8_t)(x >> 8);
+ p[2] = (uint8_t)(x >> 16);
+ p[3] = (uint8_t)(x >> 24);
+#endif
+}
+
+static inline void //
+wuffs_base__poke_u40be__no_bounds_check(uint8_t* p, uint64_t x) {
+ p[0] = (uint8_t)(x >> 32);
+ p[1] = (uint8_t)(x >> 24);
+ p[2] = (uint8_t)(x >> 16);
+ p[3] = (uint8_t)(x >> 8);
+ p[4] = (uint8_t)(x >> 0);
+}
+
+static inline void //
+wuffs_base__poke_u40le__no_bounds_check(uint8_t* p, uint64_t x) {
+ p[0] = (uint8_t)(x >> 0);
+ p[1] = (uint8_t)(x >> 8);
+ p[2] = (uint8_t)(x >> 16);
+ p[3] = (uint8_t)(x >> 24);
+ p[4] = (uint8_t)(x >> 32);
+}
+
+static inline void //
+wuffs_base__poke_u48be__no_bounds_check(uint8_t* p, uint64_t x) {
+ p[0] = (uint8_t)(x >> 40);
+ p[1] = (uint8_t)(x >> 32);
+ p[2] = (uint8_t)(x >> 24);
+ p[3] = (uint8_t)(x >> 16);
+ p[4] = (uint8_t)(x >> 8);
+ p[5] = (uint8_t)(x >> 0);
+}
+
+static inline void //
+wuffs_base__poke_u48le__no_bounds_check(uint8_t* p, uint64_t x) {
+ p[0] = (uint8_t)(x >> 0);
+ p[1] = (uint8_t)(x >> 8);
+ p[2] = (uint8_t)(x >> 16);
+ p[3] = (uint8_t)(x >> 24);
+ p[4] = (uint8_t)(x >> 32);
+ p[5] = (uint8_t)(x >> 40);
+}
+
+static inline void //
+wuffs_base__poke_u56be__no_bounds_check(uint8_t* p, uint64_t x) {
+ p[0] = (uint8_t)(x >> 48);
+ p[1] = (uint8_t)(x >> 40);
+ p[2] = (uint8_t)(x >> 32);
+ p[3] = (uint8_t)(x >> 24);
+ p[4] = (uint8_t)(x >> 16);
+ p[5] = (uint8_t)(x >> 8);
+ p[6] = (uint8_t)(x >> 0);
+}
+
+static inline void //
+wuffs_base__poke_u56le__no_bounds_check(uint8_t* p, uint64_t x) {
+ p[0] = (uint8_t)(x >> 0);
+ p[1] = (uint8_t)(x >> 8);
+ p[2] = (uint8_t)(x >> 16);
+ p[3] = (uint8_t)(x >> 24);
+ p[4] = (uint8_t)(x >> 32);
+ p[5] = (uint8_t)(x >> 40);
+ p[6] = (uint8_t)(x >> 48);
+}
+
+static inline void //
+wuffs_base__poke_u64be__no_bounds_check(uint8_t* p, uint64_t x) {
+ p[0] = (uint8_t)(x >> 56);
+ p[1] = (uint8_t)(x >> 48);
+ p[2] = (uint8_t)(x >> 40);
+ p[3] = (uint8_t)(x >> 32);
+ p[4] = (uint8_t)(x >> 24);
+ p[5] = (uint8_t)(x >> 16);
+ p[6] = (uint8_t)(x >> 8);
+ p[7] = (uint8_t)(x >> 0);
+}
+
+static inline void //
+wuffs_base__poke_u64le__no_bounds_check(uint8_t* p, uint64_t x) {
+#if defined(WUFFS_BASE__USE_MEMCPY_LE_PEEK_POKE) || \
+ (defined(__GNUC__) && !defined(__clang__) && defined(__x86_64__))
+ // This seems to perform better on gcc 10 (but not clang 9). Clang also
+ // defines "__GNUC__".
+ memcpy(p, &x, 8);
+#else
+ p[0] = (uint8_t)(x >> 0);
+ p[1] = (uint8_t)(x >> 8);
+ p[2] = (uint8_t)(x >> 16);
+ p[3] = (uint8_t)(x >> 24);
+ p[4] = (uint8_t)(x >> 32);
+ p[5] = (uint8_t)(x >> 40);
+ p[6] = (uint8_t)(x >> 48);
+ p[7] = (uint8_t)(x >> 56);
+#endif
+}
+
+// ---------------- 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__make_slice_u8_ij(uint8_t* ptr, size_t i, size_t j) {
+ wuffs_base__slice_u8 ret;
+ ret.ptr = ptr + i;
+ ret.len = (j >= i) ? (j - i) : 0;
+ return ret;
+}
+
+static inline wuffs_base__slice_u16 //
+wuffs_base__make_slice_u16_ij(uint16_t* ptr, size_t i, size_t j) {
+ wuffs_base__slice_u16 ret;
+ ret.ptr = ptr + i;
+ ret.len = (j >= i) ? (j - i) : 0;
+ return ret;
+}
+
+static inline wuffs_base__slice_u32 //
+wuffs_base__make_slice_u32_ij(uint32_t* ptr, size_t i, size_t j) {
+ wuffs_base__slice_u32 ret;
+ ret.ptr = ptr + i;
+ ret.len = (j >= i) ? (j - i) : 0;
+ return ret;
+}
+
+static inline wuffs_base__slice_u64 //
+wuffs_base__make_slice_u64_ij(uint64_t* ptr, size_t i, size_t j) {
+ wuffs_base__slice_u64 ret;
+ ret.ptr = ptr + i;
+ ret.len = (j >= i) ? (j - i) : 0;
+ return ret;
+}
+
+static inline wuffs_base__slice_u8 //
+wuffs_base__empty_slice_u8(void) {
+ wuffs_base__slice_u8 ret;
+ ret.ptr = NULL;
+ ret.len = 0;
+ return ret;
+}
+
+static inline wuffs_base__slice_u16 //
+wuffs_base__empty_slice_u16(void) {
+ wuffs_base__slice_u16 ret;
+ ret.ptr = NULL;
+ ret.len = 0;
+ return ret;
+}
+
+static inline wuffs_base__slice_u32 //
+wuffs_base__empty_slice_u32(void) {
+ wuffs_base__slice_u32 ret;
+ ret.ptr = NULL;
+ ret.len = 0;
+ return ret;
+}
+
+static inline wuffs_base__slice_u64 //
+wuffs_base__empty_slice_u64(void) {
+ wuffs_base__slice_u64 ret;
+ ret.ptr = NULL;
+ ret.len = 0;
+ return ret;
+}
+
+static inline wuffs_base__table_u8 //
+wuffs_base__make_table_u8(uint8_t* ptr,
+ size_t width,
+ size_t height,
+ size_t stride) {
+ wuffs_base__table_u8 ret;
+ ret.ptr = ptr;
+ ret.width = width;
+ ret.height = height;
+ ret.stride = stride;
+ return ret;
+}
+
+static inline wuffs_base__table_u16 //
+wuffs_base__make_table_u16(uint16_t* ptr,
+ size_t width,
+ size_t height,
+ size_t stride) {
+ wuffs_base__table_u16 ret;
+ ret.ptr = ptr;
+ ret.width = width;
+ ret.height = height;
+ ret.stride = stride;
+ return ret;
+}
+
+static inline wuffs_base__table_u32 //
+wuffs_base__make_table_u32(uint32_t* ptr,
+ size_t width,
+ size_t height,
+ size_t stride) {
+ wuffs_base__table_u32 ret;
+ ret.ptr = ptr;
+ ret.width = width;
+ ret.height = height;
+ ret.stride = stride;
+ return ret;
+}
+
+static inline wuffs_base__table_u64 //
+wuffs_base__make_table_u64(uint64_t* ptr,
+ size_t width,
+ size_t height,
+ size_t stride) {
+ wuffs_base__table_u64 ret;
+ ret.ptr = ptr;
+ ret.width = width;
+ ret.height = height;
+ ret.stride = stride;
+ return ret;
+}
+
+static inline wuffs_base__table_u8 //
+wuffs_base__empty_table_u8(void) {
+ wuffs_base__table_u8 ret;
+ ret.ptr = NULL;
+ ret.width = 0;
+ ret.height = 0;
+ ret.stride = 0;
+ return ret;
+}
+
+static inline wuffs_base__table_u16 //
+wuffs_base__empty_table_u16(void) {
+ wuffs_base__table_u16 ret;
+ ret.ptr = NULL;
+ ret.width = 0;
+ ret.height = 0;
+ ret.stride = 0;
+ return ret;
+}
+
+static inline wuffs_base__table_u32 //
+wuffs_base__empty_table_u32(void) {
+ wuffs_base__table_u32 ret;
+ ret.ptr = NULL;
+ ret.width = 0;
+ ret.height = 0;
+ ret.stride = 0;
+ return ret;
+}
+
+static inline wuffs_base__table_u64 //
+wuffs_base__empty_table_u64(void) {
+ wuffs_base__table_u64 ret;
+ ret.ptr = NULL;
+ ret.width = 0;
+ ret.height = 0;
+ ret.stride = 0;
+ return ret;
+}
+
+static inline bool //
+wuffs_base__slice_u8__overlaps(wuffs_base__slice_u8 s, wuffs_base__slice_u8 t) {
+ return ((s.ptr <= t.ptr) && (t.ptr < (s.ptr + s.len))) ||
+ ((t.ptr <= s.ptr) && (s.ptr < (t.ptr + t.len)));
+}
+
+// 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, ((size_t)(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, ((size_t)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, ((size_t)(j - i)));
+ }
+ return wuffs_base__make_slice_u8(NULL, 0);
+}
+
+// wuffs_base__table_u8__subtable_ij returns t[ix:jx, iy:jy].
+//
+// It returns an empty table if i or j is out of bounds.
+static inline wuffs_base__table_u8 //
+wuffs_base__table_u8__subtable_ij(wuffs_base__table_u8 t,
+ uint64_t ix,
+ uint64_t iy,
+ uint64_t jx,
+ uint64_t jy) {
+ if ((ix <= jx) && (jx <= SIZE_MAX) && (jx <= t.width) && //
+ (iy <= jy) && (jy <= SIZE_MAX) && (jy <= t.height)) {
+ return wuffs_base__make_table_u8(t.ptr + ix + (iy * t.stride), //
+ ((size_t)(jx - ix)), //
+ ((size_t)(jy - iy)), //
+ t.stride); //
+ }
+ return wuffs_base__make_table_u8(NULL, 0, 0, 0);
+}
+
+// wuffs_base__table__flattened_length returns the number of elements covered
+// by the 1-dimensional span that backs a 2-dimensional table. This counts the
+// elements inside the table and, when width != stride, the elements outside
+// the table but between its rows.
+//
+// For example, consider a width 10, height 4, stride 10 table. Mark its first
+// and last (inclusive) elements with 'a' and 'z'. This function returns 40.
+//
+// a123456789
+// 0123456789
+// 0123456789
+// 012345678z
+//
+// Now consider the sub-table of that from (2, 1) inclusive to (8, 4) exclusive.
+//
+// a123456789
+// 01iiiiiioo
+// ooiiiiiioo
+// ooiiiiii8z
+//
+// This function (called with width 6, height 3, stride 10) returns 26: 18 'i'
+// inside elements plus 8 'o' outside elements. Note that 26 is less than a
+// naive (height * stride = 30) computation. Indeed, advancing 29 elements from
+// the first 'i' would venture past 'z', out of bounds of the original table.
+//
+// It does not check for overflow, but if the arguments come from a table that
+// exists in memory and each element occupies a positive number of bytes then
+// the result should be bounded by the amount of allocatable memory (which
+// shouldn't overflow SIZE_MAX).
+static inline size_t //
+wuffs_base__table__flattened_length(size_t width,
+ size_t height,
+ size_t stride) {
+ if (height == 0) {
+ return 0;
+ }
+ return ((height - 1) * stride) + width;
+}
+
+// ---------------- Magic Numbers
+
+// wuffs_base__magic_number_guess_fourcc guesses the file format of some data,
+// given its starting bytes (the prefix_data argument) and whether or not there
+// may be further bytes (the prefix_closed argument; true means that
+// prefix_data is the entire data).
+//
+// It returns a positive FourCC value on success.
+//
+// It returns zero if nothing matches its hard-coded list of 'magic numbers'.
+//
+// It returns a negative value if prefix_closed is false and a longer prefix is
+// required for a conclusive result. For example, a single 'B' byte (without
+// further data) is not enough to discriminate the BMP and BPG image file
+// formats. Similarly, a single '\xFF' byte might be the start of JPEG data or
+// it might be the start of some other binary data.
+//
+// It does not do a full validity check. Like any guess made from a short
+// prefix of the data, it may return false positives. Data that starts with 99
+// bytes of valid JPEG followed by corruption or truncation is an invalid JPEG
+// image overall, but this function will still return WUFFS_BASE__FOURCC__JPEG.
+//
+// Another source of false positives is that some 'magic numbers' are valid
+// ASCII data. A file starting with "GIF87a and GIF89a are the two versions of
+// GIF" will match GIF's 'magic number' even if it's plain text, not an image.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__MAGIC sub-module, not just
+// WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC int32_t //
+wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
+ bool prefix_closed);
+
+// ---------------- Ranges and Rects
+
+// See https://github.com/google/wuffs/blob/main/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__empty_range_ii_u32(void) {
+ wuffs_base__range_ii_u32 ret;
+ ret.min_incl = 0;
+ ret.max_incl = 0;
+ return ret;
+}
+
+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__empty_range_ie_u32(void) {
+ wuffs_base__range_ie_u32 ret;
+ ret.min_incl = 0;
+ ret.max_excl = 0;
+ return ret;
+}
+
+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__empty_range_ii_u64(void) {
+ wuffs_base__range_ii_u64 ret;
+ ret.min_incl = 0;
+ ret.max_incl = 0;
+ return ret;
+}
+
+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__empty_range_ie_u64(void) {
+ wuffs_base__range_ie_u64 ret;
+ ret.min_incl = 0;
+ ret.max_excl = 0;
+ return ret;
+}
+
+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__empty_rect_ii_u32(void) {
+ wuffs_base__rect_ii_u32 ret;
+ ret.min_incl_x = 0;
+ ret.min_incl_y = 0;
+ ret.max_incl_x = 0;
+ ret.max_incl_y = 0;
+ return ret;
+}
+
+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__empty_rect_ie_u32(void) {
+ 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 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
+
+// ---------------- More Information
+
+// wuffs_base__more_information holds additional fields, typically when a Wuffs
+// method returns a [note status](/doc/note/statuses.md).
+//
+// The flavor field follows the base38 namespace
+// convention](/doc/note/base38-and-fourcc.md). The other fields' semantics
+// depends on the flavor.
+typedef struct wuffs_base__more_information__struct {
+ uint32_t flavor;
+ uint32_t w;
+ uint64_t x;
+ uint64_t y;
+ uint64_t z;
+
+#ifdef __cplusplus
+ inline void set(uint32_t flavor_arg,
+ uint32_t w_arg,
+ uint64_t x_arg,
+ uint64_t y_arg,
+ uint64_t z_arg);
+ inline uint32_t io_redirect__fourcc() const;
+ inline wuffs_base__range_ie_u64 io_redirect__range() const;
+ inline uint64_t io_seek__position() const;
+ inline uint32_t metadata__fourcc() const;
+ inline wuffs_base__range_ie_u64 metadata_raw_passthrough__range() const;
+ inline int32_t metadata_parsed__chrm(uint32_t component) const;
+ inline uint32_t metadata_parsed__gama() const;
+ inline uint32_t metadata_parsed__srgb() const;
+#endif // __cplusplus
+
+} wuffs_base__more_information;
+
+#define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT 1
+#define WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_SEEK 2
+#define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH 3
+#define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM 4
+#define WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED 5
+
+static inline wuffs_base__more_information //
+wuffs_base__empty_more_information(void) {
+ wuffs_base__more_information ret;
+ ret.flavor = 0;
+ ret.w = 0;
+ ret.x = 0;
+ ret.y = 0;
+ ret.z = 0;
+ return ret;
+}
+
+static inline void //
+wuffs_base__more_information__set(wuffs_base__more_information* m,
+ uint32_t flavor,
+ uint32_t w,
+ uint64_t x,
+ uint64_t y,
+ uint64_t z) {
+ if (!m) {
+ return;
+ }
+ m->flavor = flavor;
+ m->w = w;
+ m->x = x;
+ m->y = y;
+ m->z = z;
+}
+
+static inline uint32_t //
+wuffs_base__more_information__io_redirect__fourcc(
+ const wuffs_base__more_information* m) {
+ return m->w;
+}
+
+static inline wuffs_base__range_ie_u64 //
+wuffs_base__more_information__io_redirect__range(
+ const wuffs_base__more_information* m) {
+ wuffs_base__range_ie_u64 ret;
+ ret.min_incl = m->y;
+ ret.max_excl = m->z;
+ return ret;
+}
+
+static inline uint64_t //
+wuffs_base__more_information__io_seek__position(
+ const wuffs_base__more_information* m) {
+ return m->x;
+}
+
+static inline uint32_t //
+wuffs_base__more_information__metadata__fourcc(
+ const wuffs_base__more_information* m) {
+ return m->w;
+}
+
+static inline wuffs_base__range_ie_u64 //
+wuffs_base__more_information__metadata_raw_passthrough__range(
+ const wuffs_base__more_information* m) {
+ wuffs_base__range_ie_u64 ret;
+ ret.min_incl = m->y;
+ ret.max_excl = m->z;
+ return ret;
+}
+
+#define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_X 0
+#define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__WHITE_Y 1
+#define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_X 2
+#define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__RED_Y 3
+#define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_X 4
+#define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__GREEN_Y 5
+#define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_X 6
+#define WUFFS_BASE__MORE_INFORMATION__METADATA_PARSED__CHRM__BLUE_Y 7
+
+// wuffs_base__more_information__metadata_parsed__chrm returns chromaticity
+// values (scaled by 100000) like the PNG "cHRM" chunk. For example, the sRGB
+// color space corresponds to:
+// - ETC__CHRM__WHITE_X 31270
+// - ETC__CHRM__WHITE_Y 32900
+// - ETC__CHRM__RED_X 64000
+// - ETC__CHRM__RED_Y 33000
+// - ETC__CHRM__GREEN_X 30000
+// - ETC__CHRM__GREEN_Y 60000
+// - ETC__CHRM__BLUE_X 15000
+// - ETC__CHRM__BLUE_Y 6000
+//
+// See
+// https://ciechanow.ski/color-spaces/#chromaticity-and-white-point-coordinates
+static inline int32_t //
+wuffs_base__more_information__metadata_parsed__chrm(
+ const wuffs_base__more_information* m,
+ uint32_t component) {
+ // After the flavor and the w field (holding a FourCC), a
+ // wuffs_base__more_information holds 24 bytes of data in three uint64_t
+ // typed fields (x, y and z). We pack the eight chromaticity values (wx, wy,
+ // rx, ..., by), basically int24_t values, into 24 bytes like this:
+ // - LSB MSB
+ // - x: wx wx wx wy wy wy rx rx
+ // - y: rx ry ry ry gx gx gx gy
+ // - z: gy gy bx bx bx by by by
+ uint32_t u = 0;
+ switch (component & 7) {
+ case 0:
+ u = ((uint32_t)(m->x >> 0));
+ break;
+ case 1:
+ u = ((uint32_t)(m->x >> 24));
+ break;
+ case 2:
+ u = ((uint32_t)((m->x >> 48) | (m->y << 16)));
+ break;
+ case 3:
+ u = ((uint32_t)(m->y >> 8));
+ break;
+ case 4:
+ u = ((uint32_t)(m->y >> 32));
+ break;
+ case 5:
+ u = ((uint32_t)((m->y >> 56) | (m->z << 8)));
+ break;
+ case 6:
+ u = ((uint32_t)(m->z >> 16));
+ break;
+ case 7:
+ u = ((uint32_t)(m->z >> 40));
+ break;
+ }
+ // The left-right shifts sign-extend from 24-bit to 32-bit integers.
+ return ((int32_t)(u << 8)) >> 8;
+}
+
+// wuffs_base__more_information__metadata_parsed__gama returns inverse gamma
+// correction values (scaled by 100000) like the PNG "gAMA" chunk. For example,
+// for gamma = 2.2, this returns 45455 (approximating 100000 / 2.2).
+static inline uint32_t //
+wuffs_base__more_information__metadata_parsed__gama(
+ const wuffs_base__more_information* m) {
+ return ((uint32_t)(m->x));
+}
+
+#define WUFFS_BASE__SRGB_RENDERING_INTENT__PERCEPTUAL 0
+#define WUFFS_BASE__SRGB_RENDERING_INTENT__RELATIVE_COLORIMETRIC 1
+#define WUFFS_BASE__SRGB_RENDERING_INTENT__SATURATION 2
+#define WUFFS_BASE__SRGB_RENDERING_INTENT__ABSOLUTE_COLORIMETRIC 3
+
+// wuffs_base__more_information__metadata_parsed__srgb returns the sRGB
+// rendering intent like the PNG "sRGB" chunk.
+static inline uint32_t //
+wuffs_base__more_information__metadata_parsed__srgb(
+ const wuffs_base__more_information* m) {
+ return m->x & 3;
+}
+
+#ifdef __cplusplus
+
+inline void //
+wuffs_base__more_information::set(uint32_t flavor_arg,
+ uint32_t w_arg,
+ uint64_t x_arg,
+ uint64_t y_arg,
+ uint64_t z_arg) {
+ wuffs_base__more_information__set(this, flavor_arg, w_arg, x_arg, y_arg,
+ z_arg);
+}
+
+inline uint32_t //
+wuffs_base__more_information::io_redirect__fourcc() const {
+ return wuffs_base__more_information__io_redirect__fourcc(this);
+}
+
+inline wuffs_base__range_ie_u64 //
+wuffs_base__more_information::io_redirect__range() const {
+ return wuffs_base__more_information__io_redirect__range(this);
+}
+
+inline uint64_t //
+wuffs_base__more_information::io_seek__position() const {
+ return wuffs_base__more_information__io_seek__position(this);
+}
+
+inline uint32_t //
+wuffs_base__more_information::metadata__fourcc() const {
+ return wuffs_base__more_information__metadata__fourcc(this);
+}
+
+inline wuffs_base__range_ie_u64 //
+wuffs_base__more_information::metadata_raw_passthrough__range() const {
+ return wuffs_base__more_information__metadata_raw_passthrough__range(this);
+}
+
+inline int32_t //
+wuffs_base__more_information::metadata_parsed__chrm(uint32_t component) const {
+ return wuffs_base__more_information__metadata_parsed__chrm(this, component);
+}
+
+inline uint32_t //
+wuffs_base__more_information::metadata_parsed__gama() const {
+ return wuffs_base__more_information__metadata_parsed__gama(this);
+}
+
+inline uint32_t //
+wuffs_base__more_information::metadata_parsed__srgb() const {
+ return wuffs_base__more_information__metadata_parsed__srgb(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 wuffs_base__io_buffer_meta__struct {
+ size_t wi; // Write index. Invariant: wi <= len.
+ size_t ri; // Read index. Invariant: ri <= wi.
+ uint64_t pos; // Buffer position (relative to the start of stream).
+ 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__io_buffer__struct {
+ wuffs_base__slice_u8 data;
+ wuffs_base__io_buffer_meta meta;
+
+#ifdef __cplusplus
+ inline bool is_valid() const;
+ inline void compact();
+ inline void compact_retaining(uint64_t history_retain_length);
+ inline size_t reader_length() const;
+ inline uint8_t* reader_pointer() const;
+ inline uint64_t reader_position() const;
+ inline wuffs_base__slice_u8 reader_slice() const;
+ inline size_t writer_length() const;
+ inline uint8_t* writer_pointer() const;
+ inline uint64_t writer_position() const;
+ inline wuffs_base__slice_u8 writer_slice() 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__ptr_u8__reader(uint8_t* ptr, size_t len, bool closed) {
+ wuffs_base__io_buffer ret;
+ ret.data.ptr = ptr;
+ ret.data.len = len;
+ ret.meta.wi = len;
+ ret.meta.ri = 0;
+ ret.meta.pos = 0;
+ ret.meta.closed = closed;
+ return ret;
+}
+
+static inline wuffs_base__io_buffer //
+wuffs_base__ptr_u8__writer(uint8_t* ptr, size_t len) {
+ wuffs_base__io_buffer ret;
+ ret.data.ptr = ptr;
+ ret.data.len = len;
+ ret.meta.wi = 0;
+ ret.meta.ri = 0;
+ ret.meta.pos = 0;
+ ret.meta.closed = false;
+ return ret;
+}
+
+static inline wuffs_base__io_buffer //
+wuffs_base__slice_u8__reader(wuffs_base__slice_u8 s, bool closed) {
+ wuffs_base__io_buffer ret;
+ ret.data.ptr = s.ptr;
+ ret.data.len = s.len;
+ ret.meta.wi = s.len;
+ ret.meta.ri = 0;
+ ret.meta.pos = 0;
+ ret.meta.closed = closed;
+ return ret;
+}
+
+static inline wuffs_base__io_buffer //
+wuffs_base__slice_u8__writer(wuffs_base__slice_u8 s) {
+ wuffs_base__io_buffer ret;
+ ret.data.ptr = s.ptr;
+ ret.data.len = s.len;
+ ret.meta.wi = 0;
+ ret.meta.ri = 0;
+ ret.meta.pos = 0;
+ ret.meta.closed = false;
+ return ret;
+}
+
+static inline wuffs_base__io_buffer //
+wuffs_base__empty_io_buffer(void) {
+ 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(void) {
+ wuffs_base__io_buffer_meta ret;
+ ret.wi = 0;
+ ret.ri = 0;
+ ret.pos = 0;
+ ret.closed = false;
+ return ret;
+}
+
+static inline bool //
+wuffs_base__io_buffer__is_valid(const wuffs_base__io_buffer* buf) {
+ if (buf) {
+ if (buf->data.ptr) {
+ return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
+ } else {
+ return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
+ }
+ }
+ return false;
+}
+
+// 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 new_wi = buf->meta.wi - buf->meta.ri;
+ if (new_wi != 0) {
+ memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri, new_wi);
+ }
+ buf->meta.wi = new_wi;
+ buf->meta.ri = 0;
+}
+
+// wuffs_base__io_buffer__compact_retaining moves any written but unread bytes
+// closer to the start of the buffer. It retains H bytes of history (the most
+// recently read bytes), where H is min(buf->meta.ri, history_retain_length).
+// A postcondition is that buf->meta.ri == H.
+//
+// wuffs_base__io_buffer__compact_retaining(0) is equivalent to
+// wuffs_base__io_buffer__compact().
+//
+// For example, if buf started like this:
+//
+// +--- ri = 3
+// v
+// abcdefgh?? len = 10, pos = 900
+// ^
+// +--- wi = 8
+//
+// Then, depending on history_retain_length, the resultant buf would be:
+//
+// HRL = 0 defgh????? ri = 0 wi = 5 pos = 903
+// HRL = 1 cdefgh???? ri = 1 wi = 6 pos = 902
+// HRL = 2 bcdefgh??? ri = 2 wi = 7 pos = 901
+// HRL = 3 abcdefgh?? ri = 3 wi = 8 pos = 900
+// HRL = 4+ abcdefgh?? ri = 3 wi = 8 pos = 900
+static inline void //
+wuffs_base__io_buffer__compact_retaining(wuffs_base__io_buffer* buf,
+ uint64_t history_retain_length) {
+ if (!buf || (buf->meta.ri == 0)) {
+ return;
+ }
+ size_t old_ri = buf->meta.ri;
+ size_t new_ri = (size_t)(wuffs_base__u64__min(old_ri, history_retain_length));
+ size_t memmove_start = old_ri - new_ri;
+ buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, memmove_start);
+ size_t new_wi = buf->meta.wi - memmove_start;
+ if ((new_wi != 0) && (memmove_start != 0)) {
+ memmove(buf->data.ptr, buf->data.ptr + memmove_start, new_wi);
+ }
+ buf->meta.wi = new_wi;
+ buf->meta.ri = new_ri;
+}
+
+static inline size_t //
+wuffs_base__io_buffer__reader_length(const wuffs_base__io_buffer* buf) {
+ return buf ? buf->meta.wi - buf->meta.ri : 0;
+}
+
+static inline uint8_t* //
+wuffs_base__io_buffer__reader_pointer(const wuffs_base__io_buffer* buf) {
+ return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
+}
+
+static inline uint64_t //
+wuffs_base__io_buffer__reader_position(const wuffs_base__io_buffer* buf) {
+ return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
+}
+
+static inline wuffs_base__slice_u8 //
+wuffs_base__io_buffer__reader_slice(const wuffs_base__io_buffer* buf) {
+ return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.ri,
+ buf->meta.wi - buf->meta.ri)
+ : wuffs_base__empty_slice_u8();
+}
+
+static inline size_t //
+wuffs_base__io_buffer__writer_length(const wuffs_base__io_buffer* buf) {
+ return buf ? buf->data.len - buf->meta.wi : 0;
+}
+
+static inline uint8_t* //
+wuffs_base__io_buffer__writer_pointer(const wuffs_base__io_buffer* buf) {
+ return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
+}
+
+static inline uint64_t //
+wuffs_base__io_buffer__writer_position(const wuffs_base__io_buffer* buf) {
+ return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
+}
+
+static inline wuffs_base__slice_u8 //
+wuffs_base__io_buffer__writer_slice(const wuffs_base__io_buffer* buf) {
+ return buf ? wuffs_base__make_slice_u8(buf->data.ptr + buf->meta.wi,
+ buf->data.len - buf->meta.wi)
+ : wuffs_base__empty_slice_u8();
+}
+
+#ifdef __cplusplus
+
+inline bool //
+wuffs_base__io_buffer::is_valid() const {
+ return wuffs_base__io_buffer__is_valid(this);
+}
+
+inline void //
+wuffs_base__io_buffer::compact() {
+ wuffs_base__io_buffer__compact(this);
+}
+
+inline void //
+wuffs_base__io_buffer::compact_retaining(uint64_t history_retain_length) {
+ wuffs_base__io_buffer__compact_retaining(this, history_retain_length);
+}
+
+inline size_t //
+wuffs_base__io_buffer::reader_length() const {
+ return wuffs_base__io_buffer__reader_length(this);
+}
+
+inline uint8_t* //
+wuffs_base__io_buffer::reader_pointer() const {
+ return wuffs_base__io_buffer__reader_pointer(this);
+}
+
+inline uint64_t //
+wuffs_base__io_buffer::reader_position() const {
+ return wuffs_base__io_buffer__reader_position(this);
+}
+
+inline wuffs_base__slice_u8 //
+wuffs_base__io_buffer::reader_slice() const {
+ return wuffs_base__io_buffer__reader_slice(this);
+}
+
+inline size_t //
+wuffs_base__io_buffer::writer_length() const {
+ return wuffs_base__io_buffer__writer_length(this);
+}
+
+inline uint8_t* //
+wuffs_base__io_buffer::writer_pointer() const {
+ return wuffs_base__io_buffer__writer_pointer(this);
+}
+
+inline uint64_t //
+wuffs_base__io_buffer::writer_position() const {
+ return wuffs_base__io_buffer__writer_position(this);
+}
+
+inline wuffs_base__slice_u8 //
+wuffs_base__io_buffer::writer_slice() const {
+ return wuffs_base__io_buffer__writer_slice(this);
+}
+
+#endif // __cplusplus
+
+// ---------------- Tokens
+
+// wuffs_base__token is an element of a byte stream's tokenization.
+//
+// See https://github.com/google/wuffs/blob/main/doc/note/tokens.md
+typedef struct wuffs_base__token__struct {
+ uint64_t repr;
+
+#ifdef __cplusplus
+ inline int64_t value() const;
+ inline int64_t value_extension() const;
+ inline int64_t value_major() const;
+ inline int64_t value_base_category() const;
+ inline uint64_t value_minor() const;
+ inline uint64_t value_base_detail() const;
+ inline int64_t value_base_detail__sign_extended() const;
+ inline bool continued() const;
+ inline uint64_t length() const;
+#endif // __cplusplus
+
+} wuffs_base__token;
+
+static inline wuffs_base__token //
+wuffs_base__make_token(uint64_t repr) {
+ wuffs_base__token ret;
+ ret.repr = repr;
+ return ret;
+}
+
+// --------
+
+#define WUFFS_BASE__TOKEN__LENGTH__MAX_INCL 0xFFFF
+
+#define WUFFS_BASE__TOKEN__VALUE__SHIFT 17
+#define WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT 17
+#define WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT 42
+#define WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT 17
+#define WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT 38
+#define WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT 17
+#define WUFFS_BASE__TOKEN__CONTINUED__SHIFT 16
+#define WUFFS_BASE__TOKEN__LENGTH__SHIFT 0
+
+#define WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS 46
+
+// --------
+
+#define WUFFS_BASE__TOKEN__VBC__FILLER 0
+#define WUFFS_BASE__TOKEN__VBC__STRUCTURE 1
+#define WUFFS_BASE__TOKEN__VBC__STRING 2
+#define WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT 3
+#define WUFFS_BASE__TOKEN__VBC__LITERAL 4
+#define WUFFS_BASE__TOKEN__VBC__NUMBER 5
+#define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED 6
+#define WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED 7
+
+// --------
+
+#define WUFFS_BASE__TOKEN__VBD__FILLER__PUNCTUATION 0x00001
+#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_BLOCK 0x00002
+#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_LINE 0x00004
+
+// COMMENT_ANY is a bit-wise or of COMMENT_BLOCK AND COMMENT_LINE.
+#define WUFFS_BASE__TOKEN__VBD__FILLER__COMMENT_ANY 0x00006
+
+// --------
+
+#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH 0x00001
+#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP 0x00002
+#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE 0x00010
+#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST 0x00020
+#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT 0x00040
+#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE 0x01000
+#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST 0x02000
+#define WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT 0x04000
+
+// --------
+
+// DEFINITELY_FOO means that the destination bytes (and also the source bytes,
+// for 1_DST_1_SRC_COPY) are in the FOO format. Definitely means that the lack
+// of the bit means "maybe FOO". It does not necessarily mean "not FOO".
+//
+// CHAIN_ETC means that decoding the entire token chain forms a UTF-8 or ASCII
+// string, not just this current token. CHAIN_ETC_UTF_8 therefore distinguishes
+// Unicode (UTF-8) strings from byte strings. MUST means that the the token
+// producer (e.g. parser) must verify this. SHOULD means that the token
+// consumer (e.g. renderer) should verify this.
+//
+// When a CHAIN_ETC_UTF_8 bit is set, the parser must ensure that non-ASCII
+// code points (with multi-byte UTF-8 encodings) do not straddle token
+// boundaries. Checking UTF-8 validity can inspect each token separately.
+//
+// The lack of any particular bit is conservative: it is valid for all-ASCII
+// strings, in a single- or multi-token chain, to have none of these bits set.
+#define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_UTF_8 0x00001
+#define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8 0x00002
+#define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_UTF_8 0x00004
+#define WUFFS_BASE__TOKEN__VBD__STRING__DEFINITELY_ASCII 0x00010
+#define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_ASCII 0x00020
+#define WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_SHOULD_BE_ASCII 0x00040
+
+// CONVERT_D_DST_S_SRC means that multiples of S source bytes (possibly padded)
+// produces multiples of D destination bytes. For example,
+// CONVERT_1_DST_4_SRC_BACKSLASH_X means a source like "\\x23\\x67\\xAB", where
+// 12 src bytes encode 3 dst bytes.
+//
+// Post-processing may further transform those D destination bytes (e.g. treat
+// "\\xFF" as the Unicode code point U+00FF instead of the byte 0xFF), but that
+// is out of scope of this VBD's semantics.
+//
+// When src is the empty string, multiple conversion algorithms are applicable
+// (so these bits are not necessarily mutually exclusive), all producing the
+// same empty dst string.
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP 0x00100
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY 0x00200
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_2_SRC_HEXADECIMAL 0x00400
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_4_SRC_BACKSLASH_X 0x00800
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_STD 0x01000
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_3_DST_4_SRC_BASE_64_URL 0x02000
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_4_DST_5_SRC_ASCII_85 0x04000
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_HEX 0x08000
+#define WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_5_DST_8_SRC_BASE_32_STD 0x10000
+
+// --------
+
+#define WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED 0x00001
+#define WUFFS_BASE__TOKEN__VBD__LITERAL__NULL 0x00002
+#define WUFFS_BASE__TOKEN__VBD__LITERAL__FALSE 0x00004
+#define WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE 0x00008
+
+// --------
+
+// For a source string of "123" or "0x9A", it is valid for a tokenizer to
+// return any combination of:
+// - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT.
+// - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED.
+// - WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED.
+//
+// For a source string of "+123" or "-0x9A", only the first two are valid.
+//
+// For a source string of "123.", only the first one is valid.
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT 0x00001
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED 0x00002
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_UNSIGNED 0x00004
+
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF 0x00010
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF 0x00020
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN 0x00040
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN 0x00080
+
+// The number 300 might be represented as "\x01\x2C", "\x2C\x01\x00\x00" or
+// "300", which are big-endian, little-endian or text. For binary formats, the
+// token length (after adjusting for FORMAT_IGNORE_ETC) discriminates
+// e.g. u16 little-endian vs u32 little-endian.
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN 0x00100
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_LITTLE_ENDIAN 0x00200
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT 0x00400
+
+#define WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE 0x01000
+
+// --------
+
+// wuffs_base__token__value returns the token's high 46 bits, sign-extended. A
+// negative value means an extended token, non-negative means a simple token.
+static inline int64_t //
+wuffs_base__token__value(const wuffs_base__token* t) {
+ return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE__SHIFT;
+}
+
+// wuffs_base__token__value_extension returns a negative value if the token was
+// not an extended token.
+static inline int64_t //
+wuffs_base__token__value_extension(const wuffs_base__token* t) {
+ return (~(int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT;
+}
+
+// wuffs_base__token__value_major returns a negative value if the token was not
+// a simple token.
+static inline int64_t //
+wuffs_base__token__value_major(const wuffs_base__token* t) {
+ return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT;
+}
+
+// wuffs_base__token__value_base_category returns a negative value if the token
+// was not a simple token.
+static inline int64_t //
+wuffs_base__token__value_base_category(const wuffs_base__token* t) {
+ return ((int64_t)(t->repr)) >> WUFFS_BASE__TOKEN__VALUE_BASE_CATEGORY__SHIFT;
+}
+
+static inline uint64_t //
+wuffs_base__token__value_minor(const wuffs_base__token* t) {
+ return (t->repr >> WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) & 0x1FFFFFF;
+}
+
+static inline uint64_t //
+wuffs_base__token__value_base_detail(const wuffs_base__token* t) {
+ return (t->repr >> WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT) & 0x1FFFFF;
+}
+
+static inline int64_t //
+wuffs_base__token__value_base_detail__sign_extended(
+ const wuffs_base__token* t) {
+ // The VBD is 21 bits in the middle of t->repr. Left shift the high (64 - 21
+ // - ETC__SHIFT) bits off, then right shift (sign-extending) back down.
+ uint64_t u = t->repr << (43 - WUFFS_BASE__TOKEN__VALUE_BASE_DETAIL__SHIFT);
+ return ((int64_t)u) >> 43;
+}
+
+static inline bool //
+wuffs_base__token__continued(const wuffs_base__token* t) {
+ return t->repr & 0x10000;
+}
+
+static inline uint64_t //
+wuffs_base__token__length(const wuffs_base__token* t) {
+ return (t->repr >> WUFFS_BASE__TOKEN__LENGTH__SHIFT) & 0xFFFF;
+}
+
+#ifdef __cplusplus
+
+inline int64_t //
+wuffs_base__token::value() const {
+ return wuffs_base__token__value(this);
+}
+
+inline int64_t //
+wuffs_base__token::value_extension() const {
+ return wuffs_base__token__value_extension(this);
+}
+
+inline int64_t //
+wuffs_base__token::value_major() const {
+ return wuffs_base__token__value_major(this);
+}
+
+inline int64_t //
+wuffs_base__token::value_base_category() const {
+ return wuffs_base__token__value_base_category(this);
+}
+
+inline uint64_t //
+wuffs_base__token::value_minor() const {
+ return wuffs_base__token__value_minor(this);
+}
+
+inline uint64_t //
+wuffs_base__token::value_base_detail() const {
+ return wuffs_base__token__value_base_detail(this);
+}
+
+inline int64_t //
+wuffs_base__token::value_base_detail__sign_extended() const {
+ return wuffs_base__token__value_base_detail__sign_extended(this);
+}
+
+inline bool //
+wuffs_base__token::continued() const {
+ return wuffs_base__token__continued(this);
+}
+
+inline uint64_t //
+wuffs_base__token::length() const {
+ return wuffs_base__token__length(this);
+}
+
+#endif // __cplusplus
+
+// --------
+
+typedef WUFFS_BASE__SLICE(wuffs_base__token) wuffs_base__slice_token;
+
+static inline wuffs_base__slice_token //
+wuffs_base__make_slice_token(wuffs_base__token* ptr, size_t len) {
+ wuffs_base__slice_token ret;
+ ret.ptr = ptr;
+ ret.len = len;
+ return ret;
+}
+
+static inline wuffs_base__slice_token //
+wuffs_base__empty_slice_token(void) {
+ wuffs_base__slice_token ret;
+ ret.ptr = NULL;
+ ret.len = 0;
+ return ret;
+}
+
+// --------
+
+// wuffs_base__token_buffer_meta is the metadata for a
+// wuffs_base__token_buffer's data.
+typedef struct wuffs_base__token_buffer_meta__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__token_buffer_meta;
+
+// wuffs_base__token_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__token_buffer__struct {
+ wuffs_base__slice_token data;
+ wuffs_base__token_buffer_meta meta;
+
+#ifdef __cplusplus
+ inline bool is_valid() const;
+ inline void compact();
+ inline void compact_retaining(uint64_t history_retain_length);
+ inline uint64_t reader_length() const;
+ inline wuffs_base__token* reader_pointer() const;
+ inline wuffs_base__slice_token reader_slice() const;
+ inline uint64_t reader_token_position() const;
+ inline uint64_t writer_length() const;
+ inline uint64_t writer_token_position() const;
+ inline wuffs_base__token* writer_pointer() const;
+ inline wuffs_base__slice_token writer_slice() const;
+#endif // __cplusplus
+
+} wuffs_base__token_buffer;
+
+static inline wuffs_base__token_buffer //
+wuffs_base__make_token_buffer(wuffs_base__slice_token data,
+ wuffs_base__token_buffer_meta meta) {
+ wuffs_base__token_buffer ret;
+ ret.data = data;
+ ret.meta = meta;
+ return ret;
+}
+
+static inline wuffs_base__token_buffer_meta //
+wuffs_base__make_token_buffer_meta(size_t wi,
+ size_t ri,
+ uint64_t pos,
+ bool closed) {
+ wuffs_base__token_buffer_meta ret;
+ ret.wi = wi;
+ ret.ri = ri;
+ ret.pos = pos;
+ ret.closed = closed;
+ return ret;
+}
+
+static inline wuffs_base__token_buffer //
+wuffs_base__slice_token__reader(wuffs_base__slice_token s, bool closed) {
+ wuffs_base__token_buffer ret;
+ ret.data.ptr = s.ptr;
+ ret.data.len = s.len;
+ ret.meta.wi = s.len;
+ ret.meta.ri = 0;
+ ret.meta.pos = 0;
+ ret.meta.closed = closed;
+ return ret;
+}
+
+static inline wuffs_base__token_buffer //
+wuffs_base__slice_token__writer(wuffs_base__slice_token s) {
+ wuffs_base__token_buffer ret;
+ ret.data.ptr = s.ptr;
+ ret.data.len = s.len;
+ ret.meta.wi = 0;
+ ret.meta.ri = 0;
+ ret.meta.pos = 0;
+ ret.meta.closed = false;
+ return ret;
+}
+
+static inline wuffs_base__token_buffer //
+wuffs_base__empty_token_buffer(void) {
+ wuffs_base__token_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__token_buffer_meta //
+wuffs_base__empty_token_buffer_meta(void) {
+ wuffs_base__token_buffer_meta ret;
+ ret.wi = 0;
+ ret.ri = 0;
+ ret.pos = 0;
+ ret.closed = false;
+ return ret;
+}
+
+static inline bool //
+wuffs_base__token_buffer__is_valid(const wuffs_base__token_buffer* buf) {
+ if (buf) {
+ if (buf->data.ptr) {
+ return (buf->meta.ri <= buf->meta.wi) && (buf->meta.wi <= buf->data.len);
+ } else {
+ return (buf->meta.ri == 0) && (buf->meta.wi == 0) && (buf->data.len == 0);
+ }
+ }
+ return false;
+}
+
+// wuffs_base__token_buffer__compact moves any written but unread tokens to the
+// start of the buffer.
+static inline void //
+wuffs_base__token_buffer__compact(wuffs_base__token_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 new_wi = buf->meta.wi - buf->meta.ri;
+ if (new_wi != 0) {
+ memmove(buf->data.ptr, buf->data.ptr + buf->meta.ri,
+ new_wi * sizeof(wuffs_base__token));
+ }
+ buf->meta.wi = new_wi;
+ buf->meta.ri = 0;
+}
+
+// wuffs_base__token_buffer__compact_retaining moves any written but unread
+// tokens closer to the start of the buffer. It retains H tokens of history
+// (the most recently read tokens), where H is min(buf->meta.ri,
+// history_retain_length). A postcondition is that buf->meta.ri == H.
+//
+// wuffs_base__token_buffer__compact_retaining(0) is equivalent to
+// wuffs_base__token_buffer__compact().
+//
+// For example, if buf started like this:
+//
+// +--- ri = 3
+// v
+// abcdefgh?? len = 10, pos = 900
+// ^
+// +--- wi = 8
+//
+// Then, depending on history_retain_length, the resultant buf would be:
+//
+// HRL = 0 defgh????? ri = 0 wi = 5 pos = 903
+// HRL = 1 cdefgh???? ri = 1 wi = 6 pos = 902
+// HRL = 2 bcdefgh??? ri = 2 wi = 7 pos = 901
+// HRL = 3 abcdefgh?? ri = 3 wi = 8 pos = 900
+// HRL = 4+ abcdefgh?? ri = 3 wi = 8 pos = 900
+static inline void //
+wuffs_base__token_buffer__compact_retaining(wuffs_base__token_buffer* buf,
+ uint64_t history_retain_length) {
+ if (!buf || (buf->meta.ri == 0)) {
+ return;
+ }
+ size_t old_ri = buf->meta.ri;
+ size_t new_ri = (size_t)(wuffs_base__u64__min(old_ri, history_retain_length));
+ size_t memmove_start = old_ri - new_ri;
+ buf->meta.pos = wuffs_base__u64__sat_add(buf->meta.pos, memmove_start);
+ size_t new_wi = buf->meta.wi - memmove_start;
+ if ((new_wi != 0) && (memmove_start != 0)) {
+ memmove(buf->data.ptr, buf->data.ptr + memmove_start,
+ new_wi * sizeof(wuffs_base__token));
+ }
+ buf->meta.wi = new_wi;
+ buf->meta.ri = new_ri;
+}
+
+static inline uint64_t //
+wuffs_base__token_buffer__reader_length(const wuffs_base__token_buffer* buf) {
+ return buf ? buf->meta.wi - buf->meta.ri : 0;
+}
+
+static inline wuffs_base__token* //
+wuffs_base__token_buffer__reader_pointer(const wuffs_base__token_buffer* buf) {
+ return buf ? (buf->data.ptr + buf->meta.ri) : NULL;
+}
+
+static inline wuffs_base__slice_token //
+wuffs_base__token_buffer__reader_slice(const wuffs_base__token_buffer* buf) {
+ return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.ri,
+ buf->meta.wi - buf->meta.ri)
+ : wuffs_base__empty_slice_token();
+}
+
+static inline uint64_t //
+wuffs_base__token_buffer__reader_token_position(
+ const wuffs_base__token_buffer* buf) {
+ return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.ri) : 0;
+}
+
+static inline uint64_t //
+wuffs_base__token_buffer__writer_length(const wuffs_base__token_buffer* buf) {
+ return buf ? buf->data.len - buf->meta.wi : 0;
+}
+
+static inline wuffs_base__token* //
+wuffs_base__token_buffer__writer_pointer(const wuffs_base__token_buffer* buf) {
+ return buf ? (buf->data.ptr + buf->meta.wi) : NULL;
+}
+
+static inline wuffs_base__slice_token //
+wuffs_base__token_buffer__writer_slice(const wuffs_base__token_buffer* buf) {
+ return buf ? wuffs_base__make_slice_token(buf->data.ptr + buf->meta.wi,
+ buf->data.len - buf->meta.wi)
+ : wuffs_base__empty_slice_token();
+}
+
+static inline uint64_t //
+wuffs_base__token_buffer__writer_token_position(
+ const wuffs_base__token_buffer* buf) {
+ return buf ? wuffs_base__u64__sat_add(buf->meta.pos, buf->meta.wi) : 0;
+}
+
+#ifdef __cplusplus
+
+inline bool //
+wuffs_base__token_buffer::is_valid() const {
+ return wuffs_base__token_buffer__is_valid(this);
+}
+
+inline void //
+wuffs_base__token_buffer::compact() {
+ wuffs_base__token_buffer__compact(this);
+}
+
+inline void //
+wuffs_base__token_buffer::compact_retaining(uint64_t history_retain_length) {
+ wuffs_base__token_buffer__compact_retaining(this, history_retain_length);
+}
+
+inline uint64_t //
+wuffs_base__token_buffer::reader_length() const {
+ return wuffs_base__token_buffer__reader_length(this);
+}
+
+inline wuffs_base__token* //
+wuffs_base__token_buffer::reader_pointer() const {
+ return wuffs_base__token_buffer__reader_pointer(this);
+}
+
+inline wuffs_base__slice_token //
+wuffs_base__token_buffer::reader_slice() const {
+ return wuffs_base__token_buffer__reader_slice(this);
+}
+
+inline uint64_t //
+wuffs_base__token_buffer::reader_token_position() const {
+ return wuffs_base__token_buffer__reader_token_position(this);
+}
+
+inline uint64_t //
+wuffs_base__token_buffer::writer_length() const {
+ return wuffs_base__token_buffer__writer_length(this);
+}
+
+inline wuffs_base__token* //
+wuffs_base__token_buffer::writer_pointer() const {
+ return wuffs_base__token_buffer__writer_pointer(this);
+}
+
+inline wuffs_base__slice_token //
+wuffs_base__token_buffer::writer_slice() const {
+ return wuffs_base__token_buffer__writer_slice(this);
+}
+
+inline uint64_t //
+wuffs_base__token_buffer::writer_token_position() const {
+ return wuffs_base__token_buffer__writer_token_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)((size_t)(num_u8 * sizeof(uint8_t)));
+ if (p) {
+ return wuffs_base__make_slice_u8((uint8_t*)(p), (size_t)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)((size_t)(num_u16 * sizeof(uint16_t)));
+ if (p) {
+ return wuffs_base__make_slice_u16((uint16_t*)(p), (size_t)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)((size_t)(num_u32 * sizeof(uint32_t)));
+ if (p) {
+ return wuffs_base__make_slice_u32((uint32_t*)(p), (size_t)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)((size_t)(num_u64 * sizeof(uint64_t)));
+ if (p) {
+ return wuffs_base__make_slice_u64((uint64_t*)(p), (size_t)num_u64);
+ }
+ }
+ return wuffs_base__make_slice_u64(NULL, 0);
+}
+
+// ---------------- Images
+
+#define WUFFS_BASE__IMAGE__DIMENSION_MAX_INCL 0xFFFFFF
+
+// wuffs_base__color_u32_argb_premul is an 8 bit per channel premultiplied
+// Alpha, Red, Green, Blue color, as a uint32_t value. Its value is always
+// 0xAARRGGBB (Alpha most significant, Blue least), regardless of endianness.
+typedef uint32_t wuffs_base__color_u32_argb_premul;
+
+// wuffs_base__color_u32_argb_premul__is_valid returns whether c's Red, Green
+// and Blue channels are all less than or equal to its Alpha channel. c uses
+// premultiplied alpha, so 50% opaque 100% saturated red is 0x7F7F_0000 and a
+// value like 0x7F80_0000 is invalid.
+static inline bool //
+wuffs_base__color_u32_argb_premul__is_valid(
+ wuffs_base__color_u32_argb_premul c) {
+ uint32_t a = 0xFF & (c >> 24);
+ uint32_t r = 0xFF & (c >> 16);
+ uint32_t g = 0xFF & (c >> 8);
+ uint32_t b = 0xFF & (c >> 0);
+ return (a >= r) && (a >= g) && (a >= b);
+}
+
+static inline uint16_t //
+wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
+ wuffs_base__color_u32_argb_premul c) {
+ uint32_t r5 = 0xF800 & (c >> 8);
+ uint32_t g6 = 0x07E0 & (c >> 5);
+ uint32_t b5 = 0x001F & (c >> 3);
+ return (uint16_t)(r5 | g6 | b5);
+}
+
+static inline wuffs_base__color_u32_argb_premul //
+wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(uint16_t rgb_565) {
+ uint32_t b5 = 0x1F & (rgb_565 >> 0);
+ uint32_t b = (b5 << 3) | (b5 >> 2);
+ uint32_t g6 = 0x3F & (rgb_565 >> 5);
+ uint32_t g = (g6 << 2) | (g6 >> 4);
+ uint32_t r5 = 0x1F & (rgb_565 >> 11);
+ uint32_t r = (r5 << 3) | (r5 >> 2);
+ return 0xFF000000 | (r << 16) | (g << 8) | (b << 0);
+}
+
+static inline uint8_t //
+wuffs_base__color_u32_argb_premul__as__color_u8_gray(
+ wuffs_base__color_u32_argb_premul c) {
+ // Work in 16-bit color.
+ uint32_t cr = 0x101 * (0xFF & (c >> 16));
+ uint32_t cg = 0x101 * (0xFF & (c >> 8));
+ uint32_t cb = 0x101 * (0xFF & (c >> 0));
+
+ // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
+ // as those given by the JFIF specification.
+ //
+ // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16). We
+ // shift by 24, not just by 16, because the return value is 8-bit color, not
+ // 16-bit color.
+ uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
+ return (uint8_t)(weighted_average >> 24);
+}
+
+static inline uint16_t //
+wuffs_base__color_u32_argb_premul__as__color_u16_gray(
+ wuffs_base__color_u32_argb_premul c) {
+ // Work in 16-bit color.
+ uint32_t cr = 0x101 * (0xFF & (c >> 16));
+ uint32_t cg = 0x101 * (0xFF & (c >> 8));
+ uint32_t cb = 0x101 * (0xFF & (c >> 0));
+
+ // These coefficients (the fractions 0.299, 0.587 and 0.114) are the same
+ // as those given by the JFIF specification.
+ //
+ // Note that 19595 + 38470 + 7471 equals 65536, also known as (1 << 16).
+ uint32_t weighted_average = (19595 * cr) + (38470 * cg) + (7471 * cb) + 32768;
+ return (uint16_t)(weighted_average >> 16);
+}
+
+// wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul converts
+// from non-premultiplied alpha to premultiplied alpha.
+static inline wuffs_base__color_u32_argb_premul //
+wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
+ uint32_t argb_nonpremul) {
+ // Multiplying by 0x101 (twice, once for alpha and once for color) converts
+ // from 8-bit to 16-bit color. Shifting right by 8 undoes that.
+ //
+ // Working in the higher bit depth can produce slightly different (and
+ // arguably slightly more accurate) results. For example, given 8-bit blue
+ // and alpha of 0x80 and 0x81:
+ //
+ // - ((0x80 * 0x81 ) / 0xFF ) = 0x40 = 0x40
+ // - ((0x8080 * 0x8181) / 0xFFFF) >> 8 = 0x4101 >> 8 = 0x41
+ uint32_t a = 0xFF & (argb_nonpremul >> 24);
+ uint32_t a16 = a * (0x101 * 0x101);
+
+ uint32_t r = 0xFF & (argb_nonpremul >> 16);
+ r = ((r * a16) / 0xFFFF) >> 8;
+ uint32_t g = 0xFF & (argb_nonpremul >> 8);
+ g = ((g * a16) / 0xFFFF) >> 8;
+ uint32_t b = 0xFF & (argb_nonpremul >> 0);
+ b = ((b * a16) / 0xFFFF) >> 8;
+
+ return (a << 24) | (r << 16) | (g << 8) | (b << 0);
+}
+
+// wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul converts
+// from premultiplied alpha to non-premultiplied alpha.
+static inline uint32_t //
+wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
+ wuffs_base__color_u32_argb_premul c) {
+ uint32_t a = 0xFF & (c >> 24);
+ if (a == 0xFF) {
+ return c;
+ } else if (a == 0) {
+ return 0;
+ }
+ uint32_t a16 = a * 0x101;
+
+ uint32_t r = 0xFF & (c >> 16);
+ r = ((r * (0x101 * 0xFFFF)) / a16) >> 8;
+ uint32_t g = 0xFF & (c >> 8);
+ g = ((g * (0x101 * 0xFFFF)) / a16) >> 8;
+ uint32_t b = 0xFF & (c >> 0);
+ b = ((b * (0x101 * 0xFFFF)) / a16) >> 8;
+
+ return (a << 24) | (r << 16) | (g << 8) | (b << 0);
+}
+
+// wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul converts
+// from 4x16LE non-premultiplied alpha to 4x8 premultiplied alpha.
+static inline wuffs_base__color_u32_argb_premul //
+wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
+ uint64_t argb_nonpremul) {
+ uint32_t a16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 48)));
+
+ uint32_t r16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 32)));
+ r16 = (r16 * a16) / 0xFFFF;
+ uint32_t g16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 16)));
+ g16 = (g16 * a16) / 0xFFFF;
+ uint32_t b16 = ((uint32_t)(0xFFFF & (argb_nonpremul >> 0)));
+ b16 = (b16 * a16) / 0xFFFF;
+
+ return ((a16 >> 8) << 24) | ((r16 >> 8) << 16) | ((g16 >> 8) << 8) |
+ ((b16 >> 8) << 0);
+}
+
+// wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul converts
+// from 4x8 premultiplied alpha to 4x16LE non-premultiplied alpha.
+static inline uint64_t //
+wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
+ wuffs_base__color_u32_argb_premul c) {
+ uint32_t a = 0xFF & (c >> 24);
+ if (a == 0xFF) {
+ uint64_t r16 = 0x101 * (0xFF & (c >> 16));
+ uint64_t g16 = 0x101 * (0xFF & (c >> 8));
+ uint64_t b16 = 0x101 * (0xFF & (c >> 0));
+ return 0xFFFF000000000000u | (r16 << 32) | (g16 << 16) | (b16 << 0);
+ } else if (a == 0) {
+ return 0;
+ }
+ uint64_t a16 = a * 0x101;
+
+ uint64_t r = 0xFF & (c >> 16);
+ uint64_t r16 = (r * (0x101 * 0xFFFF)) / a16;
+ uint64_t g = 0xFF & (c >> 8);
+ uint64_t g16 = (g * (0x101 * 0xFFFF)) / a16;
+ uint64_t b = 0xFF & (c >> 0);
+ uint64_t b16 = (b * (0x101 * 0xFFFF)) / a16;
+
+ return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
+}
+
+static inline uint64_t //
+wuffs_base__color_u32__as__color_u64(uint32_t c) {
+ uint64_t a16 = 0x101 * (0xFF & (c >> 24));
+ uint64_t r16 = 0x101 * (0xFF & (c >> 16));
+ uint64_t g16 = 0x101 * (0xFF & (c >> 8));
+ uint64_t b16 = 0x101 * (0xFF & (c >> 0));
+ return (a16 << 48) | (r16 << 32) | (g16 << 16) | (b16 << 0);
+}
+
+static inline uint32_t //
+wuffs_base__color_u64__as__color_u32(uint64_t c) {
+ uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
+ uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
+ uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
+ uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
+ return (a << 24) | (r << 16) | (g << 8) | (b << 0);
+}
+
+// wuffs_base__color_ycc__as__color_u32 converts from YCbCr to 0xAARRGGBB. The
+// alpha bits are always 0xFF.
+static inline wuffs_base__color_u32_argb_premul //
+wuffs_base__color_ycc__as__color_u32(uint8_t yy, uint8_t cb, uint8_t cr) {
+ // Work in 16.16 fixed point arithmetic (so that 'one half' is (1 << 15)) and
+ // bias the chroma values by 0x80.
+ uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
+ uint32_t cb32 = (((uint32_t)cb) - 0x80);
+ uint32_t cr32 = (((uint32_t)cr) - 0x80);
+
+ // The formulae:
+ //
+ // R = Y + 1.40200 * Cr
+ // G = Y - 0.34414 * Cb - 0.71414 * Cr
+ // B = Y + 1.77200 * Cb
+ //
+ // When scaled by 1<<16:
+ //
+ // 0.34414 becomes 0x0581A = 22554.
+ // 0.71414 becomes 0x0B6D2 = 46802.
+ // 1.40200 becomes 0x166E9 = 91881.
+ // 1.77200 becomes 0x1C5A2 = 116130.
+ //
+ // Since we're working in 16.16 fixed point arithmetic, masking by 0x00FF0000
+ // (possibly followed by a shift) gives the relevant 8 bits per channel.
+ //
+ // However, we need to saturate for overflow (above 0x00FFFFFF, but not so
+ // high that the MSB Most Significant Bit is set) or for underflow (below
+ // 0x00000000 as int32_t, which means that the MSB is set as uint32_t). In
+ // both cases, some of the high 8 bits (bits 24 ..= 31) will be set.
+ //
+ // "((uint32_t)(((int32_t)x) >> 31))" just replicates x's MSB across all 32
+ // bits. Prepending that with "~" inverts those bits. Thus, "~(etc)" is
+ // either 0xFFFFFFFF (for overflow) or 0x00000000 (for underflow).
+ uint32_t rr32 = yy32 + (0x166E9 * cr32);
+ uint32_t gg32 = yy32 - (0x0581A * cb32) - (0x0B6D2 * cr32);
+ uint32_t bb32 = yy32 + (0x1C5A2 * cb32);
+ if (rr32 >> 24) {
+ rr32 = ~((uint32_t)(((int32_t)rr32) >> 31));
+ }
+ if (gg32 >> 24) {
+ gg32 = ~((uint32_t)(((int32_t)gg32) >> 31));
+ }
+ if (bb32 >> 24) {
+ bb32 = ~((uint32_t)(((int32_t)bb32) >> 31));
+ }
+ return 0xFF000000 | //
+ ((0x00FF0000 & rr32) >> 0) | //
+ ((0x00FF0000 & gg32) >> 8) | //
+ ((0x00FF0000 & bb32) >> 16);
+}
+
+// wuffs_base__color_ycc__as__color_u32_abgr is like
+// wuffs_base__color_ycc__as__color_u32 but the uint32_t returned is in
+// 0xAABBGGRR order, not 0xAARRGGBB.
+static inline uint32_t //
+wuffs_base__color_ycc__as__color_u32_abgr(uint8_t yy, uint8_t cb, uint8_t cr) {
+ uint32_t yy32 = (((uint32_t)yy) << 16) | (1 << 15);
+ uint32_t cb32 = (((uint32_t)cb) - 0x80);
+ uint32_t cr32 = (((uint32_t)cr) - 0x80);
+ uint32_t rr32 = yy32 + (0x166E9 * cr32);
+ uint32_t gg32 = yy32 - (0x0581A * cb32) - (0x0B6D2 * cr32);
+ uint32_t bb32 = yy32 + (0x1C5A2 * cb32);
+ if (rr32 >> 24) {
+ rr32 = ~((uint32_t)(((int32_t)rr32) >> 31));
+ }
+ if (gg32 >> 24) {
+ gg32 = ~((uint32_t)(((int32_t)gg32) >> 31));
+ }
+ if (bb32 >> 24) {
+ bb32 = ~((uint32_t)(((int32_t)bb32) >> 31));
+ }
+ return 0xFF000000 | //
+ ((0x00FF0000 & bb32) >> 0) | //
+ ((0x00FF0000 & gg32) >> 8) | //
+ ((0x00FF0000 & rr32) >> 16);
+}
+
+// --------
+
+typedef uint8_t wuffs_base__pixel_blend;
+
+// wuffs_base__pixel_blend encodes how to blend source and destination pixels,
+// accounting for transparency. It encompasses the Porter-Duff compositing
+// operators as well as the other blending modes defined by PDF.
+//
+// TODO: implement the other modes.
+#define WUFFS_BASE__PIXEL_BLEND__SRC ((wuffs_base__pixel_blend)0)
+#define WUFFS_BASE__PIXEL_BLEND__SRC_OVER ((wuffs_base__pixel_blend)1)
+
+// --------
+
+// wuffs_base__pixel_alpha_transparency is a pixel format's alpha channel
+// model. It is a property of the pixel format in general, not of a specific
+// pixel. An RGBA pixel format (with alpha) can still have fully opaque pixels.
+typedef uint32_t wuffs_base__pixel_alpha_transparency;
+
+#define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__OPAQUE 0
+#define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__NONPREMULTIPLIED_ALPHA 1
+#define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__PREMULTIPLIED_ALPHA 2
+#define WUFFS_BASE__PIXEL_ALPHA_TRANSPARENCY__BINARY_ALPHA 3
+
+// --------
+
+// Deprecated: use WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL.
+#define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX 4
+
+#define WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL 4
+
+#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__INDEX_PLANE 0
+#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE 3
+
+// A palette is 256 entries × 4 bytes per entry (e.g. BGRA).
+#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH 1024
+
+// 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/main/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 struct wuffs_base__pixel_format__struct {
+ uint32_t repr;
+
+#ifdef __cplusplus
+ inline bool is_valid() const;
+ inline uint32_t bits_per_pixel() const;
+ inline bool is_direct() const;
+ inline bool is_indexed() const;
+ inline bool is_interleaved() const;
+ inline bool is_planar() const;
+ inline uint32_t num_planes() const;
+ inline wuffs_base__pixel_alpha_transparency transparency() const;
+#endif // __cplusplus
+
+} wuffs_base__pixel_format;
+
+static inline wuffs_base__pixel_format //
+wuffs_base__make_pixel_format(uint32_t repr) {
+ wuffs_base__pixel_format f;
+ f.repr = repr;
+ return f;
+}
+
+// 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 0x00000000
+
+#define WUFFS_BASE__PIXEL_FORMAT__A 0x02000008
+
+#define WUFFS_BASE__PIXEL_FORMAT__Y 0x20000008
+#define WUFFS_BASE__PIXEL_FORMAT__Y_16LE 0x2000000B
+#define WUFFS_BASE__PIXEL_FORMAT__Y_16BE 0x2010000B
+#define WUFFS_BASE__PIXEL_FORMAT__YA_NONPREMUL 0x21000008
+#define WUFFS_BASE__PIXEL_FORMAT__YA_PREMUL 0x22000008
+
+#define WUFFS_BASE__PIXEL_FORMAT__YCBCR 0x40020888
+#define WUFFS_BASE__PIXEL_FORMAT__YCBCRA_NONPREMUL 0x41038888
+#define WUFFS_BASE__PIXEL_FORMAT__YCBCRK 0x50038888
+
+#define WUFFS_BASE__PIXEL_FORMAT__YCOCG 0x60020888
+#define WUFFS_BASE__PIXEL_FORMAT__YCOCGA_NONPREMUL 0x61038888
+#define WUFFS_BASE__PIXEL_FORMAT__YCOCGK 0x70038888
+
+#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL 0x81040008
+#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL 0x82040008
+#define WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY 0x83040008
+
+#define WUFFS_BASE__PIXEL_FORMAT__BGR_565 0x80000565
+#define WUFFS_BASE__PIXEL_FORMAT__BGR 0x80000888
+#define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL 0x81008888
+#define WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE 0x8100BBBB
+#define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL 0x82008888
+#define WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE 0x8200BBBB
+#define WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY 0x83008888
+#define WUFFS_BASE__PIXEL_FORMAT__BGRX 0x90008888
+
+#define WUFFS_BASE__PIXEL_FORMAT__RGB 0xA0000888
+#define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL 0xA1008888
+#define WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE 0xA100BBBB
+#define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL 0xA2008888
+#define WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE 0xA200BBBB
+#define WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY 0xA3008888
+#define WUFFS_BASE__PIXEL_FORMAT__RGBX 0xB0008888
+
+#define WUFFS_BASE__PIXEL_FORMAT__CMY 0xC0020888
+#define WUFFS_BASE__PIXEL_FORMAT__CMYK 0xD0038888
+
+extern const uint32_t wuffs_base__pixel_format__bits_per_channel[16];
+
+static inline bool //
+wuffs_base__pixel_format__is_valid(const wuffs_base__pixel_format* f) {
+ return f->repr != 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(const wuffs_base__pixel_format* f) {
+ if (((f->repr >> 16) & 0x03) != 0) {
+ return 0;
+ }
+ return wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 0)] +
+ wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 4)] +
+ wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 8)] +
+ wuffs_base__pixel_format__bits_per_channel[0x0F & (f->repr >> 12)];
+}
+
+static inline bool //
+wuffs_base__pixel_format__is_direct(const wuffs_base__pixel_format* f) {
+ return ((f->repr >> 18) & 0x01) == 0;
+}
+
+static inline bool //
+wuffs_base__pixel_format__is_indexed(const wuffs_base__pixel_format* f) {
+ return ((f->repr >> 18) & 0x01) != 0;
+}
+
+static inline bool //
+wuffs_base__pixel_format__is_interleaved(const wuffs_base__pixel_format* f) {
+ return ((f->repr >> 16) & 0x03) == 0;
+}
+
+static inline bool //
+wuffs_base__pixel_format__is_planar(const wuffs_base__pixel_format* f) {
+ return ((f->repr >> 16) & 0x03) != 0;
+}
+
+static inline uint32_t //
+wuffs_base__pixel_format__num_planes(const wuffs_base__pixel_format* f) {
+ return ((f->repr >> 16) & 0x03) + 1;
+}
+
+static inline wuffs_base__pixel_alpha_transparency //
+wuffs_base__pixel_format__transparency(const wuffs_base__pixel_format* f) {
+ return (wuffs_base__pixel_alpha_transparency)((f->repr >> 24) & 0x03);
+}
+
+#ifdef __cplusplus
+
+inline bool //
+wuffs_base__pixel_format::is_valid() const {
+ return wuffs_base__pixel_format__is_valid(this);
+}
+
+inline uint32_t //
+wuffs_base__pixel_format::bits_per_pixel() const {
+ return wuffs_base__pixel_format__bits_per_pixel(this);
+}
+
+inline bool //
+wuffs_base__pixel_format::is_direct() const {
+ return wuffs_base__pixel_format__is_direct(this);
+}
+
+inline bool //
+wuffs_base__pixel_format::is_indexed() const {
+ return wuffs_base__pixel_format__is_indexed(this);
+}
+
+inline bool //
+wuffs_base__pixel_format::is_interleaved() const {
+ return wuffs_base__pixel_format__is_interleaved(this);
+}
+
+inline bool //
+wuffs_base__pixel_format::is_planar() const {
+ return wuffs_base__pixel_format__is_planar(this);
+}
+
+inline uint32_t //
+wuffs_base__pixel_format::num_planes() const {
+ return wuffs_base__pixel_format__num_planes(this);
+}
+
+inline wuffs_base__pixel_alpha_transparency //
+wuffs_base__pixel_format::transparency() const {
+ return wuffs_base__pixel_format__transparency(this);
+}
+
+#endif // __cplusplus
+
+// --------
+
+// wuffs_base__pixel_subsampling encodes whether sample values cover one pixel
+// or cover multiple pixels.
+//
+// See https://github.com/google/wuffs/blob/main/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 struct wuffs_base__pixel_subsampling__struct {
+ uint32_t repr;
+
+#ifdef __cplusplus
+ inline uint32_t bias_x(uint32_t plane) const;
+ inline uint32_t denominator_x(uint32_t plane) const;
+ inline uint32_t bias_y(uint32_t plane) const;
+ inline uint32_t denominator_y(uint32_t plane) const;
+#endif // __cplusplus
+
+} wuffs_base__pixel_subsampling;
+
+static inline wuffs_base__pixel_subsampling //
+wuffs_base__make_pixel_subsampling(uint32_t repr) {
+ wuffs_base__pixel_subsampling s;
+ s.repr = repr;
+ return s;
+}
+
+#define WUFFS_BASE__PIXEL_SUBSAMPLING__NONE 0x00000000
+
+#define WUFFS_BASE__PIXEL_SUBSAMPLING__444 0x000000
+#define WUFFS_BASE__PIXEL_SUBSAMPLING__440 0x010100
+#define WUFFS_BASE__PIXEL_SUBSAMPLING__422 0x101000
+#define WUFFS_BASE__PIXEL_SUBSAMPLING__420 0x111100
+#define WUFFS_BASE__PIXEL_SUBSAMPLING__411 0x303000
+#define WUFFS_BASE__PIXEL_SUBSAMPLING__410 0x313100
+
+static inline uint32_t //
+wuffs_base__pixel_subsampling__bias_x(const wuffs_base__pixel_subsampling* s,
+ uint32_t plane) {
+ uint32_t shift = ((plane & 0x03) * 8) + 6;
+ return (s->repr >> shift) & 0x03;
+}
+
+static inline uint32_t //
+wuffs_base__pixel_subsampling__denominator_x(
+ const wuffs_base__pixel_subsampling* s,
+ uint32_t plane) {
+ uint32_t shift = ((plane & 0x03) * 8) + 4;
+ return ((s->repr >> shift) & 0x03) + 1;
+}
+
+static inline uint32_t //
+wuffs_base__pixel_subsampling__bias_y(const wuffs_base__pixel_subsampling* s,
+ uint32_t plane) {
+ uint32_t shift = ((plane & 0x03) * 8) + 2;
+ return (s->repr >> shift) & 0x03;
+}
+
+static inline uint32_t //
+wuffs_base__pixel_subsampling__denominator_y(
+ const wuffs_base__pixel_subsampling* s,
+ uint32_t plane) {
+ uint32_t shift = ((plane & 0x03) * 8) + 0;
+ return ((s->repr >> shift) & 0x03) + 1;
+}
+
+#ifdef __cplusplus
+
+inline uint32_t //
+wuffs_base__pixel_subsampling::bias_x(uint32_t plane) const {
+ return wuffs_base__pixel_subsampling__bias_x(this, plane);
+}
+
+inline uint32_t //
+wuffs_base__pixel_subsampling::denominator_x(uint32_t plane) const {
+ return wuffs_base__pixel_subsampling__denominator_x(this, plane);
+}
+
+inline uint32_t //
+wuffs_base__pixel_subsampling::bias_y(uint32_t plane) const {
+ return wuffs_base__pixel_subsampling__bias_y(this, plane);
+}
+
+inline uint32_t //
+wuffs_base__pixel_subsampling::denominator_y(uint32_t plane) const {
+ return wuffs_base__pixel_subsampling__denominator_y(this, plane);
+}
+
+#endif // __cplusplus
+
+// --------
+
+typedef struct wuffs_base__pixel_config__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(uint32_t pixfmt_repr,
+ uint32_t pixsub_repr,
+ 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(void) {
+ wuffs_base__pixel_config ret;
+ ret.private_impl.pixfmt.repr = 0;
+ ret.private_impl.pixsub.repr = 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,
+ uint32_t pixfmt_repr,
+ uint32_t pixsub_repr,
+ uint32_t width,
+ uint32_t height) {
+ if (!c) {
+ return;
+ }
+ if (pixfmt_repr) {
+ 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.repr = pixfmt_repr;
+ c->private_impl.pixsub.repr = pixsub_repr;
+ c->private_impl.width = width;
+ c->private_impl.height = height;
+ return;
+ }
+ }
+
+ c->private_impl.pixfmt.repr = 0;
+ c->private_impl.pixsub.repr = 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.repr = 0;
+ c->private_impl.pixsub.repr = 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.repr;
+}
+
+static inline wuffs_base__pixel_format //
+wuffs_base__pixel_config__pixel_format(const wuffs_base__pixel_config* c) {
+ return c ? c->private_impl.pixfmt : wuffs_base__make_pixel_format(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 : wuffs_base__make_pixel_subsampling(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 - WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
+ return 0;
+ }
+ n += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+ }
+
+ return n;
+}
+
+#ifdef __cplusplus
+
+inline void //
+wuffs_base__pixel_config::set(uint32_t pixfmt_repr,
+ uint32_t pixsub_repr,
+ uint32_t width,
+ uint32_t height) {
+ wuffs_base__pixel_config__set(this, pixfmt_repr, pixsub_repr, 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__image_config__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(uint32_t pixfmt_repr,
+ uint32_t pixsub_repr,
+ 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(void) {
+ 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,
+ uint32_t pixfmt_repr,
+ uint32_t pixsub_repr,
+ uint32_t width,
+ uint32_t height,
+ uint64_t first_frame_io_position,
+ bool first_frame_is_opaque) {
+ if (!c) {
+ return;
+ }
+ if (pixfmt_repr) {
+ c->pixcfg.private_impl.pixfmt.repr = pixfmt_repr;
+ c->pixcfg.private_impl.pixsub.repr = pixsub_repr;
+ 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.repr = 0;
+ c->pixcfg.private_impl.pixsub.repr = 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.repr = 0;
+ c->pixcfg.private_impl.pixsub.repr = 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(uint32_t pixfmt_repr,
+ uint32_t pixsub_repr,
+ uint32_t width,
+ uint32_t height,
+ uint64_t first_frame_io_position,
+ bool first_frame_is_opaque) {
+ wuffs_base__image_config__set(this, pixfmt_repr, pixsub_repr, 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_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 wuffs_base__frame_config__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_disposal disposal;
+ bool opaque_within_bounds;
+ bool overwrite_instead_of_blend;
+ wuffs_base__color_u32_argb_premul background_color;
+ } private_impl;
+
+#ifdef __cplusplus
+ inline void set(wuffs_base__rect_ie_u32 bounds,
+ wuffs_base__flicks duration,
+ uint64_t index,
+ uint64_t io_position,
+ wuffs_base__animation_disposal disposal,
+ bool opaque_within_bounds,
+ bool overwrite_instead_of_blend,
+ 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_disposal disposal() const;
+ inline bool opaque_within_bounds() const;
+ inline bool overwrite_instead_of_blend() 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(void) {
+ 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.disposal = 0;
+ ret.private_impl.opaque_within_bounds = false;
+ ret.private_impl.overwrite_instead_of_blend = false;
+ return ret;
+}
+
+static inline void //
+wuffs_base__frame_config__set(
+ 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_disposal disposal,
+ bool opaque_within_bounds,
+ bool overwrite_instead_of_blend,
+ 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.disposal = disposal;
+ c->private_impl.opaque_within_bounds = opaque_within_bounds;
+ c->private_impl.overwrite_instead_of_blend = overwrite_instead_of_blend;
+ 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__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;
+}
+
+// wuffs_base__frame_config__opaque_within_bounds returns whether all pixels
+// within the frame's bounds are fully opaque. It makes no claim about pixels
+// outside the frame bounds but still inside the overall image. The two
+// bounding rectangles can differ for animated images.
+//
+// Its semantics are conservative. It is valid for a fully opaque frame to have
+// this value be false: a false negative.
+//
+// If true, drawing the frame with WUFFS_BASE__PIXEL_BLEND__SRC and
+// WUFFS_BASE__PIXEL_BLEND__SRC_OVER should be equivalent, in terms of
+// resultant pixels, but the former may be faster.
+static inline bool //
+wuffs_base__frame_config__opaque_within_bounds(
+ const wuffs_base__frame_config* c) {
+ return c && c->private_impl.opaque_within_bounds;
+}
+
+// wuffs_base__frame_config__overwrite_instead_of_blend returns, for an
+// animated image, whether to ignore the previous image state (within the frame
+// bounds) when drawing this incremental frame. Equivalently, whether to use
+// WUFFS_BASE__PIXEL_BLEND__SRC instead of WUFFS_BASE__PIXEL_BLEND__SRC_OVER.
+//
+// The WebP spec (https://developers.google.com/speed/webp/docs/riff_container)
+// calls this the "Blending method" bit. WebP's "Do not blend" corresponds to
+// Wuffs' "overwrite_instead_of_blend".
+static inline bool //
+wuffs_base__frame_config__overwrite_instead_of_blend(
+ const wuffs_base__frame_config* c) {
+ return c && c->private_impl.overwrite_instead_of_blend;
+}
+
+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::set(
+ wuffs_base__rect_ie_u32 bounds,
+ wuffs_base__flicks duration,
+ uint64_t index,
+ uint64_t io_position,
+ wuffs_base__animation_disposal disposal,
+ bool opaque_within_bounds,
+ bool overwrite_instead_of_blend,
+ wuffs_base__color_u32_argb_premul background_color) {
+ wuffs_base__frame_config__set(this, bounds, duration, index, io_position,
+ disposal, opaque_within_bounds,
+ overwrite_instead_of_blend, 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_disposal //
+wuffs_base__frame_config::disposal() const {
+ return wuffs_base__frame_config__disposal(this);
+}
+
+inline bool //
+wuffs_base__frame_config::opaque_within_bounds() const {
+ return wuffs_base__frame_config__opaque_within_bounds(this);
+}
+
+inline bool //
+wuffs_base__frame_config::overwrite_instead_of_blend() const {
+ return wuffs_base__frame_config__overwrite_instead_of_blend(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_buffer__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_INCL];
+ // TODO: color spaces.
+ } private_impl;
+
+#ifdef __cplusplus
+ inline wuffs_base__status set_interleaved(
+ const wuffs_base__pixel_config* pixcfg,
+ wuffs_base__table_u8 primary_memory,
+ wuffs_base__slice_u8 palette_memory);
+ inline wuffs_base__status set_from_slice(
+ const wuffs_base__pixel_config* pixcfg,
+ wuffs_base__slice_u8 pixbuf_memory);
+ inline wuffs_base__slice_u8 palette();
+ inline wuffs_base__slice_u8 palette_or_else(wuffs_base__slice_u8 fallback);
+ inline wuffs_base__pixel_format pixel_format() const;
+ inline wuffs_base__table_u8 plane(uint32_t p);
+ inline wuffs_base__color_u32_argb_premul color_u32_at(uint32_t x,
+ uint32_t y) const;
+ inline wuffs_base__status set_color_u32_at(
+ uint32_t x,
+ uint32_t y,
+ wuffs_base__color_u32_argb_premul color);
+ inline wuffs_base__status set_color_u32_fill_rect(
+ wuffs_base__rect_ie_u32 rect,
+ wuffs_base__color_u32_argb_premul color);
+#endif // __cplusplus
+
+} wuffs_base__pixel_buffer;
+
+static inline wuffs_base__pixel_buffer //
+wuffs_base__null_pixel_buffer(void) {
+ 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_interleaved(
+ wuffs_base__pixel_buffer* pb,
+ const wuffs_base__pixel_config* pixcfg,
+ wuffs_base__table_u8 primary_memory,
+ wuffs_base__slice_u8 palette_memory) {
+ if (!pb) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ memset(pb, 0, sizeof(*pb));
+ if (!pixcfg ||
+ wuffs_base__pixel_format__is_planar(&pixcfg->private_impl.pixfmt)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt) &&
+ (palette_memory.len <
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH)) {
+ return wuffs_base__make_status(
+ wuffs_base__error__bad_argument_length_too_short);
+ }
+ 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__make_status(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 > primary_memory.width) ||
+ (pixcfg->private_impl.height > primary_memory.height)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+
+ pb->pixcfg = *pixcfg;
+ pb->private_impl.planes[0] = primary_memory;
+ if (wuffs_base__pixel_format__is_indexed(&pixcfg->private_impl.pixfmt)) {
+ wuffs_base__table_u8* tab =
+ &pb->private_impl
+ .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
+ tab->ptr = palette_memory.ptr;
+ tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+ tab->height = 1;
+ tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+static inline wuffs_base__status //
+wuffs_base__pixel_buffer__set_from_slice(wuffs_base__pixel_buffer* pb,
+ const wuffs_base__pixel_config* pixcfg,
+ wuffs_base__slice_u8 pixbuf_memory) {
+ if (!pb) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ memset(pb, 0, sizeof(*pb));
+ if (!pixcfg) {
+ return wuffs_base__make_status(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__make_status(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__make_status(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 WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH byte
+ // chunk (1024 bytes = 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 < WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return wuffs_base__make_status(
+ wuffs_base__error__bad_argument_length_too_short);
+ }
+ wuffs_base__table_u8* tab =
+ &pb->private_impl
+ .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
+ tab->ptr = ptr;
+ tab->width = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+ tab->height = 1;
+ tab->stride = WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+ ptr += WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+ len -= WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH;
+ }
+
+ 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__make_status(wuffs_base__error__bad_argument);
+ }
+ wh *= bytes_per_pixel;
+ width = ((size_t)(width * bytes_per_pixel));
+ if (wh > len) {
+ return wuffs_base__make_status(
+ wuffs_base__error__bad_argument_length_too_short);
+ }
+
+ pb->pixcfg = *pixcfg;
+ wuffs_base__table_u8* tab = &pb->private_impl.planes[0];
+ tab->ptr = ptr;
+ tab->width = width;
+ tab->height = pixcfg->private_impl.height;
+ tab->stride = width;
+ return wuffs_base__make_status(NULL);
+}
+
+// wuffs_base__pixel_buffer__palette returns the palette color data. If
+// non-empty, it will have length
+// WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH.
+static inline wuffs_base__slice_u8 //
+wuffs_base__pixel_buffer__palette(wuffs_base__pixel_buffer* pb) {
+ if (pb &&
+ wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
+ wuffs_base__table_u8* tab =
+ &pb->private_impl
+ .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
+ if ((tab->width ==
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
+ (tab->height == 1)) {
+ return wuffs_base__make_slice_u8(
+ tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
+ }
+ }
+ return wuffs_base__make_slice_u8(NULL, 0);
+}
+
+static inline wuffs_base__slice_u8 //
+wuffs_base__pixel_buffer__palette_or_else(wuffs_base__pixel_buffer* pb,
+ wuffs_base__slice_u8 fallback) {
+ if (pb &&
+ wuffs_base__pixel_format__is_indexed(&pb->pixcfg.private_impl.pixfmt)) {
+ wuffs_base__table_u8* tab =
+ &pb->private_impl
+ .planes[WUFFS_BASE__PIXEL_FORMAT__INDEXED__COLOR_PLANE];
+ if ((tab->width ==
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) &&
+ (tab->height == 1)) {
+ return wuffs_base__make_slice_u8(
+ tab->ptr, WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH);
+ }
+ }
+ return fallback;
+}
+
+static inline wuffs_base__pixel_format //
+wuffs_base__pixel_buffer__pixel_format(const wuffs_base__pixel_buffer* pb) {
+ if (pb) {
+ return pb->pixcfg.private_impl.pixfmt;
+ }
+ return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__INVALID);
+}
+
+static inline wuffs_base__table_u8 //
+wuffs_base__pixel_buffer__plane(wuffs_base__pixel_buffer* pb, uint32_t p) {
+ if (pb && (p < WUFFS_BASE__PIXEL_FORMAT__NUM_PLANES_MAX_INCL)) {
+ return pb->private_impl.planes[p];
+ }
+
+ wuffs_base__table_u8 ret;
+ ret.ptr = NULL;
+ ret.width = 0;
+ ret.height = 0;
+ ret.stride = 0;
+ return ret;
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul //
+wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
+ uint32_t x,
+ uint32_t y);
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__pixel_buffer__set_color_u32_at(
+ wuffs_base__pixel_buffer* pb,
+ uint32_t x,
+ uint32_t y,
+ wuffs_base__color_u32_argb_premul color);
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__pixel_buffer__set_color_u32_fill_rect(
+ wuffs_base__pixel_buffer* pb,
+ wuffs_base__rect_ie_u32 rect,
+ wuffs_base__color_u32_argb_premul color);
+
+#ifdef __cplusplus
+
+inline wuffs_base__status //
+wuffs_base__pixel_buffer::set_interleaved(
+ const wuffs_base__pixel_config* pixcfg_arg,
+ wuffs_base__table_u8 primary_memory,
+ wuffs_base__slice_u8 palette_memory) {
+ return wuffs_base__pixel_buffer__set_interleaved(
+ this, pixcfg_arg, primary_memory, palette_memory);
+}
+
+inline wuffs_base__status //
+wuffs_base__pixel_buffer::set_from_slice(
+ const wuffs_base__pixel_config* pixcfg_arg,
+ wuffs_base__slice_u8 pixbuf_memory) {
+ return wuffs_base__pixel_buffer__set_from_slice(this, pixcfg_arg,
+ pixbuf_memory);
+}
+
+inline wuffs_base__slice_u8 //
+wuffs_base__pixel_buffer::palette() {
+ return wuffs_base__pixel_buffer__palette(this);
+}
+
+inline wuffs_base__slice_u8 //
+wuffs_base__pixel_buffer::palette_or_else(wuffs_base__slice_u8 fallback) {
+ return wuffs_base__pixel_buffer__palette_or_else(this, fallback);
+}
+
+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);
+}
+
+inline wuffs_base__color_u32_argb_premul //
+wuffs_base__pixel_buffer::color_u32_at(uint32_t x, uint32_t y) const {
+ return wuffs_base__pixel_buffer__color_u32_at(this, x, y);
+}
+
+inline wuffs_base__status //
+wuffs_base__pixel_buffer::set_color_u32_at(
+ uint32_t x,
+ uint32_t y,
+ wuffs_base__color_u32_argb_premul color) {
+ return wuffs_base__pixel_buffer__set_color_u32_at(this, x, y, color);
+}
+
+inline wuffs_base__status //
+wuffs_base__pixel_buffer::set_color_u32_fill_rect(
+ wuffs_base__rect_ie_u32 rect,
+ wuffs_base__color_u32_argb_premul color) {
+ return wuffs_base__pixel_buffer__set_color_u32_fill_rect(this, rect, color);
+}
+
+#endif // __cplusplus
+
+// --------
+
+typedef struct wuffs_base__decode_frame_options__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
+
+// --------
+
+// wuffs_base__pixel_palette__closest_element returns the index of the palette
+// element that minimizes the sum of squared differences of the four ARGB
+// channels, working in premultiplied alpha. Ties favor the smaller index.
+//
+// The palette_slice.len may equal (N*4), for N less than 256, which means that
+// only the first N palette elements are considered. It returns 0 when N is 0.
+//
+// Applying this function on a per-pixel basis will not produce whole-of-image
+// dithering.
+WUFFS_BASE__MAYBE_STATIC uint8_t //
+wuffs_base__pixel_palette__closest_element(
+ wuffs_base__slice_u8 palette_slice,
+ wuffs_base__pixel_format palette_format,
+ wuffs_base__color_u32_argb_premul c);
+
+// --------
+
+// TODO: should the func type take restrict pointers?
+typedef uint64_t (*wuffs_base__pixel_swizzler__func)(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len);
+
+typedef uint64_t (*wuffs_base__pixel_swizzler__transparent_black_func)(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ uint64_t num_pixels,
+ uint32_t dst_pixfmt_bytes_per_pixel);
+
+typedef struct wuffs_base__pixel_swizzler__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_swizzler__func func;
+ wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func;
+ uint32_t dst_pixfmt_bytes_per_pixel;
+ uint32_t src_pixfmt_bytes_per_pixel;
+ } private_impl;
+
+#ifdef __cplusplus
+ inline wuffs_base__status prepare(wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__pixel_format src_pixfmt,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend);
+ inline uint64_t swizzle_interleaved_from_slice(
+ 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__pixel_swizzler__prepare readies the pixel swizzler so that its
+// other methods may be called.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__pixel_format src_pixfmt,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend);
+
+// wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice converts pixels
+// from a source format to a destination format.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__PIXCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
+ 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_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__pixel_format src_pixfmt,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ return wuffs_base__pixel_swizzler__prepare(this, dst_pixfmt, dst_palette,
+ src_pixfmt, src_palette, blend);
+}
+
+uint64_t //
+wuffs_base__pixel_swizzler::swizzle_interleaved_from_slice(
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src) const {
+ return wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
+ this, dst, dst_palette, src);
+}
+
+#endif // __cplusplus
+
+// ---------------- String Conversions
+
+// Options (bitwise or'ed together) for wuffs_base__parse_number_xxx
+// functions. The XXX options apply to both integer and floating point. The FXX
+// options apply only to floating point.
+
+#define WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
+
+// WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES means to accept
+// inputs like "00", "0644" and "00.7". By default, they are rejected.
+#define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES \
+ ((uint32_t)0x00000001)
+
+// WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES means to accept inputs like
+// "1__2" and "_3.141_592". By default, they are rejected.
+#define WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES ((uint32_t)0x00000002)
+
+// WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to accept
+// "1,5" and not "1.5" as one-and-a-half.
+//
+// If the caller wants to accept either, it is responsible for canonicalizing
+// the input before calling wuffs_base__parse_number_fxx. The caller also has
+// more context on e.g. exactly how to treat something like "$1,234".
+#define WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
+ ((uint32_t)0x00000010)
+
+// WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN means to reject inputs that
+// would lead to infinite or Not-a-Number floating point values. By default,
+// they are accepted.
+//
+// This affects the literal "inf" as input, but also affects inputs like
+// "1e999" that would overflow double-precision floating point.
+#define WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN ((uint32_t)0x00000020)
+
+// --------
+
+// Options (bitwise or'ed together) for wuffs_base__render_number_xxx
+// functions. The XXX options apply to both integer and floating point. The FXX
+// options apply only to floating point.
+
+#define WUFFS_BASE__RENDER_NUMBER_XXX__DEFAULT_OPTIONS ((uint32_t)0x00000000)
+
+// WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT means to render to the right side
+// (higher indexes) of the destination slice, leaving any untouched bytes on
+// the left side (lower indexes). The default is vice versa: rendering on the
+// left with slack on the right.
+#define WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT ((uint32_t)0x00000100)
+
+// WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN means to render the leading
+// "+" for non-negative numbers: "+0" and "+12.3" instead of "0" and "12.3".
+#define WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN ((uint32_t)0x00000200)
+
+// WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA means to render
+// one-and-a-half as "1,5" instead of "1.5".
+#define WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA \
+ ((uint32_t)0x00001000)
+
+// WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ETC means whether to never
+// (EXPONENT_ABSENT, equivalent to printf's "%f") or to always
+// (EXPONENT_PRESENT, equivalent to printf's "%e") render a floating point
+// number as "1.23e+05" instead of "123000".
+//
+// Having both bits set is the same has having neither bit set, where the
+// notation used depends on whether the exponent is sufficiently large: "0.5"
+// is preferred over "5e-01" but "5e-09" is preferred over "0.000000005".
+#define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT ((uint32_t)0x00002000)
+#define WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT ((uint32_t)0x00004000)
+
+// WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION means to render the
+// smallest number of digits so that parsing the resultant string will recover
+// the same double-precision floating point number.
+//
+// For example, double-precision cannot distinguish between 0.3 and
+// 0.299999999999999988897769753748434595763683319091796875, so when this bit
+// is set, rendering the latter will produce "0.3" but rendering
+// 0.3000000000000000444089209850062616169452667236328125 will produce
+// "0.30000000000000004".
+#define WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION \
+ ((uint32_t)0x00008000)
+
+// ---------------- IEEE 754 Floating Point
+
+// wuffs_base__ieee_754_bit_representation__etc converts between a double
+// precision numerical value and its IEEE 754 representations:
+// - 16-bit: 1 sign bit, 5 exponent bits, 10 explicit significand bits.
+// - 32-bit: 1 sign bit, 8 exponent bits, 23 explicit significand bits.
+// - 64-bit: 1 sign bit, 11 exponent bits, 52 explicit significand bits.
+//
+// For example, it converts between:
+// - +1.0 and 0x3C00, 0x3F80_0000 or 0x3FF0_0000_0000_0000.
+// - +5.5 and 0x4580, 0x40B0_0000 or 0x4016_0000_0000_0000.
+// - -inf and 0xFC00, 0xFF80_0000 or 0xFFF0_0000_0000_0000.
+//
+// Converting from f64 to shorter formats (f16 or f32, represented in C as
+// uint16_t and uint32_t) may be lossy. Such functions have names that look
+// like etc_truncate, as converting finite numbers produce equal or smaller
+// (closer-to-zero) finite numbers. For example, 1048576.0 is a perfectly valid
+// f64 number, but converting it to a f16 (with truncation) produces 65504.0,
+// the largest finite f16 number. Truncating a f64-typed value d to f32 does
+// not always produce the same result as the C-style cast ((float)d), as
+// casting can convert from finite numbers to infinite ones.
+//
+// Converting infinities or NaNs produces infinities or NaNs and always report
+// no loss, even though there a multiple NaN representations so that round-
+// tripping a f64-typed NaN may produce a different 64 bits. Nonetheless, the
+// etc_truncate functions preserve a NaN's "quiet vs signaling" bit.
+//
+// See https://en.wikipedia.org/wiki/Double-precision_floating-point_format
+
+typedef struct wuffs_base__lossy_value_u16__struct {
+ uint16_t value;
+ bool lossy;
+} wuffs_base__lossy_value_u16;
+
+typedef struct wuffs_base__lossy_value_u32__struct {
+ uint32_t value;
+ bool lossy;
+} wuffs_base__lossy_value_u32;
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16 //
+wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f);
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32 //
+wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f);
+
+static inline uint64_t //
+wuffs_base__ieee_754_bit_representation__from_f64_to_u64(double f) {
+ uint64_t u = 0;
+ if (sizeof(uint64_t) == sizeof(double)) {
+ memcpy(&u, &f, sizeof(uint64_t));
+ }
+ return u;
+}
+
+static inline double //
+wuffs_base__ieee_754_bit_representation__from_u16_to_f64(uint16_t u) {
+ uint64_t v = ((uint64_t)(u & 0x8000)) << 48;
+
+ do {
+ uint64_t exp = (u >> 10) & 0x1F;
+ uint64_t man = u & 0x3FF;
+ if (exp == 0x1F) { // Infinity or NaN.
+ exp = 2047;
+ } else if (exp != 0) { // Normal.
+ exp += 1008; // 1008 = 1023 - 15, the difference in biases.
+ } else if (man != 0) { // Subnormal but non-zero.
+ uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
+ exp = 1062 - clz; // 1062 = 1008 + 64 - 10.
+ man = 0x3FF & (man << (clz - 53));
+ } else { // Zero.
+ break;
+ }
+ v |= (exp << 52) | (man << 42);
+ } while (0);
+
+ double f = 0;
+ if (sizeof(uint64_t) == sizeof(double)) {
+ memcpy(&f, &v, sizeof(uint64_t));
+ }
+ return f;
+}
+
+static inline double //
+wuffs_base__ieee_754_bit_representation__from_u32_to_f64(uint32_t u) {
+ float f = 0;
+ if (sizeof(uint32_t) == sizeof(float)) {
+ memcpy(&f, &u, sizeof(uint32_t));
+ }
+ return (double)f;
+}
+
+static inline double //
+wuffs_base__ieee_754_bit_representation__from_u64_to_f64(uint64_t u) {
+ double f = 0;
+ if (sizeof(uint64_t) == sizeof(double)) {
+ memcpy(&f, &u, sizeof(uint64_t));
+ }
+ return f;
+}
+
+// ---------------- Parsing and Rendering Numbers
+
+// wuffs_base__parse_number_f64 parses the floating point number in s. For
+// example, if s contains the bytes "1.5" then it will return the double 1.5.
+//
+// It returns an error if s does not contain a floating point number.
+//
+// It does not necessarily return an error if the conversion is lossy, e.g. if
+// s is "0.3", which double-precision floating point cannot represent exactly.
+//
+// Similarly, the returned value may be infinite (and no error returned) even
+// if s was not "inf", when the input is nominally finite but sufficiently
+// larger than DBL_MAX, about 1.8e+308.
+//
+// It is similar to the C standard library's strtod function, but:
+// - Errors are returned in-band (in a result type), not out-of-band (errno).
+// - It takes a slice (a pointer and length), not a NUL-terminated C string.
+// - It does not take an optional endptr argument. It does not allow a partial
+// parse: it returns an error unless all of s is consumed.
+// - It does not allow whitespace, leading or otherwise.
+// - It does not allow hexadecimal floating point numbers.
+// - It is not affected by i18n / l10n settings such as environment variables.
+//
+// The options argument can change these, but by default, it:
+// - Allows "inf", "+Infinity" and "-NAN", case insensitive. Similarly,
+// without an explicit opt-out, it would successfully parse "1e999" as
+// infinity, even though it overflows double-precision floating point.
+// - Rejects underscores. With an explicit opt-in, "_3.141_592" would
+// successfully parse as an approximation to π.
+// - Rejects unnecessary leading zeroes: "00", "0644" and "00.7".
+// - Uses a dot '1.5' instead of a comma '1,5' for the decimal separator.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
+wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options);
+
+// wuffs_base__parse_number_i64 parses the ASCII integer in s. For example, if
+// s contains the bytes "-123" then it will return the int64_t -123.
+//
+// It returns an error if s does not contain an integer or if the integer
+// within would overflow an int64_t.
+//
+// It is similar to wuffs_base__parse_number_u64 but it returns a signed
+// integer, not an unsigned integer. It also allows a leading '+' or '-'.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 //
+wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options);
+
+// wuffs_base__parse_number_u64 parses the ASCII integer in s. For example, if
+// s contains the bytes "123" then it will return the uint64_t 123.
+//
+// It returns an error if s does not contain an integer or if the integer
+// within would overflow a uint64_t.
+//
+// It is similar to the C standard library's strtoull function, but:
+// - Errors are returned in-band (in a result type), not out-of-band (errno).
+// - It takes a slice (a pointer and length), not a NUL-terminated C string.
+// - It does not take an optional endptr argument. It does not allow a partial
+// parse: it returns an error unless all of s is consumed.
+// - It does not allow whitespace, leading or otherwise.
+// - It does not allow a leading '+' or '-'.
+// - It does not take a base argument (e.g. base 10 vs base 16). Instead, it
+// always accepts both decimal (e.g "1234", "0d5678") and hexadecimal (e.g.
+// "0x9aBC"). The caller is responsible for prior filtering of e.g. hex
+// numbers if they are unwanted. For example, Wuffs' JSON decoder will only
+// produce a wuffs_base__token for decimal numbers, not hexadecimal.
+// - It is not affected by i18n / l10n settings such as environment variables.
+//
+// The options argument can change these, but by default, it:
+// - Rejects underscores. With an explicit opt-in, "__0D_1_002" would
+// successfully parse as "one thousand and two". Underscores are still
+// rejected inside the optional 2-byte opening "0d" or "0X" that denotes
+// base-10 or base-16.
+// - Rejects unnecessary leading zeroes: "00" and "0644".
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 //
+wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options);
+
+// --------
+
+// WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL is the string length of
+// "-9223372036854775808" and "+9223372036854775807", INT64_MIN and INT64_MAX.
+#define WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL 20
+
+// WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL is the string length of
+// "+18446744073709551615", UINT64_MAX.
+#define WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL 21
+
+// wuffs_base__render_number_f64 writes the decimal encoding of x to dst and
+// returns the number of bytes written. If dst is shorter than the entire
+// encoding, it returns 0 (and no bytes are written).
+//
+// For those familiar with C's printf or Go's fmt.Printf functions:
+// - "%e" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT option.
+// - "%f" means the WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT option.
+// - "%g" means neither or both bits are set.
+//
+// The precision argument controls the number of digits rendered, excluding the
+// exponent (the "e+05" in "1.23e+05"):
+// - for "%e" and "%f" it is the number of digits after the decimal separator,
+// - for "%g" it is the number of significant digits (and trailing zeroes are
+// removed).
+//
+// A precision of 6 gives similar output to printf's defaults.
+//
+// A precision greater than 4095 is equivalent to 4095.
+//
+// The precision argument is ignored when the
+// WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION option is set. This is
+// similar to Go's strconv.FormatFloat with a negative (i.e. non-sensical)
+// precision, but there is no corresponding feature in C's printf.
+//
+// Extreme values of x will be rendered as "NaN", "Inf" (or "+Inf" if the
+// WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN option is set) or "-Inf".
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__FLOATCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
+ double x,
+ uint32_t precision,
+ uint32_t options);
+
+// wuffs_base__render_number_i64 writes the decimal encoding of x to dst and
+// returns the number of bytes written. If dst is shorter than the entire
+// encoding, it returns 0 (and no bytes are written).
+//
+// dst will never be too short if its length is at least 20, also known as
+// WUFFS_BASE__I64__BYTE_LENGTH__MAX_INCL.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
+ int64_t x,
+ uint32_t options);
+
+// wuffs_base__render_number_u64 writes the decimal encoding of x to dst and
+// returns the number of bytes written. If dst is shorter than the entire
+// encoding, it returns 0 (and no bytes are written).
+//
+// dst will never be too short if its length is at least 21, also known as
+// WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
+ uint64_t x,
+ uint32_t options);
+
+// ---------------- Base-16
+
+// Options (bitwise or'ed together) for wuffs_base__base_16__xxx functions.
+
+#define WUFFS_BASE__BASE_16__DEFAULT_OPTIONS ((uint32_t)0x00000000)
+
+// wuffs_base__base_16__decode2 converts "6A6b" to "jk", where e.g. 'j' is
+// U+006A. There are 2 src bytes for every dst byte.
+//
+// It assumes that the src bytes are two hexadecimal digits (0-9, A-F, a-f),
+// repeated. It may write nonsense bytes if not, although it will not read or
+// write out of bounds.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options);
+
+// wuffs_base__base_16__decode4 converts both "\\x6A\\x6b" and "??6a??6B" to
+// "jk", where e.g. 'j' is U+006A. There are 4 src bytes for every dst byte.
+//
+// It assumes that the src bytes are two ignored bytes and then two hexadecimal
+// digits (0-9, A-F, a-f), repeated. It may write nonsense bytes if not,
+// although it will not read or write out of bounds.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options);
+
+// wuffs_base__base_16__encode2 converts "jk" to "6A6B", where e.g. 'j' is
+// U+006A. There are 2 dst bytes for every src byte.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options);
+
+// wuffs_base__base_16__encode4 converts "jk" to "\\x6A\\x6B", where e.g. 'j'
+// is U+006A. There are 4 dst bytes for every src byte.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options);
+
+// ---------------- Base-64
+
+// Options (bitwise or'ed together) for wuffs_base__base_64__xxx functions.
+
+#define WUFFS_BASE__BASE_64__DEFAULT_OPTIONS ((uint32_t)0x00000000)
+
+// WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING means that, when decoding base-64,
+// the input may (but does not need to) be padded with '=' bytes so that the
+// overall encoded length in bytes is a multiple of 4. A successful decoding
+// will return a num_src that includes those padding bytes.
+//
+// Excess padding (e.g. three final '='s) will be rejected as bad data.
+#define WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING ((uint32_t)0x00000001)
+
+// WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING means that, when encoding base-64,
+// the output will be padded with '=' bytes so that the overall encoded length
+// in bytes is a multiple of 4.
+#define WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING ((uint32_t)0x00000002)
+
+// WUFFS_BASE__BASE_64__URL_ALPHABET means that, for base-64, the URL-friendly
+// and file-name-friendly alphabet be used, as per RFC 4648 section 5. When
+// this option bit is off, the standard alphabet from section 4 is used.
+#define WUFFS_BASE__BASE_64__URL_ALPHABET ((uint32_t)0x00000100)
+
+// wuffs_base__base_64__decode transforms base-64 encoded bytes from src to
+// arbitrary bytes in dst.
+//
+// It will not permit line breaks or other whitespace in src. Filtering those
+// out is the responsibility of the caller.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options);
+
+// wuffs_base__base_64__encode transforms arbitrary bytes from src to base-64
+// encoded bytes in dst.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__INTCONV sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options);
+
+// ---------------- Unicode and UTF-8
+
+#define WUFFS_BASE__UNICODE_CODE_POINT__MIN_INCL 0x00000000
+#define WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL 0x0010FFFF
+
+#define WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER 0x0000FFFD
+
+#define WUFFS_BASE__UNICODE_SURROGATE__MIN_INCL 0x0000D800
+#define WUFFS_BASE__UNICODE_SURROGATE__MAX_INCL 0x0000DFFF
+
+#define WUFFS_BASE__ASCII__MIN_INCL 0x00
+#define WUFFS_BASE__ASCII__MAX_INCL 0x7F
+
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH__MIN_INCL 1
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL 4
+
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MIN_INCL 0x00000000
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH_1__CODE_POINT__MAX_INCL 0x0000007F
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MIN_INCL 0x00000080
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH_2__CODE_POINT__MAX_INCL 0x000007FF
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MIN_INCL 0x00000800
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH_3__CODE_POINT__MAX_INCL 0x0000FFFF
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MIN_INCL 0x00010000
+#define WUFFS_BASE__UTF_8__BYTE_LENGTH_4__CODE_POINT__MAX_INCL 0x0010FFFF
+
+// --------
+
+// wuffs_base__utf_8__next__output is the type returned by
+// wuffs_base__utf_8__next.
+typedef struct wuffs_base__utf_8__next__output__struct {
+ uint32_t code_point;
+ uint32_t byte_length;
+
+#ifdef __cplusplus
+ inline bool is_valid() const;
+#endif // __cplusplus
+
+} wuffs_base__utf_8__next__output;
+
+static inline wuffs_base__utf_8__next__output //
+wuffs_base__make_utf_8__next__output(uint32_t code_point,
+ uint32_t byte_length) {
+ wuffs_base__utf_8__next__output ret;
+ ret.code_point = code_point;
+ ret.byte_length = byte_length;
+ return ret;
+}
+
+static inline bool //
+wuffs_base__utf_8__next__output__is_valid(
+ const wuffs_base__utf_8__next__output* o) {
+ if (o) {
+ uint32_t cp = o->code_point;
+ switch (o->byte_length) {
+ case 1:
+ return (cp <= 0x7F);
+ case 2:
+ return (0x080 <= cp) && (cp <= 0x7FF);
+ case 3:
+ // Avoid the 0xD800 ..= 0xDFFF surrogate range.
+ return ((0x0800 <= cp) && (cp <= 0xD7FF)) ||
+ ((0xE000 <= cp) && (cp <= 0xFFFF));
+ case 4:
+ return (0x00010000 <= cp) && (cp <= 0x0010FFFF);
+ }
+ }
+ return false;
+}
+
+#ifdef __cplusplus
+
+inline bool //
+wuffs_base__utf_8__next__output::is_valid() const {
+ return wuffs_base__utf_8__next__output__is_valid(this);
+}
+
+#endif // __cplusplus
+
+// --------
+
+// wuffs_base__utf_8__encode writes the UTF-8 encoding of code_point to s and
+// returns the number of bytes written. If code_point is invalid, or if s is
+// shorter than the entire encoding, it returns 0 (and no bytes are written).
+//
+// s will never be too short if its length is at least 4, also known as
+// WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
+// WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point);
+
+// wuffs_base__utf_8__next returns the next UTF-8 code point (and that code
+// point's byte length) at the start of the read-only slice (s_ptr, s_len).
+//
+// There are exactly two cases in which this function returns something where
+// wuffs_base__utf_8__next__output__is_valid is false:
+// - If s is empty then it returns {.code_point=0, .byte_length=0}.
+// - If s is non-empty and starts with invalid UTF-8 then it returns
+// {.code_point=WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, .byte_length=1}.
+//
+// Otherwise, it returns something where
+// wuffs_base__utf_8__next__output__is_valid is true.
+//
+// In any case, it always returns an output that satisfies both of:
+// - (output.code_point <= WUFFS_BASE__UNICODE_CODE_POINT__MAX_INCL).
+// - (output.byte_length <= s_len).
+//
+// If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
+// boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
+// code point, then this function may return something invalid. It is the
+// caller's responsibility to split on or otherwise manage UTF-8 boundaries.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
+// WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
+wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len);
+
+// wuffs_base__utf_8__next_from_end is like wuffs_base__utf_8__next except that
+// it looks at the end of (s_ptr, s_len) instead of the start.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
+// WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
+wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len);
+
+// wuffs_base__utf_8__longest_valid_prefix returns the largest n such that the
+// sub-slice s[..n] is valid UTF-8, where s is the read-only slice (s_ptr,
+// s_len).
+//
+// In particular, it returns s_len if and only if all of s is valid UTF-8.
+//
+// If s is a sub-slice of a larger slice of valid UTF-8, but that sub-slice
+// boundary occurs in the middle of a multi-byte UTF-8 encoding of a single
+// code point, then this function will return less than s_len. It is the
+// caller's responsibility to split on or otherwise manage UTF-8 boundaries.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
+// WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
+
+// wuffs_base__ascii__longest_valid_prefix returns the largest n such that the
+// sub-slice s[..n] is valid ASCII, where s is the read-only slice (s_ptr,
+// s_len).
+//
+// In particular, it returns s_len if and only if all of s is valid ASCII.
+// Equivalently, when none of the bytes in s have the 0x80 high bit set.
+//
+// For modular builds that divide the base module into sub-modules, using this
+// function requires the WUFFS_CONFIG__MODULE__BASE__UTF8 sub-module, not just
+// WUFFS_CONFIG__MODULE__BASE__CORE.
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len);
+
+// ---------------- Interface Declarations.
+
+// For modular builds that divide the base module into sub-modules, using these
+// functions require the WUFFS_CONFIG__MODULE__BASE__INTERFACES sub-module, not
+// just WUFFS_CONFIG__MODULE__BASE__CORE.
+
+// --------
+
+extern const char wuffs_base__hasher_u32__vtable_name[];
+
+typedef struct wuffs_base__hasher_u32__func_ptrs__struct {
+ uint32_t (*checksum_u32)(
+ const void* self);
+ uint64_t (*get_quirk)(
+ const void* self,
+ uint32_t a_key);
+ wuffs_base__status (*set_quirk)(
+ void* self,
+ uint32_t a_key,
+ uint64_t a_value);
+ wuffs_base__empty_struct (*update)(
+ void* self,
+ wuffs_base__slice_u8 a_x);
+ uint32_t (*update_u32)(
+ void* self,
+ wuffs_base__slice_u8 a_x);
+} wuffs_base__hasher_u32__func_ptrs;
+
+typedef struct wuffs_base__hasher_u32__struct wuffs_base__hasher_u32;
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_base__hasher_u32__checksum_u32(
+ const wuffs_base__hasher_u32* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__hasher_u32__get_quirk(
+ const wuffs_base__hasher_u32* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__hasher_u32__set_quirk(
+ wuffs_base__hasher_u32* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_base__hasher_u32__update(
+ wuffs_base__hasher_u32* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_base__hasher_u32__update_u32(
+ wuffs_base__hasher_u32* self,
+ wuffs_base__slice_u8 a_x);
+
+#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+struct wuffs_base__hasher_u32__struct {
+ struct {
+ uint32_t magic;
+ uint32_t active_coroutine;
+ wuffs_base__vtable first_vtable;
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_base__hasher_u32, wuffs_unique_ptr_deleter>;
+#endif
+
+ inline uint32_t
+ checksum_u32() const {
+ return wuffs_base__hasher_u32__checksum_u32(this);
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_base__hasher_u32__get_quirk(
+ this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_base__hasher_u32__set_quirk(
+ this, a_key, a_value);
+ }
+
+ inline wuffs_base__empty_struct
+ update(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_base__hasher_u32__update(
+ this, a_x);
+ }
+
+ inline uint32_t
+ update_u32(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_base__hasher_u32__update_u32(
+ this, a_x);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_base__hasher_u32__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+// --------
+
+extern const char wuffs_base__hasher_u64__vtable_name[];
+
+typedef struct wuffs_base__hasher_u64__func_ptrs__struct {
+ uint64_t (*checksum_u64)(
+ const void* self);
+ uint64_t (*get_quirk)(
+ const void* self,
+ uint32_t a_key);
+ wuffs_base__status (*set_quirk)(
+ void* self,
+ uint32_t a_key,
+ uint64_t a_value);
+ wuffs_base__empty_struct (*update)(
+ void* self,
+ wuffs_base__slice_u8 a_x);
+ uint64_t (*update_u64)(
+ void* self,
+ wuffs_base__slice_u8 a_x);
+} wuffs_base__hasher_u64__func_ptrs;
+
+typedef struct wuffs_base__hasher_u64__struct wuffs_base__hasher_u64;
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__hasher_u64__checksum_u64(
+ const wuffs_base__hasher_u64* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__hasher_u64__get_quirk(
+ const wuffs_base__hasher_u64* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__hasher_u64__set_quirk(
+ wuffs_base__hasher_u64* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_base__hasher_u64__update(
+ wuffs_base__hasher_u64* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__hasher_u64__update_u64(
+ wuffs_base__hasher_u64* self,
+ wuffs_base__slice_u8 a_x);
+
+#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+struct wuffs_base__hasher_u64__struct {
+ struct {
+ uint32_t magic;
+ uint32_t active_coroutine;
+ wuffs_base__vtable first_vtable;
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_base__hasher_u64, wuffs_unique_ptr_deleter>;
+#endif
+
+ inline uint64_t
+ checksum_u64() const {
+ return wuffs_base__hasher_u64__checksum_u64(this);
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_base__hasher_u64__get_quirk(
+ this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_base__hasher_u64__set_quirk(
+ this, a_key, a_value);
+ }
+
+ inline wuffs_base__empty_struct
+ update(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_base__hasher_u64__update(
+ this, a_x);
+ }
+
+ inline uint64_t
+ update_u64(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_base__hasher_u64__update_u64(
+ this, a_x);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_base__hasher_u64__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+// --------
+
+extern const char wuffs_base__image_decoder__vtable_name[];
+
+typedef struct wuffs_base__image_decoder__func_ptrs__struct {
+ wuffs_base__status (*decode_frame)(
+ void* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+ wuffs_base__status (*decode_frame_config)(
+ void* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+ wuffs_base__status (*decode_image_config)(
+ void* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+ wuffs_base__rect_ie_u32 (*frame_dirty_rect)(
+ const void* self);
+ uint64_t (*get_quirk)(
+ const void* self,
+ uint32_t a_key);
+ uint64_t (*history_retain_length)(
+ const void* self);
+ uint32_t (*num_animation_loops)(
+ const void* self);
+ uint64_t (*num_decoded_frame_configs)(
+ const void* self);
+ uint64_t (*num_decoded_frames)(
+ const void* self);
+ wuffs_base__status (*restart_frame)(
+ void* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+ wuffs_base__status (*set_quirk)(
+ void* self,
+ uint32_t a_key,
+ uint64_t a_value);
+ wuffs_base__empty_struct (*set_report_metadata)(
+ void* self,
+ uint32_t a_fourcc,
+ bool a_report);
+ wuffs_base__status (*tell_me_more)(
+ void* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+ wuffs_base__range_ii_u64 (*workbuf_len)(
+ const void* self);
+} wuffs_base__image_decoder__func_ptrs;
+
+typedef struct wuffs_base__image_decoder__struct wuffs_base__image_decoder;
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__decode_frame(
+ wuffs_base__image_decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__decode_frame_config(
+ wuffs_base__image_decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__decode_image_config(
+ wuffs_base__image_decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_base__image_decoder__frame_dirty_rect(
+ const wuffs_base__image_decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__image_decoder__get_quirk(
+ const wuffs_base__image_decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__image_decoder__history_retain_length(
+ const wuffs_base__image_decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_base__image_decoder__num_animation_loops(
+ const wuffs_base__image_decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__image_decoder__num_decoded_frame_configs(
+ const wuffs_base__image_decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__image_decoder__num_decoded_frames(
+ const wuffs_base__image_decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__restart_frame(
+ wuffs_base__image_decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__set_quirk(
+ wuffs_base__image_decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_base__image_decoder__set_report_metadata(
+ wuffs_base__image_decoder* self,
+ uint32_t a_fourcc,
+ bool a_report);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__tell_me_more(
+ wuffs_base__image_decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_base__image_decoder__workbuf_len(
+ const wuffs_base__image_decoder* self);
+
+#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+struct wuffs_base__image_decoder__struct {
+ struct {
+ uint32_t magic;
+ uint32_t active_coroutine;
+ wuffs_base__vtable first_vtable;
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_base__image_decoder, wuffs_unique_ptr_deleter>;
+#endif
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_base__image_decoder__decode_frame(
+ this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_base__image_decoder__decode_frame_config(
+ this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_base__image_decoder__decode_image_config(
+ this, a_dst, a_src);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_base__image_decoder__frame_dirty_rect(this);
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_base__image_decoder__get_quirk(
+ this, a_key);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_base__image_decoder__history_retain_length(this);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_base__image_decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_base__image_decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_base__image_decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_base__image_decoder__restart_frame(
+ this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_base__image_decoder__set_quirk(
+ this, a_key, a_value);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_base__image_decoder__set_report_metadata(
+ this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_base__image_decoder__tell_me_more(
+ this, a_dst, a_minfo, a_src);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_base__image_decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_base__image_decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+// --------
+
+extern const char wuffs_base__io_transformer__vtable_name[];
+
+typedef struct wuffs_base__io_transformer__func_ptrs__struct {
+ uint64_t (*get_quirk)(
+ const void* self,
+ uint32_t a_key);
+ uint64_t (*history_retain_length)(
+ const void* self);
+ wuffs_base__status (*set_quirk)(
+ void* self,
+ uint32_t a_key,
+ uint64_t a_value);
+ wuffs_base__status (*transform_io)(
+ void* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+ wuffs_base__range_ii_u64 (*workbuf_len)(
+ const void* self);
+} wuffs_base__io_transformer__func_ptrs;
+
+typedef struct wuffs_base__io_transformer__struct wuffs_base__io_transformer;
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__io_transformer__get_quirk(
+ const wuffs_base__io_transformer* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__io_transformer__history_retain_length(
+ const wuffs_base__io_transformer* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__io_transformer__set_quirk(
+ wuffs_base__io_transformer* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__io_transformer__transform_io(
+ wuffs_base__io_transformer* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_base__io_transformer__workbuf_len(
+ const wuffs_base__io_transformer* self);
+
+#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+struct wuffs_base__io_transformer__struct {
+ struct {
+ uint32_t magic;
+ uint32_t active_coroutine;
+ wuffs_base__vtable first_vtable;
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_base__io_transformer, wuffs_unique_ptr_deleter>;
+#endif
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_base__io_transformer__get_quirk(
+ this, a_key);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_base__io_transformer__history_retain_length(this);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_base__io_transformer__set_quirk(
+ this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ transform_io(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_base__io_transformer__transform_io(
+ this, a_dst, a_src, a_workbuf);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_base__io_transformer__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_base__io_transformer__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+// --------
+
+extern const char wuffs_base__token_decoder__vtable_name[];
+
+typedef struct wuffs_base__token_decoder__func_ptrs__struct {
+ wuffs_base__status (*decode_tokens)(
+ void* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+ uint64_t (*get_quirk)(
+ const void* self,
+ uint32_t a_key);
+ uint64_t (*history_retain_length)(
+ const void* self);
+ wuffs_base__status (*set_quirk)(
+ void* self,
+ uint32_t a_key,
+ uint64_t a_value);
+ wuffs_base__range_ii_u64 (*workbuf_len)(
+ const void* self);
+} wuffs_base__token_decoder__func_ptrs;
+
+typedef struct wuffs_base__token_decoder__struct wuffs_base__token_decoder;
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__token_decoder__decode_tokens(
+ wuffs_base__token_decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__token_decoder__get_quirk(
+ const wuffs_base__token_decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__token_decoder__history_retain_length(
+ const wuffs_base__token_decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__token_decoder__set_quirk(
+ wuffs_base__token_decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_base__token_decoder__workbuf_len(
+ const wuffs_base__token_decoder* self);
+
+#if defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+struct wuffs_base__token_decoder__struct {
+ struct {
+ uint32_t magic;
+ uint32_t active_coroutine;
+ wuffs_base__vtable first_vtable;
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_base__token_decoder, wuffs_unique_ptr_deleter>;
+#endif
+
+ inline wuffs_base__status
+ decode_tokens(
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_base__token_decoder__decode_tokens(
+ this, a_dst, a_src, a_workbuf);
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_base__token_decoder__get_quirk(
+ this, a_key);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_base__token_decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_base__token_decoder__set_quirk(
+ this, a_key, a_value);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_base__token_decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_base__token_decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+// ----------------
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+// ---------------- Public Consts
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_adler32__hasher__struct wuffs_adler32__hasher;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+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 options);
+
+size_t
+sizeof__wuffs_adler32__hasher(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_adler32__hasher*
+wuffs_adler32__hasher__alloc(void);
+
+static inline wuffs_base__hasher_u32*
+wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32(void) {
+ return (wuffs_base__hasher_u32*)(wuffs_adler32__hasher__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__hasher_u32*
+wuffs_adler32__hasher__upcast_as__wuffs_base__hasher_u32(
+ wuffs_adler32__hasher* p) {
+ return (wuffs_base__hasher_u32*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_adler32__hasher__get_quirk(
+ const wuffs_adler32__hasher* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_adler32__hasher__set_quirk(
+ wuffs_adler32__hasher* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_adler32__hasher__update(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_adler32__hasher__update_u32(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_adler32__hasher__checksum_u32(
+ const wuffs_adler32__hasher* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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 {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_state;
+ bool f_started;
+
+ wuffs_base__empty_struct (*choosy_up)(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_adler32__hasher, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_adler32__hasher__alloc());
+ }
+
+ static inline wuffs_base__hasher_u32::unique_ptr
+ alloc_as__wuffs_base__hasher_u32() {
+ return wuffs_base__hasher_u32::unique_ptr(
+ wuffs_adler32__hasher__alloc_as__wuffs_base__hasher_u32());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_adler32__hasher__struct() = delete;
+ wuffs_adler32__hasher__struct(const wuffs_adler32__hasher__struct&) = delete;
+ wuffs_adler32__hasher__struct& operator=(
+ const wuffs_adler32__hasher__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_adler32__hasher__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__hasher_u32*
+ upcast_as__wuffs_base__hasher_u32() {
+ return (wuffs_base__hasher_u32*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_adler32__hasher__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_adler32__hasher__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__empty_struct
+ update(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_adler32__hasher__update(this, a_x);
+ }
+
+ inline uint32_t
+ update_u32(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_adler32__hasher__update_u32(this, a_x);
+ }
+
+ inline uint32_t
+ checksum_u32() const {
+ return wuffs_adler32__hasher__checksum_u32(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_adler32__hasher__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_bmp__error__bad_header[];
+extern const char wuffs_bmp__error__bad_rle_compression[];
+extern const char wuffs_bmp__error__truncated_input[];
+extern const char wuffs_bmp__error__unsupported_bmp_file[];
+
+// ---------------- Public Consts
+
+#define WUFFS_BMP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_BMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_bmp__decoder__struct wuffs_bmp__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_bmp__decoder__initialize(
+ wuffs_bmp__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_bmp__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_bmp__decoder*
+wuffs_bmp__decoder__alloc(void);
+
+static inline wuffs_base__image_decoder*
+wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder(void) {
+ return (wuffs_base__image_decoder*)(wuffs_bmp__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__image_decoder*
+wuffs_bmp__decoder__upcast_as__wuffs_base__image_decoder(
+ wuffs_bmp__decoder* p) {
+ return (wuffs_base__image_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bmp__decoder__get_quirk(
+ const wuffs_bmp__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__set_quirk(
+ wuffs_bmp__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__decode_image_config(
+ wuffs_bmp__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__decode_frame_config(
+ wuffs_bmp__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__decode_frame(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_bmp__decoder__frame_dirty_rect(
+ const wuffs_bmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_bmp__decoder__num_animation_loops(
+ const wuffs_bmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bmp__decoder__num_decoded_frame_configs(
+ const wuffs_bmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bmp__decoder__num_decoded_frames(
+ const wuffs_bmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__restart_frame(
+ wuffs_bmp__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_bmp__decoder__set_report_metadata(
+ wuffs_bmp__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__tell_me_more(
+ wuffs_bmp__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bmp__decoder__history_retain_length(
+ const wuffs_bmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_bmp__decoder__workbuf_len(
+ const wuffs_bmp__decoder* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_bmp__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_width;
+ uint32_t f_height;
+ uint8_t f_call_sequence;
+ bool f_top_down;
+ uint32_t f_pad_per_row;
+ uint32_t f_src_pixfmt;
+ uint32_t f_io_redirect_fourcc;
+ uint64_t f_io_redirect_pos;
+ uint64_t f_frame_config_io_position;
+ uint32_t f_bitmap_info_len;
+ uint32_t f_padding;
+ uint32_t f_bits_per_pixel;
+ uint32_t f_compression;
+ uint32_t f_channel_masks[4];
+ uint8_t f_channel_shifts[4];
+ uint8_t f_channel_num_bits[4];
+ uint32_t f_dst_x;
+ uint32_t f_dst_y;
+ uint32_t f_dst_y_inc;
+ uint32_t f_pending_pad;
+ uint32_t f_rle_state;
+ uint32_t f_rle_length;
+ uint8_t f_rle_delta_x;
+ bool f_rle_padded;
+ wuffs_base__pixel_swizzler f_swizzler;
+
+ uint32_t p_decode_image_config[1];
+ uint32_t p_do_decode_image_config[1];
+ uint32_t p_decode_frame_config[1];
+ uint32_t p_do_decode_frame_config[1];
+ uint32_t p_decode_frame[1];
+ uint32_t p_do_decode_frame[1];
+ uint32_t p_tell_me_more[1];
+ uint32_t p_read_palette[1];
+ } private_impl;
+
+ struct {
+ uint8_t f_scratch[2048];
+ uint8_t f_src_palette[1024];
+
+ struct {
+ uint64_t scratch;
+ } s_do_decode_image_config[1];
+ struct {
+ uint64_t scratch;
+ } s_do_decode_frame[1];
+ struct {
+ uint32_t v_i;
+ uint64_t scratch;
+ } s_read_palette[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_bmp__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_bmp__decoder__alloc());
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_bmp__decoder__alloc_as__wuffs_base__image_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_bmp__decoder__struct() = delete;
+ wuffs_bmp__decoder__struct(const wuffs_bmp__decoder__struct&) = delete;
+ wuffs_bmp__decoder__struct& operator=(
+ const wuffs_bmp__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_bmp__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__image_decoder*
+ upcast_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_bmp__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_bmp__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_bmp__decoder__decode_image_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_bmp__decoder__decode_frame_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_bmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_bmp__decoder__frame_dirty_rect(this);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_bmp__decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_bmp__decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_bmp__decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_bmp__decoder__restart_frame(this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_bmp__decoder__set_report_metadata(this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_bmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_bmp__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_bmp__decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_bmp__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_bzip2__error__bad_huffman_code_over_subscribed[];
+extern const char wuffs_bzip2__error__bad_huffman_code_under_subscribed[];
+extern const char wuffs_bzip2__error__bad_block_header[];
+extern const char wuffs_bzip2__error__bad_block_length[];
+extern const char wuffs_bzip2__error__bad_checksum[];
+extern const char wuffs_bzip2__error__bad_header[];
+extern const char wuffs_bzip2__error__bad_number_of_sections[];
+extern const char wuffs_bzip2__error__truncated_input[];
+extern const char wuffs_bzip2__error__unsupported_block_randomization[];
+
+// ---------------- Public Consts
+
+#define WUFFS_BZIP2__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_BZIP2__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_bzip2__decoder__struct wuffs_bzip2__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_bzip2__decoder__initialize(
+ wuffs_bzip2__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_bzip2__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_bzip2__decoder*
+wuffs_bzip2__decoder__alloc(void);
+
+static inline wuffs_base__io_transformer*
+wuffs_bzip2__decoder__alloc_as__wuffs_base__io_transformer(void) {
+ return (wuffs_base__io_transformer*)(wuffs_bzip2__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__io_transformer*
+wuffs_bzip2__decoder__upcast_as__wuffs_base__io_transformer(
+ wuffs_bzip2__decoder* p) {
+ return (wuffs_base__io_transformer*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bzip2__decoder__get_quirk(
+ const wuffs_bzip2__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bzip2__decoder__set_quirk(
+ wuffs_bzip2__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bzip2__decoder__history_retain_length(
+ const wuffs_bzip2__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_bzip2__decoder__workbuf_len(
+ const wuffs_bzip2__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bzip2__decoder__transform_io(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_bzip2__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_bits;
+ uint32_t f_n_bits;
+ uint32_t f_max_incl_block_size;
+ uint32_t f_block_size;
+ bool f_decode_huffman_finished;
+ uint8_t f_decode_huffman_which;
+ uint32_t f_decode_huffman_ticks;
+ uint32_t f_decode_huffman_section;
+ uint32_t f_decode_huffman_run_shift;
+ uint32_t f_flush_pointer;
+ uint32_t f_flush_repeat_count;
+ uint8_t f_flush_prev;
+ bool f_ignore_checksum;
+ uint32_t f_final_checksum_have;
+ uint32_t f_block_checksum_have;
+ uint32_t f_block_checksum_want;
+ uint32_t f_original_pointer;
+ uint32_t f_num_symbols;
+ uint32_t f_num_huffman_codes;
+ uint32_t f_num_sections;
+ uint32_t f_code_lengths_bitmask;
+
+ uint32_t p_transform_io[1];
+ uint32_t p_do_transform_io[1];
+ uint32_t p_prepare_block[1];
+ uint32_t p_read_code_lengths[1];
+ uint32_t p_flush_slow[1];
+ uint32_t p_decode_huffman_slow[1];
+ } private_impl;
+
+ struct {
+ uint32_t f_scratch;
+ uint32_t f_letter_counts[256];
+ uint8_t f_presence[256];
+ uint8_t f_mtft[256];
+ uint8_t f_huffman_selectors[32768];
+ uint16_t f_huffman_trees[6][257][2];
+ uint16_t f_huffman_tables[6][256];
+ uint32_t f_bwt[1048576];
+
+ struct {
+ uint32_t v_i;
+ uint64_t v_tag;
+ uint32_t v_final_checksum_want;
+ } s_do_transform_io[1];
+ struct {
+ uint32_t v_i;
+ uint32_t v_selector;
+ } s_prepare_block[1];
+ struct {
+ uint32_t v_i;
+ uint32_t v_code_length;
+ } s_read_code_lengths[1];
+ struct {
+ uint32_t v_flush_pointer;
+ uint32_t v_flush_repeat_count;
+ uint8_t v_flush_prev;
+ uint32_t v_block_checksum_have;
+ uint32_t v_block_size;
+ uint8_t v_curr;
+ uint64_t scratch;
+ } s_flush_slow[1];
+ struct {
+ uint32_t v_node_index;
+ } s_decode_huffman_slow[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_bzip2__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_bzip2__decoder__alloc());
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_bzip2__decoder__alloc_as__wuffs_base__io_transformer());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_bzip2__decoder__struct() = delete;
+ wuffs_bzip2__decoder__struct(const wuffs_bzip2__decoder__struct&) = delete;
+ wuffs_bzip2__decoder__struct& operator=(
+ const wuffs_bzip2__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_bzip2__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__io_transformer*
+ upcast_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_bzip2__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_bzip2__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_bzip2__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_bzip2__decoder__workbuf_len(this);
+ }
+
+ inline wuffs_base__status
+ transform_io(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_bzip2__decoder__transform_io(this, a_dst, a_src, a_workbuf);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_bzip2__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_cbor__error__bad_input[];
+extern const char wuffs_cbor__error__unsupported_recursion_depth[];
+
+// ---------------- Public Consts
+
+#define WUFFS_CBOR__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_CBOR__DECODER_DEPTH_MAX_INCL 1024
+
+#define WUFFS_CBOR__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 2
+
+#define WUFFS_CBOR__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 9
+
+#define WUFFS_CBOR__TOKEN_VALUE_MAJOR 787997
+
+#define WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK 262143
+
+#define WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X 16777216
+
+#define WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE 8388608
+
+#define WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG 4194304
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_cbor__decoder__struct wuffs_cbor__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_cbor__decoder__initialize(
+ wuffs_cbor__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_cbor__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_cbor__decoder*
+wuffs_cbor__decoder__alloc(void);
+
+static inline wuffs_base__token_decoder*
+wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder(void) {
+ return (wuffs_base__token_decoder*)(wuffs_cbor__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__token_decoder*
+wuffs_cbor__decoder__upcast_as__wuffs_base__token_decoder(
+ wuffs_cbor__decoder* p) {
+ return (wuffs_base__token_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_cbor__decoder__get_quirk(
+ const wuffs_cbor__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_cbor__decoder__set_quirk(
+ wuffs_cbor__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_cbor__decoder__history_retain_length(
+ const wuffs_cbor__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_cbor__decoder__workbuf_len(
+ const wuffs_cbor__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_cbor__decoder__decode_tokens(
+ wuffs_cbor__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_cbor__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
+ wuffs_base__vtable null_vtable;
+
+ bool f_end_of_data;
+
+ uint32_t p_decode_tokens[1];
+ } private_impl;
+
+ struct {
+ uint32_t f_stack[64];
+ uint64_t f_container_num_remaining[1024];
+
+ struct {
+ uint64_t v_string_length;
+ uint32_t v_depth;
+ bool v_tagged;
+ uint8_t v_indefinite_string_major_type;
+ } s_decode_tokens[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_cbor__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_cbor__decoder__alloc());
+ }
+
+ static inline wuffs_base__token_decoder::unique_ptr
+ alloc_as__wuffs_base__token_decoder() {
+ return wuffs_base__token_decoder::unique_ptr(
+ wuffs_cbor__decoder__alloc_as__wuffs_base__token_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_cbor__decoder__struct() = delete;
+ wuffs_cbor__decoder__struct(const wuffs_cbor__decoder__struct&) = delete;
+ wuffs_cbor__decoder__struct& operator=(
+ const wuffs_cbor__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_cbor__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__token_decoder*
+ upcast_as__wuffs_base__token_decoder() {
+ return (wuffs_base__token_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_cbor__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_cbor__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_cbor__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_cbor__decoder__workbuf_len(this);
+ }
+
+ inline wuffs_base__status
+ decode_tokens(
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_cbor__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_cbor__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+// ---------------- Public Consts
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_crc32__ieee_hasher__struct wuffs_crc32__ieee_hasher;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+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 options);
+
+size_t
+sizeof__wuffs_crc32__ieee_hasher(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_crc32__ieee_hasher*
+wuffs_crc32__ieee_hasher__alloc(void);
+
+static inline wuffs_base__hasher_u32*
+wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32(void) {
+ return (wuffs_base__hasher_u32*)(wuffs_crc32__ieee_hasher__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__hasher_u32*
+wuffs_crc32__ieee_hasher__upcast_as__wuffs_base__hasher_u32(
+ wuffs_crc32__ieee_hasher* p) {
+ return (wuffs_base__hasher_u32*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_crc32__ieee_hasher__get_quirk(
+ const wuffs_crc32__ieee_hasher* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_crc32__ieee_hasher__set_quirk(
+ wuffs_crc32__ieee_hasher* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__update(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_crc32__ieee_hasher__update_u32(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_crc32__ieee_hasher__checksum_u32(
+ const wuffs_crc32__ieee_hasher* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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 {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_state;
+
+ wuffs_base__empty_struct (*choosy_up)(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x);
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_crc32__ieee_hasher, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_crc32__ieee_hasher__alloc());
+ }
+
+ static inline wuffs_base__hasher_u32::unique_ptr
+ alloc_as__wuffs_base__hasher_u32() {
+ return wuffs_base__hasher_u32::unique_ptr(
+ wuffs_crc32__ieee_hasher__alloc_as__wuffs_base__hasher_u32());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_crc32__ieee_hasher__struct() = delete;
+ 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 // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_crc32__ieee_hasher__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__hasher_u32*
+ upcast_as__wuffs_base__hasher_u32() {
+ return (wuffs_base__hasher_u32*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_crc32__ieee_hasher__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_crc32__ieee_hasher__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__empty_struct
+ update(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_crc32__ieee_hasher__update(this, a_x);
+ }
+
+ inline uint32_t
+ update_u32(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_crc32__ieee_hasher__update_u32(this, a_x);
+ }
+
+ inline uint32_t
+ checksum_u32() const {
+ return wuffs_crc32__ieee_hasher__checksum_u32(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_crc32__ieee_hasher__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- 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[];
+extern const char wuffs_deflate__error__truncated_input[];
+
+// ---------------- Public Consts
+
+#define WUFFS_DEFLATE__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_DEFLATE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_deflate__decoder__struct wuffs_deflate__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+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 options);
+
+size_t
+sizeof__wuffs_deflate__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_deflate__decoder*
+wuffs_deflate__decoder__alloc(void);
+
+static inline wuffs_base__io_transformer*
+wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer(void) {
+ return (wuffs_base__io_transformer*)(wuffs_deflate__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__io_transformer*
+wuffs_deflate__decoder__upcast_as__wuffs_base__io_transformer(
+ wuffs_deflate__decoder* p) {
+ return (wuffs_base__io_transformer*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+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__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_deflate__decoder__get_quirk(
+ const wuffs_deflate__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_deflate__decoder__set_quirk(
+ wuffs_deflate__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_deflate__decoder__history_retain_length(
+ const wuffs_deflate__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_deflate__decoder__workbuf_len(
+ const wuffs_deflate__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_deflate__decoder__transform_io(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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 {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_bits;
+ uint32_t f_n_bits;
+ uint64_t f_transformed_history_count;
+ uint32_t f_history_index;
+ uint32_t f_n_huffs_bits[2];
+ bool f_end_of_block;
+
+ uint32_t p_transform_io[1];
+ uint32_t p_do_transform_io[1];
+ uint32_t p_decode_blocks[1];
+ uint32_t p_decode_uncompressed[1];
+ uint32_t p_init_dynamic_huffman[1];
+ wuffs_base__status (*choosy_decode_huffman_fast64)(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+ uint32_t p_decode_huffman_slow[1];
+ } private_impl;
+
+ struct {
+ uint32_t f_huffs[2][1024];
+ uint8_t f_history[33025];
+ 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_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_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;
+ uint64_t scratch;
+ } s_decode_huffman_slow[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_deflate__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_deflate__decoder__alloc());
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_deflate__decoder__alloc_as__wuffs_base__io_transformer());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_deflate__decoder__struct() = delete;
+ wuffs_deflate__decoder__struct(const wuffs_deflate__decoder__struct&) = delete;
+ wuffs_deflate__decoder__struct& operator=(
+ const wuffs_deflate__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_deflate__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__io_transformer*
+ upcast_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)this;
+ }
+
+ inline wuffs_base__empty_struct
+ add_history(
+ wuffs_base__slice_u8 a_hist) {
+ return wuffs_deflate__decoder__add_history(this, a_hist);
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_deflate__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_deflate__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_deflate__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_deflate__decoder__workbuf_len(this);
+ }
+
+ inline wuffs_base__status
+ transform_io(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_deflate__decoder__transform_io(this, a_dst, a_src, a_workbuf);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_deflate__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_gif__error__bad_lzw_code[];
+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[];
+extern const char wuffs_gif__error__truncated_input[];
+
+// ---------------- Public Consts
+
+#define WUFFS_GIF__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_GIF__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+#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;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+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 options);
+
+size_t
+sizeof__wuffs_gif__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_gif__decoder*
+wuffs_gif__decoder__alloc(void);
+
+static inline wuffs_base__image_decoder*
+wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder(void) {
+ return (wuffs_base__image_decoder*)(wuffs_gif__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__image_decoder*
+wuffs_gif__decoder__upcast_as__wuffs_base__image_decoder(
+ wuffs_gif__decoder* p) {
+ return (wuffs_base__image_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gif__decoder__get_quirk(
+ const wuffs_gif__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_gif__decoder__set_quirk(
+ wuffs_gif__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+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__GENERATED_C_CODE
+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__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_gif__decoder__tell_me_more(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_gif__decoder__num_animation_loops(
+ const wuffs_gif__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gif__decoder__num_decoded_frame_configs(
+ const wuffs_gif__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gif__decoder__num_decoded_frames(
+ const wuffs_gif__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_gif__decoder__frame_dirty_rect(
+ const wuffs_gif__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gif__decoder__history_retain_length(
+ const wuffs_gif__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_gif__decoder__workbuf_len(
+ const wuffs_gif__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+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__GENERATED_C_CODE
+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__GENERATED_C_CODE
+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__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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 {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_width;
+ uint32_t f_height;
+ uint8_t f_call_sequence;
+ bool f_report_metadata_iccp;
+ bool f_report_metadata_xmp;
+ uint32_t f_metadata_fourcc;
+ uint64_t f_metadata_io_position;
+ bool f_quirks[7];
+ bool f_delayed_num_decoded_frames;
+ bool f_seen_header;
+ bool f_ignored_but_affects_benchmarks;
+ bool f_has_global_palette;
+ uint8_t f_interlace;
+ bool f_seen_num_animation_loops_value;
+ uint32_t f_num_animation_loops_value;
+ 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;
+ uint8_t f_gc_disposal;
+ uint64_t f_gc_duration;
+ uint64_t f_frame_config_io_position;
+ uint64_t f_num_decoded_frame_configs_value;
+ uint64_t f_num_decoded_frames_value;
+ uint32_t f_frame_rect_x0;
+ uint32_t f_frame_rect_y0;
+ uint32_t f_frame_rect_x1;
+ uint32_t f_frame_rect_y1;
+ uint32_t f_dst_x;
+ uint32_t f_dst_y;
+ uint32_t f_dirty_max_excl_y;
+ uint64_t f_compressed_ri;
+ uint64_t f_compressed_wi;
+ wuffs_base__pixel_swizzler f_swizzler;
+ uint32_t f_lzw_pending_literal_width_plus_one;
+ uint32_t f_lzw_literal_width;
+ uint32_t f_lzw_clear_code;
+ uint32_t f_lzw_end_code;
+ uint32_t f_lzw_save_code;
+ uint32_t f_lzw_prev_code;
+ uint32_t f_lzw_width;
+ uint32_t f_lzw_bits;
+ uint32_t f_lzw_n_bits;
+ uint32_t f_lzw_output_ri;
+ uint32_t f_lzw_output_wi;
+ uint32_t f_lzw_read_from_return_value;
+ uint16_t f_lzw_prefixes[4096];
+
+ uint32_t p_decode_image_config[1];
+ uint32_t p_do_decode_image_config[1];
+ uint32_t p_tell_me_more[1];
+ uint32_t p_do_tell_me_more[1];
+ uint32_t p_decode_frame_config[1];
+ uint32_t p_do_decode_frame_config[1];
+ uint32_t p_skip_frame[1];
+ uint32_t p_decode_frame[1];
+ uint32_t p_do_decode_frame[1];
+ uint32_t p_decode_up_to_id_part1[1];
+ uint32_t p_decode_header[1];
+ uint32_t p_decode_lsd[1];
+ uint32_t p_decode_extension[1];
+ uint32_t p_skip_blocks[1];
+ uint32_t p_decode_ae[1];
+ uint32_t p_decode_gc[1];
+ uint32_t p_decode_id_part0[1];
+ uint32_t p_decode_id_part1[1];
+ uint32_t p_decode_id_part2[1];
+ } private_impl;
+
+ struct {
+ uint8_t f_compressed[4096];
+ uint8_t f_palettes[2][1024];
+ uint8_t f_dst_palette[1024];
+ uint8_t f_lzw_suffixes[4096][8];
+ uint16_t f_lzw_lm1s[4096];
+ uint8_t f_lzw_output[8199];
+
+ struct {
+ uint32_t v_background_color;
+ } s_do_decode_frame_config[1];
+ struct {
+ uint64_t scratch;
+ } s_skip_frame[1];
+ struct {
+ uint8_t v_c[6];
+ uint32_t v_i;
+ } s_decode_header[1];
+ struct {
+ uint8_t v_flags;
+ uint8_t v_background_color_index;
+ uint32_t v_num_palette_entries;
+ uint32_t v_i;
+ uint64_t scratch;
+ } s_decode_lsd[1];
+ struct {
+ uint64_t scratch;
+ } s_skip_blocks[1];
+ struct {
+ uint8_t v_block_size;
+ bool v_is_animexts;
+ bool v_is_netscape;
+ bool v_is_iccp;
+ bool v_is_xmp;
+ uint64_t scratch;
+ } s_decode_ae[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_gc[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_id_part0[1];
+ struct {
+ uint8_t v_which_palette;
+ uint32_t v_num_palette_entries;
+ uint32_t v_i;
+ uint64_t scratch;
+ } s_decode_id_part1[1];
+ struct {
+ uint64_t v_block_size;
+ bool v_need_block_size;
+ uint64_t scratch;
+ } s_decode_id_part2[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_gif__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_gif__decoder__alloc());
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_gif__decoder__alloc_as__wuffs_base__image_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_gif__decoder__struct() = delete;
+ wuffs_gif__decoder__struct(const wuffs_gif__decoder__struct&) = delete;
+ wuffs_gif__decoder__struct& operator=(
+ const wuffs_gif__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_gif__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__image_decoder*
+ upcast_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_gif__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_gif__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_gif__decoder__decode_image_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_gif__decoder__set_report_metadata(this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_gif__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_gif__decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_gif__decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_gif__decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_gif__decoder__frame_dirty_rect(this);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_gif__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_gif__decoder__workbuf_len(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_gif__decoder__restart_frame(this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_gif__decoder__decode_frame_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_gif__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_gif__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_gzip__error__bad_checksum[];
+extern const char wuffs_gzip__error__bad_compression_method[];
+extern const char wuffs_gzip__error__bad_encoding_flags[];
+extern const char wuffs_gzip__error__bad_header[];
+extern const char wuffs_gzip__error__truncated_input[];
+
+// ---------------- Public Consts
+
+#define WUFFS_GZIP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_GZIP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_gzip__decoder__struct wuffs_gzip__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_gzip__decoder__initialize(
+ wuffs_gzip__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_gzip__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_gzip__decoder*
+wuffs_gzip__decoder__alloc(void);
+
+static inline wuffs_base__io_transformer*
+wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer(void) {
+ return (wuffs_base__io_transformer*)(wuffs_gzip__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__io_transformer*
+wuffs_gzip__decoder__upcast_as__wuffs_base__io_transformer(
+ wuffs_gzip__decoder* p) {
+ return (wuffs_base__io_transformer*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gzip__decoder__get_quirk(
+ const wuffs_gzip__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_gzip__decoder__set_quirk(
+ wuffs_gzip__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gzip__decoder__history_retain_length(
+ const wuffs_gzip__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_gzip__decoder__workbuf_len(
+ const wuffs_gzip__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_gzip__decoder__transform_io(
+ wuffs_gzip__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_gzip__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
+ wuffs_base__vtable null_vtable;
+
+ bool f_ignore_checksum;
+
+ uint32_t p_transform_io[1];
+ uint32_t p_do_transform_io[1];
+ } private_impl;
+
+ struct {
+ wuffs_crc32__ieee_hasher f_checksum;
+ wuffs_deflate__decoder f_flate;
+
+ struct {
+ uint8_t v_flags;
+ uint32_t v_checksum_got;
+ uint32_t v_decoded_length_got;
+ uint32_t v_checksum_want;
+ uint64_t scratch;
+ } s_do_transform_io[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_gzip__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_gzip__decoder__alloc());
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_gzip__decoder__alloc_as__wuffs_base__io_transformer());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_gzip__decoder__struct() = delete;
+ wuffs_gzip__decoder__struct(const wuffs_gzip__decoder__struct&) = delete;
+ wuffs_gzip__decoder__struct& operator=(
+ const wuffs_gzip__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_gzip__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__io_transformer*
+ upcast_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_gzip__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_gzip__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_gzip__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_gzip__decoder__workbuf_len(this);
+ }
+
+ inline wuffs_base__status
+ transform_io(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_gzip__decoder__transform_io(this, a_dst, a_src, a_workbuf);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_gzip__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_jpeg__error__bad_dht_marker[];
+extern const char wuffs_jpeg__error__bad_dqt_marker[];
+extern const char wuffs_jpeg__error__bad_dri_marker[];
+extern const char wuffs_jpeg__error__bad_sof_marker[];
+extern const char wuffs_jpeg__error__bad_sos_marker[];
+extern const char wuffs_jpeg__error__bad_header[];
+extern const char wuffs_jpeg__error__bad_marker[];
+extern const char wuffs_jpeg__error__missing_huffman_table[];
+extern const char wuffs_jpeg__error__missing_quantization_table[];
+extern const char wuffs_jpeg__error__truncated_input[];
+extern const char wuffs_jpeg__error__unsupported_arithmetic_coding[];
+extern const char wuffs_jpeg__error__unsupported_color_model[];
+extern const char wuffs_jpeg__error__unsupported_fractional_sampling[];
+extern const char wuffs_jpeg__error__unsupported_hierarchical_coding[];
+extern const char wuffs_jpeg__error__unsupported_implicit_height[];
+extern const char wuffs_jpeg__error__unsupported_lossless_coding[];
+extern const char wuffs_jpeg__error__unsupported_marker[];
+extern const char wuffs_jpeg__error__unsupported_precision_12_bits[];
+extern const char wuffs_jpeg__error__unsupported_precision_16_bits[];
+extern const char wuffs_jpeg__error__unsupported_precision[];
+extern const char wuffs_jpeg__error__unsupported_scan_count[];
+
+// ---------------- Public Consts
+
+#define WUFFS_JPEG__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_JPEG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 51552191232
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_jpeg__decoder__struct wuffs_jpeg__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_jpeg__decoder__initialize(
+ wuffs_jpeg__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_jpeg__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_jpeg__decoder*
+wuffs_jpeg__decoder__alloc(void);
+
+static inline wuffs_base__image_decoder*
+wuffs_jpeg__decoder__alloc_as__wuffs_base__image_decoder(void) {
+ return (wuffs_base__image_decoder*)(wuffs_jpeg__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__image_decoder*
+wuffs_jpeg__decoder__upcast_as__wuffs_base__image_decoder(
+ wuffs_jpeg__decoder* p) {
+ return (wuffs_base__image_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_jpeg__decoder__get_quirk(
+ const wuffs_jpeg__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__set_quirk(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__decode_image_config(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__decode_frame_config(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__decode_frame(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_jpeg__decoder__frame_dirty_rect(
+ const wuffs_jpeg__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_jpeg__decoder__num_animation_loops(
+ const wuffs_jpeg__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_jpeg__decoder__num_decoded_frame_configs(
+ const wuffs_jpeg__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_jpeg__decoder__num_decoded_frames(
+ const wuffs_jpeg__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__restart_frame(
+ wuffs_jpeg__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_jpeg__decoder__set_report_metadata(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__tell_me_more(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_jpeg__decoder__history_retain_length(
+ const wuffs_jpeg__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_jpeg__decoder__workbuf_len(
+ const wuffs_jpeg__decoder* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_jpeg__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_width;
+ uint32_t f_height;
+ uint32_t f_width_in_mcus;
+ uint32_t f_height_in_mcus;
+ uint8_t f_call_sequence;
+ bool f_test_only_interrupt_decode_mcu;
+ bool f_is_jfif;
+ uint8_t f_is_adobe;
+ bool f_is_rgb_or_cmyk;
+ uint8_t f_sof_marker;
+ uint8_t f_next_restart_marker;
+ uint8_t f_max_incl_components_h;
+ uint8_t f_max_incl_components_v;
+ uint32_t f_num_components;
+ uint8_t f_components_c[4];
+ uint8_t f_components_h[4];
+ uint8_t f_components_v[4];
+ uint8_t f_components_tq[4];
+ uint32_t f_components_workbuf_widths[4];
+ uint32_t f_components_workbuf_heights[4];
+ uint64_t f_components_workbuf_offsets[9];
+ uint32_t f_scan_count;
+ uint32_t f_scan_num_components;
+ uint8_t f_scan_comps_cselector[4];
+ uint8_t f_scan_comps_td[4];
+ uint8_t f_scan_comps_ta[4];
+ uint8_t f_scan_ss;
+ uint8_t f_scan_se;
+ uint8_t f_scan_ah;
+ uint8_t f_scan_al;
+ uint32_t f_scan_width_in_mcus;
+ uint32_t f_scan_height_in_mcus;
+ uint8_t f_scan_comps_bx_offset[16];
+ uint8_t f_scan_comps_by_offset[16];
+ uint32_t f_mcu_num_blocks;
+ uint32_t f_mcu_current_block;
+ uint32_t f_mcu_zig_index;
+ uint8_t f_mcu_blocks_sselector[16];
+ uint64_t f_mcu_blocks_offset[10];
+ uint32_t f_mcu_blocks_mx_mul[10];
+ uint32_t f_mcu_blocks_my_mul[10];
+ uint8_t f_mcu_blocks_dc_hselector[10];
+ uint8_t f_mcu_blocks_ac_hselector[10];
+ uint16_t f_mcu_previous_dc_values[4];
+ uint8_t f_block_smoothing_lowest_scan_al[4][10];
+ uint16_t f_block_smoothing_dc_values[5][5];
+ uint32_t f_block_smoothing_mx_max_incl;
+ uint32_t f_block_smoothing_my_max_incl;
+ uint16_t f_restart_interval;
+ uint16_t f_saved_restart_interval;
+ uint16_t f_restarts_remaining;
+ uint16_t f_eob_run;
+ uint64_t f_frame_config_io_position;
+ uint32_t f_payload_length;
+ bool f_seen_dqt[4];
+ bool f_saved_seen_dqt[4];
+ bool f_seen_dht[8];
+ uint64_t f_bitstream_bits;
+ uint32_t f_bitstream_n_bits;
+ uint32_t f_bitstream_ri;
+ uint32_t f_bitstream_wi;
+ bool f_bitstream_is_closed;
+ uint32_t f_bitstream_padding;
+ uint16_t f_quant_tables[4][64];
+ uint16_t f_saved_quant_tables[4][64];
+ uint8_t f_huff_tables_symbols[8][256];
+ uint32_t f_huff_tables_slow[8][16];
+ uint16_t f_huff_tables_fast[8][256];
+ wuffs_base__pixel_swizzler f_swizzler;
+
+ wuffs_base__empty_struct (*choosy_decode_idct)(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_dst_buffer,
+ uint64_t a_dst_stride,
+ uint32_t a_q);
+ uint32_t p_decode_image_config[1];
+ uint32_t p_do_decode_image_config[1];
+ uint32_t p_decode_dqt[1];
+ uint32_t p_decode_dri[1];
+ uint32_t p_decode_appn[1];
+ uint32_t p_decode_sof[1];
+ uint32_t p_decode_frame_config[1];
+ uint32_t p_do_decode_frame_config[1];
+ uint32_t p_decode_frame[1];
+ uint32_t p_do_decode_frame[1];
+ uint32_t p_decode_dht[1];
+ uint32_t p_decode_sos[1];
+ uint32_t p_prepare_scan[1];
+ wuffs_base__empty_struct (*choosy_load_mcu_blocks_for_single_component)(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_csel);
+ uint32_t p_skip_past_the_next_restart_marker[1];
+ uint32_t (*choosy_decode_mcu)(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my);
+ } private_impl;
+
+ struct {
+ uint8_t f_bitstream_buffer[2048];
+ uint16_t f_mcu_blocks[10][64];
+ uint8_t f_swizzle_ycck_scratch_buffer_2k[2048];
+ uint8_t f_dht_temp_counts[16];
+ uint8_t f_dht_temp_bit_lengths[256];
+ uint16_t f_dht_temp_bit_strings[256];
+ uint8_t f_dst_palette[1024];
+
+ struct {
+ uint8_t v_marker;
+ uint64_t scratch;
+ } s_do_decode_image_config[1];
+ struct {
+ uint8_t v_q;
+ uint32_t v_i;
+ } s_decode_dqt[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_dri[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_appn[1];
+ struct {
+ uint32_t v_i;
+ uint64_t scratch;
+ } s_decode_sof[1];
+ struct {
+ uint8_t v_marker;
+ uint64_t scratch;
+ } s_do_decode_frame[1];
+ struct {
+ uint8_t v_tc4_th;
+ uint32_t v_total_count;
+ uint32_t v_i;
+ } s_decode_dht[1];
+ struct {
+ uint32_t v_my;
+ uint32_t v_mx;
+ } s_decode_sos[1];
+ struct {
+ uint32_t v_i;
+ uint64_t scratch;
+ } s_prepare_scan[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_jpeg__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_jpeg__decoder__alloc());
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_jpeg__decoder__alloc_as__wuffs_base__image_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_jpeg__decoder__struct() = delete;
+ wuffs_jpeg__decoder__struct(const wuffs_jpeg__decoder__struct&) = delete;
+ wuffs_jpeg__decoder__struct& operator=(
+ const wuffs_jpeg__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_jpeg__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__image_decoder*
+ upcast_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_jpeg__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_jpeg__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_jpeg__decoder__decode_image_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_jpeg__decoder__decode_frame_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_jpeg__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_jpeg__decoder__frame_dirty_rect(this);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_jpeg__decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_jpeg__decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_jpeg__decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_jpeg__decoder__restart_frame(this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_jpeg__decoder__set_report_metadata(this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_jpeg__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_jpeg__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_jpeg__decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_jpeg__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_json__error__bad_c0_control_code[];
+extern const char wuffs_json__error__bad_utf_8[];
+extern const char wuffs_json__error__bad_backslash_escape[];
+extern const char wuffs_json__error__bad_input[];
+extern const char wuffs_json__error__bad_new_line_in_a_string[];
+extern const char wuffs_json__error__bad_quirk_combination[];
+extern const char wuffs_json__error__unsupported_number_length[];
+extern const char wuffs_json__error__unsupported_recursion_depth[];
+
+// ---------------- Public Consts
+
+#define WUFFS_JSON__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_JSON__DECODER_DEPTH_MAX_INCL 1024
+
+#define WUFFS_JSON__DECODER_DST_TOKEN_BUFFER_LENGTH_MIN_INCL 1
+
+#define WUFFS_JSON__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 100
+
+#define WUFFS_JSON__QUIRK_ALLOW_ASCII_CONTROL_CODES 1225364480
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_A 1225364481
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_CAPITAL_U 1225364482
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_E 1225364483
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_NEW_LINE 1225364484
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_QUESTION_MARK 1225364485
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_SINGLE_QUOTE 1225364486
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_V 1225364487
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_X_AS_CODE_POINTS 1225364489
+
+#define WUFFS_JSON__QUIRK_ALLOW_BACKSLASH_ZERO 1225364490
+
+#define WUFFS_JSON__QUIRK_ALLOW_COMMENT_BLOCK 1225364491
+
+#define WUFFS_JSON__QUIRK_ALLOW_COMMENT_LINE 1225364492
+
+#define WUFFS_JSON__QUIRK_ALLOW_EXTRA_COMMA 1225364493
+
+#define WUFFS_JSON__QUIRK_ALLOW_INF_NAN_NUMBERS 1225364494
+
+#define WUFFS_JSON__QUIRK_ALLOW_LEADING_ASCII_RECORD_SEPARATOR 1225364495
+
+#define WUFFS_JSON__QUIRK_ALLOW_LEADING_UNICODE_BYTE_ORDER_MARK 1225364496
+
+#define WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER 1225364497
+
+#define WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF 1225364498
+
+#define WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T 1225364499
+
+#define WUFFS_JSON__QUIRK_REPLACE_INVALID_UNICODE 1225364500
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_json__decoder__struct wuffs_json__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_json__decoder__initialize(
+ wuffs_json__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_json__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_json__decoder*
+wuffs_json__decoder__alloc(void);
+
+static inline wuffs_base__token_decoder*
+wuffs_json__decoder__alloc_as__wuffs_base__token_decoder(void) {
+ return (wuffs_base__token_decoder*)(wuffs_json__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__token_decoder*
+wuffs_json__decoder__upcast_as__wuffs_base__token_decoder(
+ wuffs_json__decoder* p) {
+ return (wuffs_base__token_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_json__decoder__get_quirk(
+ const wuffs_json__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_json__decoder__set_quirk(
+ wuffs_json__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_json__decoder__history_retain_length(
+ const wuffs_json__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_json__decoder__workbuf_len(
+ const wuffs_json__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_json__decoder__decode_tokens(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_json__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__token_decoder;
+ wuffs_base__vtable null_vtable;
+
+ bool f_quirks[21];
+ bool f_allow_leading_ars;
+ bool f_allow_leading_ubom;
+ bool f_end_of_data;
+ uint8_t f_trailer_stop;
+ uint8_t f_comment_type;
+
+ uint32_t p_decode_tokens[1];
+ uint32_t p_decode_leading[1];
+ uint32_t p_decode_comment[1];
+ uint32_t p_decode_inf_nan[1];
+ uint32_t p_decode_trailer[1];
+ } private_impl;
+
+ struct {
+ uint32_t f_stack[32];
+
+ struct {
+ uint32_t v_depth;
+ uint32_t v_expect;
+ uint32_t v_expect_after_value;
+ } s_decode_tokens[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_json__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_json__decoder__alloc());
+ }
+
+ static inline wuffs_base__token_decoder::unique_ptr
+ alloc_as__wuffs_base__token_decoder() {
+ return wuffs_base__token_decoder::unique_ptr(
+ wuffs_json__decoder__alloc_as__wuffs_base__token_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_json__decoder__struct() = delete;
+ wuffs_json__decoder__struct(const wuffs_json__decoder__struct&) = delete;
+ wuffs_json__decoder__struct& operator=(
+ const wuffs_json__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_json__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__token_decoder*
+ upcast_as__wuffs_base__token_decoder() {
+ return (wuffs_base__token_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_json__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_json__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_json__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_json__decoder__workbuf_len(this);
+ }
+
+ inline wuffs_base__status
+ decode_tokens(
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_json__decoder__decode_tokens(this, a_dst, a_src, a_workbuf);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_json__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_lzw__error__bad_code[];
+extern const char wuffs_lzw__error__truncated_input[];
+
+// ---------------- Public Consts
+
+#define WUFFS_LZW__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_LZW__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_LZW__QUIRK_LITERAL_WIDTH_PLUS_ONE 1348378624
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_lzw__decoder__struct wuffs_lzw__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+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 options);
+
+size_t
+sizeof__wuffs_lzw__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_lzw__decoder*
+wuffs_lzw__decoder__alloc(void);
+
+static inline wuffs_base__io_transformer*
+wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer(void) {
+ return (wuffs_base__io_transformer*)(wuffs_lzw__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__io_transformer*
+wuffs_lzw__decoder__upcast_as__wuffs_base__io_transformer(
+ wuffs_lzw__decoder* p) {
+ return (wuffs_base__io_transformer*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_lzw__decoder__get_quirk(
+ const wuffs_lzw__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_lzw__decoder__set_quirk(
+ wuffs_lzw__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_lzw__decoder__history_retain_length(
+ const wuffs_lzw__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_lzw__decoder__workbuf_len(
+ const wuffs_lzw__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_lzw__decoder__transform_io(
+ wuffs_lzw__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
+wuffs_lzw__decoder__flush(
+ wuffs_lzw__decoder* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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 {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_pending_literal_width_plus_one;
+ 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_transform_io[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;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_lzw__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_lzw__decoder__alloc());
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_lzw__decoder__alloc_as__wuffs_base__io_transformer());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_lzw__decoder__struct() = delete;
+ wuffs_lzw__decoder__struct(const wuffs_lzw__decoder__struct&) = delete;
+ wuffs_lzw__decoder__struct& operator=(
+ const wuffs_lzw__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_lzw__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__io_transformer*
+ upcast_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_lzw__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_lzw__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_lzw__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_lzw__decoder__workbuf_len(this);
+ }
+
+ inline wuffs_base__status
+ transform_io(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_lzw__decoder__transform_io(this, a_dst, a_src, a_workbuf);
+ }
+
+ inline wuffs_base__slice_u8
+ flush() {
+ return wuffs_lzw__decoder__flush(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_lzw__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_netpbm__error__bad_header[];
+extern const char wuffs_netpbm__error__truncated_input[];
+extern const char wuffs_netpbm__error__unsupported_netpbm_file[];
+
+// ---------------- Public Consts
+
+#define WUFFS_NETPBM__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_NETPBM__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_netpbm__decoder__struct wuffs_netpbm__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_netpbm__decoder__initialize(
+ wuffs_netpbm__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_netpbm__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_netpbm__decoder*
+wuffs_netpbm__decoder__alloc(void);
+
+static inline wuffs_base__image_decoder*
+wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder(void) {
+ return (wuffs_base__image_decoder*)(wuffs_netpbm__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__image_decoder*
+wuffs_netpbm__decoder__upcast_as__wuffs_base__image_decoder(
+ wuffs_netpbm__decoder* p) {
+ return (wuffs_base__image_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_netpbm__decoder__get_quirk(
+ const wuffs_netpbm__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__set_quirk(
+ wuffs_netpbm__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__decode_image_config(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__decode_frame_config(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__decode_frame(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_netpbm__decoder__frame_dirty_rect(
+ const wuffs_netpbm__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_netpbm__decoder__num_animation_loops(
+ const wuffs_netpbm__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_netpbm__decoder__num_decoded_frame_configs(
+ const wuffs_netpbm__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_netpbm__decoder__num_decoded_frames(
+ const wuffs_netpbm__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__restart_frame(
+ wuffs_netpbm__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_netpbm__decoder__set_report_metadata(
+ wuffs_netpbm__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__tell_me_more(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_netpbm__decoder__history_retain_length(
+ const wuffs_netpbm__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_netpbm__decoder__workbuf_len(
+ const wuffs_netpbm__decoder* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_netpbm__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_pixfmt;
+ uint32_t f_width;
+ uint32_t f_height;
+ uint32_t f_max_value;
+ uint8_t f_call_sequence;
+ uint64_t f_frame_config_io_position;
+ uint32_t f_dst_x;
+ uint32_t f_dst_y;
+ wuffs_base__pixel_swizzler f_swizzler;
+
+ uint32_t p_decode_image_config[1];
+ uint32_t p_do_decode_image_config[1];
+ uint32_t p_decode_frame_config[1];
+ uint32_t p_do_decode_frame_config[1];
+ uint32_t p_decode_frame[1];
+ uint32_t p_do_decode_frame[1];
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_netpbm__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_netpbm__decoder__alloc());
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_netpbm__decoder__alloc_as__wuffs_base__image_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_netpbm__decoder__struct() = delete;
+ wuffs_netpbm__decoder__struct(const wuffs_netpbm__decoder__struct&) = delete;
+ wuffs_netpbm__decoder__struct& operator=(
+ const wuffs_netpbm__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_netpbm__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__image_decoder*
+ upcast_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_netpbm__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_netpbm__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_netpbm__decoder__decode_image_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_netpbm__decoder__decode_frame_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_netpbm__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_netpbm__decoder__frame_dirty_rect(this);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_netpbm__decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_netpbm__decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_netpbm__decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_netpbm__decoder__restart_frame(this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_netpbm__decoder__set_report_metadata(this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_netpbm__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_netpbm__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_netpbm__decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_netpbm__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_nie__error__bad_header[];
+extern const char wuffs_nie__error__truncated_input[];
+extern const char wuffs_nie__error__unsupported_nie_file[];
+
+// ---------------- Public Consts
+
+#define WUFFS_NIE__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_NIE__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_nie__decoder__struct wuffs_nie__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_nie__decoder__initialize(
+ wuffs_nie__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_nie__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_nie__decoder*
+wuffs_nie__decoder__alloc(void);
+
+static inline wuffs_base__image_decoder*
+wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder(void) {
+ return (wuffs_base__image_decoder*)(wuffs_nie__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__image_decoder*
+wuffs_nie__decoder__upcast_as__wuffs_base__image_decoder(
+ wuffs_nie__decoder* p) {
+ return (wuffs_base__image_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_nie__decoder__get_quirk(
+ const wuffs_nie__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__set_quirk(
+ wuffs_nie__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__decode_image_config(
+ wuffs_nie__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__decode_frame_config(
+ wuffs_nie__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__decode_frame(
+ wuffs_nie__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_nie__decoder__frame_dirty_rect(
+ const wuffs_nie__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_nie__decoder__num_animation_loops(
+ const wuffs_nie__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_nie__decoder__num_decoded_frame_configs(
+ const wuffs_nie__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_nie__decoder__num_decoded_frames(
+ const wuffs_nie__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__restart_frame(
+ wuffs_nie__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_nie__decoder__set_report_metadata(
+ wuffs_nie__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__tell_me_more(
+ wuffs_nie__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_nie__decoder__history_retain_length(
+ const wuffs_nie__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_nie__decoder__workbuf_len(
+ const wuffs_nie__decoder* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_nie__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_pixfmt;
+ uint32_t f_width;
+ uint32_t f_height;
+ uint8_t f_call_sequence;
+ uint32_t f_dst_x;
+ uint32_t f_dst_y;
+ wuffs_base__pixel_swizzler f_swizzler;
+
+ uint32_t p_decode_image_config[1];
+ uint32_t p_do_decode_image_config[1];
+ uint32_t p_decode_frame_config[1];
+ uint32_t p_do_decode_frame_config[1];
+ uint32_t p_decode_frame[1];
+ uint32_t p_do_decode_frame[1];
+ } private_impl;
+
+ struct {
+ struct {
+ uint64_t scratch;
+ } s_do_decode_image_config[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_nie__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_nie__decoder__alloc());
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_nie__decoder__alloc_as__wuffs_base__image_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_nie__decoder__struct() = delete;
+ wuffs_nie__decoder__struct(const wuffs_nie__decoder__struct&) = delete;
+ wuffs_nie__decoder__struct& operator=(
+ const wuffs_nie__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_nie__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__image_decoder*
+ upcast_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_nie__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_nie__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_nie__decoder__decode_image_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_nie__decoder__decode_frame_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_nie__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_nie__decoder__frame_dirty_rect(this);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_nie__decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_nie__decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_nie__decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_nie__decoder__restart_frame(this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_nie__decoder__set_report_metadata(this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_nie__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_nie__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_nie__decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_nie__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_zlib__note__dictionary_required[];
+extern const char wuffs_zlib__error__bad_checksum[];
+extern const char wuffs_zlib__error__bad_compression_method[];
+extern const char wuffs_zlib__error__bad_compression_window_size[];
+extern const char wuffs_zlib__error__bad_parity_check[];
+extern const char wuffs_zlib__error__incorrect_dictionary[];
+extern const char wuffs_zlib__error__truncated_input[];
+
+// ---------------- Public Consts
+
+#define WUFFS_ZLIB__QUIRK_JUST_RAW_DEFLATE 2113790976
+
+#define WUFFS_ZLIB__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_ZLIB__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 1
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_zlib__decoder__struct wuffs_zlib__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_zlib__decoder__initialize(
+ wuffs_zlib__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_zlib__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_zlib__decoder*
+wuffs_zlib__decoder__alloc(void);
+
+static inline wuffs_base__io_transformer*
+wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer(void) {
+ return (wuffs_base__io_transformer*)(wuffs_zlib__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__io_transformer*
+wuffs_zlib__decoder__upcast_as__wuffs_base__io_transformer(
+ wuffs_zlib__decoder* p) {
+ return (wuffs_base__io_transformer*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_zlib__decoder__dictionary_id(
+ const wuffs_zlib__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_zlib__decoder__add_dictionary(
+ wuffs_zlib__decoder* self,
+ wuffs_base__slice_u8 a_dict);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_zlib__decoder__get_quirk(
+ const wuffs_zlib__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_zlib__decoder__set_quirk(
+ wuffs_zlib__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_zlib__decoder__history_retain_length(
+ const wuffs_zlib__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_zlib__decoder__workbuf_len(
+ const wuffs_zlib__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_zlib__decoder__transform_io(
+ wuffs_zlib__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_zlib__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__io_transformer;
+ wuffs_base__vtable null_vtable;
+
+ bool f_bad_call_sequence;
+ bool f_header_complete;
+ bool f_got_dictionary;
+ bool f_want_dictionary;
+ bool f_quirks[1];
+ bool f_ignore_checksum;
+ uint32_t f_dict_id_got;
+ uint32_t f_dict_id_want;
+
+ uint32_t p_transform_io[1];
+ uint32_t p_do_transform_io[1];
+ } private_impl;
+
+ struct {
+ wuffs_adler32__hasher f_checksum;
+ wuffs_adler32__hasher f_dict_id_hasher;
+ wuffs_deflate__decoder f_flate;
+
+ struct {
+ uint32_t v_checksum_got;
+ uint64_t scratch;
+ } s_do_transform_io[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_zlib__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_zlib__decoder__alloc());
+ }
+
+ static inline wuffs_base__io_transformer::unique_ptr
+ alloc_as__wuffs_base__io_transformer() {
+ return wuffs_base__io_transformer::unique_ptr(
+ wuffs_zlib__decoder__alloc_as__wuffs_base__io_transformer());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_zlib__decoder__struct() = delete;
+ wuffs_zlib__decoder__struct(const wuffs_zlib__decoder__struct&) = delete;
+ wuffs_zlib__decoder__struct& operator=(
+ const wuffs_zlib__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_zlib__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__io_transformer*
+ upcast_as__wuffs_base__io_transformer() {
+ return (wuffs_base__io_transformer*)this;
+ }
+
+ inline uint32_t
+ dictionary_id() const {
+ return wuffs_zlib__decoder__dictionary_id(this);
+ }
+
+ inline wuffs_base__empty_struct
+ add_dictionary(
+ wuffs_base__slice_u8 a_dict) {
+ return wuffs_zlib__decoder__add_dictionary(this, a_dict);
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_zlib__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_zlib__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_zlib__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_zlib__decoder__workbuf_len(this);
+ }
+
+ inline wuffs_base__status
+ transform_io(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ return wuffs_zlib__decoder__transform_io(this, a_dst, a_src, a_workbuf);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_zlib__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_png__error__bad_animation_sequence_number[];
+extern const char wuffs_png__error__bad_checksum[];
+extern const char wuffs_png__error__bad_chunk[];
+extern const char wuffs_png__error__bad_filter[];
+extern const char wuffs_png__error__bad_header[];
+extern const char wuffs_png__error__bad_text_chunk_not_latin_1[];
+extern const char wuffs_png__error__missing_palette[];
+extern const char wuffs_png__error__truncated_input[];
+extern const char wuffs_png__error__unsupported_cgbi_extension[];
+extern const char wuffs_png__error__unsupported_png_compression_method[];
+extern const char wuffs_png__error__unsupported_png_file[];
+
+// ---------------- Public Consts
+
+#define WUFFS_PNG__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_PNG__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 2251799562027015
+
+#define WUFFS_PNG__DECODER_SRC_IO_BUFFER_LENGTH_MIN_INCL 8
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_png__decoder__struct wuffs_png__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_png__decoder__initialize(
+ wuffs_png__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_png__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_png__decoder*
+wuffs_png__decoder__alloc(void);
+
+static inline wuffs_base__image_decoder*
+wuffs_png__decoder__alloc_as__wuffs_base__image_decoder(void) {
+ return (wuffs_base__image_decoder*)(wuffs_png__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__image_decoder*
+wuffs_png__decoder__upcast_as__wuffs_base__image_decoder(
+ wuffs_png__decoder* p) {
+ return (wuffs_base__image_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_png__decoder__get_quirk(
+ const wuffs_png__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__set_quirk(
+ wuffs_png__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__decode_image_config(
+ wuffs_png__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__decode_frame_config(
+ wuffs_png__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__decode_frame(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_png__decoder__frame_dirty_rect(
+ const wuffs_png__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_png__decoder__num_animation_loops(
+ const wuffs_png__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_png__decoder__num_decoded_frame_configs(
+ const wuffs_png__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_png__decoder__num_decoded_frames(
+ const wuffs_png__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__restart_frame(
+ wuffs_png__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_png__decoder__set_report_metadata(
+ wuffs_png__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__tell_me_more(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_png__decoder__history_retain_length(
+ const wuffs_png__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_png__decoder__workbuf_len(
+ const wuffs_png__decoder* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_png__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_width;
+ uint32_t f_height;
+ uint64_t f_pass_bytes_per_row;
+ uint64_t f_workbuf_wi;
+ uint64_t f_workbuf_hist_pos_base;
+ uint64_t f_overall_workbuf_length;
+ uint64_t f_pass_workbuf_length;
+ uint8_t f_call_sequence;
+ bool f_report_metadata_chrm;
+ bool f_report_metadata_exif;
+ bool f_report_metadata_gama;
+ bool f_report_metadata_iccp;
+ bool f_report_metadata_kvp;
+ bool f_report_metadata_srgb;
+ bool f_ignore_checksum;
+ uint8_t f_depth;
+ uint8_t f_color_type;
+ uint8_t f_filter_distance;
+ uint8_t f_interlace_pass;
+ bool f_seen_actl;
+ bool f_seen_chrm;
+ bool f_seen_fctl;
+ bool f_seen_exif;
+ bool f_seen_gama;
+ bool f_seen_iccp;
+ bool f_seen_idat;
+ bool f_seen_ihdr;
+ bool f_seen_plte;
+ bool f_seen_srgb;
+ bool f_seen_trns;
+ bool f_metadata_is_zlib_compressed;
+ bool f_zlib_is_dirty;
+ uint32_t f_chunk_type;
+ uint8_t f_chunk_type_array[4];
+ uint32_t f_chunk_length;
+ uint64_t f_remap_transparency;
+ uint32_t f_dst_pixfmt;
+ uint32_t f_src_pixfmt;
+ uint32_t f_num_animation_frames_value;
+ uint32_t f_num_animation_loops_value;
+ uint32_t f_num_decoded_frame_configs_value;
+ uint32_t f_num_decoded_frames_value;
+ uint32_t f_frame_rect_x0;
+ uint32_t f_frame_rect_y0;
+ uint32_t f_frame_rect_x1;
+ uint32_t f_frame_rect_y1;
+ uint32_t f_first_rect_x0;
+ uint32_t f_first_rect_y0;
+ uint32_t f_first_rect_x1;
+ uint32_t f_first_rect_y1;
+ uint64_t f_frame_config_io_position;
+ uint64_t f_first_config_io_position;
+ uint64_t f_frame_duration;
+ uint64_t f_first_duration;
+ uint8_t f_frame_disposal;
+ uint8_t f_first_disposal;
+ bool f_frame_overwrite_instead_of_blend;
+ bool f_first_overwrite_instead_of_blend;
+ uint32_t f_next_animation_seq_num;
+ uint32_t f_metadata_flavor;
+ uint32_t f_metadata_fourcc;
+ uint64_t f_metadata_x;
+ uint64_t f_metadata_y;
+ uint64_t f_metadata_z;
+ uint32_t f_ztxt_ri;
+ uint32_t f_ztxt_wi;
+ uint64_t f_ztxt_hist_pos;
+ wuffs_base__pixel_swizzler f_swizzler;
+
+ wuffs_base__empty_struct (*choosy_filter_1)(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr);
+ wuffs_base__empty_struct (*choosy_filter_3)(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+ wuffs_base__empty_struct (*choosy_filter_4)(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+ uint32_t p_decode_image_config[1];
+ uint32_t p_do_decode_image_config[1];
+ uint32_t p_decode_ihdr[1];
+ uint32_t p_decode_other_chunk[1];
+ uint32_t p_decode_actl[1];
+ uint32_t p_decode_chrm[1];
+ uint32_t p_decode_fctl[1];
+ uint32_t p_decode_gama[1];
+ uint32_t p_decode_iccp[1];
+ uint32_t p_decode_plte[1];
+ uint32_t p_decode_srgb[1];
+ uint32_t p_decode_trns[1];
+ uint32_t p_decode_frame_config[1];
+ uint32_t p_do_decode_frame_config[1];
+ uint32_t p_skip_frame[1];
+ uint32_t p_decode_frame[1];
+ uint32_t p_do_decode_frame[1];
+ uint32_t p_decode_pass[1];
+ uint32_t p_tell_me_more[1];
+ uint32_t p_do_tell_me_more[1];
+ wuffs_base__status (*choosy_filter_and_swizzle)(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf);
+ } private_impl;
+
+ struct {
+ wuffs_crc32__ieee_hasher f_crc32;
+ wuffs_zlib__decoder f_zlib;
+ uint8_t f_dst_palette[1024];
+ uint8_t f_src_palette[1024];
+
+ struct {
+ uint32_t v_checksum_have;
+ uint64_t scratch;
+ } s_do_decode_image_config[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_ihdr[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_other_chunk[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_actl[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_chrm[1];
+ struct {
+ uint32_t v_x0;
+ uint32_t v_x1;
+ uint32_t v_y1;
+ uint64_t scratch;
+ } s_decode_fctl[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_gama[1];
+ struct {
+ uint32_t v_num_entries;
+ uint32_t v_i;
+ uint64_t scratch;
+ } s_decode_plte[1];
+ struct {
+ uint32_t v_i;
+ uint32_t v_n;
+ uint64_t scratch;
+ } s_decode_trns[1];
+ struct {
+ uint64_t scratch;
+ } s_do_decode_frame_config[1];
+ struct {
+ uint64_t scratch;
+ } s_skip_frame[1];
+ struct {
+ uint64_t scratch;
+ } s_do_decode_frame[1];
+ struct {
+ uint64_t scratch;
+ } s_decode_pass[1];
+ struct {
+ wuffs_base__status v_zlib_status;
+ uint64_t scratch;
+ } s_do_tell_me_more[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_png__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_png__decoder__alloc());
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_png__decoder__alloc_as__wuffs_base__image_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_png__decoder__struct() = delete;
+ wuffs_png__decoder__struct(const wuffs_png__decoder__struct&) = delete;
+ wuffs_png__decoder__struct& operator=(
+ const wuffs_png__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_png__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__image_decoder*
+ upcast_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_png__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_png__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_png__decoder__decode_image_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_png__decoder__decode_frame_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_png__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_png__decoder__frame_dirty_rect(this);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_png__decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_png__decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_png__decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_png__decoder__restart_frame(this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_png__decoder__set_report_metadata(this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_png__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_png__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_png__decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_png__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_tga__error__bad_header[];
+extern const char wuffs_tga__error__bad_run_length_encoding[];
+extern const char wuffs_tga__error__truncated_input[];
+extern const char wuffs_tga__error__unsupported_tga_file[];
+
+// ---------------- Public Consts
+
+#define WUFFS_TGA__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_TGA__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_tga__decoder__struct wuffs_tga__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_tga__decoder__initialize(
+ wuffs_tga__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_tga__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_tga__decoder*
+wuffs_tga__decoder__alloc(void);
+
+static inline wuffs_base__image_decoder*
+wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder(void) {
+ return (wuffs_base__image_decoder*)(wuffs_tga__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__image_decoder*
+wuffs_tga__decoder__upcast_as__wuffs_base__image_decoder(
+ wuffs_tga__decoder* p) {
+ return (wuffs_base__image_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_tga__decoder__get_quirk(
+ const wuffs_tga__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__set_quirk(
+ wuffs_tga__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__decode_image_config(
+ wuffs_tga__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__decode_frame_config(
+ wuffs_tga__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__decode_frame(
+ wuffs_tga__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_tga__decoder__frame_dirty_rect(
+ const wuffs_tga__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_tga__decoder__num_animation_loops(
+ const wuffs_tga__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_tga__decoder__num_decoded_frame_configs(
+ const wuffs_tga__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_tga__decoder__num_decoded_frames(
+ const wuffs_tga__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__restart_frame(
+ wuffs_tga__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_tga__decoder__set_report_metadata(
+ wuffs_tga__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__tell_me_more(
+ wuffs_tga__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_tga__decoder__history_retain_length(
+ const wuffs_tga__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_tga__decoder__workbuf_len(
+ const wuffs_tga__decoder* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_tga__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_width;
+ uint32_t f_height;
+ uint8_t f_call_sequence;
+ uint8_t f_header_id_length;
+ uint8_t f_header_color_map_type;
+ uint8_t f_header_image_type;
+ uint16_t f_header_color_map_first_entry_index;
+ uint16_t f_header_color_map_length;
+ uint8_t f_header_color_map_entry_size;
+ uint8_t f_header_pixel_depth;
+ uint8_t f_header_image_descriptor;
+ bool f_opaque;
+ uint32_t f_scratch_bytes_per_pixel;
+ uint32_t f_src_bytes_per_pixel;
+ uint32_t f_src_pixfmt;
+ uint64_t f_frame_config_io_position;
+ wuffs_base__pixel_swizzler f_swizzler;
+
+ uint32_t p_decode_image_config[1];
+ uint32_t p_do_decode_image_config[1];
+ uint32_t p_decode_frame_config[1];
+ uint32_t p_do_decode_frame_config[1];
+ uint32_t p_decode_frame[1];
+ uint32_t p_do_decode_frame[1];
+ } private_impl;
+
+ struct {
+ uint8_t f_dst_palette[1024];
+ uint8_t f_src_palette[1024];
+ uint8_t f_scratch[4];
+
+ struct {
+ uint32_t v_i;
+ uint64_t scratch;
+ } s_do_decode_image_config[1];
+ struct {
+ uint64_t v_dst_bytes_per_pixel;
+ uint32_t v_dst_x;
+ uint32_t v_dst_y;
+ uint64_t v_mark;
+ uint32_t v_num_pixels32;
+ uint32_t v_lit_length;
+ uint32_t v_run_length;
+ uint64_t v_num_dst_bytes;
+ uint64_t scratch;
+ } s_do_decode_frame[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_tga__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_tga__decoder__alloc());
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_tga__decoder__alloc_as__wuffs_base__image_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_tga__decoder__struct() = delete;
+ wuffs_tga__decoder__struct(const wuffs_tga__decoder__struct&) = delete;
+ wuffs_tga__decoder__struct& operator=(
+ const wuffs_tga__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_tga__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__image_decoder*
+ upcast_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_tga__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_tga__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_tga__decoder__decode_image_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_tga__decoder__decode_frame_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_tga__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_tga__decoder__frame_dirty_rect(this);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_tga__decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_tga__decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_tga__decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_tga__decoder__restart_frame(this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_tga__decoder__set_report_metadata(this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_tga__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_tga__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_tga__decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_tga__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+extern const char wuffs_wbmp__error__bad_header[];
+extern const char wuffs_wbmp__error__truncated_input[];
+
+// ---------------- Public Consts
+
+#define WUFFS_WBMP__DECODER_HISTORY_RETAIN_LENGTH_MAX_INCL_WORST_CASE 0
+
+#define WUFFS_WBMP__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE 0
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_wbmp__decoder__struct wuffs_wbmp__decoder;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_wbmp__decoder__initialize(
+ wuffs_wbmp__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_wbmp__decoder(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_wbmp__decoder*
+wuffs_wbmp__decoder__alloc(void);
+
+static inline wuffs_base__image_decoder*
+wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder(void) {
+ return (wuffs_base__image_decoder*)(wuffs_wbmp__decoder__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__image_decoder*
+wuffs_wbmp__decoder__upcast_as__wuffs_base__image_decoder(
+ wuffs_wbmp__decoder* p) {
+ return (wuffs_base__image_decoder*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_wbmp__decoder__get_quirk(
+ const wuffs_wbmp__decoder* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__set_quirk(
+ wuffs_wbmp__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__decode_image_config(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__decode_frame_config(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__decode_frame(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_wbmp__decoder__frame_dirty_rect(
+ const wuffs_wbmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_wbmp__decoder__num_animation_loops(
+ const wuffs_wbmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_wbmp__decoder__num_decoded_frame_configs(
+ const wuffs_wbmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_wbmp__decoder__num_decoded_frames(
+ const wuffs_wbmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__restart_frame(
+ wuffs_wbmp__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_wbmp__decoder__set_report_metadata(
+ wuffs_wbmp__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__tell_me_more(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_wbmp__decoder__history_retain_length(
+ const wuffs_wbmp__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_wbmp__decoder__workbuf_len(
+ const wuffs_wbmp__decoder* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_wbmp__decoder__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__image_decoder;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_width;
+ uint32_t f_height;
+ uint8_t f_call_sequence;
+ uint64_t f_frame_config_io_position;
+ wuffs_base__pixel_swizzler f_swizzler;
+
+ uint32_t p_decode_image_config[1];
+ uint32_t p_do_decode_image_config[1];
+ uint32_t p_decode_frame_config[1];
+ uint32_t p_do_decode_frame_config[1];
+ uint32_t p_decode_frame[1];
+ uint32_t p_do_decode_frame[1];
+ } private_impl;
+
+ struct {
+ struct {
+ uint32_t v_i;
+ uint32_t v_p;
+ } s_do_decode_image_config[1];
+ struct {
+ uint64_t v_dst_bytes_per_pixel;
+ uint32_t v_dst_x;
+ uint32_t v_dst_y;
+ uint8_t v_src[1];
+ uint8_t v_c;
+ } s_do_decode_frame[1];
+ } private_data;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_wbmp__decoder, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_wbmp__decoder__alloc());
+ }
+
+ static inline wuffs_base__image_decoder::unique_ptr
+ alloc_as__wuffs_base__image_decoder() {
+ return wuffs_base__image_decoder::unique_ptr(
+ wuffs_wbmp__decoder__alloc_as__wuffs_base__image_decoder());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_wbmp__decoder__struct() = delete;
+ wuffs_wbmp__decoder__struct(const wuffs_wbmp__decoder__struct&) = delete;
+ wuffs_wbmp__decoder__struct& operator=(
+ const wuffs_wbmp__decoder__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_wbmp__decoder__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__image_decoder*
+ upcast_as__wuffs_base__image_decoder() {
+ return (wuffs_base__image_decoder*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_wbmp__decoder__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_wbmp__decoder__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__status
+ decode_image_config(
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_wbmp__decoder__decode_image_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame_config(
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_wbmp__decoder__decode_frame_config(this, a_dst, a_src);
+ }
+
+ inline wuffs_base__status
+ decode_frame(
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ return wuffs_wbmp__decoder__decode_frame(this, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ }
+
+ inline wuffs_base__rect_ie_u32
+ frame_dirty_rect() const {
+ return wuffs_wbmp__decoder__frame_dirty_rect(this);
+ }
+
+ inline uint32_t
+ num_animation_loops() const {
+ return wuffs_wbmp__decoder__num_animation_loops(this);
+ }
+
+ inline uint64_t
+ num_decoded_frame_configs() const {
+ return wuffs_wbmp__decoder__num_decoded_frame_configs(this);
+ }
+
+ inline uint64_t
+ num_decoded_frames() const {
+ return wuffs_wbmp__decoder__num_decoded_frames(this);
+ }
+
+ inline wuffs_base__status
+ restart_frame(
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ return wuffs_wbmp__decoder__restart_frame(this, a_index, a_io_position);
+ }
+
+ inline wuffs_base__empty_struct
+ set_report_metadata(
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_wbmp__decoder__set_report_metadata(this, a_fourcc, a_report);
+ }
+
+ inline wuffs_base__status
+ tell_me_more(
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_wbmp__decoder__tell_me_more(this, a_dst, a_minfo, a_src);
+ }
+
+ inline uint64_t
+ history_retain_length() const {
+ return wuffs_wbmp__decoder__history_retain_length(this);
+ }
+
+ inline wuffs_base__range_ii_u64
+ workbuf_len() const {
+ return wuffs_wbmp__decoder__workbuf_len(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_wbmp__decoder__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+// ---------------- Public Consts
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_xxhash32__hasher__struct wuffs_xxhash32__hasher;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_xxhash32__hasher__initialize(
+ wuffs_xxhash32__hasher* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_xxhash32__hasher(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_xxhash32__hasher*
+wuffs_xxhash32__hasher__alloc(void);
+
+static inline wuffs_base__hasher_u32*
+wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32(void) {
+ return (wuffs_base__hasher_u32*)(wuffs_xxhash32__hasher__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__hasher_u32*
+wuffs_xxhash32__hasher__upcast_as__wuffs_base__hasher_u32(
+ wuffs_xxhash32__hasher* p) {
+ return (wuffs_base__hasher_u32*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_xxhash32__hasher__get_quirk(
+ const wuffs_xxhash32__hasher* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_xxhash32__hasher__set_quirk(
+ wuffs_xxhash32__hasher* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_xxhash32__hasher__update(
+ wuffs_xxhash32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_xxhash32__hasher__update_u32(
+ wuffs_xxhash32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_xxhash32__hasher__checksum_u32(
+ const wuffs_xxhash32__hasher* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_xxhash32__hasher__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__hasher_u32;
+ wuffs_base__vtable null_vtable;
+
+ uint32_t f_length_modulo_u32;
+ bool f_length_overflows_u32;
+ uint8_t f_padding0;
+ uint8_t f_padding1;
+ uint8_t f_buf_len;
+ uint8_t f_buf_data[16];
+ uint32_t f_v0;
+ uint32_t f_v1;
+ uint32_t f_v2;
+ uint32_t f_v3;
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_xxhash32__hasher, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_xxhash32__hasher__alloc());
+ }
+
+ static inline wuffs_base__hasher_u32::unique_ptr
+ alloc_as__wuffs_base__hasher_u32() {
+ return wuffs_base__hasher_u32::unique_ptr(
+ wuffs_xxhash32__hasher__alloc_as__wuffs_base__hasher_u32());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_xxhash32__hasher__struct() = delete;
+ wuffs_xxhash32__hasher__struct(const wuffs_xxhash32__hasher__struct&) = delete;
+ wuffs_xxhash32__hasher__struct& operator=(
+ const wuffs_xxhash32__hasher__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_xxhash32__hasher__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__hasher_u32*
+ upcast_as__wuffs_base__hasher_u32() {
+ return (wuffs_base__hasher_u32*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_xxhash32__hasher__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_xxhash32__hasher__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__empty_struct
+ update(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_xxhash32__hasher__update(this, a_x);
+ }
+
+ inline uint32_t
+ update_u32(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_xxhash32__hasher__update_u32(this, a_x);
+ }
+
+ inline uint32_t
+ checksum_u32() const {
+ return wuffs_xxhash32__hasher__checksum_u32(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_xxhash32__hasher__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32) || defined(WUFFS_NONMONOLITHIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC)
+
+// ---------------- Status Codes
+
+// ---------------- Public Consts
+
+// ---------------- Struct Declarations
+
+typedef struct wuffs_xxhash64__hasher__struct wuffs_xxhash64__hasher;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- 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 options.
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_xxhash64__hasher__initialize(
+ wuffs_xxhash64__hasher* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options);
+
+size_t
+sizeof__wuffs_xxhash64__hasher(void);
+
+// ---------------- Allocs
+
+// These functions allocate and initialize Wuffs structs. They return NULL if
+// memory allocation fails. If they return non-NULL, there is no need to call
+// wuffs_foo__bar__initialize, but the caller is responsible for eventually
+// calling free on the returned pointer. That pointer is effectively a C++
+// std::unique_ptr<T, wuffs_unique_ptr_deleter>.
+
+wuffs_xxhash64__hasher*
+wuffs_xxhash64__hasher__alloc(void);
+
+static inline wuffs_base__hasher_u64*
+wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64(void) {
+ return (wuffs_base__hasher_u64*)(wuffs_xxhash64__hasher__alloc());
+}
+
+// ---------------- Upcasts
+
+static inline wuffs_base__hasher_u64*
+wuffs_xxhash64__hasher__upcast_as__wuffs_base__hasher_u64(
+ wuffs_xxhash64__hasher* p) {
+ return (wuffs_base__hasher_u64*)p;
+}
+
+// ---------------- Public Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_xxhash64__hasher__get_quirk(
+ const wuffs_xxhash64__hasher* self,
+ uint32_t a_key);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_xxhash64__hasher__set_quirk(
+ wuffs_xxhash64__hasher* self,
+ uint32_t a_key,
+ uint64_t a_value);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_xxhash64__hasher__update(
+ wuffs_xxhash64__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_xxhash64__hasher__update_u64(
+ wuffs_xxhash64__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_xxhash64__hasher__checksum_u64(
+ const wuffs_xxhash64__hasher* self);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+// ---------------- 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_xxhash64__hasher__struct {
+ // 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;
+ wuffs_base__vtable vtable_for__wuffs_base__hasher_u64;
+ wuffs_base__vtable null_vtable;
+
+ uint64_t f_length_modulo_u64;
+ bool f_length_overflows_u64;
+ uint8_t f_padding0;
+ uint8_t f_padding1;
+ uint8_t f_padding2;
+ uint32_t f_buf_len;
+ uint8_t f_buf_data[32];
+ uint64_t f_v0;
+ uint64_t f_v1;
+ uint64_t f_v2;
+ uint64_t f_v3;
+ } private_impl;
+
+#ifdef __cplusplus
+#if defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+ using unique_ptr = std::unique_ptr<wuffs_xxhash64__hasher, wuffs_unique_ptr_deleter>;
+
+ // On failure, the alloc_etc functions return nullptr. They don't throw.
+
+ static inline unique_ptr
+ alloc() {
+ return unique_ptr(wuffs_xxhash64__hasher__alloc());
+ }
+
+ static inline wuffs_base__hasher_u64::unique_ptr
+ alloc_as__wuffs_base__hasher_u64() {
+ return wuffs_base__hasher_u64::unique_ptr(
+ wuffs_xxhash64__hasher__alloc_as__wuffs_base__hasher_u64());
+ }
+#endif // defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#if defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+ // Disallow constructing or copying an object via standard C++ mechanisms,
+ // e.g. the "new" operator, as this struct is intentionally opaque. Its total
+ // size and field layout is not part of the public, stable, memory-safe API.
+ // Use malloc or memcpy and the sizeof__wuffs_foo__bar function instead, and
+ // call wuffs_foo__bar__baz methods (which all take a "this"-like pointer as
+ // their first argument) rather than tweaking bar.private_impl.qux fields.
+ //
+ // In C, we can just leave wuffs_foo__bar as an incomplete type (unless
+ // WUFFS_IMPLEMENTATION is #define'd). In C++, we define a complete type in
+ // order to provide convenience methods. These forward on "this", so that you
+ // can write "bar->baz(etc)" instead of "wuffs_foo__bar__baz(bar, etc)".
+ wuffs_xxhash64__hasher__struct() = delete;
+ wuffs_xxhash64__hasher__struct(const wuffs_xxhash64__hasher__struct&) = delete;
+ wuffs_xxhash64__hasher__struct& operator=(
+ const wuffs_xxhash64__hasher__struct&) = delete;
+#endif // defined(WUFFS_BASE__HAVE_EQ_DELETE) && !defined(WUFFS_IMPLEMENTATION)
+
+#if !defined(WUFFS_IMPLEMENTATION)
+ // As above, the size of the struct is not part of the public API, and unless
+ // WUFFS_IMPLEMENTATION is #define'd, this struct type T should be heap
+ // allocated, not stack allocated. Its size is not intended to be known at
+ // compile time, but it is unfortunately divulged as a side effect of
+ // defining C++ convenience methods. Use "sizeof__T()", calling the function,
+ // instead of "sizeof T", invoking the operator. To make the two values
+ // different, so that passing the latter will be rejected by the initialize
+ // function, we add an arbitrary amount of dead weight.
+ uint8_t dead_weight[123000000]; // 123 MB.
+#endif // !defined(WUFFS_IMPLEMENTATION)
+
+ inline wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+ initialize(
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options) {
+ return wuffs_xxhash64__hasher__initialize(
+ this, sizeof_star_self, wuffs_version, options);
+ }
+
+ inline wuffs_base__hasher_u64*
+ upcast_as__wuffs_base__hasher_u64() {
+ return (wuffs_base__hasher_u64*)this;
+ }
+
+ inline uint64_t
+ get_quirk(
+ uint32_t a_key) const {
+ return wuffs_xxhash64__hasher__get_quirk(this, a_key);
+ }
+
+ inline wuffs_base__status
+ set_quirk(
+ uint32_t a_key,
+ uint64_t a_value) {
+ return wuffs_xxhash64__hasher__set_quirk(this, a_key, a_value);
+ }
+
+ inline wuffs_base__empty_struct
+ update(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_xxhash64__hasher__update(this, a_x);
+ }
+
+ inline uint64_t
+ update_u64(
+ wuffs_base__slice_u8 a_x) {
+ return wuffs_xxhash64__hasher__update_u64(this, a_x);
+ }
+
+ inline uint64_t
+ checksum_u64() const {
+ return wuffs_xxhash64__hasher__checksum_u64(this);
+ }
+
+#endif // __cplusplus
+}; // struct wuffs_xxhash64__hasher__struct
+
+#endif // defined(__cplusplus) || defined(WUFFS_IMPLEMENTATION)
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64) || defined(WUFFS_NONMONOLITHIC)
+
+#if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+// ---------------- Auxiliary - Base
+
+// Auxiliary code is discussed at
+// https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
+
+#include <stdio.h>
+
+#include <string>
+
+namespace wuffs_aux {
+
+using IOBuffer = wuffs_base__io_buffer;
+
+// MemOwner represents ownership of some memory. Dynamically allocated memory
+// (e.g. from malloc or new) is typically paired with free or delete, invoked
+// when the std::unique_ptr is destroyed. Statically allocated memory might use
+// MemOwner(nullptr, &free), even if that statically allocated memory is not
+// nullptr, since calling free(nullptr) is a no-op.
+using MemOwner = std::unique_ptr<void, decltype(&free)>;
+
+namespace sync_io {
+
+// --------
+
+// DynIOBuffer is an IOBuffer that is backed by a dynamically sized byte array.
+// It owns that backing array and will free it in its destructor.
+//
+// The array size can be explicitly extended (by calling the grow method) but,
+// unlike a C++ std::vector, there is no implicit extension (e.g. by calling
+// std::vector::insert) and its maximum size is capped by the max_incl
+// constructor argument.
+//
+// It contains an IOBuffer-typed field whose reader side provides access to
+// previously written bytes and whose writer side provides access to the
+// allocated but not-yet-written-to slack space. For Go programmers, this slack
+// space is roughly analogous to the s[len(s):cap(s)] space of a slice s.
+class DynIOBuffer {
+ public:
+ enum GrowResult {
+ OK = 0,
+ FailedMaxInclExceeded = 1,
+ FailedOutOfMemory = 2,
+ };
+
+ // m_buf holds the dynamically sized byte array and its read/write indexes:
+ // - m_buf.meta.wi is roughly analogous to a Go slice's length.
+ // - m_buf.data.len is roughly analogous to a Go slice's capacity. It is
+ // also equal to the m_buf.data.ptr malloc/realloc size.
+ //
+ // Users should not modify the m_buf.data.ptr or m_buf.data.len fields (as
+ // they are conceptually private to this class), but they can modify the
+ // bytes referenced by that pointer-length pair (e.g. compactions).
+ IOBuffer m_buf;
+
+ // m_max_incl is an inclusive upper bound on the backing array size.
+ const uint64_t m_max_incl;
+
+ // Constructor and destructor.
+ explicit DynIOBuffer(uint64_t max_incl);
+ ~DynIOBuffer();
+
+ // Drop frees the byte array and resets m_buf. The DynIOBuffer can still be
+ // used after a drop call. It just restarts from zero.
+ void drop();
+
+ // grow ensures that the byte array size is at least min_incl and at most
+ // max_incl. It returns FailedMaxInclExceeded if that would require
+ // allocating more than max_incl bytes, including the case where (min_incl >
+ // max_incl). It returns FailedOutOfMemory if memory allocation failed.
+ GrowResult grow(uint64_t min_incl);
+
+ private:
+ // Delete the copy and assign constructors.
+ DynIOBuffer(const DynIOBuffer&) = delete;
+ DynIOBuffer& operator=(const DynIOBuffer&) = delete;
+
+ static uint64_t round_up(uint64_t min_incl, uint64_t max_incl);
+};
+
+// --------
+
+class Input {
+ public:
+ virtual ~Input();
+
+ virtual IOBuffer* BringsItsOwnIOBuffer();
+ virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length) = 0;
+};
+
+// --------
+
+// FileInput is an Input that reads from a file source.
+//
+// It does not take responsibility for closing the file when done.
+class FileInput : public Input {
+ public:
+ FileInput(FILE* f);
+
+ virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length);
+
+ private:
+ FILE* m_f;
+
+ // Delete the copy and assign constructors.
+ FileInput(const FileInput&) = delete;
+ FileInput& operator=(const FileInput&) = delete;
+};
+
+// --------
+
+// MemoryInput is an Input that reads from an in-memory source.
+//
+// It does not take responsibility for freeing the memory when done.
+class MemoryInput : public Input {
+ public:
+ MemoryInput(const char* ptr, size_t len);
+ MemoryInput(const uint8_t* ptr, size_t len);
+
+ virtual IOBuffer* BringsItsOwnIOBuffer();
+ virtual std::string CopyIn(IOBuffer* dst, uint64_t history_retain_length);
+
+ private:
+ IOBuffer m_io;
+
+ // Delete the copy and assign constructors.
+ MemoryInput(const MemoryInput&) = delete;
+ MemoryInput& operator=(const MemoryInput&) = delete;
+};
+
+// --------
+
+} // namespace sync_io
+
+} // namespace wuffs_aux
+
+// ---------------- Auxiliary - CBOR
+
+namespace wuffs_aux {
+
+struct DecodeCborResult {
+ DecodeCborResult(std::string&& error_message0, uint64_t cursor_position0);
+
+ std::string error_message;
+ uint64_t cursor_position;
+};
+
+class DecodeCborCallbacks {
+ public:
+ virtual ~DecodeCborCallbacks();
+
+ // AppendXxx are called for leaf nodes: literals, numbers, strings, etc.
+
+ virtual std::string AppendNull() = 0;
+ virtual std::string AppendUndefined() = 0;
+ virtual std::string AppendBool(bool val) = 0;
+ virtual std::string AppendF64(double val) = 0;
+ virtual std::string AppendI64(int64_t val) = 0;
+ virtual std::string AppendU64(uint64_t val) = 0;
+ virtual std::string AppendByteString(std::string&& val) = 0;
+ virtual std::string AppendTextString(std::string&& val) = 0;
+ virtual std::string AppendMinus1MinusX(uint64_t val) = 0;
+ virtual std::string AppendCborSimpleValue(uint8_t val) = 0;
+ virtual std::string AppendCborTag(uint64_t val) = 0;
+
+ // Push and Pop are called for container nodes: CBOR arrays (lists) and CBOR
+ // maps (dictionaries).
+ //
+ // The flags bits combine exactly one of:
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
+ // and exactly one of:
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
+
+ virtual std::string Push(uint32_t flags) = 0;
+ virtual std::string Pop(uint32_t flags) = 0;
+
+ // Done is always the last Callback method called by DecodeCbor, whether or
+ // not parsing the input as CBOR encountered an error. Even when successful,
+ // trailing data may remain in input and buffer.
+ //
+ // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
+ // as DecodeCbor may then de-allocate the backing array.
+ //
+ // The default Done implementation is a no-op.
+ virtual void //
+ Done(DecodeCborResult& result, sync_io::Input& input, IOBuffer& buffer);
+};
+
+// The FooArgBar types add structure to Foo's optional arguments. They wrap
+// inner representations for several reasons:
+// - It provides a home for the DefaultValue static method, for Foo callers
+// that want to override some but not all optional arguments.
+// - It provides the "Bar" name at Foo call sites, which can help self-
+// document Foo calls with many arguemnts.
+// - It provides some type safety against accidentally transposing or omitting
+// adjacent fundamentally-numeric-typed optional arguments.
+
+// DecodeCborArgQuirks wraps an optional argument to DecodeCbor.
+struct DecodeCborArgQuirks {
+ explicit DecodeCborArgQuirks(wuffs_base__slice_u32 repr0);
+ explicit DecodeCborArgQuirks(uint32_t* ptr, size_t len);
+
+ // DefaultValue returns an empty slice.
+ static DecodeCborArgQuirks DefaultValue();
+
+ wuffs_base__slice_u32 repr;
+};
+
+// DecodeCbor calls callbacks based on the CBOR-formatted data in input.
+//
+// On success, the returned error_message is empty and cursor_position counts
+// the number of bytes consumed. On failure, error_message is non-empty and
+// cursor_position is the location of the error. That error may be a content
+// error (invalid CBOR) or an input error (e.g. network failure).
+DecodeCborResult //
+DecodeCbor(DecodeCborCallbacks& callbacks,
+ sync_io::Input& input,
+ DecodeCborArgQuirks quirks = DecodeCborArgQuirks::DefaultValue());
+
+} // namespace wuffs_aux
+
+// ---------------- Auxiliary - Image
+
+namespace wuffs_aux {
+
+struct DecodeImageResult {
+ DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
+ wuffs_base__pixel_buffer pixbuf0,
+ std::string&& error_message0);
+ DecodeImageResult(std::string&& error_message0);
+
+ MemOwner pixbuf_mem_owner;
+ wuffs_base__pixel_buffer pixbuf;
+ std::string error_message;
+};
+
+// DecodeImageCallbacks are the callbacks given to DecodeImage. They are always
+// called in this order:
+// 1. SelectDecoder
+// 2. HandleMetadata
+// 3. SelectPixfmt
+// 4. AllocPixbuf
+// 5. AllocWorkbuf
+// 6. Done
+//
+// It may return early - the third callback might not be invoked if the second
+// one fails - but the final callback (Done) is always invoked.
+class DecodeImageCallbacks {
+ public:
+ // AllocPixbufResult holds a memory allocation (the result of malloc or new,
+ // a statically allocated pointer, etc), or an error message. The memory is
+ // de-allocated when mem_owner goes out of scope and is destroyed.
+ struct AllocPixbufResult {
+ AllocPixbufResult(MemOwner&& mem_owner0, wuffs_base__pixel_buffer pixbuf0);
+ AllocPixbufResult(std::string&& error_message0);
+
+ MemOwner mem_owner;
+ wuffs_base__pixel_buffer pixbuf;
+ std::string error_message;
+ };
+
+ // AllocWorkbufResult holds a memory allocation (the result of malloc or new,
+ // a statically allocated pointer, etc), or an error message. The memory is
+ // de-allocated when mem_owner goes out of scope and is destroyed.
+ struct AllocWorkbufResult {
+ AllocWorkbufResult(MemOwner&& mem_owner0, wuffs_base__slice_u8 workbuf0);
+ AllocWorkbufResult(std::string&& error_message0);
+
+ MemOwner mem_owner;
+ wuffs_base__slice_u8 workbuf;
+ std::string error_message;
+ };
+
+ virtual ~DecodeImageCallbacks();
+
+ // SelectDecoder returns the image decoder for the input data's file format.
+ // Returning a nullptr means failure (DecodeImage_UnsupportedImageFormat).
+ //
+ // Common formats will have a FourCC value in the range [1 ..= 0x7FFF_FFFF],
+ // such as WUFFS_BASE__FOURCC__JPEG. A zero FourCC value means that Wuffs'
+ // standard library did not recognize the image format but if SelectDecoder
+ // was overridden, it may examine the input data's starting bytes and still
+ // provide its own image decoder, e.g. for an exotic image file format that's
+ // not in Wuffs' standard library. The prefix_etc fields have the same
+ // meaning as wuffs_base__magic_number_guess_fourcc arguments. SelectDecoder
+ // implementations should not modify prefix_data's contents.
+ //
+ // SelectDecoder might be called more than once, since some image file
+ // formats can wrap others. For example, a nominal BMP file can actually
+ // contain a JPEG or a PNG.
+ //
+ // The default SelectDecoder accepts the FOURCC codes listed below. For
+ // modular builds (i.e. when #define'ing WUFFS_CONFIG__MODULES), acceptance
+ // of the ETC file format is optional (for each value of ETC) and depends on
+ // the corresponding module to be enabled at compile time (i.e. #define'ing
+ // WUFFS_CONFIG__MODULE__ETC).
+ // - WUFFS_BASE__FOURCC__BMP
+ // - WUFFS_BASE__FOURCC__GIF
+ // - WUFFS_BASE__FOURCC__JPEG
+ // - WUFFS_BASE__FOURCC__NIE
+ // - WUFFS_BASE__FOURCC__NPBM
+ // - WUFFS_BASE__FOURCC__PNG
+ // - WUFFS_BASE__FOURCC__TGA
+ // - WUFFS_BASE__FOURCC__WBMP
+ virtual wuffs_base__image_decoder::unique_ptr //
+ SelectDecoder(uint32_t fourcc,
+ wuffs_base__slice_u8 prefix_data,
+ bool prefix_closed);
+
+ // HandleMetadata acknowledges image metadata. minfo.flavor will be one of:
+ // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH
+ // - WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED
+ // If it is ETC__METADATA_RAW_ETC then raw contains the metadata bytes. Those
+ // bytes should not be retained beyond the the HandleMetadata call.
+ //
+ // minfo.metadata__fourcc() will typically match one of the
+ // DecodeImageArgFlags bits. For example, if (REPORT_METADATA_CHRM |
+ // REPORT_METADATA_GAMA) was passed to DecodeImage then the metadata FourCC
+ // will be either WUFFS_BASE__FOURCC__CHRM or WUFFS_BASE__FOURCC__GAMA.
+ //
+ // It returns an error message, or an empty string on success.
+ virtual std::string //
+ HandleMetadata(const wuffs_base__more_information& minfo,
+ wuffs_base__slice_u8 raw);
+
+ // SelectPixfmt returns the destination pixel format for AllocPixbuf. It
+ // should return wuffs_base__make_pixel_format(etc) called with one of:
+ // - WUFFS_BASE__PIXEL_FORMAT__BGR_565
+ // - WUFFS_BASE__PIXEL_FORMAT__BGR
+ // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL
+ // - WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE
+ // - WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL
+ // - WUFFS_BASE__PIXEL_FORMAT__RGB
+ // - WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL
+ // - WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL
+ // or return image_config.pixcfg.pixel_format(). The latter means to use the
+ // image file's natural pixel format. For example, GIF images' natural pixel
+ // format is an indexed one.
+ //
+ // Returning otherwise means failure (DecodeImage_UnsupportedPixelFormat).
+ //
+ // The default SelectPixfmt implementation returns
+ // wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL) which
+ // is 4 bytes per pixel (8 bits per channel × 4 channels).
+ virtual wuffs_base__pixel_format //
+ SelectPixfmt(const wuffs_base__image_config& image_config);
+
+ // AllocPixbuf allocates the pixel buffer.
+ //
+ // allow_uninitialized_memory will be true if a valid background_color was
+ // passed to DecodeImage, since the pixel buffer's contents will be
+ // overwritten with that color after AllocPixbuf returns.
+ //
+ // The default AllocPixbuf implementation allocates either uninitialized or
+ // zeroed memory. Zeroed memory typically corresponds to filling with opaque
+ // black or transparent black, depending on the pixel format.
+ virtual AllocPixbufResult //
+ AllocPixbuf(const wuffs_base__image_config& image_config,
+ bool allow_uninitialized_memory);
+
+ // AllocWorkbuf allocates the work buffer. The allocated buffer's length
+ // should be at least len_range.min_incl, but larger allocations (up to
+ // len_range.max_incl) may have better performance (by using more memory).
+ //
+ // The default AllocWorkbuf implementation allocates len_range.max_incl bytes
+ // of either uninitialized or zeroed memory.
+ virtual AllocWorkbufResult //
+ AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
+ bool allow_uninitialized_memory);
+
+ // Done is always the last Callback method called by DecodeImage, whether or
+ // not parsing the input encountered an error. Even when successful, trailing
+ // data may remain in input and buffer.
+ //
+ // The image_decoder is the one returned by SelectDecoder (if SelectDecoder
+ // was successful), or a no-op unique_ptr otherwise. Like any unique_ptr,
+ // ownership moves to the Done implementation.
+ //
+ // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
+ // as DecodeImage may then de-allocate the backing array.
+ //
+ // The default Done implementation is a no-op, other than running the
+ // image_decoder unique_ptr destructor.
+ virtual void //
+ Done(DecodeImageResult& result,
+ sync_io::Input& input,
+ IOBuffer& buffer,
+ wuffs_base__image_decoder::unique_ptr image_decoder);
+};
+
+extern const char DecodeImage_BufferIsTooShort[];
+extern const char DecodeImage_MaxInclDimensionExceeded[];
+extern const char DecodeImage_MaxInclMetadataLengthExceeded[];
+extern const char DecodeImage_OutOfMemory[];
+extern const char DecodeImage_UnexpectedEndOfFile[];
+extern const char DecodeImage_UnsupportedImageFormat[];
+extern const char DecodeImage_UnsupportedMetadata[];
+extern const char DecodeImage_UnsupportedPixelBlend[];
+extern const char DecodeImage_UnsupportedPixelConfiguration[];
+extern const char DecodeImage_UnsupportedPixelFormat[];
+
+// The FooArgBar types add structure to Foo's optional arguments. They wrap
+// inner representations for several reasons:
+// - It provides a home for the DefaultValue static method, for Foo callers
+// that want to override some but not all optional arguments.
+// - It provides the "Bar" name at Foo call sites, which can help self-
+// document Foo calls with many arguemnts.
+// - It provides some type safety against accidentally transposing or omitting
+// adjacent fundamentally-numeric-typed optional arguments.
+
+// DecodeImageArgQuirks wraps an optional argument to DecodeImage.
+struct DecodeImageArgQuirks {
+ explicit DecodeImageArgQuirks(wuffs_base__slice_u32 repr0);
+ explicit DecodeImageArgQuirks(uint32_t* ptr, size_t len);
+
+ // DefaultValue returns an empty slice.
+ static DecodeImageArgQuirks DefaultValue();
+
+ wuffs_base__slice_u32 repr;
+};
+
+// DecodeImageArgFlags wraps an optional argument to DecodeImage.
+struct DecodeImageArgFlags {
+ explicit DecodeImageArgFlags(uint64_t repr0);
+
+ // DefaultValue returns 0.
+ static DecodeImageArgFlags DefaultValue();
+
+ // TODO: support all of the REPORT_METADATA_ETC flags, not just CHRM, EXIF,
+ // GAMA, ICCP, KVP, SRGB and XMP.
+
+ // Background Color.
+ static constexpr uint64_t REPORT_METADATA_BGCL = 0x0001;
+ // Primary Chromaticities and White Point.
+ static constexpr uint64_t REPORT_METADATA_CHRM = 0x0002;
+ // Exchangeable Image File Format.
+ static constexpr uint64_t REPORT_METADATA_EXIF = 0x0004;
+ // Gamma Correction.
+ static constexpr uint64_t REPORT_METADATA_GAMA = 0x0008;
+ // International Color Consortium Profile.
+ static constexpr uint64_t REPORT_METADATA_ICCP = 0x0010;
+ // Key-Value Pair.
+ //
+ // For PNG files, this includes iTXt, tEXt and zTXt chunks. In the
+ // HandleMetadata callback, the raw argument contains UTF-8 strings.
+ static constexpr uint64_t REPORT_METADATA_KVP = 0x0020;
+ // Modification Time.
+ static constexpr uint64_t REPORT_METADATA_MTIM = 0x0040;
+ // Offset (2-Dimensional).
+ static constexpr uint64_t REPORT_METADATA_OFS2 = 0x0080;
+ // Physical Dimensions.
+ static constexpr uint64_t REPORT_METADATA_PHYD = 0x0100;
+ // Standard Red Green Blue (Rendering Intent).
+ static constexpr uint64_t REPORT_METADATA_SRGB = 0x0200;
+ // Extensible Metadata Platform.
+ static constexpr uint64_t REPORT_METADATA_XMP = 0x0400;
+
+ uint64_t repr;
+};
+
+// DecodeImageArgPixelBlend wraps an optional argument to DecodeImage.
+struct DecodeImageArgPixelBlend {
+ explicit DecodeImageArgPixelBlend(wuffs_base__pixel_blend repr0);
+
+ // DefaultValue returns WUFFS_BASE__PIXEL_BLEND__SRC.
+ static DecodeImageArgPixelBlend DefaultValue();
+
+ wuffs_base__pixel_blend repr;
+};
+
+// DecodeImageArgBackgroundColor wraps an optional argument to DecodeImage.
+struct DecodeImageArgBackgroundColor {
+ explicit DecodeImageArgBackgroundColor(
+ wuffs_base__color_u32_argb_premul repr0);
+
+ // DefaultValue returns 1, an invalid wuffs_base__color_u32_argb_premul.
+ static DecodeImageArgBackgroundColor DefaultValue();
+
+ wuffs_base__color_u32_argb_premul repr;
+};
+
+// DecodeImageArgMaxInclDimension wraps an optional argument to DecodeImage.
+struct DecodeImageArgMaxInclDimension {
+ explicit DecodeImageArgMaxInclDimension(uint32_t repr0);
+
+ // DefaultValue returns 1048575 = 0x000F_FFFF, more than 1 million pixels.
+ static DecodeImageArgMaxInclDimension DefaultValue();
+
+ uint32_t repr;
+};
+
+// DecodeImageArgMaxInclMetadataLength wraps an optional argument to
+// DecodeImage.
+struct DecodeImageArgMaxInclMetadataLength {
+ explicit DecodeImageArgMaxInclMetadataLength(uint64_t repr0);
+
+ // DefaultValue returns 16777215 = 0x00FF_FFFF, one less than 16 MiB.
+ static DecodeImageArgMaxInclMetadataLength DefaultValue();
+
+ uint64_t repr;
+};
+
+// DecodeImage decodes the image data in input. A variety of image file formats
+// can be decoded, depending on what callbacks.SelectDecoder returns.
+//
+// For animated formats, only the first frame is returned, since the API is
+// simpler for synchronous I/O and having DecodeImage only return when
+// completely done, but rendering animation often involves handling other
+// events in between animation frames. To decode multiple frames of animated
+// images, or for asynchronous I/O (e.g. when decoding an image streamed over
+// the network), use Wuffs' lower level C API instead of its higher level,
+// simplified C++ API (the wuffs_aux API).
+//
+// The DecodeImageResult's fields depend on whether decoding succeeded:
+// - On total success, the error_message is empty and pixbuf.pixcfg.is_valid()
+// is true.
+// - On partial success (e.g. the input file was truncated but we are still
+// able to decode some of the pixels), error_message is non-empty but
+// pixbuf.pixcfg.is_valid() is still true. It is up to the caller whether to
+// accept or reject partial success.
+// - On failure, the error_message is non_empty and pixbuf.pixcfg.is_valid()
+// is false.
+//
+// The callbacks allocate the pixel buffer memory and work buffer memory. On
+// success, pixel buffer memory ownership is passed to the DecodeImage caller
+// as the returned pixbuf_mem_owner. Regardless of success or failure, the work
+// buffer memory is deleted.
+//
+// The pixel_blend (one of the constants listed below) determines how to
+// composite the decoded image over the pixel buffer's original pixels (as
+// returned by callbacks.AllocPixbuf):
+// - WUFFS_BASE__PIXEL_BLEND__SRC
+// - WUFFS_BASE__PIXEL_BLEND__SRC_OVER
+//
+// The background_color is used to fill the pixel buffer after
+// callbacks.AllocPixbuf returns, if it is valid in the
+// wuffs_base__color_u32_argb_premul__is_valid sense. The default value,
+// 0x0000_0001, is not valid since its Blue channel value (0x01) is greater
+// than its Alpha channel value (0x00). A valid background_color will typically
+// be overwritten when pixel_blend is WUFFS_BASE__PIXEL_BLEND__SRC, but might
+// still be visible on partial (not total) success or when pixel_blend is
+// WUFFS_BASE__PIXEL_BLEND__SRC_OVER and the decoded image is not fully opaque.
+//
+// Decoding fails (with DecodeImage_MaxInclDimensionExceeded) if the image's
+// width or height is greater than max_incl_dimension or if any opted-in (via
+// flags bits) metadata is longer than max_incl_metadata_length.
+DecodeImageResult //
+DecodeImage(DecodeImageCallbacks& callbacks,
+ sync_io::Input& input,
+ DecodeImageArgQuirks quirks = DecodeImageArgQuirks::DefaultValue(),
+ DecodeImageArgFlags flags = DecodeImageArgFlags::DefaultValue(),
+ DecodeImageArgPixelBlend pixel_blend =
+ DecodeImageArgPixelBlend::DefaultValue(),
+ DecodeImageArgBackgroundColor background_color =
+ DecodeImageArgBackgroundColor::DefaultValue(),
+ DecodeImageArgMaxInclDimension max_incl_dimension =
+ DecodeImageArgMaxInclDimension::DefaultValue(),
+ DecodeImageArgMaxInclMetadataLength max_incl_metadata_length =
+ DecodeImageArgMaxInclMetadataLength::DefaultValue());
+
+} // namespace wuffs_aux
+
+// ---------------- Auxiliary - JSON
+
+namespace wuffs_aux {
+
+struct DecodeJsonResult {
+ DecodeJsonResult(std::string&& error_message0, uint64_t cursor_position0);
+
+ std::string error_message;
+ uint64_t cursor_position;
+};
+
+class DecodeJsonCallbacks {
+ public:
+ virtual ~DecodeJsonCallbacks();
+
+ // AppendXxx are called for leaf nodes: literals, numbers and strings. For
+ // strings, the Callbacks implementation is responsible for tracking map keys
+ // versus other values.
+
+ virtual std::string AppendNull() = 0;
+ virtual std::string AppendBool(bool val) = 0;
+ virtual std::string AppendF64(double val) = 0;
+ virtual std::string AppendI64(int64_t val) = 0;
+ virtual std::string AppendTextString(std::string&& val) = 0;
+
+ // Push and Pop are called for container nodes: JSON arrays (lists) and JSON
+ // objects (dictionaries).
+ //
+ // The flags bits combine exactly one of:
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_NONE
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_LIST
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__FROM_DICT
+ // and exactly one of:
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_NONE
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST
+ // - WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_DICT
+
+ virtual std::string Push(uint32_t flags) = 0;
+ virtual std::string Pop(uint32_t flags) = 0;
+
+ // Done is always the last Callback method called by DecodeJson, whether or
+ // not parsing the input as JSON encountered an error. Even when successful,
+ // trailing data may remain in input and buffer. See "Unintuitive JSON
+ // Parsing" (https://nullprogram.com/blog/2019/12/28/) which discusses JSON
+ // parsing and when it stops.
+ //
+ // Do not keep a reference to buffer or buffer.data.ptr after Done returns,
+ // as DecodeJson may then de-allocate the backing array.
+ //
+ // The default Done implementation is a no-op.
+ virtual void //
+ Done(DecodeJsonResult& result, sync_io::Input& input, IOBuffer& buffer);
+};
+
+extern const char DecodeJson_BadJsonPointer[];
+extern const char DecodeJson_NoMatch[];
+
+// The FooArgBar types add structure to Foo's optional arguments. They wrap
+// inner representations for several reasons:
+// - It provides a home for the DefaultValue static method, for Foo callers
+// that want to override some but not all optional arguments.
+// - It provides the "Bar" name at Foo call sites, which can help self-
+// document Foo calls with many arguemnts.
+// - It provides some type safety against accidentally transposing or omitting
+// adjacent fundamentally-numeric-typed optional arguments.
+
+// DecodeJsonArgQuirks wraps an optional argument to DecodeJson.
+struct DecodeJsonArgQuirks {
+ explicit DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0);
+ explicit DecodeJsonArgQuirks(uint32_t* ptr, size_t len);
+
+ // DefaultValue returns an empty slice.
+ static DecodeJsonArgQuirks DefaultValue();
+
+ wuffs_base__slice_u32 repr;
+};
+
+// DecodeJsonArgJsonPointer wraps an optional argument to DecodeJson.
+struct DecodeJsonArgJsonPointer {
+ explicit DecodeJsonArgJsonPointer(std::string repr0);
+
+ // DefaultValue returns an empty string.
+ static DecodeJsonArgJsonPointer DefaultValue();
+
+ std::string repr;
+};
+
+// DecodeJson calls callbacks based on the JSON-formatted data in input.
+//
+// On success, the returned error_message is empty and cursor_position counts
+// the number of bytes consumed. On failure, error_message is non-empty and
+// cursor_position is the location of the error. That error may be a content
+// error (invalid JSON) or an input error (e.g. network failure).
+//
+// json_pointer is a query in the JSON Pointer (RFC 6901) syntax. The callbacks
+// run for the input's sub-node that matches the query. DecodeJson_NoMatch is
+// returned if no matching sub-node was found. The empty query matches the
+// input's root node, consistent with JSON Pointer semantics.
+//
+// The JSON Pointer implementation is greedy: duplicate keys are not rejected
+// but only the first match for each '/'-separated fragment is followed.
+DecodeJsonResult //
+DecodeJson(DecodeJsonCallbacks& callbacks,
+ sync_io::Input& input,
+ DecodeJsonArgQuirks quirks = DecodeJsonArgQuirks::DefaultValue(),
+ DecodeJsonArgJsonPointer json_pointer =
+ DecodeJsonArgJsonPointer::DefaultValue());
+
+} // namespace wuffs_aux
+
+#endif // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+// ‼ WUFFS C HEADER ENDS HERE.
+#ifdef WUFFS_IMPLEMENTATION
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+// ---------------- Fundamentals
+
+// WUFFS_BASE__MAGIC is a magic number to check that initializers are called.
+// It's not foolproof, given C doesn't automatically zero memory before use,
+// but it should catch 99.99% of cases.
+//
+// Its (non-zero) value is arbitrary, based on md5sum("wuffs").
+#define WUFFS_BASE__MAGIC ((uint32_t)0x3CCB6C71)
+
+// WUFFS_BASE__DISABLED is a magic number to indicate that a non-recoverable
+// error was previously encountered.
+//
+// Its (non-zero) value is arbitrary, based on md5sum("disabled").
+#define WUFFS_BASE__DISABLED ((uint32_t)0x075AE3D2)
+
+// Use switch cases for coroutine suspension points, similar to the technique
+// in https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
+//
+// The implicit fallthrough is intentional.
+//
+// We use trivial macros instead of an explicit assignment and case statement
+// so that clang-format doesn't get confused by the unusual "case"s.
+#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0 case 0:;
+#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT(n) \
+ coro_susp_point = n; \
+ case n:;
+
+#define WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(n) \
+ if (!status.repr) { \
+ goto ok; \
+ } else if (*status.repr != '$') { \
+ goto exit; \
+ } \
+ coro_susp_point = n; \
+ goto suspend; \
+ case n:;
+
+// The "defined(__clang__)" isn't redundant. While vanilla clang defines
+// __GNUC__, clang-cl (which mimics MSVC's cl.exe) does not.
+#if defined(__GNUC__) || defined(__clang__)
+#define WUFFS_BASE__LIKELY(expr) (__builtin_expect(!!(expr), 1))
+#define WUFFS_BASE__UNLIKELY(expr) (__builtin_expect(!!(expr), 0))
+#else
+#define WUFFS_BASE__LIKELY(expr) (expr)
+#define WUFFS_BASE__UNLIKELY(expr) (expr)
+#endif
+
+// --------
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+static inline uint8_t* //
+wuffs_base__strip_const_from_u8_ptr(const uint8_t* ptr) {
+ return (uint8_t*)ptr;
+}
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+// --------
+
+static inline wuffs_base__empty_struct //
+wuffs_base__ignore_status(wuffs_base__status z) {
+ return wuffs_base__make_empty_struct();
+}
+
+static inline wuffs_base__status //
+wuffs_base__status__ensure_not_a_suspension(wuffs_base__status z) {
+ if (z.repr && (*z.repr == '$')) {
+ z.repr = wuffs_base__error__cannot_return_a_suspension;
+ }
+ return z;
+}
+
+// --------
+
+// wuffs_base__iterate_total_advance returns the exclusive pointer-offset at
+// which iteration should stop. The overall slice has length total_len, each
+// iteration's sub-slice has length iter_len and are placed iter_advance apart.
+//
+// The iter_advance may not be larger than iter_len. The iter_advance may be
+// smaller than iter_len, in which case the sub-slices will overlap.
+//
+// The return value r satisfies ((0 <= r) && (r <= total_len)).
+//
+// For example, if total_len = 15, iter_len = 5 and iter_advance = 3, there are
+// four iterations at offsets 0, 3, 6 and 9. This function returns 12.
+//
+// 0123456789012345
+// [....]
+// [....]
+// [....]
+// [....]
+// $
+// 0123456789012345
+//
+// For example, if total_len = 15, iter_len = 5 and iter_advance = 5, there are
+// three iterations at offsets 0, 5 and 10. This function returns 15.
+//
+// 0123456789012345
+// [....]
+// [....]
+// [....]
+// $
+// 0123456789012345
+static inline size_t //
+wuffs_base__iterate_total_advance(size_t total_len,
+ size_t iter_len,
+ size_t iter_advance) {
+ if (total_len >= iter_len) {
+ size_t n = total_len - iter_len;
+ return ((n / iter_advance) * iter_advance) + iter_advance;
+ }
+ return 0;
+}
+
+// ---------------- Numeric Types
+
+extern const uint8_t wuffs_base__low_bits_mask__u8[8];
+extern const uint16_t wuffs_base__low_bits_mask__u16[16];
+extern const uint32_t wuffs_base__low_bits_mask__u32[32];
+extern const uint64_t wuffs_base__low_bits_mask__u64[64];
+
+#define WUFFS_BASE__LOW_BITS_MASK__U8(n) (wuffs_base__low_bits_mask__u8[n])
+#define WUFFS_BASE__LOW_BITS_MASK__U16(n) (wuffs_base__low_bits_mask__u16[n])
+#define WUFFS_BASE__LOW_BITS_MASK__U32(n) (wuffs_base__low_bits_mask__u32[n])
+#define WUFFS_BASE__LOW_BITS_MASK__U64(n) (wuffs_base__low_bits_mask__u64[n])
+
+// --------
+
+static inline void //
+wuffs_base__u8__sat_add_indirect(uint8_t* x, uint8_t y) {
+ *x = wuffs_base__u8__sat_add(*x, y);
+}
+
+static inline void //
+wuffs_base__u8__sat_sub_indirect(uint8_t* x, uint8_t y) {
+ *x = wuffs_base__u8__sat_sub(*x, y);
+}
+
+static inline void //
+wuffs_base__u16__sat_add_indirect(uint16_t* x, uint16_t y) {
+ *x = wuffs_base__u16__sat_add(*x, y);
+}
+
+static inline void //
+wuffs_base__u16__sat_sub_indirect(uint16_t* x, uint16_t y) {
+ *x = wuffs_base__u16__sat_sub(*x, y);
+}
+
+static inline void //
+wuffs_base__u32__sat_add_indirect(uint32_t* x, uint32_t y) {
+ *x = wuffs_base__u32__sat_add(*x, y);
+}
+
+static inline void //
+wuffs_base__u32__sat_sub_indirect(uint32_t* x, uint32_t y) {
+ *x = wuffs_base__u32__sat_sub(*x, y);
+}
+
+static inline void //
+wuffs_base__u64__sat_add_indirect(uint64_t* x, uint64_t y) {
+ *x = wuffs_base__u64__sat_add(*x, y);
+}
+
+static inline void //
+wuffs_base__u64__sat_sub_indirect(uint64_t* x, uint64_t y) {
+ *x = wuffs_base__u64__sat_sub(*x, y);
+}
+
+// ---------------- Numeric Types (Utility)
+
+#define wuffs_base__utility__sign_extend_convert_u16_u32(a) \
+ ((uint32_t)(int32_t)(int16_t)(a))
+
+#define wuffs_base__utility__sign_extend_rshift_u32(a, n) \
+ ((uint32_t)(((int32_t)(a)) >> (n)))
+
+#define wuffs_base__utility__sign_extend_rshift_u64(a, n) \
+ ((uint64_t)(((int64_t)(a)) >> (n)))
+
+// ---------------- Slices and Tables
+
+// wuffs_base__slice_u8__prefix returns up to the first up_to bytes of s.
+static inline wuffs_base__slice_u8 //
+wuffs_base__slice_u8__prefix(wuffs_base__slice_u8 s, uint64_t up_to) {
+ if (((uint64_t)(s.len)) > up_to) {
+ s.len = ((size_t)up_to);
+ }
+ return s;
+}
+
+// wuffs_base__slice_u8__suffix returns up to the last up_to bytes of s.
+static inline wuffs_base__slice_u8 //
+wuffs_base__slice_u8__suffix(wuffs_base__slice_u8 s, uint64_t up_to) {
+ if (((uint64_t)(s.len)) > up_to) {
+ s.ptr += ((uint64_t)(s.len)) - up_to;
+ s.len = ((size_t)up_to);
+ }
+ return s;
+}
+
+// wuffs_base__slice_u8__copy_from_slice calls memmove(dst.ptr, src.ptr, len)
+// where len is the minimum of dst.len and src.len.
+//
+// Passing a wuffs_base__slice_u8 with all fields NULL or zero (a valid, empty
+// slice) is valid and results in a no-op.
+static inline uint64_t //
+wuffs_base__slice_u8__copy_from_slice(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src) {
+ size_t len = dst.len < src.len ? dst.len : src.len;
+ if (len > 0) {
+ memmove(dst.ptr, src.ptr, len);
+ }
+ return len;
+}
+
+static inline wuffs_base__empty_struct //
+wuffs_base__bulk_load_host_endian(void* ptr,
+ size_t len,
+ wuffs_base__slice_u8 src) {
+ if (len && (len <= src.len)) {
+ memmove(ptr, src.ptr, len);
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+static inline wuffs_base__empty_struct //
+wuffs_base__bulk_memset(void* ptr, size_t len, uint8_t byte_value) {
+ if (len) {
+ memset(ptr, byte_value, len);
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+static inline wuffs_base__empty_struct //
+wuffs_base__bulk_save_host_endian(void* ptr,
+ size_t len,
+ wuffs_base__slice_u8 dst) {
+ if (len && (len <= dst.len)) {
+ memmove(dst.ptr, ptr, len);
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// --------
+
+static inline wuffs_base__slice_u8 //
+wuffs_base__table_u8__row_u32(wuffs_base__table_u8 t, uint32_t y) {
+ if (y < t.height) {
+ return wuffs_base__make_slice_u8(t.ptr + (t.stride * y), t.width);
+ }
+ return wuffs_base__make_slice_u8(NULL, 0);
+}
+
+// ---------------- Slices and Tables (Utility)
+
+#define wuffs_base__utility__empty_slice_u8 wuffs_base__empty_slice_u8
+
+// ---------------- Ranges and Rects
+
+static inline uint32_t //
+wuffs_base__range_ii_u32__get_min_incl(const wuffs_base__range_ii_u32* r) {
+ return r->min_incl;
+}
+
+static inline uint32_t //
+wuffs_base__range_ii_u32__get_max_incl(const wuffs_base__range_ii_u32* r) {
+ return r->max_incl;
+}
+
+static inline uint32_t //
+wuffs_base__range_ie_u32__get_min_incl(const wuffs_base__range_ie_u32* r) {
+ return r->min_incl;
+}
+
+static inline uint32_t //
+wuffs_base__range_ie_u32__get_max_excl(const wuffs_base__range_ie_u32* r) {
+ return r->max_excl;
+}
+
+static inline uint64_t //
+wuffs_base__range_ii_u64__get_min_incl(const wuffs_base__range_ii_u64* r) {
+ return r->min_incl;
+}
+
+static inline uint64_t //
+wuffs_base__range_ii_u64__get_max_incl(const wuffs_base__range_ii_u64* r) {
+ return r->max_incl;
+}
+
+static inline uint64_t //
+wuffs_base__range_ie_u64__get_min_incl(const wuffs_base__range_ie_u64* r) {
+ return r->min_incl;
+}
+
+static inline uint64_t //
+wuffs_base__range_ie_u64__get_max_excl(const wuffs_base__range_ie_u64* r) {
+ return r->max_excl;
+}
+
+// ---------------- Ranges and Rects (Utility)
+
+#define wuffs_base__utility__empty_range_ii_u32 wuffs_base__empty_range_ii_u32
+#define wuffs_base__utility__empty_range_ie_u32 wuffs_base__empty_range_ie_u32
+#define wuffs_base__utility__empty_range_ii_u64 wuffs_base__empty_range_ii_u64
+#define wuffs_base__utility__empty_range_ie_u64 wuffs_base__empty_range_ie_u64
+#define wuffs_base__utility__empty_rect_ii_u32 wuffs_base__empty_rect_ii_u32
+#define wuffs_base__utility__empty_rect_ie_u32 wuffs_base__empty_rect_ie_u32
+#define wuffs_base__utility__make_range_ii_u32 wuffs_base__make_range_ii_u32
+#define wuffs_base__utility__make_range_ie_u32 wuffs_base__make_range_ie_u32
+#define wuffs_base__utility__make_range_ii_u64 wuffs_base__make_range_ii_u64
+#define wuffs_base__utility__make_range_ie_u64 wuffs_base__make_range_ie_u64
+#define wuffs_base__utility__make_rect_ii_u32 wuffs_base__make_rect_ii_u32
+#define wuffs_base__utility__make_rect_ie_u32 wuffs_base__make_rect_ie_u32
+
+// ---------------- I/O
+
+static inline uint64_t //
+wuffs_base__io__count_since(uint64_t mark, uint64_t index) {
+ if (index >= mark) {
+ return index - mark;
+ }
+ return 0;
+}
+
+// TODO: drop the "const" in "const uint8_t* ptr". Some though required about
+// the base.io_reader.since method returning a mutable "slice base.u8".
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-qual"
+#endif
+static inline wuffs_base__slice_u8 //
+wuffs_base__io__since(uint64_t mark, uint64_t index, const uint8_t* ptr) {
+ if (index >= mark) {
+ return wuffs_base__make_slice_u8(((uint8_t*)ptr) + mark,
+ ((size_t)(index - mark)));
+ }
+ return wuffs_base__make_slice_u8(NULL, 0);
+}
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+
+// --------
+
+static inline void //
+wuffs_base__io_reader__limit(const uint8_t** ptr_io2_r,
+ const uint8_t* iop_r,
+ uint64_t limit) {
+ if (((uint64_t)(*ptr_io2_r - iop_r)) > limit) {
+ *ptr_io2_r = iop_r + limit;
+ }
+}
+
+static inline uint32_t //
+wuffs_base__io_reader__limited_copy_u32_to_slice(const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r,
+ uint32_t length,
+ wuffs_base__slice_u8 dst) {
+ const uint8_t* iop_r = *ptr_iop_r;
+ size_t n = dst.len;
+ if (n > length) {
+ n = length;
+ }
+ if (n > ((size_t)(io2_r - iop_r))) {
+ n = (size_t)(io2_r - iop_r);
+ }
+ if (n > 0) {
+ memmove(dst.ptr, iop_r, n);
+ *ptr_iop_r += n;
+ }
+ return (uint32_t)(n);
+}
+
+// wuffs_base__io_reader__match7 returns whether the io_reader's upcoming bytes
+// start with the given prefix (up to 7 bytes long). It is peek-like, not
+// read-like, in that there are no side-effects.
+//
+// The low 3 bits of a hold the prefix length, n.
+//
+// The high 56 bits of a hold the prefix itself, in little-endian order. The
+// first prefix byte is in bits 8..=15, the second prefix byte is in bits
+// 16..=23, etc. The high (8 * (7 - n)) bits are ignored.
+//
+// There are three possible return values:
+// - 0 means success.
+// - 1 means inconclusive, equivalent to "$short read".
+// - 2 means failure.
+static inline uint32_t //
+wuffs_base__io_reader__match7(const uint8_t* iop_r,
+ const uint8_t* io2_r,
+ wuffs_base__io_buffer* r,
+ uint64_t a) {
+ uint32_t n = a & 7;
+ a >>= 8;
+ if ((io2_r - iop_r) >= 8) {
+ uint64_t x = wuffs_base__peek_u64le__no_bounds_check(iop_r);
+ uint32_t shift = 8 * (8 - n);
+ return ((a << shift) == (x << shift)) ? 0 : 2;
+ }
+ for (; n > 0; n--) {
+ if (iop_r >= io2_r) {
+ return (r && r->meta.closed) ? 2 : 1;
+ } else if (*iop_r != ((uint8_t)(a))) {
+ return 2;
+ }
+ iop_r++;
+ a >>= 8;
+ }
+ return 0;
+}
+
+static inline wuffs_base__io_buffer* //
+wuffs_base__io_reader__set(wuffs_base__io_buffer* b,
+ const uint8_t** ptr_iop_r,
+ const uint8_t** ptr_io0_r,
+ const uint8_t** ptr_io1_r,
+ const uint8_t** ptr_io2_r,
+ wuffs_base__slice_u8 data,
+ uint64_t history_position) {
+ b->data = data;
+ b->meta.wi = data.len;
+ b->meta.ri = 0;
+ b->meta.pos = history_position;
+ b->meta.closed = false;
+
+ *ptr_iop_r = data.ptr;
+ *ptr_io0_r = data.ptr;
+ *ptr_io1_r = data.ptr;
+ *ptr_io2_r = data.ptr + data.len;
+
+ return b;
+}
+
+// --------
+
+static inline uint64_t //
+wuffs_base__io_writer__copy_from_slice(uint8_t** ptr_iop_w,
+ uint8_t* io2_w,
+ wuffs_base__slice_u8 src) {
+ uint8_t* iop_w = *ptr_iop_w;
+ size_t n = src.len;
+ if (n > ((size_t)(io2_w - iop_w))) {
+ n = (size_t)(io2_w - iop_w);
+ }
+ if (n > 0) {
+ memmove(iop_w, src.ptr, n);
+ *ptr_iop_w += n;
+ }
+ return (uint64_t)(n);
+}
+
+static inline void //
+wuffs_base__io_writer__limit(uint8_t** ptr_io2_w,
+ uint8_t* iop_w,
+ uint64_t limit) {
+ if (((uint64_t)(*ptr_io2_w - iop_w)) > limit) {
+ *ptr_io2_w = iop_w + limit;
+ }
+}
+
+static inline uint32_t //
+wuffs_base__io_writer__limited_copy_u32_from_history(uint8_t** ptr_iop_w,
+ uint8_t* io0_w,
+ uint8_t* io2_w,
+ uint32_t length,
+ uint32_t distance) {
+ if (!distance) {
+ return 0;
+ }
+ uint8_t* p = *ptr_iop_w;
+ if ((size_t)(p - io0_w) < (size_t)(distance)) {
+ return 0;
+ }
+ uint8_t* q = p - distance;
+ size_t n = (size_t)(io2_w - p);
+ if ((size_t)(length) > n) {
+ length = (uint32_t)(n);
+ } else {
+ n = (size_t)(length);
+ }
+ // TODO: unrolling by 3 seems best for the std/deflate benchmarks, but that
+ // is mostly because 3 is the minimum length for the deflate format. This
+ // function implementation shouldn't overfit to that one format. Perhaps the
+ // limited_copy_u32_from_history Wuffs method should also take an unroll hint
+ // argument, and the cgen can look if that argument is the constant
+ // expression '3'.
+ //
+ // See also wuffs_base__io_writer__limited_copy_u32_from_history_fast below.
+ for (; n >= 3; n -= 3) {
+ *p++ = *q++;
+ *p++ = *q++;
+ *p++ = *q++;
+ }
+ for (; n; n--) {
+ *p++ = *q++;
+ }
+ *ptr_iop_w = p;
+ return length;
+}
+
+// wuffs_base__io_writer__limited_copy_u32_from_history_fast is like the
+// wuffs_base__io_writer__limited_copy_u32_from_history function above, but has
+// stronger pre-conditions.
+//
+// The caller needs to prove that:
+// - length <= (io2_w - *ptr_iop_w)
+// - distance >= 1
+// - distance <= (*ptr_iop_w - io0_w)
+static inline uint32_t //
+wuffs_base__io_writer__limited_copy_u32_from_history_fast(uint8_t** ptr_iop_w,
+ uint8_t* io0_w,
+ uint8_t* io2_w,
+ uint32_t length,
+ uint32_t distance) {
+ uint8_t* p = *ptr_iop_w;
+ uint8_t* q = p - distance;
+ uint32_t n = length;
+ for (; n >= 3; n -= 3) {
+ *p++ = *q++;
+ *p++ = *q++;
+ *p++ = *q++;
+ }
+ for (; n; n--) {
+ *p++ = *q++;
+ }
+ *ptr_iop_w = p;
+ return length;
+}
+
+// wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast
+// copies the previous byte (the one immediately before *ptr_iop_w), copying 8
+// byte chunks at a time. Each chunk contains 8 repetitions of the same byte.
+//
+// In terms of number of bytes copied, length is rounded up to a multiple of 8.
+// As a special case, a zero length rounds up to 8 (even though 0 is already a
+// multiple of 8), since there is always at least one 8 byte chunk copied.
+//
+// In terms of advancing *ptr_iop_w, length is not rounded up.
+//
+// The caller needs to prove that:
+// - (length + 8) <= (io2_w - *ptr_iop_w)
+// - distance == 1
+// - distance <= (*ptr_iop_w - io0_w)
+static inline uint32_t //
+wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
+ uint8_t** ptr_iop_w,
+ uint8_t* io0_w,
+ uint8_t* io2_w,
+ uint32_t length,
+ uint32_t distance) {
+ uint8_t* p = *ptr_iop_w;
+ uint64_t x = p[-1];
+ x |= x << 8;
+ x |= x << 16;
+ x |= x << 32;
+ uint32_t n = length;
+ while (1) {
+ wuffs_base__poke_u64le__no_bounds_check(p, x);
+ if (n <= 8) {
+ p += n;
+ break;
+ }
+ p += 8;
+ n -= 8;
+ }
+ *ptr_iop_w = p;
+ return length;
+}
+
+// wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast is
+// like the wuffs_base__io_writer__limited_copy_u32_from_history_fast function
+// above, but copies 8 byte chunks at a time.
+//
+// In terms of number of bytes copied, length is rounded up to a multiple of 8.
+// As a special case, a zero length rounds up to 8 (even though 0 is already a
+// multiple of 8), since there is always at least one 8 byte chunk copied.
+//
+// In terms of advancing *ptr_iop_w, length is not rounded up.
+//
+// The caller needs to prove that:
+// - (length + 8) <= (io2_w - *ptr_iop_w)
+// - distance >= 8
+// - distance <= (*ptr_iop_w - io0_w)
+static inline uint32_t //
+wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
+ uint8_t** ptr_iop_w,
+ uint8_t* io0_w,
+ uint8_t* io2_w,
+ uint32_t length,
+ uint32_t distance) {
+ uint8_t* p = *ptr_iop_w;
+ uint8_t* q = p - distance;
+ uint32_t n = length;
+ while (1) {
+ memcpy(p, q, 8);
+ if (n <= 8) {
+ p += n;
+ break;
+ }
+ p += 8;
+ q += 8;
+ n -= 8;
+ }
+ *ptr_iop_w = p;
+ return length;
+}
+
+static inline uint32_t //
+wuffs_base__io_writer__limited_copy_u32_from_reader(uint8_t** ptr_iop_w,
+ uint8_t* io2_w,
+ uint32_t length,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r) {
+ uint8_t* iop_w = *ptr_iop_w;
+ size_t n = length;
+ if (n > ((size_t)(io2_w - iop_w))) {
+ n = (size_t)(io2_w - iop_w);
+ }
+ const uint8_t* iop_r = *ptr_iop_r;
+ if (n > ((size_t)(io2_r - iop_r))) {
+ n = (size_t)(io2_r - iop_r);
+ }
+ if (n > 0) {
+ memmove(iop_w, iop_r, n);
+ *ptr_iop_w += n;
+ *ptr_iop_r += n;
+ }
+ return (uint32_t)(n);
+}
+
+static inline uint32_t //
+wuffs_base__io_writer__limited_copy_u32_from_slice(uint8_t** ptr_iop_w,
+ uint8_t* io2_w,
+ uint32_t length,
+ wuffs_base__slice_u8 src) {
+ uint8_t* iop_w = *ptr_iop_w;
+ size_t n = src.len;
+ if (n > length) {
+ n = length;
+ }
+ if (n > ((size_t)(io2_w - iop_w))) {
+ n = (size_t)(io2_w - iop_w);
+ }
+ if (n > 0) {
+ memmove(iop_w, src.ptr, n);
+ *ptr_iop_w += n;
+ }
+ return (uint32_t)(n);
+}
+
+static inline wuffs_base__io_buffer* //
+wuffs_base__io_writer__set(wuffs_base__io_buffer* b,
+ uint8_t** ptr_iop_w,
+ uint8_t** ptr_io0_w,
+ uint8_t** ptr_io1_w,
+ uint8_t** ptr_io2_w,
+ wuffs_base__slice_u8 data,
+ uint64_t history_position) {
+ b->data = data;
+ b->meta.wi = 0;
+ b->meta.ri = 0;
+ b->meta.pos = history_position;
+ b->meta.closed = false;
+
+ *ptr_iop_w = data.ptr;
+ *ptr_io0_w = data.ptr;
+ *ptr_io1_w = data.ptr;
+ *ptr_io2_w = data.ptr + data.len;
+
+ return b;
+}
+
+// ---------------- I/O (Utility)
+
+#define wuffs_base__utility__empty_io_reader wuffs_base__empty_io_reader
+#define wuffs_base__utility__empty_io_writer wuffs_base__empty_io_writer
+
+// ---------------- Tokens
+
+// ---------------- Tokens (Utility)
+
+// ---------------- Memory Allocation
+
+// ---------------- Images
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
+ const wuffs_base__pixel_swizzler* p,
+ uint32_t up_to_num_pixels,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r);
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
+ const wuffs_base__pixel_swizzler* p,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r);
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
+ const wuffs_base__pixel_swizzler* p,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ uint64_t num_pixels);
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__pixel_swizzler__swizzle_ycck(
+ const wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_buffer* dst,
+ wuffs_base__slice_u8 dst_palette,
+ uint32_t width,
+ uint32_t height,
+ wuffs_base__slice_u8 src0,
+ wuffs_base__slice_u8 src1,
+ wuffs_base__slice_u8 src2,
+ wuffs_base__slice_u8 src3,
+ uint32_t width0,
+ uint32_t width1,
+ uint32_t width2,
+ uint32_t width3,
+ uint32_t height0,
+ uint32_t height1,
+ uint32_t height2,
+ uint32_t height3,
+ uint32_t stride0,
+ uint32_t stride1,
+ uint32_t stride2,
+ uint32_t stride3,
+ uint8_t h0,
+ uint8_t h1,
+ uint8_t h2,
+ uint8_t h3,
+ uint8_t v0,
+ uint8_t v1,
+ uint8_t v2,
+ uint8_t v3,
+ bool is_rgb_or_cmyk,
+ bool triangle_filter_for_2to1,
+ wuffs_base__slice_u8 scratch_buffer_2k);
+
+// ---------------- Images (Utility)
+
+#define wuffs_base__utility__make_pixel_format wuffs_base__make_pixel_format
+
+// ---------------- String Conversions
+
+// ---------------- Unicode and UTF-8
+
+// ----------------
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+ defined(WUFFS_CONFIG__MODULE__BASE__CORE)
+
+const uint8_t wuffs_base__low_bits_mask__u8[8] = {
+ 0x00, 0x01, 0x03, 0x07, 0x0F, 0x1F, 0x3F, 0x7F,
+};
+
+const uint16_t wuffs_base__low_bits_mask__u16[16] = {
+ 0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F,
+ 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
+};
+
+const uint32_t wuffs_base__low_bits_mask__u32[32] = {
+ 0x00000000, 0x00000001, 0x00000003, 0x00000007, 0x0000000F, 0x0000001F,
+ 0x0000003F, 0x0000007F, 0x000000FF, 0x000001FF, 0x000003FF, 0x000007FF,
+ 0x00000FFF, 0x00001FFF, 0x00003FFF, 0x00007FFF, 0x0000FFFF, 0x0001FFFF,
+ 0x0003FFFF, 0x0007FFFF, 0x000FFFFF, 0x001FFFFF, 0x003FFFFF, 0x007FFFFF,
+ 0x00FFFFFF, 0x01FFFFFF, 0x03FFFFFF, 0x07FFFFFF, 0x0FFFFFFF, 0x1FFFFFFF,
+ 0x3FFFFFFF, 0x7FFFFFFF,
+};
+
+const uint64_t wuffs_base__low_bits_mask__u64[64] = {
+ 0x0000000000000000, 0x0000000000000001, 0x0000000000000003,
+ 0x0000000000000007, 0x000000000000000F, 0x000000000000001F,
+ 0x000000000000003F, 0x000000000000007F, 0x00000000000000FF,
+ 0x00000000000001FF, 0x00000000000003FF, 0x00000000000007FF,
+ 0x0000000000000FFF, 0x0000000000001FFF, 0x0000000000003FFF,
+ 0x0000000000007FFF, 0x000000000000FFFF, 0x000000000001FFFF,
+ 0x000000000003FFFF, 0x000000000007FFFF, 0x00000000000FFFFF,
+ 0x00000000001FFFFF, 0x00000000003FFFFF, 0x00000000007FFFFF,
+ 0x0000000000FFFFFF, 0x0000000001FFFFFF, 0x0000000003FFFFFF,
+ 0x0000000007FFFFFF, 0x000000000FFFFFFF, 0x000000001FFFFFFF,
+ 0x000000003FFFFFFF, 0x000000007FFFFFFF, 0x00000000FFFFFFFF,
+ 0x00000001FFFFFFFF, 0x00000003FFFFFFFF, 0x00000007FFFFFFFF,
+ 0x0000000FFFFFFFFF, 0x0000001FFFFFFFFF, 0x0000003FFFFFFFFF,
+ 0x0000007FFFFFFFFF, 0x000000FFFFFFFFFF, 0x000001FFFFFFFFFF,
+ 0x000003FFFFFFFFFF, 0x000007FFFFFFFFFF, 0x00000FFFFFFFFFFF,
+ 0x00001FFFFFFFFFFF, 0x00003FFFFFFFFFFF, 0x00007FFFFFFFFFFF,
+ 0x0000FFFFFFFFFFFF, 0x0001FFFFFFFFFFFF, 0x0003FFFFFFFFFFFF,
+ 0x0007FFFFFFFFFFFF, 0x000FFFFFFFFFFFFF, 0x001FFFFFFFFFFFFF,
+ 0x003FFFFFFFFFFFFF, 0x007FFFFFFFFFFFFF, 0x00FFFFFFFFFFFFFF,
+ 0x01FFFFFFFFFFFFFF, 0x03FFFFFFFFFFFFFF, 0x07FFFFFFFFFFFFFF,
+ 0x0FFFFFFFFFFFFFFF, 0x1FFFFFFFFFFFFFFF, 0x3FFFFFFFFFFFFFFF,
+ 0x7FFFFFFFFFFFFFFF,
+};
+
+const uint32_t wuffs_base__pixel_format__bits_per_channel[16] = {
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x0A, 0x0C, 0x10, 0x18, 0x20, 0x30, 0x40,
+};
+
+const char wuffs_base__note__i_o_redirect[] = "@base: I/O redirect";
+const char wuffs_base__note__end_of_data[] = "@base: end of data";
+const char wuffs_base__note__metadata_reported[] = "@base: metadata reported";
+const char wuffs_base__suspension__even_more_information[] = "$base: even more information";
+const char wuffs_base__suspension__mispositioned_read[] = "$base: mispositioned read";
+const char wuffs_base__suspension__mispositioned_write[] = "$base: mispositioned write";
+const char wuffs_base__suspension__short_read[] = "$base: short read";
+const char wuffs_base__suspension__short_write[] = "$base: short write";
+const char wuffs_base__error__bad_i_o_position[] = "#base: bad I/O position";
+const char wuffs_base__error__bad_argument_length_too_short[] = "#base: bad argument (length too short)";
+const char wuffs_base__error__bad_argument[] = "#base: bad argument";
+const char wuffs_base__error__bad_call_sequence[] = "#base: bad call sequence";
+const char wuffs_base__error__bad_data[] = "#base: bad data";
+const char wuffs_base__error__bad_receiver[] = "#base: bad receiver";
+const char wuffs_base__error__bad_restart[] = "#base: bad restart";
+const char wuffs_base__error__bad_sizeof_receiver[] = "#base: bad sizeof receiver";
+const char wuffs_base__error__bad_vtable[] = "#base: bad vtable";
+const char wuffs_base__error__bad_workbuf_length[] = "#base: bad workbuf length";
+const char wuffs_base__error__bad_wuffs_version[] = "#base: bad wuffs version";
+const char wuffs_base__error__cannot_return_a_suspension[] = "#base: cannot return a suspension";
+const char wuffs_base__error__disabled_by_previous_error[] = "#base: disabled by previous error";
+const char wuffs_base__error__initialize_falsely_claimed_already_zeroed[] = "#base: initialize falsely claimed already zeroed";
+const char wuffs_base__error__initialize_not_called[] = "#base: initialize not called";
+const char wuffs_base__error__interleaved_coroutine_calls[] = "#base: interleaved coroutine calls";
+const char wuffs_base__error__no_more_information[] = "#base: no more information";
+const char wuffs_base__error__not_enough_data[] = "#base: not enough data";
+const char wuffs_base__error__out_of_bounds[] = "#base: out of bounds";
+const char wuffs_base__error__unsupported_image_dimension[] = "#base: unsupported image dimension";
+const char wuffs_base__error__unsupported_method[] = "#base: unsupported method";
+const char wuffs_base__error__unsupported_option[] = "#base: unsupported option";
+const char wuffs_base__error__unsupported_pixel_swizzler_option[] = "#base: unsupported pixel swizzler option";
+const char wuffs_base__error__too_much_data[] = "#base: too much data";
+
+const char wuffs_base__hasher_u32__vtable_name[] = "{vtable}wuffs_base__hasher_u32";
+const char wuffs_base__hasher_u64__vtable_name[] = "{vtable}wuffs_base__hasher_u64";
+const char wuffs_base__image_decoder__vtable_name[] = "{vtable}wuffs_base__image_decoder";
+const char wuffs_base__io_transformer__vtable_name[] = "{vtable}wuffs_base__io_transformer";
+const char wuffs_base__token_decoder__vtable_name[] = "{vtable}wuffs_base__token_decoder";
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE__CORE)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+ defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
+
+// ---------------- Interface Definitions.
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_base__hasher_u32__checksum_u32(
+ const wuffs_base__hasher_u32* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
+ const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->checksum_u32)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__hasher_u32__get_quirk(
+ const wuffs_base__hasher_u32* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
+ const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->get_quirk)(self, a_key);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__hasher_u32__set_quirk(
+ wuffs_base__hasher_u32* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
+ const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->set_quirk)(self, a_key, a_value);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_base__hasher_u32__update(
+ wuffs_base__hasher_u32* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
+ const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->update)(self, a_x);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_empty_struct();
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_base__hasher_u32__update_u32(
+ wuffs_base__hasher_u32* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return 0;
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u32__vtable_name) {
+ const wuffs_base__hasher_u32__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u32__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->update_u32)(self, a_x);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+// --------
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__hasher_u64__checksum_u64(
+ const wuffs_base__hasher_u64* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
+ const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->checksum_u64)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__hasher_u64__get_quirk(
+ const wuffs_base__hasher_u64* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
+ const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->get_quirk)(self, a_key);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__hasher_u64__set_quirk(
+ wuffs_base__hasher_u64* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
+ const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->set_quirk)(self, a_key, a_value);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_base__hasher_u64__update(
+ wuffs_base__hasher_u64* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
+ const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->update)(self, a_x);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_empty_struct();
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__hasher_u64__update_u64(
+ wuffs_base__hasher_u64* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return 0;
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__hasher_u64__vtable_name) {
+ const wuffs_base__hasher_u64__func_ptrs* func_ptrs =
+ (const wuffs_base__hasher_u64__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->update_u64)(self, a_x);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+// --------
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__decode_frame(
+ wuffs_base__image_decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->decode_frame)(self, a_dst, a_src, a_blend, a_workbuf, a_opts);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__decode_frame_config(
+ wuffs_base__image_decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->decode_frame_config)(self, a_dst, a_src);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__decode_image_config(
+ wuffs_base__image_decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->decode_image_config)(self, a_dst, a_src);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_base__image_decoder__frame_dirty_rect(
+ const wuffs_base__image_decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->frame_dirty_rect)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__utility__empty_rect_ie_u32();
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__image_decoder__get_quirk(
+ const wuffs_base__image_decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->get_quirk)(self, a_key);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__image_decoder__history_retain_length(
+ const wuffs_base__image_decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->history_retain_length)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_base__image_decoder__num_animation_loops(
+ const wuffs_base__image_decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->num_animation_loops)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__image_decoder__num_decoded_frame_configs(
+ const wuffs_base__image_decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->num_decoded_frame_configs)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__image_decoder__num_decoded_frames(
+ const wuffs_base__image_decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->num_decoded_frames)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__restart_frame(
+ wuffs_base__image_decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->restart_frame)(self, a_index, a_io_position);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__set_quirk(
+ wuffs_base__image_decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->set_quirk)(self, a_key, a_value);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_base__image_decoder__set_report_metadata(
+ wuffs_base__image_decoder* self,
+ uint32_t a_fourcc,
+ bool a_report) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->set_report_metadata)(self, a_fourcc, a_report);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_empty_struct();
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__image_decoder__tell_me_more(
+ wuffs_base__image_decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->tell_me_more)(self, a_dst, a_minfo, a_src);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_base__image_decoder__workbuf_len(
+ const wuffs_base__image_decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__image_decoder__vtable_name) {
+ const wuffs_base__image_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__image_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->workbuf_len)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__utility__empty_range_ii_u64();
+}
+
+// --------
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__io_transformer__get_quirk(
+ const wuffs_base__io_transformer* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
+ const wuffs_base__io_transformer__func_ptrs* func_ptrs =
+ (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->get_quirk)(self, a_key);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__io_transformer__history_retain_length(
+ const wuffs_base__io_transformer* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
+ const wuffs_base__io_transformer__func_ptrs* func_ptrs =
+ (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->history_retain_length)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__io_transformer__set_quirk(
+ wuffs_base__io_transformer* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
+ const wuffs_base__io_transformer__func_ptrs* func_ptrs =
+ (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->set_quirk)(self, a_key, a_value);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__io_transformer__transform_io(
+ wuffs_base__io_transformer* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
+ const wuffs_base__io_transformer__func_ptrs* func_ptrs =
+ (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->transform_io)(self, a_dst, a_src, a_workbuf);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_base__io_transformer__workbuf_len(
+ const wuffs_base__io_transformer* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__io_transformer__vtable_name) {
+ const wuffs_base__io_transformer__func_ptrs* func_ptrs =
+ (const wuffs_base__io_transformer__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->workbuf_len)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__utility__empty_range_ii_u64();
+}
+
+// --------
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__token_decoder__decode_tokens(
+ wuffs_base__token_decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+ const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->decode_tokens)(self, a_dst, a_src, a_workbuf);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__token_decoder__get_quirk(
+ const wuffs_base__token_decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+ const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->get_quirk)(self, a_key);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_base__token_decoder__history_retain_length(
+ const wuffs_base__token_decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+ const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->history_retain_length)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return 0;
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_base__token_decoder__set_quirk(
+ wuffs_base__token_decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+ const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->set_quirk)(self, a_key, a_value);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__bad_vtable);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_base__token_decoder__workbuf_len(
+ const wuffs_base__token_decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ const wuffs_base__vtable* v = &self->private_impl.first_vtable;
+ int i;
+ for (i = 0; i < 63; i++) {
+ if (v->vtable_name == wuffs_base__token_decoder__vtable_name) {
+ const wuffs_base__token_decoder__func_ptrs* func_ptrs =
+ (const wuffs_base__token_decoder__func_ptrs*)(v->function_pointers);
+ return (*func_ptrs->workbuf_len)(self);
+ } else if (v->vtable_name == NULL) {
+ break;
+ }
+ v++;
+ }
+
+ return wuffs_base__utility__empty_range_ii_u64();
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE__INTERFACES)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+ defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
+
+// ---------------- IEEE 754 Floating Point
+
+// The etc__hpd_left_shift and etc__powers_of_5 tables were printed by
+// script/print-hpd-left-shift.go. That script has an optional -comments flag,
+// whose output is not copied here, which prints further detail.
+//
+// These tables are used in
+// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits.
+
+// wuffs_base__private_implementation__hpd_left_shift[i] encodes the number of
+// new digits created after multiplying a positive integer by (1 << i): the
+// additional length in the decimal representation. For example, shifting "234"
+// by 3 (equivalent to multiplying by 8) will produce "1872". Going from a
+// 3-length string to a 4-length string means that 1 new digit was added (and
+// existing digits may have changed).
+//
+// Shifting by i can add either N or N-1 new digits, depending on whether the
+// original positive integer compares >= or < to the i'th power of 5 (as 10
+// equals 2 * 5). Comparison is lexicographic, not numerical.
+//
+// For example, shifting by 4 (i.e. multiplying by 16) can add 1 or 2 new
+// digits, depending on a lexicographic comparison to (5 ** 4), i.e. "625":
+// - ("1" << 4) is "16", which adds 1 new digit.
+// - ("5678" << 4) is "90848", which adds 1 new digit.
+// - ("624" << 4) is "9984", which adds 1 new digit.
+// - ("62498" << 4) is "999968", which adds 1 new digit.
+// - ("625" << 4) is "10000", which adds 2 new digits.
+// - ("625001" << 4) is "10000016", which adds 2 new digits.
+// - ("7008" << 4) is "112128", which adds 2 new digits.
+// - ("99" << 4) is "1584", which adds 2 new digits.
+//
+// Thus, when i is 4, N is 2 and (5 ** i) is "625". This etc__hpd_left_shift
+// array encodes this as:
+// - etc__hpd_left_shift[4] is 0x1006 = (2 << 11) | 0x0006.
+// - etc__hpd_left_shift[5] is 0x1009 = (? << 11) | 0x0009.
+// where the ? isn't relevant for i == 4.
+//
+// The high 5 bits of etc__hpd_left_shift[i] is N, the higher of the two
+// possible number of new digits. The low 11 bits are an offset into the
+// etc__powers_of_5 array (of length 0x051C, so offsets fit in 11 bits). When i
+// is 4, its offset and the next one is 6 and 9, and etc__powers_of_5[6 .. 9]
+// is the string "\x06\x02\x05", so the relevant power of 5 is "625".
+//
+// Thanks to Ken Thompson for the original idea.
+static const uint16_t wuffs_base__private_implementation__hpd_left_shift[65] = {
+ 0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817,
+ 0x181D, 0x2024, 0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067,
+ 0x3073, 0x3080, 0x388E, 0x389C, 0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF,
+ 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169, 0x5180, 0x5998, 0x59B0,
+ 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B, 0x72AA,
+ 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC,
+ 0x8C02, 0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C,
+ 0x051C, 0x051C,
+};
+
+// wuffs_base__private_implementation__powers_of_5 contains the powers of 5,
+// concatenated together: "5", "25", "125", "625", "3125", etc.
+static const uint8_t wuffs_base__private_implementation__powers_of_5[0x051C] = {
+ 5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9,
+ 0, 6, 2, 5, 1, 9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2,
+ 5, 2, 4, 4, 1, 4, 0, 6, 2, 5, 1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5,
+ 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2, 5, 1, 5, 2, 5, 8, 7, 8, 9, 0,
+ 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6, 9, 7, 2, 6, 5,
+ 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1,
+ 6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4,
+ 1, 8, 5, 7, 9, 1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7,
+ 8, 1, 2, 5, 5, 9, 6, 0, 4, 6, 4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0,
+ 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1, 4, 9, 0, 1, 1, 6, 1, 1, 9, 3,
+ 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2, 3, 8, 2, 8, 1,
+ 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6,
+ 2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5,
+ 7, 4, 6, 1, 5, 4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0,
+ 7, 7, 3, 9, 2, 5, 7, 8, 1, 2, 5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6,
+ 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5, 3, 2, 1, 8, 2, 6, 9, 3, 4, 8,
+ 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4, 6, 7, 4, 0, 7,
+ 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6,
+ 1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8,
+ 0, 6, 6, 4, 0, 6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9,
+ 0, 3, 3, 2, 0, 3, 1, 2, 5, 3, 6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2,
+ 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8, 9, 8, 9, 4, 0, 3, 5, 4, 5, 8,
+ 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4, 7, 0, 1, 7, 7,
+ 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5,
+ 0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3,
+ 7, 3, 6, 7, 5, 4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2,
+ 5, 1, 1, 3, 6, 8, 6, 8, 3, 7, 7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9,
+ 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8, 8, 6, 0, 8, 0, 8, 0, 1, 4, 8,
+ 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0, 9, 4, 3, 0, 4,
+ 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0,
+ 8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5,
+ 6, 2, 5, 7, 1, 0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1,
+ 2, 4, 2, 6, 7, 5, 7, 8, 1, 2, 5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5,
+ 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8, 9, 0, 6, 2, 5, 1, 7, 7, 6, 3,
+ 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0, 6, 6, 8, 9, 4,
+ 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3,
+ 8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8,
+ 5, 0, 0, 6, 2, 6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2,
+ 5, 2, 2, 2, 0, 4, 4, 6, 0, 4, 9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6,
+ 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1, 1, 0, 2, 2, 3, 0, 2, 4, 6, 2,
+ 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8, 2, 0, 3, 1, 2,
+ 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5,
+ 8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5,
+ 6, 2, 8, 9, 1, 3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8,
+ 1, 2, 5, 1, 3, 8, 7, 7, 7, 8, 7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9,
+ 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0, 6, 2, 5, 6, 9, 3, 8, 8, 9, 3,
+ 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2, 5, 5, 6, 7, 6,
+ 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1,
+ 8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1,
+ 7, 3, 4, 7, 2, 3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4,
+ 8, 1, 3, 9, 1, 9, 0, 6, 7, 3, 8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7,
+ 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2, 2, 4, 0, 6, 9, 5, 9, 5, 3, 3,
+ 6, 9, 1, 4, 0, 6, 2, 5,
+};
+
+// --------
+
+// wuffs_base__private_implementation__powers_of_10 contains truncated
+// approximations to the powers of 10, ranging from 1e-307 to 1e+288 inclusive,
+// as 596 pairs of uint64_t values (a 128-bit mantissa).
+//
+// There's also an implicit third column (implied by a linear formula involving
+// the base-10 exponent) that is the base-2 exponent, biased by a magic
+// constant. That constant (1214 or 0x04BE) equals 1023 + 191. 1023 is the bias
+// for IEEE 754 double-precision floating point. 191 is ((3 * 64) - 1) and
+// wuffs_base__private_implementation__parse_number_f64_eisel_lemire works with
+// multiples-of-64-bit mantissas.
+//
+// For example, the third row holds the approximation to 1e-305:
+// 0xE0B62E29_29ABA83C_331ACDAB_FE94DE87 * (2 ** (0x0049 - 0x04BE))
+//
+// Similarly, 1e+4 is approximated by:
+// 0x9C400000_00000000_00000000_00000000 * (2 ** (0x044C - 0x04BE))
+//
+// Similarly, 1e+68 is approximated by:
+// 0xED63A231_D4C4FB27_4CA7AAA8_63EE4BDD * (2 ** (0x0520 - 0x04BE))
+//
+// This table was generated by by script/print-mpb-powers-of-10.go
+static const uint64_t wuffs_base__private_implementation__powers_of_10[596][2] =
+ {
+ {0xA5D3B6D479F8E056, 0x8FD0C16206306BAB}, // 1e-307
+ {0x8F48A4899877186C, 0xB3C4F1BA87BC8696}, // 1e-306
+ {0x331ACDABFE94DE87, 0xE0B62E2929ABA83C}, // 1e-305
+ {0x9FF0C08B7F1D0B14, 0x8C71DCD9BA0B4925}, // 1e-304
+ {0x07ECF0AE5EE44DD9, 0xAF8E5410288E1B6F}, // 1e-303
+ {0xC9E82CD9F69D6150, 0xDB71E91432B1A24A}, // 1e-302
+ {0xBE311C083A225CD2, 0x892731AC9FAF056E}, // 1e-301
+ {0x6DBD630A48AAF406, 0xAB70FE17C79AC6CA}, // 1e-300
+ {0x092CBBCCDAD5B108, 0xD64D3D9DB981787D}, // 1e-299
+ {0x25BBF56008C58EA5, 0x85F0468293F0EB4E}, // 1e-298
+ {0xAF2AF2B80AF6F24E, 0xA76C582338ED2621}, // 1e-297
+ {0x1AF5AF660DB4AEE1, 0xD1476E2C07286FAA}, // 1e-296
+ {0x50D98D9FC890ED4D, 0x82CCA4DB847945CA}, // 1e-295
+ {0xE50FF107BAB528A0, 0xA37FCE126597973C}, // 1e-294
+ {0x1E53ED49A96272C8, 0xCC5FC196FEFD7D0C}, // 1e-293
+ {0x25E8E89C13BB0F7A, 0xFF77B1FCBEBCDC4F}, // 1e-292
+ {0x77B191618C54E9AC, 0x9FAACF3DF73609B1}, // 1e-291
+ {0xD59DF5B9EF6A2417, 0xC795830D75038C1D}, // 1e-290
+ {0x4B0573286B44AD1D, 0xF97AE3D0D2446F25}, // 1e-289
+ {0x4EE367F9430AEC32, 0x9BECCE62836AC577}, // 1e-288
+ {0x229C41F793CDA73F, 0xC2E801FB244576D5}, // 1e-287
+ {0x6B43527578C1110F, 0xF3A20279ED56D48A}, // 1e-286
+ {0x830A13896B78AAA9, 0x9845418C345644D6}, // 1e-285
+ {0x23CC986BC656D553, 0xBE5691EF416BD60C}, // 1e-284
+ {0x2CBFBE86B7EC8AA8, 0xEDEC366B11C6CB8F}, // 1e-283
+ {0x7BF7D71432F3D6A9, 0x94B3A202EB1C3F39}, // 1e-282
+ {0xDAF5CCD93FB0CC53, 0xB9E08A83A5E34F07}, // 1e-281
+ {0xD1B3400F8F9CFF68, 0xE858AD248F5C22C9}, // 1e-280
+ {0x23100809B9C21FA1, 0x91376C36D99995BE}, // 1e-279
+ {0xABD40A0C2832A78A, 0xB58547448FFFFB2D}, // 1e-278
+ {0x16C90C8F323F516C, 0xE2E69915B3FFF9F9}, // 1e-277
+ {0xAE3DA7D97F6792E3, 0x8DD01FAD907FFC3B}, // 1e-276
+ {0x99CD11CFDF41779C, 0xB1442798F49FFB4A}, // 1e-275
+ {0x40405643D711D583, 0xDD95317F31C7FA1D}, // 1e-274
+ {0x482835EA666B2572, 0x8A7D3EEF7F1CFC52}, // 1e-273
+ {0xDA3243650005EECF, 0xAD1C8EAB5EE43B66}, // 1e-272
+ {0x90BED43E40076A82, 0xD863B256369D4A40}, // 1e-271
+ {0x5A7744A6E804A291, 0x873E4F75E2224E68}, // 1e-270
+ {0x711515D0A205CB36, 0xA90DE3535AAAE202}, // 1e-269
+ {0x0D5A5B44CA873E03, 0xD3515C2831559A83}, // 1e-268
+ {0xE858790AFE9486C2, 0x8412D9991ED58091}, // 1e-267
+ {0x626E974DBE39A872, 0xA5178FFF668AE0B6}, // 1e-266
+ {0xFB0A3D212DC8128F, 0xCE5D73FF402D98E3}, // 1e-265
+ {0x7CE66634BC9D0B99, 0x80FA687F881C7F8E}, // 1e-264
+ {0x1C1FFFC1EBC44E80, 0xA139029F6A239F72}, // 1e-263
+ {0xA327FFB266B56220, 0xC987434744AC874E}, // 1e-262
+ {0x4BF1FF9F0062BAA8, 0xFBE9141915D7A922}, // 1e-261
+ {0x6F773FC3603DB4A9, 0x9D71AC8FADA6C9B5}, // 1e-260
+ {0xCB550FB4384D21D3, 0xC4CE17B399107C22}, // 1e-259
+ {0x7E2A53A146606A48, 0xF6019DA07F549B2B}, // 1e-258
+ {0x2EDA7444CBFC426D, 0x99C102844F94E0FB}, // 1e-257
+ {0xFA911155FEFB5308, 0xC0314325637A1939}, // 1e-256
+ {0x793555AB7EBA27CA, 0xF03D93EEBC589F88}, // 1e-255
+ {0x4BC1558B2F3458DE, 0x96267C7535B763B5}, // 1e-254
+ {0x9EB1AAEDFB016F16, 0xBBB01B9283253CA2}, // 1e-253
+ {0x465E15A979C1CADC, 0xEA9C227723EE8BCB}, // 1e-252
+ {0x0BFACD89EC191EC9, 0x92A1958A7675175F}, // 1e-251
+ {0xCEF980EC671F667B, 0xB749FAED14125D36}, // 1e-250
+ {0x82B7E12780E7401A, 0xE51C79A85916F484}, // 1e-249
+ {0xD1B2ECB8B0908810, 0x8F31CC0937AE58D2}, // 1e-248
+ {0x861FA7E6DCB4AA15, 0xB2FE3F0B8599EF07}, // 1e-247
+ {0x67A791E093E1D49A, 0xDFBDCECE67006AC9}, // 1e-246
+ {0xE0C8BB2C5C6D24E0, 0x8BD6A141006042BD}, // 1e-245
+ {0x58FAE9F773886E18, 0xAECC49914078536D}, // 1e-244
+ {0xAF39A475506A899E, 0xDA7F5BF590966848}, // 1e-243
+ {0x6D8406C952429603, 0x888F99797A5E012D}, // 1e-242
+ {0xC8E5087BA6D33B83, 0xAAB37FD7D8F58178}, // 1e-241
+ {0xFB1E4A9A90880A64, 0xD5605FCDCF32E1D6}, // 1e-240
+ {0x5CF2EEA09A55067F, 0x855C3BE0A17FCD26}, // 1e-239
+ {0xF42FAA48C0EA481E, 0xA6B34AD8C9DFC06F}, // 1e-238
+ {0xF13B94DAF124DA26, 0xD0601D8EFC57B08B}, // 1e-237
+ {0x76C53D08D6B70858, 0x823C12795DB6CE57}, // 1e-236
+ {0x54768C4B0C64CA6E, 0xA2CB1717B52481ED}, // 1e-235
+ {0xA9942F5DCF7DFD09, 0xCB7DDCDDA26DA268}, // 1e-234
+ {0xD3F93B35435D7C4C, 0xFE5D54150B090B02}, // 1e-233
+ {0xC47BC5014A1A6DAF, 0x9EFA548D26E5A6E1}, // 1e-232
+ {0x359AB6419CA1091B, 0xC6B8E9B0709F109A}, // 1e-231
+ {0xC30163D203C94B62, 0xF867241C8CC6D4C0}, // 1e-230
+ {0x79E0DE63425DCF1D, 0x9B407691D7FC44F8}, // 1e-229
+ {0x985915FC12F542E4, 0xC21094364DFB5636}, // 1e-228
+ {0x3E6F5B7B17B2939D, 0xF294B943E17A2BC4}, // 1e-227
+ {0xA705992CEECF9C42, 0x979CF3CA6CEC5B5A}, // 1e-226
+ {0x50C6FF782A838353, 0xBD8430BD08277231}, // 1e-225
+ {0xA4F8BF5635246428, 0xECE53CEC4A314EBD}, // 1e-224
+ {0x871B7795E136BE99, 0x940F4613AE5ED136}, // 1e-223
+ {0x28E2557B59846E3F, 0xB913179899F68584}, // 1e-222
+ {0x331AEADA2FE589CF, 0xE757DD7EC07426E5}, // 1e-221
+ {0x3FF0D2C85DEF7621, 0x9096EA6F3848984F}, // 1e-220
+ {0x0FED077A756B53A9, 0xB4BCA50B065ABE63}, // 1e-219
+ {0xD3E8495912C62894, 0xE1EBCE4DC7F16DFB}, // 1e-218
+ {0x64712DD7ABBBD95C, 0x8D3360F09CF6E4BD}, // 1e-217
+ {0xBD8D794D96AACFB3, 0xB080392CC4349DEC}, // 1e-216
+ {0xECF0D7A0FC5583A0, 0xDCA04777F541C567}, // 1e-215
+ {0xF41686C49DB57244, 0x89E42CAAF9491B60}, // 1e-214
+ {0x311C2875C522CED5, 0xAC5D37D5B79B6239}, // 1e-213
+ {0x7D633293366B828B, 0xD77485CB25823AC7}, // 1e-212
+ {0xAE5DFF9C02033197, 0x86A8D39EF77164BC}, // 1e-211
+ {0xD9F57F830283FDFC, 0xA8530886B54DBDEB}, // 1e-210
+ {0xD072DF63C324FD7B, 0xD267CAA862A12D66}, // 1e-209
+ {0x4247CB9E59F71E6D, 0x8380DEA93DA4BC60}, // 1e-208
+ {0x52D9BE85F074E608, 0xA46116538D0DEB78}, // 1e-207
+ {0x67902E276C921F8B, 0xCD795BE870516656}, // 1e-206
+ {0x00BA1CD8A3DB53B6, 0x806BD9714632DFF6}, // 1e-205
+ {0x80E8A40ECCD228A4, 0xA086CFCD97BF97F3}, // 1e-204
+ {0x6122CD128006B2CD, 0xC8A883C0FDAF7DF0}, // 1e-203
+ {0x796B805720085F81, 0xFAD2A4B13D1B5D6C}, // 1e-202
+ {0xCBE3303674053BB0, 0x9CC3A6EEC6311A63}, // 1e-201
+ {0xBEDBFC4411068A9C, 0xC3F490AA77BD60FC}, // 1e-200
+ {0xEE92FB5515482D44, 0xF4F1B4D515ACB93B}, // 1e-199
+ {0x751BDD152D4D1C4A, 0x991711052D8BF3C5}, // 1e-198
+ {0xD262D45A78A0635D, 0xBF5CD54678EEF0B6}, // 1e-197
+ {0x86FB897116C87C34, 0xEF340A98172AACE4}, // 1e-196
+ {0xD45D35E6AE3D4DA0, 0x9580869F0E7AAC0E}, // 1e-195
+ {0x8974836059CCA109, 0xBAE0A846D2195712}, // 1e-194
+ {0x2BD1A438703FC94B, 0xE998D258869FACD7}, // 1e-193
+ {0x7B6306A34627DDCF, 0x91FF83775423CC06}, // 1e-192
+ {0x1A3BC84C17B1D542, 0xB67F6455292CBF08}, // 1e-191
+ {0x20CABA5F1D9E4A93, 0xE41F3D6A7377EECA}, // 1e-190
+ {0x547EB47B7282EE9C, 0x8E938662882AF53E}, // 1e-189
+ {0xE99E619A4F23AA43, 0xB23867FB2A35B28D}, // 1e-188
+ {0x6405FA00E2EC94D4, 0xDEC681F9F4C31F31}, // 1e-187
+ {0xDE83BC408DD3DD04, 0x8B3C113C38F9F37E}, // 1e-186
+ {0x9624AB50B148D445, 0xAE0B158B4738705E}, // 1e-185
+ {0x3BADD624DD9B0957, 0xD98DDAEE19068C76}, // 1e-184
+ {0xE54CA5D70A80E5D6, 0x87F8A8D4CFA417C9}, // 1e-183
+ {0x5E9FCF4CCD211F4C, 0xA9F6D30A038D1DBC}, // 1e-182
+ {0x7647C3200069671F, 0xD47487CC8470652B}, // 1e-181
+ {0x29ECD9F40041E073, 0x84C8D4DFD2C63F3B}, // 1e-180
+ {0xF468107100525890, 0xA5FB0A17C777CF09}, // 1e-179
+ {0x7182148D4066EEB4, 0xCF79CC9DB955C2CC}, // 1e-178
+ {0xC6F14CD848405530, 0x81AC1FE293D599BF}, // 1e-177
+ {0xB8ADA00E5A506A7C, 0xA21727DB38CB002F}, // 1e-176
+ {0xA6D90811F0E4851C, 0xCA9CF1D206FDC03B}, // 1e-175
+ {0x908F4A166D1DA663, 0xFD442E4688BD304A}, // 1e-174
+ {0x9A598E4E043287FE, 0x9E4A9CEC15763E2E}, // 1e-173
+ {0x40EFF1E1853F29FD, 0xC5DD44271AD3CDBA}, // 1e-172
+ {0xD12BEE59E68EF47C, 0xF7549530E188C128}, // 1e-171
+ {0x82BB74F8301958CE, 0x9A94DD3E8CF578B9}, // 1e-170
+ {0xE36A52363C1FAF01, 0xC13A148E3032D6E7}, // 1e-169
+ {0xDC44E6C3CB279AC1, 0xF18899B1BC3F8CA1}, // 1e-168
+ {0x29AB103A5EF8C0B9, 0x96F5600F15A7B7E5}, // 1e-167
+ {0x7415D448F6B6F0E7, 0xBCB2B812DB11A5DE}, // 1e-166
+ {0x111B495B3464AD21, 0xEBDF661791D60F56}, // 1e-165
+ {0xCAB10DD900BEEC34, 0x936B9FCEBB25C995}, // 1e-164
+ {0x3D5D514F40EEA742, 0xB84687C269EF3BFB}, // 1e-163
+ {0x0CB4A5A3112A5112, 0xE65829B3046B0AFA}, // 1e-162
+ {0x47F0E785EABA72AB, 0x8FF71A0FE2C2E6DC}, // 1e-161
+ {0x59ED216765690F56, 0xB3F4E093DB73A093}, // 1e-160
+ {0x306869C13EC3532C, 0xE0F218B8D25088B8}, // 1e-159
+ {0x1E414218C73A13FB, 0x8C974F7383725573}, // 1e-158
+ {0xE5D1929EF90898FA, 0xAFBD2350644EEACF}, // 1e-157
+ {0xDF45F746B74ABF39, 0xDBAC6C247D62A583}, // 1e-156
+ {0x6B8BBA8C328EB783, 0x894BC396CE5DA772}, // 1e-155
+ {0x066EA92F3F326564, 0xAB9EB47C81F5114F}, // 1e-154
+ {0xC80A537B0EFEFEBD, 0xD686619BA27255A2}, // 1e-153
+ {0xBD06742CE95F5F36, 0x8613FD0145877585}, // 1e-152
+ {0x2C48113823B73704, 0xA798FC4196E952E7}, // 1e-151
+ {0xF75A15862CA504C5, 0xD17F3B51FCA3A7A0}, // 1e-150
+ {0x9A984D73DBE722FB, 0x82EF85133DE648C4}, // 1e-149
+ {0xC13E60D0D2E0EBBA, 0xA3AB66580D5FDAF5}, // 1e-148
+ {0x318DF905079926A8, 0xCC963FEE10B7D1B3}, // 1e-147
+ {0xFDF17746497F7052, 0xFFBBCFE994E5C61F}, // 1e-146
+ {0xFEB6EA8BEDEFA633, 0x9FD561F1FD0F9BD3}, // 1e-145
+ {0xFE64A52EE96B8FC0, 0xC7CABA6E7C5382C8}, // 1e-144
+ {0x3DFDCE7AA3C673B0, 0xF9BD690A1B68637B}, // 1e-143
+ {0x06BEA10CA65C084E, 0x9C1661A651213E2D}, // 1e-142
+ {0x486E494FCFF30A62, 0xC31BFA0FE5698DB8}, // 1e-141
+ {0x5A89DBA3C3EFCCFA, 0xF3E2F893DEC3F126}, // 1e-140
+ {0xF89629465A75E01C, 0x986DDB5C6B3A76B7}, // 1e-139
+ {0xF6BBB397F1135823, 0xBE89523386091465}, // 1e-138
+ {0x746AA07DED582E2C, 0xEE2BA6C0678B597F}, // 1e-137
+ {0xA8C2A44EB4571CDC, 0x94DB483840B717EF}, // 1e-136
+ {0x92F34D62616CE413, 0xBA121A4650E4DDEB}, // 1e-135
+ {0x77B020BAF9C81D17, 0xE896A0D7E51E1566}, // 1e-134
+ {0x0ACE1474DC1D122E, 0x915E2486EF32CD60}, // 1e-133
+ {0x0D819992132456BA, 0xB5B5ADA8AAFF80B8}, // 1e-132
+ {0x10E1FFF697ED6C69, 0xE3231912D5BF60E6}, // 1e-131
+ {0xCA8D3FFA1EF463C1, 0x8DF5EFABC5979C8F}, // 1e-130
+ {0xBD308FF8A6B17CB2, 0xB1736B96B6FD83B3}, // 1e-129
+ {0xAC7CB3F6D05DDBDE, 0xDDD0467C64BCE4A0}, // 1e-128
+ {0x6BCDF07A423AA96B, 0x8AA22C0DBEF60EE4}, // 1e-127
+ {0x86C16C98D2C953C6, 0xAD4AB7112EB3929D}, // 1e-126
+ {0xE871C7BF077BA8B7, 0xD89D64D57A607744}, // 1e-125
+ {0x11471CD764AD4972, 0x87625F056C7C4A8B}, // 1e-124
+ {0xD598E40D3DD89BCF, 0xA93AF6C6C79B5D2D}, // 1e-123
+ {0x4AFF1D108D4EC2C3, 0xD389B47879823479}, // 1e-122
+ {0xCEDF722A585139BA, 0x843610CB4BF160CB}, // 1e-121
+ {0xC2974EB4EE658828, 0xA54394FE1EEDB8FE}, // 1e-120
+ {0x733D226229FEEA32, 0xCE947A3DA6A9273E}, // 1e-119
+ {0x0806357D5A3F525F, 0x811CCC668829B887}, // 1e-118
+ {0xCA07C2DCB0CF26F7, 0xA163FF802A3426A8}, // 1e-117
+ {0xFC89B393DD02F0B5, 0xC9BCFF6034C13052}, // 1e-116
+ {0xBBAC2078D443ACE2, 0xFC2C3F3841F17C67}, // 1e-115
+ {0xD54B944B84AA4C0D, 0x9D9BA7832936EDC0}, // 1e-114
+ {0x0A9E795E65D4DF11, 0xC5029163F384A931}, // 1e-113
+ {0x4D4617B5FF4A16D5, 0xF64335BCF065D37D}, // 1e-112
+ {0x504BCED1BF8E4E45, 0x99EA0196163FA42E}, // 1e-111
+ {0xE45EC2862F71E1D6, 0xC06481FB9BCF8D39}, // 1e-110
+ {0x5D767327BB4E5A4C, 0xF07DA27A82C37088}, // 1e-109
+ {0x3A6A07F8D510F86F, 0x964E858C91BA2655}, // 1e-108
+ {0x890489F70A55368B, 0xBBE226EFB628AFEA}, // 1e-107
+ {0x2B45AC74CCEA842E, 0xEADAB0ABA3B2DBE5}, // 1e-106
+ {0x3B0B8BC90012929D, 0x92C8AE6B464FC96F}, // 1e-105
+ {0x09CE6EBB40173744, 0xB77ADA0617E3BBCB}, // 1e-104
+ {0xCC420A6A101D0515, 0xE55990879DDCAABD}, // 1e-103
+ {0x9FA946824A12232D, 0x8F57FA54C2A9EAB6}, // 1e-102
+ {0x47939822DC96ABF9, 0xB32DF8E9F3546564}, // 1e-101
+ {0x59787E2B93BC56F7, 0xDFF9772470297EBD}, // 1e-100
+ {0x57EB4EDB3C55B65A, 0x8BFBEA76C619EF36}, // 1e-99
+ {0xEDE622920B6B23F1, 0xAEFAE51477A06B03}, // 1e-98
+ {0xE95FAB368E45ECED, 0xDAB99E59958885C4}, // 1e-97
+ {0x11DBCB0218EBB414, 0x88B402F7FD75539B}, // 1e-96
+ {0xD652BDC29F26A119, 0xAAE103B5FCD2A881}, // 1e-95
+ {0x4BE76D3346F0495F, 0xD59944A37C0752A2}, // 1e-94
+ {0x6F70A4400C562DDB, 0x857FCAE62D8493A5}, // 1e-93
+ {0xCB4CCD500F6BB952, 0xA6DFBD9FB8E5B88E}, // 1e-92
+ {0x7E2000A41346A7A7, 0xD097AD07A71F26B2}, // 1e-91
+ {0x8ED400668C0C28C8, 0x825ECC24C873782F}, // 1e-90
+ {0x728900802F0F32FA, 0xA2F67F2DFA90563B}, // 1e-89
+ {0x4F2B40A03AD2FFB9, 0xCBB41EF979346BCA}, // 1e-88
+ {0xE2F610C84987BFA8, 0xFEA126B7D78186BC}, // 1e-87
+ {0x0DD9CA7D2DF4D7C9, 0x9F24B832E6B0F436}, // 1e-86
+ {0x91503D1C79720DBB, 0xC6EDE63FA05D3143}, // 1e-85
+ {0x75A44C6397CE912A, 0xF8A95FCF88747D94}, // 1e-84
+ {0xC986AFBE3EE11ABA, 0x9B69DBE1B548CE7C}, // 1e-83
+ {0xFBE85BADCE996168, 0xC24452DA229B021B}, // 1e-82
+ {0xFAE27299423FB9C3, 0xF2D56790AB41C2A2}, // 1e-81
+ {0xDCCD879FC967D41A, 0x97C560BA6B0919A5}, // 1e-80
+ {0x5400E987BBC1C920, 0xBDB6B8E905CB600F}, // 1e-79
+ {0x290123E9AAB23B68, 0xED246723473E3813}, // 1e-78
+ {0xF9A0B6720AAF6521, 0x9436C0760C86E30B}, // 1e-77
+ {0xF808E40E8D5B3E69, 0xB94470938FA89BCE}, // 1e-76
+ {0xB60B1D1230B20E04, 0xE7958CB87392C2C2}, // 1e-75
+ {0xB1C6F22B5E6F48C2, 0x90BD77F3483BB9B9}, // 1e-74
+ {0x1E38AEB6360B1AF3, 0xB4ECD5F01A4AA828}, // 1e-73
+ {0x25C6DA63C38DE1B0, 0xE2280B6C20DD5232}, // 1e-72
+ {0x579C487E5A38AD0E, 0x8D590723948A535F}, // 1e-71
+ {0x2D835A9DF0C6D851, 0xB0AF48EC79ACE837}, // 1e-70
+ {0xF8E431456CF88E65, 0xDCDB1B2798182244}, // 1e-69
+ {0x1B8E9ECB641B58FF, 0x8A08F0F8BF0F156B}, // 1e-68
+ {0xE272467E3D222F3F, 0xAC8B2D36EED2DAC5}, // 1e-67
+ {0x5B0ED81DCC6ABB0F, 0xD7ADF884AA879177}, // 1e-66
+ {0x98E947129FC2B4E9, 0x86CCBB52EA94BAEA}, // 1e-65
+ {0x3F2398D747B36224, 0xA87FEA27A539E9A5}, // 1e-64
+ {0x8EEC7F0D19A03AAD, 0xD29FE4B18E88640E}, // 1e-63
+ {0x1953CF68300424AC, 0x83A3EEEEF9153E89}, // 1e-62
+ {0x5FA8C3423C052DD7, 0xA48CEAAAB75A8E2B}, // 1e-61
+ {0x3792F412CB06794D, 0xCDB02555653131B6}, // 1e-60
+ {0xE2BBD88BBEE40BD0, 0x808E17555F3EBF11}, // 1e-59
+ {0x5B6ACEAEAE9D0EC4, 0xA0B19D2AB70E6ED6}, // 1e-58
+ {0xF245825A5A445275, 0xC8DE047564D20A8B}, // 1e-57
+ {0xEED6E2F0F0D56712, 0xFB158592BE068D2E}, // 1e-56
+ {0x55464DD69685606B, 0x9CED737BB6C4183D}, // 1e-55
+ {0xAA97E14C3C26B886, 0xC428D05AA4751E4C}, // 1e-54
+ {0xD53DD99F4B3066A8, 0xF53304714D9265DF}, // 1e-53
+ {0xE546A8038EFE4029, 0x993FE2C6D07B7FAB}, // 1e-52
+ {0xDE98520472BDD033, 0xBF8FDB78849A5F96}, // 1e-51
+ {0x963E66858F6D4440, 0xEF73D256A5C0F77C}, // 1e-50
+ {0xDDE7001379A44AA8, 0x95A8637627989AAD}, // 1e-49
+ {0x5560C018580D5D52, 0xBB127C53B17EC159}, // 1e-48
+ {0xAAB8F01E6E10B4A6, 0xE9D71B689DDE71AF}, // 1e-47
+ {0xCAB3961304CA70E8, 0x9226712162AB070D}, // 1e-46
+ {0x3D607B97C5FD0D22, 0xB6B00D69BB55C8D1}, // 1e-45
+ {0x8CB89A7DB77C506A, 0xE45C10C42A2B3B05}, // 1e-44
+ {0x77F3608E92ADB242, 0x8EB98A7A9A5B04E3}, // 1e-43
+ {0x55F038B237591ED3, 0xB267ED1940F1C61C}, // 1e-42
+ {0x6B6C46DEC52F6688, 0xDF01E85F912E37A3}, // 1e-41
+ {0x2323AC4B3B3DA015, 0x8B61313BBABCE2C6}, // 1e-40
+ {0xABEC975E0A0D081A, 0xAE397D8AA96C1B77}, // 1e-39
+ {0x96E7BD358C904A21, 0xD9C7DCED53C72255}, // 1e-38
+ {0x7E50D64177DA2E54, 0x881CEA14545C7575}, // 1e-37
+ {0xDDE50BD1D5D0B9E9, 0xAA242499697392D2}, // 1e-36
+ {0x955E4EC64B44E864, 0xD4AD2DBFC3D07787}, // 1e-35
+ {0xBD5AF13BEF0B113E, 0x84EC3C97DA624AB4}, // 1e-34
+ {0xECB1AD8AEACDD58E, 0xA6274BBDD0FADD61}, // 1e-33
+ {0x67DE18EDA5814AF2, 0xCFB11EAD453994BA}, // 1e-32
+ {0x80EACF948770CED7, 0x81CEB32C4B43FCF4}, // 1e-31
+ {0xA1258379A94D028D, 0xA2425FF75E14FC31}, // 1e-30
+ {0x096EE45813A04330, 0xCAD2F7F5359A3B3E}, // 1e-29
+ {0x8BCA9D6E188853FC, 0xFD87B5F28300CA0D}, // 1e-28
+ {0x775EA264CF55347D, 0x9E74D1B791E07E48}, // 1e-27
+ {0x95364AFE032A819D, 0xC612062576589DDA}, // 1e-26
+ {0x3A83DDBD83F52204, 0xF79687AED3EEC551}, // 1e-25
+ {0xC4926A9672793542, 0x9ABE14CD44753B52}, // 1e-24
+ {0x75B7053C0F178293, 0xC16D9A0095928A27}, // 1e-23
+ {0x5324C68B12DD6338, 0xF1C90080BAF72CB1}, // 1e-22
+ {0xD3F6FC16EBCA5E03, 0x971DA05074DA7BEE}, // 1e-21
+ {0x88F4BB1CA6BCF584, 0xBCE5086492111AEA}, // 1e-20
+ {0x2B31E9E3D06C32E5, 0xEC1E4A7DB69561A5}, // 1e-19
+ {0x3AFF322E62439FCF, 0x9392EE8E921D5D07}, // 1e-18
+ {0x09BEFEB9FAD487C2, 0xB877AA3236A4B449}, // 1e-17
+ {0x4C2EBE687989A9B3, 0xE69594BEC44DE15B}, // 1e-16
+ {0x0F9D37014BF60A10, 0x901D7CF73AB0ACD9}, // 1e-15
+ {0x538484C19EF38C94, 0xB424DC35095CD80F}, // 1e-14
+ {0x2865A5F206B06FB9, 0xE12E13424BB40E13}, // 1e-13
+ {0xF93F87B7442E45D3, 0x8CBCCC096F5088CB}, // 1e-12
+ {0xF78F69A51539D748, 0xAFEBFF0BCB24AAFE}, // 1e-11
+ {0xB573440E5A884D1B, 0xDBE6FECEBDEDD5BE}, // 1e-10
+ {0x31680A88F8953030, 0x89705F4136B4A597}, // 1e-9
+ {0xFDC20D2B36BA7C3D, 0xABCC77118461CEFC}, // 1e-8
+ {0x3D32907604691B4C, 0xD6BF94D5E57A42BC}, // 1e-7
+ {0xA63F9A49C2C1B10F, 0x8637BD05AF6C69B5}, // 1e-6
+ {0x0FCF80DC33721D53, 0xA7C5AC471B478423}, // 1e-5
+ {0xD3C36113404EA4A8, 0xD1B71758E219652B}, // 1e-4
+ {0x645A1CAC083126E9, 0x83126E978D4FDF3B}, // 1e-3
+ {0x3D70A3D70A3D70A3, 0xA3D70A3D70A3D70A}, // 1e-2
+ {0xCCCCCCCCCCCCCCCC, 0xCCCCCCCCCCCCCCCC}, // 1e-1
+ {0x0000000000000000, 0x8000000000000000}, // 1e0
+ {0x0000000000000000, 0xA000000000000000}, // 1e1
+ {0x0000000000000000, 0xC800000000000000}, // 1e2
+ {0x0000000000000000, 0xFA00000000000000}, // 1e3
+ {0x0000000000000000, 0x9C40000000000000}, // 1e4
+ {0x0000000000000000, 0xC350000000000000}, // 1e5
+ {0x0000000000000000, 0xF424000000000000}, // 1e6
+ {0x0000000000000000, 0x9896800000000000}, // 1e7
+ {0x0000000000000000, 0xBEBC200000000000}, // 1e8
+ {0x0000000000000000, 0xEE6B280000000000}, // 1e9
+ {0x0000000000000000, 0x9502F90000000000}, // 1e10
+ {0x0000000000000000, 0xBA43B74000000000}, // 1e11
+ {0x0000000000000000, 0xE8D4A51000000000}, // 1e12
+ {0x0000000000000000, 0x9184E72A00000000}, // 1e13
+ {0x0000000000000000, 0xB5E620F480000000}, // 1e14
+ {0x0000000000000000, 0xE35FA931A0000000}, // 1e15
+ {0x0000000000000000, 0x8E1BC9BF04000000}, // 1e16
+ {0x0000000000000000, 0xB1A2BC2EC5000000}, // 1e17
+ {0x0000000000000000, 0xDE0B6B3A76400000}, // 1e18
+ {0x0000000000000000, 0x8AC7230489E80000}, // 1e19
+ {0x0000000000000000, 0xAD78EBC5AC620000}, // 1e20
+ {0x0000000000000000, 0xD8D726B7177A8000}, // 1e21
+ {0x0000000000000000, 0x878678326EAC9000}, // 1e22
+ {0x0000000000000000, 0xA968163F0A57B400}, // 1e23
+ {0x0000000000000000, 0xD3C21BCECCEDA100}, // 1e24
+ {0x0000000000000000, 0x84595161401484A0}, // 1e25
+ {0x0000000000000000, 0xA56FA5B99019A5C8}, // 1e26
+ {0x0000000000000000, 0xCECB8F27F4200F3A}, // 1e27
+ {0x4000000000000000, 0x813F3978F8940984}, // 1e28
+ {0x5000000000000000, 0xA18F07D736B90BE5}, // 1e29
+ {0xA400000000000000, 0xC9F2C9CD04674EDE}, // 1e30
+ {0x4D00000000000000, 0xFC6F7C4045812296}, // 1e31
+ {0xF020000000000000, 0x9DC5ADA82B70B59D}, // 1e32
+ {0x6C28000000000000, 0xC5371912364CE305}, // 1e33
+ {0xC732000000000000, 0xF684DF56C3E01BC6}, // 1e34
+ {0x3C7F400000000000, 0x9A130B963A6C115C}, // 1e35
+ {0x4B9F100000000000, 0xC097CE7BC90715B3}, // 1e36
+ {0x1E86D40000000000, 0xF0BDC21ABB48DB20}, // 1e37
+ {0x1314448000000000, 0x96769950B50D88F4}, // 1e38
+ {0x17D955A000000000, 0xBC143FA4E250EB31}, // 1e39
+ {0x5DCFAB0800000000, 0xEB194F8E1AE525FD}, // 1e40
+ {0x5AA1CAE500000000, 0x92EFD1B8D0CF37BE}, // 1e41
+ {0xF14A3D9E40000000, 0xB7ABC627050305AD}, // 1e42
+ {0x6D9CCD05D0000000, 0xE596B7B0C643C719}, // 1e43
+ {0xE4820023A2000000, 0x8F7E32CE7BEA5C6F}, // 1e44
+ {0xDDA2802C8A800000, 0xB35DBF821AE4F38B}, // 1e45
+ {0xD50B2037AD200000, 0xE0352F62A19E306E}, // 1e46
+ {0x4526F422CC340000, 0x8C213D9DA502DE45}, // 1e47
+ {0x9670B12B7F410000, 0xAF298D050E4395D6}, // 1e48
+ {0x3C0CDD765F114000, 0xDAF3F04651D47B4C}, // 1e49
+ {0xA5880A69FB6AC800, 0x88D8762BF324CD0F}, // 1e50
+ {0x8EEA0D047A457A00, 0xAB0E93B6EFEE0053}, // 1e51
+ {0x72A4904598D6D880, 0xD5D238A4ABE98068}, // 1e52
+ {0x47A6DA2B7F864750, 0x85A36366EB71F041}, // 1e53
+ {0x999090B65F67D924, 0xA70C3C40A64E6C51}, // 1e54
+ {0xFFF4B4E3F741CF6D, 0xD0CF4B50CFE20765}, // 1e55
+ {0xBFF8F10E7A8921A4, 0x82818F1281ED449F}, // 1e56
+ {0xAFF72D52192B6A0D, 0xA321F2D7226895C7}, // 1e57
+ {0x9BF4F8A69F764490, 0xCBEA6F8CEB02BB39}, // 1e58
+ {0x02F236D04753D5B4, 0xFEE50B7025C36A08}, // 1e59
+ {0x01D762422C946590, 0x9F4F2726179A2245}, // 1e60
+ {0x424D3AD2B7B97EF5, 0xC722F0EF9D80AAD6}, // 1e61
+ {0xD2E0898765A7DEB2, 0xF8EBAD2B84E0D58B}, // 1e62
+ {0x63CC55F49F88EB2F, 0x9B934C3B330C8577}, // 1e63
+ {0x3CBF6B71C76B25FB, 0xC2781F49FFCFA6D5}, // 1e64
+ {0x8BEF464E3945EF7A, 0xF316271C7FC3908A}, // 1e65
+ {0x97758BF0E3CBB5AC, 0x97EDD871CFDA3A56}, // 1e66
+ {0x3D52EEED1CBEA317, 0xBDE94E8E43D0C8EC}, // 1e67
+ {0x4CA7AAA863EE4BDD, 0xED63A231D4C4FB27}, // 1e68
+ {0x8FE8CAA93E74EF6A, 0x945E455F24FB1CF8}, // 1e69
+ {0xB3E2FD538E122B44, 0xB975D6B6EE39E436}, // 1e70
+ {0x60DBBCA87196B616, 0xE7D34C64A9C85D44}, // 1e71
+ {0xBC8955E946FE31CD, 0x90E40FBEEA1D3A4A}, // 1e72
+ {0x6BABAB6398BDBE41, 0xB51D13AEA4A488DD}, // 1e73
+ {0xC696963C7EED2DD1, 0xE264589A4DCDAB14}, // 1e74
+ {0xFC1E1DE5CF543CA2, 0x8D7EB76070A08AEC}, // 1e75
+ {0x3B25A55F43294BCB, 0xB0DE65388CC8ADA8}, // 1e76
+ {0x49EF0EB713F39EBE, 0xDD15FE86AFFAD912}, // 1e77
+ {0x6E3569326C784337, 0x8A2DBF142DFCC7AB}, // 1e78
+ {0x49C2C37F07965404, 0xACB92ED9397BF996}, // 1e79
+ {0xDC33745EC97BE906, 0xD7E77A8F87DAF7FB}, // 1e80
+ {0x69A028BB3DED71A3, 0x86F0AC99B4E8DAFD}, // 1e81
+ {0xC40832EA0D68CE0C, 0xA8ACD7C0222311BC}, // 1e82
+ {0xF50A3FA490C30190, 0xD2D80DB02AABD62B}, // 1e83
+ {0x792667C6DA79E0FA, 0x83C7088E1AAB65DB}, // 1e84
+ {0x577001B891185938, 0xA4B8CAB1A1563F52}, // 1e85
+ {0xED4C0226B55E6F86, 0xCDE6FD5E09ABCF26}, // 1e86
+ {0x544F8158315B05B4, 0x80B05E5AC60B6178}, // 1e87
+ {0x696361AE3DB1C721, 0xA0DC75F1778E39D6}, // 1e88
+ {0x03BC3A19CD1E38E9, 0xC913936DD571C84C}, // 1e89
+ {0x04AB48A04065C723, 0xFB5878494ACE3A5F}, // 1e90
+ {0x62EB0D64283F9C76, 0x9D174B2DCEC0E47B}, // 1e91
+ {0x3BA5D0BD324F8394, 0xC45D1DF942711D9A}, // 1e92
+ {0xCA8F44EC7EE36479, 0xF5746577930D6500}, // 1e93
+ {0x7E998B13CF4E1ECB, 0x9968BF6ABBE85F20}, // 1e94
+ {0x9E3FEDD8C321A67E, 0xBFC2EF456AE276E8}, // 1e95
+ {0xC5CFE94EF3EA101E, 0xEFB3AB16C59B14A2}, // 1e96
+ {0xBBA1F1D158724A12, 0x95D04AEE3B80ECE5}, // 1e97
+ {0x2A8A6E45AE8EDC97, 0xBB445DA9CA61281F}, // 1e98
+ {0xF52D09D71A3293BD, 0xEA1575143CF97226}, // 1e99
+ {0x593C2626705F9C56, 0x924D692CA61BE758}, // 1e100
+ {0x6F8B2FB00C77836C, 0xB6E0C377CFA2E12E}, // 1e101
+ {0x0B6DFB9C0F956447, 0xE498F455C38B997A}, // 1e102
+ {0x4724BD4189BD5EAC, 0x8EDF98B59A373FEC}, // 1e103
+ {0x58EDEC91EC2CB657, 0xB2977EE300C50FE7}, // 1e104
+ {0x2F2967B66737E3ED, 0xDF3D5E9BC0F653E1}, // 1e105
+ {0xBD79E0D20082EE74, 0x8B865B215899F46C}, // 1e106
+ {0xECD8590680A3AA11, 0xAE67F1E9AEC07187}, // 1e107
+ {0xE80E6F4820CC9495, 0xDA01EE641A708DE9}, // 1e108
+ {0x3109058D147FDCDD, 0x884134FE908658B2}, // 1e109
+ {0xBD4B46F0599FD415, 0xAA51823E34A7EEDE}, // 1e110
+ {0x6C9E18AC7007C91A, 0xD4E5E2CDC1D1EA96}, // 1e111
+ {0x03E2CF6BC604DDB0, 0x850FADC09923329E}, // 1e112
+ {0x84DB8346B786151C, 0xA6539930BF6BFF45}, // 1e113
+ {0xE612641865679A63, 0xCFE87F7CEF46FF16}, // 1e114
+ {0x4FCB7E8F3F60C07E, 0x81F14FAE158C5F6E}, // 1e115
+ {0xE3BE5E330F38F09D, 0xA26DA3999AEF7749}, // 1e116
+ {0x5CADF5BFD3072CC5, 0xCB090C8001AB551C}, // 1e117
+ {0x73D9732FC7C8F7F6, 0xFDCB4FA002162A63}, // 1e118
+ {0x2867E7FDDCDD9AFA, 0x9E9F11C4014DDA7E}, // 1e119
+ {0xB281E1FD541501B8, 0xC646D63501A1511D}, // 1e120
+ {0x1F225A7CA91A4226, 0xF7D88BC24209A565}, // 1e121
+ {0x3375788DE9B06958, 0x9AE757596946075F}, // 1e122
+ {0x0052D6B1641C83AE, 0xC1A12D2FC3978937}, // 1e123
+ {0xC0678C5DBD23A49A, 0xF209787BB47D6B84}, // 1e124
+ {0xF840B7BA963646E0, 0x9745EB4D50CE6332}, // 1e125
+ {0xB650E5A93BC3D898, 0xBD176620A501FBFF}, // 1e126
+ {0xA3E51F138AB4CEBE, 0xEC5D3FA8CE427AFF}, // 1e127
+ {0xC66F336C36B10137, 0x93BA47C980E98CDF}, // 1e128
+ {0xB80B0047445D4184, 0xB8A8D9BBE123F017}, // 1e129
+ {0xA60DC059157491E5, 0xE6D3102AD96CEC1D}, // 1e130
+ {0x87C89837AD68DB2F, 0x9043EA1AC7E41392}, // 1e131
+ {0x29BABE4598C311FB, 0xB454E4A179DD1877}, // 1e132
+ {0xF4296DD6FEF3D67A, 0xE16A1DC9D8545E94}, // 1e133
+ {0x1899E4A65F58660C, 0x8CE2529E2734BB1D}, // 1e134
+ {0x5EC05DCFF72E7F8F, 0xB01AE745B101E9E4}, // 1e135
+ {0x76707543F4FA1F73, 0xDC21A1171D42645D}, // 1e136
+ {0x6A06494A791C53A8, 0x899504AE72497EBA}, // 1e137
+ {0x0487DB9D17636892, 0xABFA45DA0EDBDE69}, // 1e138
+ {0x45A9D2845D3C42B6, 0xD6F8D7509292D603}, // 1e139
+ {0x0B8A2392BA45A9B2, 0x865B86925B9BC5C2}, // 1e140
+ {0x8E6CAC7768D7141E, 0xA7F26836F282B732}, // 1e141
+ {0x3207D795430CD926, 0xD1EF0244AF2364FF}, // 1e142
+ {0x7F44E6BD49E807B8, 0x8335616AED761F1F}, // 1e143
+ {0x5F16206C9C6209A6, 0xA402B9C5A8D3A6E7}, // 1e144
+ {0x36DBA887C37A8C0F, 0xCD036837130890A1}, // 1e145
+ {0xC2494954DA2C9789, 0x802221226BE55A64}, // 1e146
+ {0xF2DB9BAA10B7BD6C, 0xA02AA96B06DEB0FD}, // 1e147
+ {0x6F92829494E5ACC7, 0xC83553C5C8965D3D}, // 1e148
+ {0xCB772339BA1F17F9, 0xFA42A8B73ABBF48C}, // 1e149
+ {0xFF2A760414536EFB, 0x9C69A97284B578D7}, // 1e150
+ {0xFEF5138519684ABA, 0xC38413CF25E2D70D}, // 1e151
+ {0x7EB258665FC25D69, 0xF46518C2EF5B8CD1}, // 1e152
+ {0xEF2F773FFBD97A61, 0x98BF2F79D5993802}, // 1e153
+ {0xAAFB550FFACFD8FA, 0xBEEEFB584AFF8603}, // 1e154
+ {0x95BA2A53F983CF38, 0xEEAABA2E5DBF6784}, // 1e155
+ {0xDD945A747BF26183, 0x952AB45CFA97A0B2}, // 1e156
+ {0x94F971119AEEF9E4, 0xBA756174393D88DF}, // 1e157
+ {0x7A37CD5601AAB85D, 0xE912B9D1478CEB17}, // 1e158
+ {0xAC62E055C10AB33A, 0x91ABB422CCB812EE}, // 1e159
+ {0x577B986B314D6009, 0xB616A12B7FE617AA}, // 1e160
+ {0xED5A7E85FDA0B80B, 0xE39C49765FDF9D94}, // 1e161
+ {0x14588F13BE847307, 0x8E41ADE9FBEBC27D}, // 1e162
+ {0x596EB2D8AE258FC8, 0xB1D219647AE6B31C}, // 1e163
+ {0x6FCA5F8ED9AEF3BB, 0xDE469FBD99A05FE3}, // 1e164
+ {0x25DE7BB9480D5854, 0x8AEC23D680043BEE}, // 1e165
+ {0xAF561AA79A10AE6A, 0xADA72CCC20054AE9}, // 1e166
+ {0x1B2BA1518094DA04, 0xD910F7FF28069DA4}, // 1e167
+ {0x90FB44D2F05D0842, 0x87AA9AFF79042286}, // 1e168
+ {0x353A1607AC744A53, 0xA99541BF57452B28}, // 1e169
+ {0x42889B8997915CE8, 0xD3FA922F2D1675F2}, // 1e170
+ {0x69956135FEBADA11, 0x847C9B5D7C2E09B7}, // 1e171
+ {0x43FAB9837E699095, 0xA59BC234DB398C25}, // 1e172
+ {0x94F967E45E03F4BB, 0xCF02B2C21207EF2E}, // 1e173
+ {0x1D1BE0EEBAC278F5, 0x8161AFB94B44F57D}, // 1e174
+ {0x6462D92A69731732, 0xA1BA1BA79E1632DC}, // 1e175
+ {0x7D7B8F7503CFDCFE, 0xCA28A291859BBF93}, // 1e176
+ {0x5CDA735244C3D43E, 0xFCB2CB35E702AF78}, // 1e177
+ {0x3A0888136AFA64A7, 0x9DEFBF01B061ADAB}, // 1e178
+ {0x088AAA1845B8FDD0, 0xC56BAEC21C7A1916}, // 1e179
+ {0x8AAD549E57273D45, 0xF6C69A72A3989F5B}, // 1e180
+ {0x36AC54E2F678864B, 0x9A3C2087A63F6399}, // 1e181
+ {0x84576A1BB416A7DD, 0xC0CB28A98FCF3C7F}, // 1e182
+ {0x656D44A2A11C51D5, 0xF0FDF2D3F3C30B9F}, // 1e183
+ {0x9F644AE5A4B1B325, 0x969EB7C47859E743}, // 1e184
+ {0x873D5D9F0DDE1FEE, 0xBC4665B596706114}, // 1e185
+ {0xA90CB506D155A7EA, 0xEB57FF22FC0C7959}, // 1e186
+ {0x09A7F12442D588F2, 0x9316FF75DD87CBD8}, // 1e187
+ {0x0C11ED6D538AEB2F, 0xB7DCBF5354E9BECE}, // 1e188
+ {0x8F1668C8A86DA5FA, 0xE5D3EF282A242E81}, // 1e189
+ {0xF96E017D694487BC, 0x8FA475791A569D10}, // 1e190
+ {0x37C981DCC395A9AC, 0xB38D92D760EC4455}, // 1e191
+ {0x85BBE253F47B1417, 0xE070F78D3927556A}, // 1e192
+ {0x93956D7478CCEC8E, 0x8C469AB843B89562}, // 1e193
+ {0x387AC8D1970027B2, 0xAF58416654A6BABB}, // 1e194
+ {0x06997B05FCC0319E, 0xDB2E51BFE9D0696A}, // 1e195
+ {0x441FECE3BDF81F03, 0x88FCF317F22241E2}, // 1e196
+ {0xD527E81CAD7626C3, 0xAB3C2FDDEEAAD25A}, // 1e197
+ {0x8A71E223D8D3B074, 0xD60B3BD56A5586F1}, // 1e198
+ {0xF6872D5667844E49, 0x85C7056562757456}, // 1e199
+ {0xB428F8AC016561DB, 0xA738C6BEBB12D16C}, // 1e200
+ {0xE13336D701BEBA52, 0xD106F86E69D785C7}, // 1e201
+ {0xECC0024661173473, 0x82A45B450226B39C}, // 1e202
+ {0x27F002D7F95D0190, 0xA34D721642B06084}, // 1e203
+ {0x31EC038DF7B441F4, 0xCC20CE9BD35C78A5}, // 1e204
+ {0x7E67047175A15271, 0xFF290242C83396CE}, // 1e205
+ {0x0F0062C6E984D386, 0x9F79A169BD203E41}, // 1e206
+ {0x52C07B78A3E60868, 0xC75809C42C684DD1}, // 1e207
+ {0xA7709A56CCDF8A82, 0xF92E0C3537826145}, // 1e208
+ {0x88A66076400BB691, 0x9BBCC7A142B17CCB}, // 1e209
+ {0x6ACFF893D00EA435, 0xC2ABF989935DDBFE}, // 1e210
+ {0x0583F6B8C4124D43, 0xF356F7EBF83552FE}, // 1e211
+ {0xC3727A337A8B704A, 0x98165AF37B2153DE}, // 1e212
+ {0x744F18C0592E4C5C, 0xBE1BF1B059E9A8D6}, // 1e213
+ {0x1162DEF06F79DF73, 0xEDA2EE1C7064130C}, // 1e214
+ {0x8ADDCB5645AC2BA8, 0x9485D4D1C63E8BE7}, // 1e215
+ {0x6D953E2BD7173692, 0xB9A74A0637CE2EE1}, // 1e216
+ {0xC8FA8DB6CCDD0437, 0xE8111C87C5C1BA99}, // 1e217
+ {0x1D9C9892400A22A2, 0x910AB1D4DB9914A0}, // 1e218
+ {0x2503BEB6D00CAB4B, 0xB54D5E4A127F59C8}, // 1e219
+ {0x2E44AE64840FD61D, 0xE2A0B5DC971F303A}, // 1e220
+ {0x5CEAECFED289E5D2, 0x8DA471A9DE737E24}, // 1e221
+ {0x7425A83E872C5F47, 0xB10D8E1456105DAD}, // 1e222
+ {0xD12F124E28F77719, 0xDD50F1996B947518}, // 1e223
+ {0x82BD6B70D99AAA6F, 0x8A5296FFE33CC92F}, // 1e224
+ {0x636CC64D1001550B, 0xACE73CBFDC0BFB7B}, // 1e225
+ {0x3C47F7E05401AA4E, 0xD8210BEFD30EFA5A}, // 1e226
+ {0x65ACFAEC34810A71, 0x8714A775E3E95C78}, // 1e227
+ {0x7F1839A741A14D0D, 0xA8D9D1535CE3B396}, // 1e228
+ {0x1EDE48111209A050, 0xD31045A8341CA07C}, // 1e229
+ {0x934AED0AAB460432, 0x83EA2B892091E44D}, // 1e230
+ {0xF81DA84D5617853F, 0xA4E4B66B68B65D60}, // 1e231
+ {0x36251260AB9D668E, 0xCE1DE40642E3F4B9}, // 1e232
+ {0xC1D72B7C6B426019, 0x80D2AE83E9CE78F3}, // 1e233
+ {0xB24CF65B8612F81F, 0xA1075A24E4421730}, // 1e234
+ {0xDEE033F26797B627, 0xC94930AE1D529CFC}, // 1e235
+ {0x169840EF017DA3B1, 0xFB9B7CD9A4A7443C}, // 1e236
+ {0x8E1F289560EE864E, 0x9D412E0806E88AA5}, // 1e237
+ {0xF1A6F2BAB92A27E2, 0xC491798A08A2AD4E}, // 1e238
+ {0xAE10AF696774B1DB, 0xF5B5D7EC8ACB58A2}, // 1e239
+ {0xACCA6DA1E0A8EF29, 0x9991A6F3D6BF1765}, // 1e240
+ {0x17FD090A58D32AF3, 0xBFF610B0CC6EDD3F}, // 1e241
+ {0xDDFC4B4CEF07F5B0, 0xEFF394DCFF8A948E}, // 1e242
+ {0x4ABDAF101564F98E, 0x95F83D0A1FB69CD9}, // 1e243
+ {0x9D6D1AD41ABE37F1, 0xBB764C4CA7A4440F}, // 1e244
+ {0x84C86189216DC5ED, 0xEA53DF5FD18D5513}, // 1e245
+ {0x32FD3CF5B4E49BB4, 0x92746B9BE2F8552C}, // 1e246
+ {0x3FBC8C33221DC2A1, 0xB7118682DBB66A77}, // 1e247
+ {0x0FABAF3FEAA5334A, 0xE4D5E82392A40515}, // 1e248
+ {0x29CB4D87F2A7400E, 0x8F05B1163BA6832D}, // 1e249
+ {0x743E20E9EF511012, 0xB2C71D5BCA9023F8}, // 1e250
+ {0x914DA9246B255416, 0xDF78E4B2BD342CF6}, // 1e251
+ {0x1AD089B6C2F7548E, 0x8BAB8EEFB6409C1A}, // 1e252
+ {0xA184AC2473B529B1, 0xAE9672ABA3D0C320}, // 1e253
+ {0xC9E5D72D90A2741E, 0xDA3C0F568CC4F3E8}, // 1e254
+ {0x7E2FA67C7A658892, 0x8865899617FB1871}, // 1e255
+ {0xDDBB901B98FEEAB7, 0xAA7EEBFB9DF9DE8D}, // 1e256
+ {0x552A74227F3EA565, 0xD51EA6FA85785631}, // 1e257
+ {0xD53A88958F87275F, 0x8533285C936B35DE}, // 1e258
+ {0x8A892ABAF368F137, 0xA67FF273B8460356}, // 1e259
+ {0x2D2B7569B0432D85, 0xD01FEF10A657842C}, // 1e260
+ {0x9C3B29620E29FC73, 0x8213F56A67F6B29B}, // 1e261
+ {0x8349F3BA91B47B8F, 0xA298F2C501F45F42}, // 1e262
+ {0x241C70A936219A73, 0xCB3F2F7642717713}, // 1e263
+ {0xED238CD383AA0110, 0xFE0EFB53D30DD4D7}, // 1e264
+ {0xF4363804324A40AA, 0x9EC95D1463E8A506}, // 1e265
+ {0xB143C6053EDCD0D5, 0xC67BB4597CE2CE48}, // 1e266
+ {0xDD94B7868E94050A, 0xF81AA16FDC1B81DA}, // 1e267
+ {0xCA7CF2B4191C8326, 0x9B10A4E5E9913128}, // 1e268
+ {0xFD1C2F611F63A3F0, 0xC1D4CE1F63F57D72}, // 1e269
+ {0xBC633B39673C8CEC, 0xF24A01A73CF2DCCF}, // 1e270
+ {0xD5BE0503E085D813, 0x976E41088617CA01}, // 1e271
+ {0x4B2D8644D8A74E18, 0xBD49D14AA79DBC82}, // 1e272
+ {0xDDF8E7D60ED1219E, 0xEC9C459D51852BA2}, // 1e273
+ {0xCABB90E5C942B503, 0x93E1AB8252F33B45}, // 1e274
+ {0x3D6A751F3B936243, 0xB8DA1662E7B00A17}, // 1e275
+ {0x0CC512670A783AD4, 0xE7109BFBA19C0C9D}, // 1e276
+ {0x27FB2B80668B24C5, 0x906A617D450187E2}, // 1e277
+ {0xB1F9F660802DEDF6, 0xB484F9DC9641E9DA}, // 1e278
+ {0x5E7873F8A0396973, 0xE1A63853BBD26451}, // 1e279
+ {0xDB0B487B6423E1E8, 0x8D07E33455637EB2}, // 1e280
+ {0x91CE1A9A3D2CDA62, 0xB049DC016ABC5E5F}, // 1e281
+ {0x7641A140CC7810FB, 0xDC5C5301C56B75F7}, // 1e282
+ {0xA9E904C87FCB0A9D, 0x89B9B3E11B6329BA}, // 1e283
+ {0x546345FA9FBDCD44, 0xAC2820D9623BF429}, // 1e284
+ {0xA97C177947AD4095, 0xD732290FBACAF133}, // 1e285
+ {0x49ED8EABCCCC485D, 0x867F59A9D4BED6C0}, // 1e286
+ {0x5C68F256BFFF5A74, 0xA81F301449EE8C70}, // 1e287
+ {0x73832EEC6FFF3111, 0xD226FC195C6A2F8C}, // 1e288
+};
+
+// wuffs_base__private_implementation__f64_powers_of_10 holds powers of 10 that
+// can be exactly represented by a float64 (what C calls a double).
+static const double wuffs_base__private_implementation__f64_powers_of_10[23] = {
+ 1e0, 1e1, 1e2, 1e3, 1e4, 1e5, 1e6, 1e7, 1e8, 1e9, 1e10, 1e11,
+ 1e12, 1e13, 1e14, 1e15, 1e16, 1e17, 1e18, 1e19, 1e20, 1e21, 1e22,
+};
+
+// ---------------- IEEE 754 Floating Point
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u16 //
+wuffs_base__ieee_754_bit_representation__from_f64_to_u16_truncate(double f) {
+ uint64_t u = 0;
+ if (sizeof(uint64_t) == sizeof(double)) {
+ memcpy(&u, &f, sizeof(uint64_t));
+ }
+ uint16_t neg = ((uint16_t)((u >> 63) << 15));
+ u &= 0x7FFFFFFFFFFFFFFF;
+ uint64_t exp = u >> 52;
+ uint64_t man = u & 0x000FFFFFFFFFFFFF;
+
+ if (exp == 0x7FF) {
+ if (man == 0) { // Infinity.
+ wuffs_base__lossy_value_u16 ret;
+ ret.value = neg | 0x7C00;
+ ret.lossy = false;
+ return ret;
+ }
+ // NaN. Shift the 52 mantissa bits to 10 mantissa bits, keeping the most
+ // significant mantissa bit (quiet vs signaling NaNs). Also set the low 9
+ // bits of ret.value so that the 10-bit mantissa is non-zero.
+ wuffs_base__lossy_value_u16 ret;
+ ret.value = neg | 0x7DFF | ((uint16_t)(man >> 42));
+ ret.lossy = false;
+ return ret;
+
+ } else if (exp > 0x40E) { // Truncate to the largest finite f16.
+ wuffs_base__lossy_value_u16 ret;
+ ret.value = neg | 0x7BFF;
+ ret.lossy = true;
+ return ret;
+
+ } else if (exp <= 0x3E6) { // Truncate to zero.
+ wuffs_base__lossy_value_u16 ret;
+ ret.value = neg;
+ ret.lossy = (u != 0);
+ return ret;
+
+ } else if (exp <= 0x3F0) { // Normal f64, subnormal f16.
+ // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
+ // 10-bit mantissa and then adjust for the exponent.
+ man |= 0x0010000000000000;
+ uint32_t shift = ((uint32_t)(1051 - exp)); // 1051 = 0x3F0 + 53 - 10.
+ uint64_t shifted_man = man >> shift;
+ wuffs_base__lossy_value_u16 ret;
+ ret.value = neg | ((uint16_t)shifted_man);
+ ret.lossy = (shifted_man << shift) != man;
+ return ret;
+ }
+
+ // Normal f64, normal f16.
+
+ // Re-bias from 1023 to 15 and shift above f16's 10 mantissa bits.
+ exp = (exp - 1008) << 10; // 1008 = 1023 - 15 = 0x3FF - 0xF.
+
+ // Convert from a 52-bit mantissa (excluding the implicit bit) to a 10-bit
+ // mantissa (again excluding the implicit bit). We lose some information if
+ // any of the bottom 42 bits are non-zero.
+ wuffs_base__lossy_value_u16 ret;
+ ret.value = neg | ((uint16_t)exp) | ((uint16_t)(man >> 42));
+ ret.lossy = (man << 22) != 0;
+ return ret;
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__lossy_value_u32 //
+wuffs_base__ieee_754_bit_representation__from_f64_to_u32_truncate(double f) {
+ uint64_t u = 0;
+ if (sizeof(uint64_t) == sizeof(double)) {
+ memcpy(&u, &f, sizeof(uint64_t));
+ }
+ uint32_t neg = ((uint32_t)(u >> 63)) << 31;
+ u &= 0x7FFFFFFFFFFFFFFF;
+ uint64_t exp = u >> 52;
+ uint64_t man = u & 0x000FFFFFFFFFFFFF;
+
+ if (exp == 0x7FF) {
+ if (man == 0) { // Infinity.
+ wuffs_base__lossy_value_u32 ret;
+ ret.value = neg | 0x7F800000;
+ ret.lossy = false;
+ return ret;
+ }
+ // NaN. Shift the 52 mantissa bits to 23 mantissa bits, keeping the most
+ // significant mantissa bit (quiet vs signaling NaNs). Also set the low 22
+ // bits of ret.value so that the 23-bit mantissa is non-zero.
+ wuffs_base__lossy_value_u32 ret;
+ ret.value = neg | 0x7FBFFFFF | ((uint32_t)(man >> 29));
+ ret.lossy = false;
+ return ret;
+
+ } else if (exp > 0x47E) { // Truncate to the largest finite f32.
+ wuffs_base__lossy_value_u32 ret;
+ ret.value = neg | 0x7F7FFFFF;
+ ret.lossy = true;
+ return ret;
+
+ } else if (exp <= 0x369) { // Truncate to zero.
+ wuffs_base__lossy_value_u32 ret;
+ ret.value = neg;
+ ret.lossy = (u != 0);
+ return ret;
+
+ } else if (exp <= 0x380) { // Normal f64, subnormal f32.
+ // Convert from a 53-bit mantissa (after realizing the implicit bit) to a
+ // 23-bit mantissa and then adjust for the exponent.
+ man |= 0x0010000000000000;
+ uint32_t shift = ((uint32_t)(926 - exp)); // 926 = 0x380 + 53 - 23.
+ uint64_t shifted_man = man >> shift;
+ wuffs_base__lossy_value_u32 ret;
+ ret.value = neg | ((uint32_t)shifted_man);
+ ret.lossy = (shifted_man << shift) != man;
+ return ret;
+ }
+
+ // Normal f64, normal f32.
+
+ // Re-bias from 1023 to 127 and shift above f32's 23 mantissa bits.
+ exp = (exp - 896) << 23; // 896 = 1023 - 127 = 0x3FF - 0x7F.
+
+ // Convert from a 52-bit mantissa (excluding the implicit bit) to a 23-bit
+ // mantissa (again excluding the implicit bit). We lose some information if
+ // any of the bottom 29 bits are non-zero.
+ wuffs_base__lossy_value_u32 ret;
+ ret.value = neg | ((uint32_t)exp) | ((uint32_t)(man >> 29));
+ ret.lossy = (man << 35) != 0;
+ return ret;
+}
+
+// --------
+
+#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE 2047
+#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION 800
+
+// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL is the largest N
+// such that ((10 << N) < (1 << 64)).
+#define WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL 60
+
+// wuffs_base__private_implementation__high_prec_dec (abbreviated as HPD) is a
+// fixed precision floating point decimal number, augmented with ±infinity
+// values, but it cannot represent NaN (Not a Number).
+//
+// "High precision" means that the mantissa holds 800 decimal digits. 800 is
+// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION.
+//
+// An HPD isn't for general purpose arithmetic, only for conversions to and
+// from IEEE 754 double-precision floating point, where the largest and
+// smallest positive, finite values are approximately 1.8e+308 and 4.9e-324.
+// HPD exponents above +2047 mean infinity, below -2047 mean zero. The ±2047
+// bounds are further away from zero than ±(324 + 800), where 800 and 2047 is
+// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION and
+// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
+//
+// digits[.. num_digits] are the number's digits in big-endian order. The
+// uint8_t values are in the range [0 ..= 9], not ['0' ..= '9'], where e.g. '7'
+// is the ASCII value 0x37.
+//
+// decimal_point is the index (within digits) of the decimal point. It may be
+// negative or be larger than num_digits, in which case the explicit digits are
+// padded with implicit zeroes.
+//
+// For example, if num_digits is 3 and digits is "\x07\x08\x09":
+// - A decimal_point of -2 means ".00789"
+// - A decimal_point of -1 means ".0789"
+// - A decimal_point of +0 means ".789"
+// - A decimal_point of +1 means "7.89"
+// - A decimal_point of +2 means "78.9"
+// - A decimal_point of +3 means "789."
+// - A decimal_point of +4 means "7890."
+// - A decimal_point of +5 means "78900."
+//
+// As above, a decimal_point higher than +2047 means that the overall value is
+// infinity, lower than -2047 means zero.
+//
+// negative is a sign bit. An HPD can distinguish positive and negative zero.
+//
+// truncated is whether there are more than
+// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION digits, and at
+// least one of those extra digits are non-zero. The existence of long-tail
+// digits can affect rounding.
+//
+// The "all fields are zero" value is valid, and represents the number +0.
+typedef struct wuffs_base__private_implementation__high_prec_dec__struct {
+ uint32_t num_digits;
+ int32_t decimal_point;
+ bool negative;
+ bool truncated;
+ uint8_t digits[WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION];
+} wuffs_base__private_implementation__high_prec_dec;
+
+// wuffs_base__private_implementation__high_prec_dec__trim trims trailing
+// zeroes from the h->digits[.. h->num_digits] slice. They have no benefit,
+// since we explicitly track h->decimal_point.
+//
+// Preconditions:
+// - h is non-NULL.
+static inline void //
+wuffs_base__private_implementation__high_prec_dec__trim(
+ wuffs_base__private_implementation__high_prec_dec* h) {
+ while ((h->num_digits > 0) && (h->digits[h->num_digits - 1] == 0)) {
+ h->num_digits--;
+ }
+}
+
+// wuffs_base__private_implementation__high_prec_dec__assign sets h to
+// represent the number x.
+//
+// Preconditions:
+// - h is non-NULL.
+static void //
+wuffs_base__private_implementation__high_prec_dec__assign(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ uint64_t x,
+ bool negative) {
+ uint32_t n = 0;
+
+ // Set h->digits.
+ if (x > 0) {
+ // Calculate the digits, working right-to-left. After we determine n (how
+ // many digits there are), copy from buf to h->digits.
+ //
+ // UINT64_MAX, 18446744073709551615, is 20 digits long. It can be faster to
+ // copy a constant number of bytes than a variable number (20 instead of
+ // n). Make buf large enough (and start writing to it from the middle) so
+ // that can we always copy 20 bytes: the slice buf[(20-n) .. (40-n)].
+ uint8_t buf[40] = {0};
+ uint8_t* ptr = &buf[20];
+ do {
+ uint64_t remaining = x / 10;
+ x -= remaining * 10;
+ ptr--;
+ *ptr = (uint8_t)x;
+ n++;
+ x = remaining;
+ } while (x > 0);
+ memcpy(h->digits, ptr, 20);
+ }
+
+ // Set h's other fields.
+ h->num_digits = n;
+ h->decimal_point = (int32_t)n;
+ h->negative = negative;
+ h->truncated = false;
+ wuffs_base__private_implementation__high_prec_dec__trim(h);
+}
+
+static wuffs_base__status //
+wuffs_base__private_implementation__high_prec_dec__parse(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ wuffs_base__slice_u8 s,
+ uint32_t options) {
+ if (!h) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ h->num_digits = 0;
+ h->decimal_point = 0;
+ h->negative = false;
+ h->truncated = false;
+
+ uint8_t* p = s.ptr;
+ uint8_t* q = s.ptr + s.len;
+
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
+ for (;; p++) {
+ if (p >= q) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ } else if (*p != '_') {
+ break;
+ }
+ }
+ }
+
+ // Parse sign.
+ do {
+ if (*p == '+') {
+ p++;
+ } else if (*p == '-') {
+ h->negative = true;
+ p++;
+ } else {
+ break;
+ }
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
+ for (;; p++) {
+ if (p >= q) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ } else if (*p != '_') {
+ break;
+ }
+ }
+ }
+ } while (0);
+
+ // Parse digits, up to (and including) a '.', 'E' or 'e'. Examples for each
+ // limb in this if-else chain:
+ // - "0.789"
+ // - "1002.789"
+ // - ".789"
+ // - Other (invalid input).
+ uint32_t nd = 0;
+ int32_t dp = 0;
+ bool no_digits_before_separator = false;
+ if (('0' == *p) &&
+ !(options &
+ WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES)) {
+ p++;
+ for (;; p++) {
+ if (p >= q) {
+ goto after_all;
+ } else if (*p ==
+ ((options &
+ WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
+ ? ','
+ : '.')) {
+ p++;
+ goto after_sep;
+ } else if ((*p == 'E') || (*p == 'e')) {
+ p++;
+ goto after_exp;
+ } else if ((*p != '_') ||
+ !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ }
+
+ } else if (('0' <= *p) && (*p <= '9')) {
+ if (*p == '0') {
+ for (; (p < q) && (*p == '0'); p++) {
+ }
+ } else {
+ h->digits[nd++] = (uint8_t)(*p - '0');
+ dp = (int32_t)nd;
+ p++;
+ }
+
+ for (;; p++) {
+ if (p >= q) {
+ goto after_all;
+ } else if (('0' <= *p) && (*p <= '9')) {
+ if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
+ h->digits[nd++] = (uint8_t)(*p - '0');
+ dp = (int32_t)nd;
+ } else if ('0' != *p) {
+ // Long-tail non-zeroes set the truncated bit.
+ h->truncated = true;
+ }
+ } else if (*p ==
+ ((options &
+ WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
+ ? ','
+ : '.')) {
+ p++;
+ goto after_sep;
+ } else if ((*p == 'E') || (*p == 'e')) {
+ p++;
+ goto after_exp;
+ } else if ((*p != '_') ||
+ !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ }
+
+ } else if (*p == ((options &
+ WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
+ ? ','
+ : '.')) {
+ p++;
+ no_digits_before_separator = true;
+
+ } else {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+
+after_sep:
+ for (;; p++) {
+ if (p >= q) {
+ goto after_all;
+ } else if ('0' == *p) {
+ if (nd == 0) {
+ // Track leading zeroes implicitly.
+ dp--;
+ } else if (nd <
+ WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
+ h->digits[nd++] = (uint8_t)(*p - '0');
+ }
+ } else if (('0' < *p) && (*p <= '9')) {
+ if (nd < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
+ h->digits[nd++] = (uint8_t)(*p - '0');
+ } else {
+ // Long-tail non-zeroes set the truncated bit.
+ h->truncated = true;
+ }
+ } else if ((*p == 'E') || (*p == 'e')) {
+ p++;
+ goto after_exp;
+ } else if ((*p != '_') ||
+ !(options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ }
+
+after_exp:
+ do {
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
+ for (;; p++) {
+ if (p >= q) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ } else if (*p != '_') {
+ break;
+ }
+ }
+ }
+
+ int32_t exp_sign = +1;
+ if (*p == '+') {
+ p++;
+ } else if (*p == '-') {
+ exp_sign = -1;
+ p++;
+ }
+
+ int32_t exp = 0;
+ const int32_t exp_large =
+ WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE +
+ WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
+ bool saw_exp_digits = false;
+ for (; p < q; p++) {
+ if ((*p == '_') &&
+ (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
+ // No-op.
+ } else if (('0' <= *p) && (*p <= '9')) {
+ saw_exp_digits = true;
+ if (exp < exp_large) {
+ exp = (10 * exp) + ((int32_t)(*p - '0'));
+ }
+ } else {
+ break;
+ }
+ }
+ if (!saw_exp_digits) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ dp += exp_sign * exp;
+ } while (0);
+
+after_all:
+ if (p != q) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ h->num_digits = nd;
+ if (nd == 0) {
+ if (no_digits_before_separator) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ h->decimal_point = 0;
+ } else if (dp <
+ -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
+ h->decimal_point =
+ -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE - 1;
+ } else if (dp >
+ +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
+ h->decimal_point =
+ +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE + 1;
+ } else {
+ h->decimal_point = dp;
+ }
+ wuffs_base__private_implementation__high_prec_dec__trim(h);
+ return wuffs_base__make_status(NULL);
+}
+
+// --------
+
+// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
+// returns the number of additional decimal digits when left-shifting by shift.
+//
+// See below for preconditions.
+static uint32_t //
+wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ uint32_t shift) {
+ // Masking with 0x3F should be unnecessary (assuming the preconditions) but
+ // it's cheap and ensures that we don't overflow the
+ // wuffs_base__private_implementation__hpd_left_shift array.
+ shift &= 63;
+
+ uint32_t x_a = wuffs_base__private_implementation__hpd_left_shift[shift];
+ uint32_t x_b = wuffs_base__private_implementation__hpd_left_shift[shift + 1];
+ uint32_t num_new_digits = x_a >> 11;
+ uint32_t pow5_a = 0x7FF & x_a;
+ uint32_t pow5_b = 0x7FF & x_b;
+
+ const uint8_t* pow5 =
+ &wuffs_base__private_implementation__powers_of_5[pow5_a];
+ uint32_t i = 0;
+ uint32_t n = pow5_b - pow5_a;
+ for (; i < n; i++) {
+ if (i >= h->num_digits) {
+ return num_new_digits - 1;
+ } else if (h->digits[i] == pow5[i]) {
+ continue;
+ } else if (h->digits[i] < pow5[i]) {
+ return num_new_digits - 1;
+ } else {
+ return num_new_digits;
+ }
+ }
+ return num_new_digits;
+}
+
+// --------
+
+// wuffs_base__private_implementation__high_prec_dec__rounded_integer returns
+// the integral (non-fractional) part of h, provided that it is 18 or fewer
+// decimal digits. For 19 or more digits, it returns UINT64_MAX. Note that:
+// - (1 << 53) is 9007199254740992, which has 16 decimal digits.
+// - (1 << 56) is 72057594037927936, which has 17 decimal digits.
+// - (1 << 59) is 576460752303423488, which has 18 decimal digits.
+// - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
+// and that IEEE 754 double precision has 52 mantissa bits.
+//
+// That integral part is rounded-to-even: rounding 7.5 or 8.5 both give 8.
+//
+// h's negative bit is ignored: rounding -8.6 returns 9.
+//
+// See below for preconditions.
+static uint64_t //
+wuffs_base__private_implementation__high_prec_dec__rounded_integer(
+ wuffs_base__private_implementation__high_prec_dec* h) {
+ if ((h->num_digits == 0) || (h->decimal_point < 0)) {
+ return 0;
+ } else if (h->decimal_point > 18) {
+ return UINT64_MAX;
+ }
+
+ uint32_t dp = (uint32_t)(h->decimal_point);
+ uint64_t n = 0;
+ uint32_t i = 0;
+ for (; i < dp; i++) {
+ n = (10 * n) + ((i < h->num_digits) ? h->digits[i] : 0);
+ }
+
+ bool round_up = false;
+ if (dp < h->num_digits) {
+ round_up = h->digits[dp] >= 5;
+ if ((h->digits[dp] == 5) && (dp + 1 == h->num_digits)) {
+ // We are exactly halfway. If we're truncated, round up, otherwise round
+ // to even.
+ round_up = h->truncated || //
+ ((dp > 0) && (1 & h->digits[dp - 1]));
+ }
+ }
+ if (round_up) {
+ n++;
+ }
+
+ return n;
+}
+
+// wuffs_base__private_implementation__high_prec_dec__small_xshift shifts h's
+// number (where 'x' is 'l' or 'r' for left or right) by a small shift value.
+//
+// Preconditions:
+// - h is non-NULL.
+// - h->decimal_point is "not extreme".
+// - shift is non-zero.
+// - shift is "a small shift".
+//
+// "Not extreme" means within
+// ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
+//
+// "A small shift" means not more than
+// WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
+//
+// wuffs_base__private_implementation__high_prec_dec__rounded_integer and
+// wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits
+// have the same preconditions.
+//
+// wuffs_base__private_implementation__high_prec_dec__lshift keeps the first
+// two preconditions but not the last two. Its shift argument is signed and
+// does not need to be "small": zero is a no-op, positive means left shift and
+// negative means right shift.
+
+static void //
+wuffs_base__private_implementation__high_prec_dec__small_lshift(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ uint32_t shift) {
+ if (h->num_digits == 0) {
+ return;
+ }
+ uint32_t num_new_digits =
+ wuffs_base__private_implementation__high_prec_dec__lshift_num_new_digits(
+ h, shift);
+ uint32_t rx = h->num_digits - 1; // Read index.
+ uint32_t wx = h->num_digits - 1 + num_new_digits; // Write index.
+ uint64_t n = 0;
+
+ // Repeat: pick up a digit, put down a digit, right to left.
+ while (((int32_t)rx) >= 0) {
+ n += ((uint64_t)(h->digits[rx])) << shift;
+ uint64_t quo = n / 10;
+ uint64_t rem = n - (10 * quo);
+ if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
+ h->digits[wx] = (uint8_t)rem;
+ } else if (rem > 0) {
+ h->truncated = true;
+ }
+ n = quo;
+ wx--;
+ rx--;
+ }
+
+ // Put down leading digits, right to left.
+ while (n > 0) {
+ uint64_t quo = n / 10;
+ uint64_t rem = n - (10 * quo);
+ if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
+ h->digits[wx] = (uint8_t)rem;
+ } else if (rem > 0) {
+ h->truncated = true;
+ }
+ n = quo;
+ wx--;
+ }
+
+ // Finish.
+ h->num_digits += num_new_digits;
+ if (h->num_digits >
+ WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
+ h->num_digits = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION;
+ }
+ h->decimal_point += (int32_t)num_new_digits;
+ wuffs_base__private_implementation__high_prec_dec__trim(h);
+}
+
+static void //
+wuffs_base__private_implementation__high_prec_dec__small_rshift(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ uint32_t shift) {
+ uint32_t rx = 0; // Read index.
+ uint32_t wx = 0; // Write index.
+ uint64_t n = 0;
+
+ // Pick up enough leading digits to cover the first shift.
+ while ((n >> shift) == 0) {
+ if (rx < h->num_digits) {
+ // Read a digit.
+ n = (10 * n) + h->digits[rx++];
+ } else if (n == 0) {
+ // h's number used to be zero and remains zero.
+ return;
+ } else {
+ // Read sufficient implicit trailing zeroes.
+ while ((n >> shift) == 0) {
+ n = 10 * n;
+ rx++;
+ }
+ break;
+ }
+ }
+ h->decimal_point -= ((int32_t)(rx - 1));
+ if (h->decimal_point <
+ -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
+ // After the shift, h's number is effectively zero.
+ h->num_digits = 0;
+ h->decimal_point = 0;
+ h->truncated = false;
+ return;
+ }
+
+ // Repeat: pick up a digit, put down a digit, left to right.
+ uint64_t mask = (((uint64_t)(1)) << shift) - 1;
+ while (rx < h->num_digits) {
+ uint8_t new_digit = ((uint8_t)(n >> shift));
+ n = (10 * (n & mask)) + h->digits[rx++];
+ h->digits[wx++] = new_digit;
+ }
+
+ // Put down trailing digits, left to right.
+ while (n > 0) {
+ uint8_t new_digit = ((uint8_t)(n >> shift));
+ n = 10 * (n & mask);
+ if (wx < WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DIGITS_PRECISION) {
+ h->digits[wx++] = new_digit;
+ } else if (new_digit > 0) {
+ h->truncated = true;
+ }
+ }
+
+ // Finish.
+ h->num_digits = wx;
+ wuffs_base__private_implementation__high_prec_dec__trim(h);
+}
+
+static void //
+wuffs_base__private_implementation__high_prec_dec__lshift(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ int32_t shift) {
+ if (shift > 0) {
+ while (shift > +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
+ wuffs_base__private_implementation__high_prec_dec__small_lshift(
+ h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
+ shift -= WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
+ }
+ wuffs_base__private_implementation__high_prec_dec__small_lshift(
+ h, ((uint32_t)(+shift)));
+ } else if (shift < 0) {
+ while (shift < -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
+ wuffs_base__private_implementation__high_prec_dec__small_rshift(
+ h, WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL);
+ shift += WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
+ }
+ wuffs_base__private_implementation__high_prec_dec__small_rshift(
+ h, ((uint32_t)(-shift)));
+ }
+}
+
+// --------
+
+// wuffs_base__private_implementation__high_prec_dec__round_etc rounds h's
+// number. For those functions that take an n argument, rounding produces at
+// most n digits (which is not necessarily at most n decimal places). Negative
+// n values are ignored, as well as any n greater than or equal to h's number
+// of digits. The etc__round_just_enough function implicitly chooses an n to
+// implement WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION.
+//
+// Preconditions:
+// - h is non-NULL.
+// - h->decimal_point is "not extreme".
+//
+// "Not extreme" means within
+// ±WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE.
+
+static void //
+wuffs_base__private_implementation__high_prec_dec__round_down(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ int32_t n) {
+ if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
+ return;
+ }
+ h->num_digits = (uint32_t)(n);
+ wuffs_base__private_implementation__high_prec_dec__trim(h);
+}
+
+static void //
+wuffs_base__private_implementation__high_prec_dec__round_up(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ int32_t n) {
+ if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
+ return;
+ }
+
+ for (n--; n >= 0; n--) {
+ if (h->digits[n] < 9) {
+ h->digits[n]++;
+ h->num_digits = (uint32_t)(n + 1);
+ return;
+ }
+ }
+
+ // The number is all 9s. Change to a single 1 and adjust the decimal point.
+ h->digits[0] = 1;
+ h->num_digits = 1;
+ h->decimal_point++;
+}
+
+static void //
+wuffs_base__private_implementation__high_prec_dec__round_nearest(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ int32_t n) {
+ if ((n < 0) || (h->num_digits <= (uint32_t)n)) {
+ return;
+ }
+ bool up = h->digits[n] >= 5;
+ if ((h->digits[n] == 5) && ((n + 1) == ((int32_t)(h->num_digits)))) {
+ up = h->truncated || //
+ ((n > 0) && ((h->digits[n - 1] & 1) != 0));
+ }
+
+ if (up) {
+ wuffs_base__private_implementation__high_prec_dec__round_up(h, n);
+ } else {
+ wuffs_base__private_implementation__high_prec_dec__round_down(h, n);
+ }
+}
+
+static void //
+wuffs_base__private_implementation__high_prec_dec__round_just_enough(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ int32_t exp2,
+ uint64_t mantissa) {
+ // The magic numbers 52 and 53 in this function are because IEEE 754 double
+ // precision has 52 mantissa bits.
+ //
+ // Let f be the floating point number represented by exp2 and mantissa (and
+ // also the number in h): the number (mantissa * (2 ** (exp2 - 52))).
+ //
+ // If f is zero or a small integer, we can return early.
+ if ((mantissa == 0) ||
+ ((exp2 < 53) && (h->decimal_point >= ((int32_t)(h->num_digits))))) {
+ return;
+ }
+
+ // The smallest normal f has an exp2 of -1022 and a mantissa of (1 << 52).
+ // Subnormal numbers have the same exp2 but a smaller mantissa.
+ static const int32_t min_incl_normal_exp2 = -1022;
+ static const uint64_t min_incl_normal_mantissa = 0x0010000000000000ul;
+
+ // Compute lower and upper bounds such that any number between them (possibly
+ // inclusive) will round to f. First, the lower bound. Our number f is:
+ // ((mantissa + 0) * (2 ** ( exp2 - 52)))
+ //
+ // The next lowest floating point number is:
+ // ((mantissa - 1) * (2 ** ( exp2 - 52)))
+ // unless (mantissa - 1) drops the (1 << 52) bit and exp2 is not the
+ // min_incl_normal_exp2. Either way, call it:
+ // ((l_mantissa) * (2 ** (l_exp2 - 52)))
+ //
+ // The lower bound is halfway between them (noting that 52 became 53):
+ // (((2 * l_mantissa) + 1) * (2 ** (l_exp2 - 53)))
+ int32_t l_exp2 = exp2;
+ uint64_t l_mantissa = mantissa - 1;
+ if ((exp2 > min_incl_normal_exp2) && (mantissa <= min_incl_normal_mantissa)) {
+ l_exp2 = exp2 - 1;
+ l_mantissa = (2 * mantissa) - 1;
+ }
+ wuffs_base__private_implementation__high_prec_dec lower;
+ wuffs_base__private_implementation__high_prec_dec__assign(
+ &lower, (2 * l_mantissa) + 1, false);
+ wuffs_base__private_implementation__high_prec_dec__lshift(&lower,
+ l_exp2 - 53);
+
+ // Next, the upper bound. Our number f is:
+ // ((mantissa + 0) * (2 ** (exp2 - 52)))
+ //
+ // The next highest floating point number is:
+ // ((mantissa + 1) * (2 ** (exp2 - 52)))
+ //
+ // The upper bound is halfway between them (noting that 52 became 53):
+ // (((2 * mantissa) + 1) * (2 ** (exp2 - 53)))
+ wuffs_base__private_implementation__high_prec_dec upper;
+ wuffs_base__private_implementation__high_prec_dec__assign(
+ &upper, (2 * mantissa) + 1, false);
+ wuffs_base__private_implementation__high_prec_dec__lshift(&upper, exp2 - 53);
+
+ // The lower and upper bounds are possible outputs only if the original
+ // mantissa is even, so that IEEE round-to-even would round to the original
+ // mantissa and not its neighbors.
+ bool inclusive = (mantissa & 1) == 0;
+
+ // As we walk the digits, we want to know whether rounding up would fall
+ // within the upper bound. This is tracked by upper_delta:
+ // - When -1, the digits of h and upper are the same so far.
+ // - When +0, we saw a difference of 1 between h and upper on a previous
+ // digit and subsequently only 9s for h and 0s for upper. Thus, rounding
+ // up may fall outside of the bound if !inclusive.
+ // - When +1, the difference is greater than 1 and we know that rounding up
+ // falls within the bound.
+ //
+ // This is a state machine with three states. The numerical value for each
+ // state (-1, +0 or +1) isn't important, other than their order.
+ int upper_delta = -1;
+
+ // We can now figure out the shortest number of digits required. Walk the
+ // digits until h has distinguished itself from lower or upper.
+ //
+ // The zi and zd variables are indexes and digits, for z in l (lower), h (the
+ // number) and u (upper).
+ //
+ // The lower, h and upper numbers may have their decimal points at different
+ // places. In this case, upper is the longest, so we iterate ui starting from
+ // 0 and iterate li and hi starting from either 0 or -1.
+ int32_t ui = 0;
+ for (;; ui++) {
+ // Calculate hd, the middle number's digit.
+ int32_t hi = ui - upper.decimal_point + h->decimal_point;
+ if (hi >= ((int32_t)(h->num_digits))) {
+ break;
+ }
+ uint8_t hd = (((uint32_t)hi) < h->num_digits) ? h->digits[hi] : 0;
+
+ // Calculate ld, the lower bound's digit.
+ int32_t li = ui - upper.decimal_point + lower.decimal_point;
+ uint8_t ld = (((uint32_t)li) < lower.num_digits) ? lower.digits[li] : 0;
+
+ // We can round down (truncate) if lower has a different digit than h or if
+ // lower is inclusive and is exactly the result of rounding down (i.e. we
+ // have reached the final digit of lower).
+ bool can_round_down =
+ (ld != hd) || //
+ (inclusive && ((li + 1) == ((int32_t)(lower.num_digits))));
+
+ // Calculate ud, the upper bound's digit, and update upper_delta.
+ uint8_t ud = (((uint32_t)ui) < upper.num_digits) ? upper.digits[ui] : 0;
+ if (upper_delta < 0) {
+ if ((hd + 1) < ud) {
+ // For example:
+ // h = 12345???
+ // upper = 12347???
+ upper_delta = +1;
+ } else if (hd != ud) {
+ // For example:
+ // h = 12345???
+ // upper = 12346???
+ upper_delta = +0;
+ }
+ } else if (upper_delta == 0) {
+ if ((hd != 9) || (ud != 0)) {
+ // For example:
+ // h = 1234598?
+ // upper = 1234600?
+ upper_delta = +1;
+ }
+ }
+
+ // We can round up if upper has a different digit than h and either upper
+ // is inclusive or upper is bigger than the result of rounding up.
+ bool can_round_up =
+ (upper_delta > 0) || //
+ ((upper_delta == 0) && //
+ (inclusive || ((ui + 1) < ((int32_t)(upper.num_digits)))));
+
+ // If we can round either way, round to nearest. If we can round only one
+ // way, do it. If we can't round, continue the loop.
+ if (can_round_down) {
+ if (can_round_up) {
+ wuffs_base__private_implementation__high_prec_dec__round_nearest(
+ h, hi + 1);
+ return;
+ } else {
+ wuffs_base__private_implementation__high_prec_dec__round_down(h,
+ hi + 1);
+ return;
+ }
+ } else {
+ if (can_round_up) {
+ wuffs_base__private_implementation__high_prec_dec__round_up(h, hi + 1);
+ return;
+ }
+ }
+ }
+}
+
+// --------
+
+// wuffs_base__private_implementation__parse_number_f64_eisel_lemire produces
+// the IEEE 754 double-precision value for an exact mantissa and base-10
+// exponent. For example:
+// - when parsing "12345.678e+02", man is 12345678 and exp10 is -1.
+// - when parsing "-12", man is 12 and exp10 is 0. Processing the leading
+// minus sign is the responsibility of the caller, not this function.
+//
+// On success, it returns a non-negative int64_t such that the low 63 bits hold
+// the 11-bit exponent and 52-bit mantissa.
+//
+// On failure, it returns a negative value.
+//
+// The algorithm is based on an original idea by Michael Eisel that was refined
+// by Daniel Lemire. See
+// https://lemire.me/blog/2020/03/10/fast-float-parsing-in-practice/
+// and
+// https://nigeltao.github.io/blog/2020/eisel-lemire.html
+//
+// Preconditions:
+// - man is non-zero.
+// - exp10 is in the range [-307 ..= 288], the same range of the
+// wuffs_base__private_implementation__powers_of_10 array.
+//
+// The exp10 range (and the fact that man is in the range [1 ..= UINT64_MAX],
+// approximately [1 ..= 1.85e+19]) means that (man * (10 ** exp10)) is in the
+// range [1e-307 ..= 1.85e+307]. This is entirely within the range of normal
+// (neither subnormal nor non-finite) f64 values: DBL_MIN and DBL_MAX are
+// approximately 2.23e–308 and 1.80e+308.
+static int64_t //
+wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
+ uint64_t man,
+ int32_t exp10) {
+ // Look up the (possibly truncated) base-2 representation of (10 ** exp10).
+ // The look-up table was constructed so that it is already normalized: the
+ // table entry's mantissa's MSB (most significant bit) is on.
+ const uint64_t* po10 =
+ &wuffs_base__private_implementation__powers_of_10[exp10 + 307][0];
+
+ // Normalize the man argument. The (man != 0) precondition means that a
+ // non-zero bit exists.
+ uint32_t clz = wuffs_base__count_leading_zeroes_u64(man);
+ man <<= clz;
+
+ // Calculate the return value's base-2 exponent. We might tweak it by ±1
+ // later, but its initial value comes from a linear scaling of exp10,
+ // converting from power-of-10 to power-of-2, and adjusting by clz.
+ //
+ // The magic constants are:
+ // - 1087 = 1023 + 64. The 1023 is the f64 exponent bias. The 64 is because
+ // the look-up table uses 64-bit mantissas.
+ // - 217706 is such that the ratio 217706 / 65536 ≈ 3.321930 is close enough
+ // (over the practical range of exp10) to log(10) / log(2) ≈ 3.321928.
+ // - 65536 = 1<<16 is arbitrary but a power of 2, so division is a shift.
+ //
+ // Equality of the linearly-scaled value and the actual power-of-2, over the
+ // range of exp10 arguments that this function accepts, is confirmed by
+ // script/print-mpb-powers-of-10.go
+ uint64_t ret_exp2 =
+ ((uint64_t)(((217706 * exp10) >> 16) + 1087)) - ((uint64_t)clz);
+
+ // Multiply the two mantissas. Normalization means that both mantissas are at
+ // least (1<<63), so the 128-bit product must be at least (1<<126). The high
+ // 64 bits of the product, x_hi, must therefore be at least (1<<62).
+ //
+ // As a consequence, x_hi has either 0 or 1 leading zeroes. Shifting x_hi
+ // right by either 9 or 10 bits (depending on x_hi's MSB) will therefore
+ // leave the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on.
+ wuffs_base__multiply_u64__output x = wuffs_base__multiply_u64(man, po10[1]);
+ uint64_t x_hi = x.hi;
+ uint64_t x_lo = x.lo;
+
+ // Before we shift right by at least 9 bits, recall that the look-up table
+ // entry was possibly truncated. We have so far only calculated a lower bound
+ // for the product (man * e), where e is (10 ** exp10). The upper bound would
+ // add a further (man * 1) to the 128-bit product, which overflows the lower
+ // 64-bit limb if ((x_lo + man) < man).
+ //
+ // If overflow occurs, that adds 1 to x_hi. Since we're about to shift right
+ // by at least 9 bits, that carried 1 can be ignored unless the higher 64-bit
+ // limb's low 9 bits are all on.
+ //
+ // For example, parsing "9999999999999999999" will take the if-true branch
+ // here, since:
+ // - x_hi = 0x4563918244F3FFFF
+ // - x_lo = 0x8000000000000000
+ // - man = 0x8AC7230489E7FFFF
+ if (((x_hi & 0x1FF) == 0x1FF) && ((x_lo + man) < man)) {
+ // Refine our calculation of (man * e). Before, our approximation of e used
+ // a "low resolution" 64-bit mantissa. Now use a "high resolution" 128-bit
+ // mantissa. We've already calculated x = (man * bits_0_to_63_incl_of_e).
+ // Now calculate y = (man * bits_64_to_127_incl_of_e).
+ wuffs_base__multiply_u64__output y = wuffs_base__multiply_u64(man, po10[0]);
+ uint64_t y_hi = y.hi;
+ uint64_t y_lo = y.lo;
+
+ // Merge the 128-bit x and 128-bit y, which overlap by 64 bits, to
+ // calculate the 192-bit product of the 64-bit man by the 128-bit e.
+ // As we exit this if-block, we only care about the high 128 bits
+ // (merged_hi and merged_lo) of that 192-bit product.
+ //
+ // For example, parsing "1.234e-45" will take the if-true branch here,
+ // since:
+ // - x_hi = 0x70B7E3696DB29FFF
+ // - x_lo = 0xE040000000000000
+ // - y_hi = 0x33718BBEAB0E0D7A
+ // - y_lo = 0xA880000000000000
+ uint64_t merged_hi = x_hi;
+ uint64_t merged_lo = x_lo + y_hi;
+ if (merged_lo < x_lo) {
+ merged_hi++; // Carry the overflow bit.
+ }
+
+ // The "high resolution" approximation of e is still a lower bound. Once
+ // again, see if the upper bound is large enough to produce a different
+ // result. This time, if it does, give up instead of reaching for an even
+ // more precise approximation to e.
+ //
+ // This three-part check is similar to the two-part check that guarded the
+ // if block that we're now in, but it has an extra term for the middle 64
+ // bits (checking that adding 1 to merged_lo would overflow).
+ //
+ // For example, parsing "5.9604644775390625e-8" will take the if-true
+ // branch here, since:
+ // - merged_hi = 0x7FFFFFFFFFFFFFFF
+ // - merged_lo = 0xFFFFFFFFFFFFFFFF
+ // - y_lo = 0x4DB3FFC120988200
+ // - man = 0xD3C21BCECCEDA100
+ if (((merged_hi & 0x1FF) == 0x1FF) && ((merged_lo + 1) == 0) &&
+ (y_lo + man < man)) {
+ return -1;
+ }
+
+ // Replace the 128-bit x with merged.
+ x_hi = merged_hi;
+ x_lo = merged_lo;
+ }
+
+ // As mentioned above, shifting x_hi right by either 9 or 10 bits will leave
+ // the top 10 MSBs (bits 54 ..= 63) off and the 11th MSB (bit 53) on. If the
+ // MSB (before shifting) was on, adjust ret_exp2 for the larger shift.
+ //
+ // Having bit 53 on (and higher bits off) means that ret_mantissa is a 54-bit
+ // number.
+ uint64_t msb = x_hi >> 63;
+ uint64_t ret_mantissa = x_hi >> (msb + 9);
+ ret_exp2 -= 1 ^ msb;
+
+ // IEEE 754 rounds to-nearest with ties rounded to-even. Rounding to-even can
+ // be tricky. If we're half-way between two exactly representable numbers
+ // (x's low 73 bits are zero and the next 2 bits that matter are "01"), give
+ // up instead of trying to pick the winner.
+ //
+ // Technically, we could tighten the condition by changing "73" to "73 or 74,
+ // depending on msb", but a flat "73" is simpler.
+ //
+ // For example, parsing "1e+23" will take the if-true branch here, since:
+ // - x_hi = 0x54B40B1F852BDA00
+ // - ret_mantissa = 0x002A5A058FC295ED
+ if ((x_lo == 0) && ((x_hi & 0x1FF) == 0) && ((ret_mantissa & 3) == 1)) {
+ return -1;
+ }
+
+ // If we're not halfway then it's rounding to-nearest. Starting with a 54-bit
+ // number, carry the lowest bit (bit 0) up if it's on. Regardless of whether
+ // it was on or off, shifting right by one then produces a 53-bit number. If
+ // carrying up overflowed, shift again.
+ ret_mantissa += ret_mantissa & 1;
+ ret_mantissa >>= 1;
+ // This if block is equivalent to (but benchmarks slightly faster than) the
+ // following branchless form:
+ // uint64_t overflow_adjustment = ret_mantissa >> 53;
+ // ret_mantissa >>= overflow_adjustment;
+ // ret_exp2 += overflow_adjustment;
+ //
+ // For example, parsing "7.2057594037927933e+16" will take the if-true
+ // branch here, since:
+ // - x_hi = 0x7FFFFFFFFFFFFE80
+ // - ret_mantissa = 0x0020000000000000
+ if ((ret_mantissa >> 53) > 0) {
+ ret_mantissa >>= 1;
+ ret_exp2++;
+ }
+
+ // Starting with a 53-bit number, IEEE 754 double-precision normal numbers
+ // have an implicit mantissa bit. Mask that away and keep the low 52 bits.
+ ret_mantissa &= 0x000FFFFFFFFFFFFF;
+
+ // Pack the bits and return.
+ return ((int64_t)(ret_mantissa | (ret_exp2 << 52)));
+}
+
+// --------
+
+static wuffs_base__result_f64 //
+wuffs_base__private_implementation__parse_number_f64_special(
+ wuffs_base__slice_u8 s,
+ uint32_t options) {
+ do {
+ if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
+ goto fail;
+ }
+
+ uint8_t* p = s.ptr;
+ uint8_t* q = s.ptr + s.len;
+
+ for (; (p < q) && (*p == '_'); p++) {
+ }
+ if (p >= q) {
+ goto fail;
+ }
+
+ // Parse sign.
+ bool negative = false;
+ do {
+ if (*p == '+') {
+ p++;
+ } else if (*p == '-') {
+ negative = true;
+ p++;
+ } else {
+ break;
+ }
+ for (; (p < q) && (*p == '_'); p++) {
+ }
+ } while (0);
+ if (p >= q) {
+ goto fail;
+ }
+
+ bool nan = false;
+ switch (p[0]) {
+ case 'I':
+ case 'i':
+ if (((q - p) < 3) || //
+ ((p[1] != 'N') && (p[1] != 'n')) || //
+ ((p[2] != 'F') && (p[2] != 'f'))) {
+ goto fail;
+ }
+ p += 3;
+
+ if ((p >= q) || (*p == '_')) {
+ break;
+ } else if (((q - p) < 5) || //
+ ((p[0] != 'I') && (p[0] != 'i')) || //
+ ((p[1] != 'N') && (p[1] != 'n')) || //
+ ((p[2] != 'I') && (p[2] != 'i')) || //
+ ((p[3] != 'T') && (p[3] != 't')) || //
+ ((p[4] != 'Y') && (p[4] != 'y'))) {
+ goto fail;
+ }
+ p += 5;
+
+ if ((p >= q) || (*p == '_')) {
+ break;
+ }
+ goto fail;
+
+ case 'N':
+ case 'n':
+ if (((q - p) < 3) || //
+ ((p[1] != 'A') && (p[1] != 'a')) || //
+ ((p[2] != 'N') && (p[2] != 'n'))) {
+ goto fail;
+ }
+ p += 3;
+
+ if ((p >= q) || (*p == '_')) {
+ nan = true;
+ break;
+ }
+ goto fail;
+
+ default:
+ goto fail;
+ }
+
+ // Finish.
+ for (; (p < q) && (*p == '_'); p++) {
+ }
+ if (p != q) {
+ goto fail;
+ }
+ wuffs_base__result_f64 ret;
+ ret.status.repr = NULL;
+ ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
+ (nan ? 0x7FFFFFFFFFFFFFFF : 0x7FF0000000000000) |
+ (negative ? 0x8000000000000000 : 0));
+ return ret;
+ } while (0);
+
+fail:
+ do {
+ wuffs_base__result_f64 ret;
+ ret.status.repr = wuffs_base__error__bad_argument;
+ ret.value = 0;
+ return ret;
+ } while (0);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
+wuffs_base__private_implementation__high_prec_dec__to_f64(
+ wuffs_base__private_implementation__high_prec_dec* h,
+ uint32_t options) {
+ do {
+ // powers converts decimal powers of 10 to binary powers of 2. For example,
+ // (10000 >> 13) is 1. It stops before the elements exceed 60, also known
+ // as WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
+ //
+ // This rounds down (1<<13 is a lower bound for 1e4). Adding 1 to the array
+ // element value rounds up (1<<14 is an upper bound for 1e4) while staying
+ // at or below WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL.
+ //
+ // When starting in the range [1e+1 .. 1e+2] (i.e. h->decimal_point == +2),
+ // powers[2] == 6 and so:
+ // - Right shifting by 6+0 produces the range [10/64 .. 100/64] =
+ // [0.156250 .. 1.56250]. The resultant h->decimal_point is +0 or +1.
+ // - Right shifting by 6+1 produces the range [10/128 .. 100/128] =
+ // [0.078125 .. 0.78125]. The resultant h->decimal_point is -1 or -0.
+ //
+ // When starting in the range [1e-3 .. 1e-2] (i.e. h->decimal_point == -2),
+ // powers[2] == 6 and so:
+ // - Left shifting by 6+0 produces the range [0.001*64 .. 0.01*64] =
+ // [0.064 .. 0.64]. The resultant h->decimal_point is -1 or -0.
+ // - Left shifting by 6+1 produces the range [0.001*128 .. 0.01*128] =
+ // [0.128 .. 1.28]. The resultant h->decimal_point is +0 or +1.
+ //
+ // Thus, when targeting h->decimal_point being +0 or +1, use (powers[n]+0)
+ // when right shifting but (powers[n]+1) when left shifting.
+ static const uint32_t num_powers = 19;
+ static const uint8_t powers[19] = {
+ 0, 3, 6, 9, 13, 16, 19, 23, 26, 29, //
+ 33, 36, 39, 43, 46, 49, 53, 56, 59, //
+ };
+
+ // Handle zero and obvious extremes. The largest and smallest positive
+ // finite f64 values are approximately 1.8e+308 and 4.9e-324.
+ if ((h->num_digits == 0) || (h->decimal_point < -326)) {
+ goto zero;
+ } else if (h->decimal_point > 310) {
+ goto infinity;
+ }
+
+ // Try the fast Eisel-Lemire algorithm again. Calculating the (man, exp10)
+ // pair from the high_prec_dec h is more correct but slower than the
+ // approach taken in wuffs_base__parse_number_f64. The latter is optimized
+ // for the common cases (e.g. assuming no underscores or a leading '+'
+ // sign) rather than the full set of cases allowed by the Wuffs API.
+ //
+ // When we have 19 or fewer mantissa digits, run Eisel-Lemire once (trying
+ // for an exact result). When we have more than 19 mantissa digits, run it
+ // twice to get a lower and upper bound. We still have an exact result
+ // (within f64's rounding margin) if both bounds are equal (and valid).
+ uint32_t i_max = h->num_digits;
+ if (i_max > 19) {
+ i_max = 19;
+ }
+ int32_t exp10 = h->decimal_point - ((int32_t)i_max);
+ if ((-307 <= exp10) && (exp10 <= 288)) {
+ uint64_t man = 0;
+ uint32_t i;
+ for (i = 0; i < i_max; i++) {
+ man = (10 * man) + h->digits[i];
+ }
+ while (man != 0) { // The 'while' is just an 'if' that we can 'break'.
+ int64_t r0 =
+ wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
+ man + 0, exp10);
+ if (r0 < 0) {
+ break;
+ } else if (h->num_digits > 19) {
+ int64_t r1 =
+ wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
+ man + 1, exp10);
+ if (r1 != r0) {
+ break;
+ }
+ }
+ wuffs_base__result_f64 ret;
+ ret.status.repr = NULL;
+ ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
+ ((uint64_t)r0) | (((uint64_t)(h->negative)) << 63));
+ return ret;
+ }
+ }
+
+ // When Eisel-Lemire fails, fall back to Simple Decimal Conversion. See
+ // https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html
+ //
+ // Scale by powers of 2 until we're in the range [0.1 .. 10]. Equivalently,
+ // that h->decimal_point is +0 or +1.
+ //
+ // First we shift right while at or above 10...
+ const int32_t f64_bias = -1023;
+ int32_t exp2 = 0;
+ while (h->decimal_point > 1) {
+ uint32_t n = (uint32_t)(+h->decimal_point);
+ uint32_t shift =
+ (n < num_powers)
+ ? powers[n]
+ : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
+
+ wuffs_base__private_implementation__high_prec_dec__small_rshift(h, shift);
+ if (h->decimal_point <
+ -WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
+ goto zero;
+ }
+ exp2 += (int32_t)shift;
+ }
+ // ...then we shift left while below 0.1.
+ while (h->decimal_point < 0) {
+ uint32_t shift;
+ uint32_t n = (uint32_t)(-h->decimal_point);
+ shift = (n < num_powers)
+ // The +1 is per "when targeting h->decimal_point being +0 or
+ // +1... when left shifting" in the powers comment above.
+ ? (powers[n] + 1)
+ : WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
+
+ wuffs_base__private_implementation__high_prec_dec__small_lshift(h, shift);
+ if (h->decimal_point >
+ +WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__DECIMAL_POINT__RANGE) {
+ goto infinity;
+ }
+ exp2 -= (int32_t)shift;
+ }
+
+ // To get from "in the range [0.1 .. 10]" to "in the range [1 .. 2]" (which
+ // will give us our exponent in base-2), the mantissa's first 3 digits will
+ // determine the final left shift, equal to 52 (the number of explicit f64
+ // bits) plus an additional adjustment.
+ int man3 = (100 * h->digits[0]) +
+ ((h->num_digits > 1) ? (10 * h->digits[1]) : 0) +
+ ((h->num_digits > 2) ? h->digits[2] : 0);
+ int32_t additional_lshift = 0;
+ if (h->decimal_point == 0) { // The value is in [0.1 .. 1].
+ if (man3 < 125) {
+ additional_lshift = +4;
+ } else if (man3 < 250) {
+ additional_lshift = +3;
+ } else if (man3 < 500) {
+ additional_lshift = +2;
+ } else {
+ additional_lshift = +1;
+ }
+ } else { // The value is in [1 .. 10].
+ if (man3 < 200) {
+ additional_lshift = -0;
+ } else if (man3 < 400) {
+ additional_lshift = -1;
+ } else if (man3 < 800) {
+ additional_lshift = -2;
+ } else {
+ additional_lshift = -3;
+ }
+ }
+ exp2 -= additional_lshift;
+ uint32_t final_lshift = (uint32_t)(52 + additional_lshift);
+
+ // The minimum normal exponent is (f64_bias + 1).
+ while ((f64_bias + 1) > exp2) {
+ uint32_t n = (uint32_t)((f64_bias + 1) - exp2);
+ if (n > WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL) {
+ n = WUFFS_BASE__PRIVATE_IMPLEMENTATION__HPD__SHIFT__MAX_INCL;
+ }
+ wuffs_base__private_implementation__high_prec_dec__small_rshift(h, n);
+ exp2 += (int32_t)n;
+ }
+
+ // Check for overflow.
+ if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1.
+ goto infinity;
+ }
+
+ // Extract 53 bits for the mantissa (in base-2).
+ wuffs_base__private_implementation__high_prec_dec__small_lshift(
+ h, final_lshift);
+ uint64_t man2 =
+ wuffs_base__private_implementation__high_prec_dec__rounded_integer(h);
+
+ // Rounding might have added one bit. If so, shift and re-check overflow.
+ if ((man2 >> 53) != 0) {
+ man2 >>= 1;
+ exp2++;
+ if ((exp2 - f64_bias) >= 0x07FF) { // (1 << 11) - 1.
+ goto infinity;
+ }
+ }
+
+ // Handle subnormal numbers.
+ if ((man2 >> 52) == 0) {
+ exp2 = f64_bias;
+ }
+
+ // Pack the bits and return.
+ uint64_t exp2_bits =
+ (uint64_t)((exp2 - f64_bias) & 0x07FF); // (1 << 11) - 1.
+ uint64_t bits = (man2 & 0x000FFFFFFFFFFFFF) | // (1 << 52) - 1.
+ (exp2_bits << 52) | //
+ (h->negative ? 0x8000000000000000 : 0); // (1 << 63).
+
+ wuffs_base__result_f64 ret;
+ ret.status.repr = NULL;
+ ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
+ return ret;
+ } while (0);
+
+zero:
+ do {
+ uint64_t bits = h->negative ? 0x8000000000000000 : 0;
+
+ wuffs_base__result_f64 ret;
+ ret.status.repr = NULL;
+ ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
+ return ret;
+ } while (0);
+
+infinity:
+ do {
+ if (options & WUFFS_BASE__PARSE_NUMBER_FXX__REJECT_INF_AND_NAN) {
+ wuffs_base__result_f64 ret;
+ ret.status.repr = wuffs_base__error__bad_argument;
+ ret.value = 0;
+ return ret;
+ }
+
+ uint64_t bits = h->negative ? 0xFFF0000000000000 : 0x7FF0000000000000;
+
+ wuffs_base__result_f64 ret;
+ ret.status.repr = NULL;
+ ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(bits);
+ return ret;
+ } while (0);
+}
+
+static inline bool //
+wuffs_base__private_implementation__is_decimal_digit(uint8_t c) {
+ return ('0' <= c) && (c <= '9');
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_f64 //
+wuffs_base__parse_number_f64(wuffs_base__slice_u8 s, uint32_t options) {
+ // In practice, almost all "dd.ddddE±xxx" numbers can be represented
+ // losslessly by a uint64_t mantissa "dddddd" and an int32_t base-10
+ // exponent, adjusting "xxx" for the position (if present) of the decimal
+ // separator '.' or ','.
+ //
+ // This (u64 man, i32 exp10) data structure is superficially similar to the
+ // "Do It Yourself Floating Point" type from Loitsch (†), but the exponent
+ // here is base-10, not base-2.
+ //
+ // If s's number fits in a (man, exp10), parse that pair with the
+ // Eisel-Lemire algorithm. If not, or if Eisel-Lemire fails, parsing s with
+ // the fallback algorithm is slower but comprehensive.
+ //
+ // † "Printing Floating-Point Numbers Quickly and Accurately with Integers"
+ // (https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf).
+ // Florian Loitsch is also the primary contributor to
+ // https://github.com/google/double-conversion
+ do {
+ // Calculating that (man, exp10) pair needs to stay within s's bounds.
+ // Provided that s isn't extremely long, work on a NUL-terminated copy of
+ // s's contents. The NUL byte isn't a valid part of "±dd.ddddE±xxx".
+ //
+ // As the pointer p walks the contents, it's faster to repeatedly check "is
+ // *p a valid digit" than "is p within bounds and *p a valid digit".
+ if (s.len >= 256) {
+ goto fallback;
+ }
+ uint8_t z[256];
+ memcpy(&z[0], s.ptr, s.len);
+ z[s.len] = 0;
+ const uint8_t* p = &z[0];
+
+ // Look for a leading minus sign. Technically, we could also look for an
+ // optional plus sign, but the "script/process-json-numbers.c with -p"
+ // benchmark is noticably slower if we do. It's optional and, in practice,
+ // usually absent. Let the fallback catch it.
+ bool negative = (*p == '-');
+ if (negative) {
+ p++;
+ }
+
+ // After walking "dd.dddd", comparing p later with p now will produce the
+ // number of "d"s and "."s.
+ const uint8_t* const start_of_digits_ptr = p;
+
+ // Walk the "d"s before a '.', 'E', NUL byte, etc. If it starts with '0',
+ // it must be a single '0'. If it starts with a non-zero decimal digit, it
+ // can be a sequence of decimal digits.
+ //
+ // Update the man variable during the walk. It's OK if man overflows now.
+ // We'll detect that later.
+ uint64_t man;
+ if (*p == '0') {
+ man = 0;
+ p++;
+ if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
+ goto fallback;
+ }
+ } else if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
+ man = ((uint8_t)(*p - '0'));
+ p++;
+ for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
+ man = (10 * man) + ((uint8_t)(*p - '0'));
+ }
+ } else {
+ goto fallback;
+ }
+
+ // Walk the "d"s after the optional decimal separator ('.' or ','),
+ // updating the man and exp10 variables.
+ int32_t exp10 = 0;
+ if (*p ==
+ ((options & WUFFS_BASE__PARSE_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
+ ? ','
+ : '.')) {
+ p++;
+ const uint8_t* first_after_separator_ptr = p;
+ if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
+ goto fallback;
+ }
+ man = (10 * man) + ((uint8_t)(*p - '0'));
+ p++;
+ for (; wuffs_base__private_implementation__is_decimal_digit(*p); p++) {
+ man = (10 * man) + ((uint8_t)(*p - '0'));
+ }
+ exp10 = ((int32_t)(first_after_separator_ptr - p));
+ }
+
+ // Count the number of digits:
+ // - for an input of "314159", digit_count is 6.
+ // - for an input of "3.14159", digit_count is 7.
+ //
+ // This is off-by-one if there is a decimal separator. That's OK for now.
+ // We'll correct for that later. The "script/process-json-numbers.c with
+ // -p" benchmark is noticably slower if we try to correct for that now.
+ uint32_t digit_count = (uint32_t)(p - start_of_digits_ptr);
+
+ // Update exp10 for the optional exponent, starting with 'E' or 'e'.
+ if ((*p | 0x20) == 'e') {
+ p++;
+ int32_t exp_sign = +1;
+ if (*p == '-') {
+ p++;
+ exp_sign = -1;
+ } else if (*p == '+') {
+ p++;
+ }
+ if (!wuffs_base__private_implementation__is_decimal_digit(*p)) {
+ goto fallback;
+ }
+ int32_t exp_num = ((uint8_t)(*p - '0'));
+ p++;
+ // The rest of the exp_num walking has a peculiar control flow but, once
+ // again, the "script/process-json-numbers.c with -p" benchmark is
+ // sensitive to alternative formulations.
+ if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
+ exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
+ p++;
+ }
+ if (wuffs_base__private_implementation__is_decimal_digit(*p)) {
+ exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
+ p++;
+ }
+ while (wuffs_base__private_implementation__is_decimal_digit(*p)) {
+ if (exp_num > 0x1000000) {
+ goto fallback;
+ }
+ exp_num = (10 * exp_num) + ((uint8_t)(*p - '0'));
+ p++;
+ }
+ exp10 += exp_sign * exp_num;
+ }
+
+ // The Wuffs API is that the original slice has no trailing data. It also
+ // allows underscores, which we don't catch here but the fallback should.
+ if (p != &z[s.len]) {
+ goto fallback;
+ }
+
+ // Check that the uint64_t typed man variable has not overflowed, based on
+ // digit_count.
+ //
+ // For reference:
+ // - (1 << 63) is 9223372036854775808, which has 19 decimal digits.
+ // - (1 << 64) is 18446744073709551616, which has 20 decimal digits.
+ // - 19 nines, 9999999999999999999, is 0x8AC7230489E7FFFF, which has 64
+ // bits and 16 hexadecimal digits.
+ // - 20 nines, 99999999999999999999, is 0x56BC75E2D630FFFFF, which has 67
+ // bits and 17 hexadecimal digits.
+ if (digit_count > 19) {
+ // Even if we have more than 19 pseudo-digits, it's not yet definitely an
+ // overflow. Recall that digit_count might be off-by-one (too large) if
+ // there's a decimal separator. It will also over-report the number of
+ // meaningful digits if the input looks something like "0.000dddExxx".
+ //
+ // We adjust by the number of leading '0's and '.'s and re-compare to 19.
+ // Once again, technically, we could skip ','s too, but that perturbs the
+ // "script/process-json-numbers.c with -p" benchmark.
+ const uint8_t* q = start_of_digits_ptr;
+ for (; (*q == '0') || (*q == '.'); q++) {
+ }
+ digit_count -= (uint32_t)(q - start_of_digits_ptr);
+ if (digit_count > 19) {
+ goto fallback;
+ }
+ }
+
+ // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
+ // preconditions include that exp10 is in the range [-307 ..= 288].
+ if ((exp10 < -307) || (288 < exp10)) {
+ goto fallback;
+ }
+
+ // If both man and (10 ** exp10) are exactly representable by a double, we
+ // don't need to run the Eisel-Lemire algorithm.
+ if ((-22 <= exp10) && (exp10 <= 22) && ((man >> 53) == 0)) {
+ double d = (double)man;
+ if (exp10 >= 0) {
+ d *= wuffs_base__private_implementation__f64_powers_of_10[+exp10];
+ } else {
+ d /= wuffs_base__private_implementation__f64_powers_of_10[-exp10];
+ }
+ wuffs_base__result_f64 ret;
+ ret.status.repr = NULL;
+ ret.value = negative ? -d : +d;
+ return ret;
+ }
+
+ // The wuffs_base__private_implementation__parse_number_f64_eisel_lemire
+ // preconditions include that man is non-zero. Parsing "0" should be caught
+ // by the "If both man and (10 ** exp10)" above, but "0e99" might not.
+ if (man == 0) {
+ goto fallback;
+ }
+
+ // Our man and exp10 are in range. Run the Eisel-Lemire algorithm.
+ int64_t r =
+ wuffs_base__private_implementation__parse_number_f64_eisel_lemire(
+ man, exp10);
+ if (r < 0) {
+ goto fallback;
+ }
+ wuffs_base__result_f64 ret;
+ ret.status.repr = NULL;
+ ret.value = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
+ ((uint64_t)r) | (((uint64_t)negative) << 63));
+ return ret;
+ } while (0);
+
+fallback:
+ do {
+ wuffs_base__private_implementation__high_prec_dec h;
+ wuffs_base__status status =
+ wuffs_base__private_implementation__high_prec_dec__parse(&h, s,
+ options);
+ if (status.repr) {
+ return wuffs_base__private_implementation__parse_number_f64_special(
+ s, options);
+ }
+ return wuffs_base__private_implementation__high_prec_dec__to_f64(&h,
+ options);
+ } while (0);
+}
+
+// --------
+
+static inline size_t //
+wuffs_base__private_implementation__render_inf(wuffs_base__slice_u8 dst,
+ bool neg,
+ uint32_t options) {
+ if (neg) {
+ if (dst.len < 4) {
+ return 0;
+ }
+ wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492D); // '-Inf'le.
+ return 4;
+ }
+
+ if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
+ if (dst.len < 4) {
+ return 0;
+ }
+ wuffs_base__poke_u32le__no_bounds_check(dst.ptr, 0x666E492B); // '+Inf'le.
+ return 4;
+ }
+
+ if (dst.len < 3) {
+ return 0;
+ }
+ wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x666E49); // 'Inf'le.
+ return 3;
+}
+
+static inline size_t //
+wuffs_base__private_implementation__render_nan(wuffs_base__slice_u8 dst) {
+ if (dst.len < 3) {
+ return 0;
+ }
+ wuffs_base__poke_u24le__no_bounds_check(dst.ptr, 0x4E614E); // 'NaN'le.
+ return 3;
+}
+
+static size_t //
+wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
+ wuffs_base__slice_u8 dst,
+ wuffs_base__private_implementation__high_prec_dec* h,
+ uint32_t precision,
+ uint32_t options) {
+ size_t n = (h->negative ||
+ (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
+ ? 1
+ : 0;
+ if (h->decimal_point <= 0) {
+ n += 1;
+ } else {
+ n += (size_t)(h->decimal_point);
+ }
+ if (precision > 0) {
+ n += precision + 1; // +1 for the '.'.
+ }
+
+ // Don't modify dst if the formatted number won't fit.
+ if (n > dst.len) {
+ return 0;
+ }
+
+ // Align-left or align-right.
+ uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
+ ? &dst.ptr[dst.len - n]
+ : &dst.ptr[0];
+
+ // Leading "±".
+ if (h->negative) {
+ *ptr++ = '-';
+ } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
+ *ptr++ = '+';
+ }
+
+ // Integral digits.
+ if (h->decimal_point <= 0) {
+ *ptr++ = '0';
+ } else {
+ uint32_t m =
+ wuffs_base__u32__min(h->num_digits, (uint32_t)(h->decimal_point));
+ uint32_t i = 0;
+ for (; i < m; i++) {
+ *ptr++ = (uint8_t)('0' | h->digits[i]);
+ }
+ for (; i < (uint32_t)(h->decimal_point); i++) {
+ *ptr++ = '0';
+ }
+ }
+
+ // Separator and then fractional digits.
+ if (precision > 0) {
+ *ptr++ =
+ (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
+ ? ','
+ : '.';
+ uint32_t i = 0;
+ for (; i < precision; i++) {
+ uint32_t j = ((uint32_t)(h->decimal_point)) + i;
+ *ptr++ = (uint8_t)('0' | ((j < h->num_digits) ? h->digits[j] : 0));
+ }
+ }
+
+ return n;
+}
+
+static size_t //
+wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
+ wuffs_base__slice_u8 dst,
+ wuffs_base__private_implementation__high_prec_dec* h,
+ uint32_t precision,
+ uint32_t options) {
+ int32_t exp = 0;
+ if (h->num_digits > 0) {
+ exp = h->decimal_point - 1;
+ }
+ bool negative_exp = exp < 0;
+ if (negative_exp) {
+ exp = -exp;
+ }
+
+ size_t n = (h->negative ||
+ (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN))
+ ? 4
+ : 3; // Mininum 3 bytes: first digit and then "e±".
+ if (precision > 0) {
+ n += precision + 1; // +1 for the '.'.
+ }
+ n += (exp < 100) ? 2 : 3;
+
+ // Don't modify dst if the formatted number won't fit.
+ if (n > dst.len) {
+ return 0;
+ }
+
+ // Align-left or align-right.
+ uint8_t* ptr = (options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
+ ? &dst.ptr[dst.len - n]
+ : &dst.ptr[0];
+
+ // Leading "±".
+ if (h->negative) {
+ *ptr++ = '-';
+ } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
+ *ptr++ = '+';
+ }
+
+ // Integral digit.
+ if (h->num_digits > 0) {
+ *ptr++ = (uint8_t)('0' | h->digits[0]);
+ } else {
+ *ptr++ = '0';
+ }
+
+ // Separator and then fractional digits.
+ if (precision > 0) {
+ *ptr++ =
+ (options & WUFFS_BASE__RENDER_NUMBER_FXX__DECIMAL_SEPARATOR_IS_A_COMMA)
+ ? ','
+ : '.';
+ uint32_t i = 1;
+ uint32_t j = wuffs_base__u32__min(h->num_digits, precision + 1);
+ for (; i < j; i++) {
+ *ptr++ = (uint8_t)('0' | h->digits[i]);
+ }
+ for (; i <= precision; i++) {
+ *ptr++ = '0';
+ }
+ }
+
+ // Exponent: "e±" and then 2 or 3 digits.
+ *ptr++ = 'e';
+ *ptr++ = negative_exp ? '-' : '+';
+ if (exp < 10) {
+ *ptr++ = '0';
+ *ptr++ = (uint8_t)('0' | exp);
+ } else if (exp < 100) {
+ *ptr++ = (uint8_t)('0' | (exp / 10));
+ *ptr++ = (uint8_t)('0' | (exp % 10));
+ } else {
+ int32_t e = exp / 100;
+ exp -= e * 100;
+ *ptr++ = (uint8_t)('0' | e);
+ *ptr++ = (uint8_t)('0' | (exp / 10));
+ *ptr++ = (uint8_t)('0' | (exp % 10));
+ }
+
+ return n;
+}
+
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__render_number_f64(wuffs_base__slice_u8 dst,
+ double x,
+ uint32_t precision,
+ uint32_t options) {
+ // Decompose x (64 bits) into negativity (1 bit), base-2 exponent (11 bits
+ // with a -1023 bias) and mantissa (52 bits).
+ uint64_t bits = wuffs_base__ieee_754_bit_representation__from_f64_to_u64(x);
+ bool neg = (bits >> 63) != 0;
+ int32_t exp2 = ((int32_t)(bits >> 52)) & 0x7FF;
+ uint64_t man = bits & 0x000FFFFFFFFFFFFFul;
+
+ // Apply the exponent bias and set the implicit top bit of the mantissa,
+ // unless x is subnormal. Also take care of Inf and NaN.
+ if (exp2 == 0x7FF) {
+ if (man != 0) {
+ return wuffs_base__private_implementation__render_nan(dst);
+ }
+ return wuffs_base__private_implementation__render_inf(dst, neg, options);
+ } else if (exp2 == 0) {
+ exp2 = -1022;
+ } else {
+ exp2 -= 1023;
+ man |= 0x0010000000000000ul;
+ }
+
+ // Ensure that precision isn't too large.
+ if (precision > 4095) {
+ precision = 4095;
+ }
+
+ // Convert from the (neg, exp2, man) tuple to an HPD.
+ wuffs_base__private_implementation__high_prec_dec h;
+ wuffs_base__private_implementation__high_prec_dec__assign(&h, man, neg);
+ if (h.num_digits > 0) {
+ wuffs_base__private_implementation__high_prec_dec__lshift(
+ &h, exp2 - 52); // 52 mantissa bits.
+ }
+
+ // Handle the "%e" and "%f" formats.
+ switch (options & (WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT |
+ WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT)) {
+ case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_ABSENT: // The "%"f" format.
+ if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
+ wuffs_base__private_implementation__high_prec_dec__round_just_enough(
+ &h, exp2, man);
+ int32_t p = ((int32_t)(h.num_digits)) - h.decimal_point;
+ precision = ((uint32_t)(wuffs_base__i32__max(0, p)));
+ } else {
+ wuffs_base__private_implementation__high_prec_dec__round_nearest(
+ &h, ((int32_t)precision) + h.decimal_point);
+ }
+ return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
+ dst, &h, precision, options);
+
+ case WUFFS_BASE__RENDER_NUMBER_FXX__EXPONENT_PRESENT: // The "%e" format.
+ if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
+ wuffs_base__private_implementation__high_prec_dec__round_just_enough(
+ &h, exp2, man);
+ precision = (h.num_digits > 0) ? (h.num_digits - 1) : 0;
+ } else {
+ wuffs_base__private_implementation__high_prec_dec__round_nearest(
+ &h, ((int32_t)precision) + 1);
+ }
+ return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
+ dst, &h, precision, options);
+ }
+
+ // We have the "%g" format and so precision means the number of significant
+ // digits, not the number of digits after the decimal separator. Perform
+ // rounding and determine whether to use "%e" or "%f".
+ int32_t e_threshold = 0;
+ if (options & WUFFS_BASE__RENDER_NUMBER_FXX__JUST_ENOUGH_PRECISION) {
+ wuffs_base__private_implementation__high_prec_dec__round_just_enough(
+ &h, exp2, man);
+ precision = h.num_digits;
+ e_threshold = 6;
+ } else {
+ if (precision == 0) {
+ precision = 1;
+ }
+ wuffs_base__private_implementation__high_prec_dec__round_nearest(
+ &h, ((int32_t)precision));
+ e_threshold = ((int32_t)precision);
+ int32_t nd = ((int32_t)(h.num_digits));
+ if ((e_threshold > nd) && (nd >= h.decimal_point)) {
+ e_threshold = nd;
+ }
+ }
+
+ // Use the "%e" format if the exponent is large.
+ int32_t e = h.decimal_point - 1;
+ if ((e < -4) || (e_threshold <= e)) {
+ uint32_t p = wuffs_base__u32__min(precision, h.num_digits);
+ return wuffs_base__private_implementation__high_prec_dec__render_exponent_present(
+ dst, &h, (p > 0) ? (p - 1) : 0, options);
+ }
+
+ // Use the "%f" format otherwise.
+ int32_t p = ((int32_t)precision);
+ if (p > h.decimal_point) {
+ p = ((int32_t)(h.num_digits));
+ }
+ precision = ((uint32_t)(wuffs_base__i32__max(0, p - h.decimal_point)));
+ return wuffs_base__private_implementation__high_prec_dec__render_exponent_absent(
+ dst, &h, precision, options);
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE__FLOATCONV)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+ defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
+
+// ---------------- Integer
+
+// wuffs_base__parse_number__foo_digits entries are 0x00 for invalid digits,
+// and (0x80 | v) for valid digits, where v is the 4 bit value.
+
+static const uint8_t wuffs_base__parse_number__decimal_digits[256] = {
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'.
+ 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'.
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF.
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF.
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+};
+
+static const uint8_t wuffs_base__parse_number__hexadecimal_digits[256] = {
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
+ 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, // 0x30 ..= 0x37. '0'-'7'.
+ 0x88, 0x89, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F. '8'-'9'.
+
+ 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x40 ..= 0x47. 'A'-'F'.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
+ 0x00, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F, 0x00, // 0x60 ..= 0x67. 'a'-'f'.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x80 ..= 0x87.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x88 ..= 0x8F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x90 ..= 0x97.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x98 ..= 0x9F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA0 ..= 0xA7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xA8 ..= 0xAF.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB0 ..= 0xB7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xB8 ..= 0xBF.
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC0 ..= 0xC7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xC8 ..= 0xCF.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD0 ..= 0xD7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xD8 ..= 0xDF.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE0 ..= 0xE7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xE8 ..= 0xEF.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF0 ..= 0xF7.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0xF8 ..= 0xFF.
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+};
+
+static const uint8_t wuffs_base__private_implementation__encode_base16[16] = {
+ 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, // 0x00 ..= 0x07.
+ 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, // 0x08 ..= 0x0F.
+};
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_i64 //
+wuffs_base__parse_number_i64(wuffs_base__slice_u8 s, uint32_t options) {
+ uint8_t* p = s.ptr;
+ uint8_t* q = s.ptr + s.len;
+
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
+ for (; (p < q) && (*p == '_'); p++) {
+ }
+ }
+
+ bool negative = false;
+ if (p >= q) {
+ goto fail_bad_argument;
+ } else if (*p == '-') {
+ p++;
+ negative = true;
+ } else if (*p == '+') {
+ p++;
+ }
+
+ do {
+ wuffs_base__result_u64 r = wuffs_base__parse_number_u64(
+ wuffs_base__make_slice_u8(p, (size_t)(q - p)), options);
+ if (r.status.repr != NULL) {
+ wuffs_base__result_i64 ret;
+ ret.status.repr = r.status.repr;
+ ret.value = 0;
+ return ret;
+ } else if (negative) {
+ if (r.value < 0x8000000000000000) {
+ wuffs_base__result_i64 ret;
+ ret.status.repr = NULL;
+ ret.value = -(int64_t)(r.value);
+ return ret;
+ } else if (r.value == 0x8000000000000000) {
+ wuffs_base__result_i64 ret;
+ ret.status.repr = NULL;
+ ret.value = INT64_MIN;
+ return ret;
+ }
+ goto fail_out_of_bounds;
+ } else if (r.value > 0x7FFFFFFFFFFFFFFF) {
+ goto fail_out_of_bounds;
+ } else {
+ wuffs_base__result_i64 ret;
+ ret.status.repr = NULL;
+ ret.value = +(int64_t)(r.value);
+ return ret;
+ }
+ } while (0);
+
+fail_bad_argument:
+ do {
+ wuffs_base__result_i64 ret;
+ ret.status.repr = wuffs_base__error__bad_argument;
+ ret.value = 0;
+ return ret;
+ } while (0);
+
+fail_out_of_bounds:
+ do {
+ wuffs_base__result_i64 ret;
+ ret.status.repr = wuffs_base__error__out_of_bounds;
+ ret.value = 0;
+ return ret;
+ } while (0);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__result_u64 //
+wuffs_base__parse_number_u64(wuffs_base__slice_u8 s, uint32_t options) {
+ uint8_t* p = s.ptr;
+ uint8_t* q = s.ptr + s.len;
+
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
+ for (; (p < q) && (*p == '_'); p++) {
+ }
+ }
+
+ if (p >= q) {
+ goto fail_bad_argument;
+
+ } else if (*p == '0') {
+ p++;
+ if (p >= q) {
+ goto ok_zero;
+ }
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
+ if (*p == '_') {
+ p++;
+ for (; p < q; p++) {
+ if (*p != '_') {
+ if (options &
+ WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
+ goto decimal;
+ }
+ goto fail_bad_argument;
+ }
+ }
+ goto ok_zero;
+ }
+ }
+
+ if ((*p == 'x') || (*p == 'X')) {
+ p++;
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
+ for (; (p < q) && (*p == '_'); p++) {
+ }
+ }
+ if (p < q) {
+ goto hexadecimal;
+ }
+
+ } else if ((*p == 'd') || (*p == 'D')) {
+ p++;
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES) {
+ for (; (p < q) && (*p == '_'); p++) {
+ }
+ }
+ if (p < q) {
+ goto decimal;
+ }
+ }
+
+ if (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_MULTIPLE_LEADING_ZEROES) {
+ goto decimal;
+ }
+ goto fail_bad_argument;
+ }
+
+decimal:
+ do {
+ uint64_t v = wuffs_base__parse_number__decimal_digits[*p++];
+ if (v == 0) {
+ goto fail_bad_argument;
+ }
+ v &= 0x0F;
+
+ // UINT64_MAX is 18446744073709551615, which is ((10 * max10) + max1).
+ const uint64_t max10 = 1844674407370955161u;
+ const uint8_t max1 = 5;
+
+ for (; p < q; p++) {
+ if ((*p == '_') &&
+ (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
+ continue;
+ }
+ uint8_t digit = wuffs_base__parse_number__decimal_digits[*p];
+ if (digit == 0) {
+ goto fail_bad_argument;
+ }
+ digit &= 0x0F;
+ if ((v > max10) || ((v == max10) && (digit > max1))) {
+ goto fail_out_of_bounds;
+ }
+ v = (10 * v) + ((uint64_t)(digit));
+ }
+
+ wuffs_base__result_u64 ret;
+ ret.status.repr = NULL;
+ ret.value = v;
+ return ret;
+ } while (0);
+
+hexadecimal:
+ do {
+ uint64_t v = wuffs_base__parse_number__hexadecimal_digits[*p++];
+ if (v == 0) {
+ goto fail_bad_argument;
+ }
+ v &= 0x0F;
+
+ for (; p < q; p++) {
+ if ((*p == '_') &&
+ (options & WUFFS_BASE__PARSE_NUMBER_XXX__ALLOW_UNDERSCORES)) {
+ continue;
+ }
+ uint8_t digit = wuffs_base__parse_number__hexadecimal_digits[*p];
+ if (digit == 0) {
+ goto fail_bad_argument;
+ }
+ digit &= 0x0F;
+ if ((v >> 60) != 0) {
+ goto fail_out_of_bounds;
+ }
+ v = (v << 4) | ((uint64_t)(digit));
+ }
+
+ wuffs_base__result_u64 ret;
+ ret.status.repr = NULL;
+ ret.value = v;
+ return ret;
+ } while (0);
+
+ok_zero:
+ do {
+ wuffs_base__result_u64 ret;
+ ret.status.repr = NULL;
+ ret.value = 0;
+ return ret;
+ } while (0);
+
+fail_bad_argument:
+ do {
+ wuffs_base__result_u64 ret;
+ ret.status.repr = wuffs_base__error__bad_argument;
+ ret.value = 0;
+ return ret;
+ } while (0);
+
+fail_out_of_bounds:
+ do {
+ wuffs_base__result_u64 ret;
+ ret.status.repr = wuffs_base__error__out_of_bounds;
+ ret.value = 0;
+ return ret;
+ } while (0);
+}
+
+// --------
+
+// wuffs_base__render_number__first_hundred contains the decimal encodings of
+// the first one hundred numbers [0 ..= 99].
+static const uint8_t wuffs_base__render_number__first_hundred[200] = {
+ '0', '0', '0', '1', '0', '2', '0', '3', '0', '4', //
+ '0', '5', '0', '6', '0', '7', '0', '8', '0', '9', //
+ '1', '0', '1', '1', '1', '2', '1', '3', '1', '4', //
+ '1', '5', '1', '6', '1', '7', '1', '8', '1', '9', //
+ '2', '0', '2', '1', '2', '2', '2', '3', '2', '4', //
+ '2', '5', '2', '6', '2', '7', '2', '8', '2', '9', //
+ '3', '0', '3', '1', '3', '2', '3', '3', '3', '4', //
+ '3', '5', '3', '6', '3', '7', '3', '8', '3', '9', //
+ '4', '0', '4', '1', '4', '2', '4', '3', '4', '4', //
+ '4', '5', '4', '6', '4', '7', '4', '8', '4', '9', //
+ '5', '0', '5', '1', '5', '2', '5', '3', '5', '4', //
+ '5', '5', '5', '6', '5', '7', '5', '8', '5', '9', //
+ '6', '0', '6', '1', '6', '2', '6', '3', '6', '4', //
+ '6', '5', '6', '6', '6', '7', '6', '8', '6', '9', //
+ '7', '0', '7', '1', '7', '2', '7', '3', '7', '4', //
+ '7', '5', '7', '6', '7', '7', '7', '8', '7', '9', //
+ '8', '0', '8', '1', '8', '2', '8', '3', '8', '4', //
+ '8', '5', '8', '6', '8', '7', '8', '8', '8', '9', //
+ '9', '0', '9', '1', '9', '2', '9', '3', '9', '4', //
+ '9', '5', '9', '6', '9', '7', '9', '8', '9', '9', //
+};
+
+static size_t //
+wuffs_base__private_implementation__render_number_u64(wuffs_base__slice_u8 dst,
+ uint64_t x,
+ uint32_t options,
+ bool neg) {
+ uint8_t buf[WUFFS_BASE__U64__BYTE_LENGTH__MAX_INCL];
+ uint8_t* ptr = &buf[0] + sizeof(buf);
+
+ while (x >= 100) {
+ size_t index = ((size_t)((x % 100) * 2));
+ x /= 100;
+ uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
+ uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
+ ptr -= 2;
+ ptr[0] = s0;
+ ptr[1] = s1;
+ }
+
+ if (x < 10) {
+ ptr -= 1;
+ ptr[0] = (uint8_t)('0' + x);
+ } else {
+ size_t index = ((size_t)(x * 2));
+ uint8_t s0 = wuffs_base__render_number__first_hundred[index + 0];
+ uint8_t s1 = wuffs_base__render_number__first_hundred[index + 1];
+ ptr -= 2;
+ ptr[0] = s0;
+ ptr[1] = s1;
+ }
+
+ if (neg) {
+ ptr -= 1;
+ ptr[0] = '-';
+ } else if (options & WUFFS_BASE__RENDER_NUMBER_XXX__LEADING_PLUS_SIGN) {
+ ptr -= 1;
+ ptr[0] = '+';
+ }
+
+ size_t n = sizeof(buf) - ((size_t)(ptr - &buf[0]));
+ if (n > dst.len) {
+ return 0;
+ }
+ memcpy(dst.ptr + ((options & WUFFS_BASE__RENDER_NUMBER_XXX__ALIGN_RIGHT)
+ ? (dst.len - n)
+ : 0),
+ ptr, n);
+ return n;
+}
+
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__render_number_i64(wuffs_base__slice_u8 dst,
+ int64_t x,
+ uint32_t options) {
+ uint64_t u = (uint64_t)x;
+ bool neg = x < 0;
+ if (neg) {
+ u = 1 + ~u;
+ }
+ return wuffs_base__private_implementation__render_number_u64(dst, u, options,
+ neg);
+}
+
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__render_number_u64(wuffs_base__slice_u8 dst,
+ uint64_t x,
+ uint32_t options) {
+ return wuffs_base__private_implementation__render_number_u64(dst, x, options,
+ false);
+}
+
+// ---------------- Base-16
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_16__decode2(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options) {
+ wuffs_base__transform__output o;
+ size_t src_len2 = src.len / 2;
+ size_t len;
+ if (dst.len < src_len2) {
+ len = dst.len;
+ o.status.repr = wuffs_base__suspension__short_write;
+ } else {
+ len = src_len2;
+ if (!src_closed) {
+ o.status.repr = wuffs_base__suspension__short_read;
+ } else if (src.len & 1) {
+ o.status.repr = wuffs_base__error__bad_data;
+ } else {
+ o.status.repr = NULL;
+ }
+ }
+
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ while (n--) {
+ *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[0]] << 4) |
+ (wuffs_base__parse_number__hexadecimal_digits[s[1]] & 0x0F));
+ d += 1;
+ s += 2;
+ }
+
+ o.num_dst = len;
+ o.num_src = len * 2;
+ return o;
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_16__decode4(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options) {
+ wuffs_base__transform__output o;
+ size_t src_len4 = src.len / 4;
+ size_t len = dst.len < src_len4 ? dst.len : src_len4;
+ if (dst.len < src_len4) {
+ len = dst.len;
+ o.status.repr = wuffs_base__suspension__short_write;
+ } else {
+ len = src_len4;
+ if (!src_closed) {
+ o.status.repr = wuffs_base__suspension__short_read;
+ } else if (src.len & 1) {
+ o.status.repr = wuffs_base__error__bad_data;
+ } else {
+ o.status.repr = NULL;
+ }
+ }
+
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ while (n--) {
+ *d = (uint8_t)((wuffs_base__parse_number__hexadecimal_digits[s[2]] << 4) |
+ (wuffs_base__parse_number__hexadecimal_digits[s[3]] & 0x0F));
+ d += 1;
+ s += 4;
+ }
+
+ o.num_dst = len;
+ o.num_src = len * 4;
+ return o;
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_16__encode2(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options) {
+ wuffs_base__transform__output o;
+ size_t dst_len2 = dst.len / 2;
+ size_t len;
+ if (dst_len2 < src.len) {
+ len = dst_len2;
+ o.status.repr = wuffs_base__suspension__short_write;
+ } else {
+ len = src.len;
+ if (!src_closed) {
+ o.status.repr = wuffs_base__suspension__short_read;
+ } else {
+ o.status.repr = NULL;
+ }
+ }
+
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ while (n--) {
+ uint8_t c = *s;
+ d[0] = wuffs_base__private_implementation__encode_base16[c >> 4];
+ d[1] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
+ d += 2;
+ s += 1;
+ }
+
+ o.num_dst = len * 2;
+ o.num_src = len;
+ return o;
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_16__encode4(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options) {
+ wuffs_base__transform__output o;
+ size_t dst_len4 = dst.len / 4;
+ size_t len;
+ if (dst_len4 < src.len) {
+ len = dst_len4;
+ o.status.repr = wuffs_base__suspension__short_write;
+ } else {
+ len = src.len;
+ if (!src_closed) {
+ o.status.repr = wuffs_base__suspension__short_read;
+ } else {
+ o.status.repr = NULL;
+ }
+ }
+
+ uint8_t* d = dst.ptr;
+ uint8_t* s = src.ptr;
+ size_t n = len;
+
+ while (n--) {
+ uint8_t c = *s;
+ d[0] = '\\';
+ d[1] = 'x';
+ d[2] = wuffs_base__private_implementation__encode_base16[c >> 4];
+ d[3] = wuffs_base__private_implementation__encode_base16[c & 0x0F];
+ d += 4;
+ s += 1;
+ }
+
+ o.num_dst = len * 4;
+ o.num_src = len;
+ return o;
+}
+
+// ---------------- Base-64
+
+// The two base-64 alphabets, std and url, differ only in the last two codes.
+// - std: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
+// - url: "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
+
+static const uint8_t wuffs_base__base_64__decode_std[256] = {
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27.
+ 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, 0x80, 0x3F, // 0x28 ..= 0x2F.
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37.
+ 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F.
+
+ 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47.
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F.
+ 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57.
+ 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x58 ..= 0x5F.
+ 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67.
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F.
+ 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77.
+ 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F.
+
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF.
+
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+};
+
+static const uint8_t wuffs_base__base_64__decode_url[256] = {
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x00 ..= 0x07.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x08 ..= 0x0F.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x10 ..= 0x17.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x18 ..= 0x1F.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x20 ..= 0x27.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x3E, 0x80, 0x80, // 0x28 ..= 0x2F.
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, // 0x30 ..= 0x37.
+ 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x38 ..= 0x3F.
+
+ 0x80, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, // 0x40 ..= 0x47.
+ 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, // 0x48 ..= 0x4F.
+ 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, // 0x50 ..= 0x57.
+ 0x17, 0x18, 0x19, 0x80, 0x80, 0x80, 0x80, 0x3F, // 0x58 ..= 0x5F.
+ 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, // 0x60 ..= 0x67.
+ 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, // 0x68 ..= 0x6F.
+ 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, // 0x70 ..= 0x77.
+ 0x31, 0x32, 0x33, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x78 ..= 0x7F.
+
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x80 ..= 0x87.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x88 ..= 0x8F.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x90 ..= 0x97.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0x98 ..= 0x9F.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA0 ..= 0xA7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xA8 ..= 0xAF.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB0 ..= 0xB7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xB8 ..= 0xBF.
+
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC0 ..= 0xC7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xC8 ..= 0xCF.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD0 ..= 0xD7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xD8 ..= 0xDF.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE0 ..= 0xE7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xE8 ..= 0xEF.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+};
+
+static const uint8_t wuffs_base__base_64__encode_std[64] = {
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07.
+ 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F.
+ 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17.
+ 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F.
+ 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27.
+ 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F.
+ 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37.
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2B, 0x2F, // 0x38 ..= 0x3F.
+};
+
+static const uint8_t wuffs_base__base_64__encode_url[64] = {
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+ 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, // 0x00 ..= 0x07.
+ 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F, 0x50, // 0x08 ..= 0x0F.
+ 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, // 0x10 ..= 0x17.
+ 0x59, 0x5A, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, // 0x18 ..= 0x1F.
+ 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, // 0x20 ..= 0x27.
+ 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, // 0x28 ..= 0x2F.
+ 0x77, 0x78, 0x79, 0x7A, 0x30, 0x31, 0x32, 0x33, // 0x30 ..= 0x37.
+ 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x2D, 0x5F, // 0x38 ..= 0x3F.
+};
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_64__decode(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options) {
+ const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
+ ? wuffs_base__base_64__decode_url
+ : wuffs_base__base_64__decode_std;
+ wuffs_base__transform__output o;
+ uint8_t* d_ptr = dst.ptr;
+ size_t d_len = dst.len;
+ const uint8_t* s_ptr = src.ptr;
+ size_t s_len = src.len;
+ bool pad = false;
+
+ while (s_len >= 4) {
+ uint32_t s = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
+ uint32_t s0 = alphabet[0xFF & (s >> 0)];
+ uint32_t s1 = alphabet[0xFF & (s >> 8)];
+ uint32_t s2 = alphabet[0xFF & (s >> 16)];
+ uint32_t s3 = alphabet[0xFF & (s >> 24)];
+
+ if (((s0 | s1 | s2 | s3) & 0xC0) != 0) {
+ if (s_len > 4) {
+ o.status.repr = wuffs_base__error__bad_data;
+ goto done;
+ } else if (!src_closed) {
+ o.status.repr = wuffs_base__suspension__short_read;
+ goto done;
+ } else if ((options & WUFFS_BASE__BASE_64__DECODE_ALLOW_PADDING) &&
+ (s_ptr[3] == '=')) {
+ pad = true;
+ if (s_ptr[2] == '=') {
+ goto src2;
+ }
+ goto src3;
+ }
+ o.status.repr = wuffs_base__error__bad_data;
+ goto done;
+ }
+
+ if (d_len < 3) {
+ o.status.repr = wuffs_base__suspension__short_write;
+ goto done;
+ }
+
+ s_ptr += 4;
+ s_len -= 4;
+ s = (s0 << 18) | (s1 << 12) | (s2 << 6) | (s3 << 0);
+ *d_ptr++ = (uint8_t)(s >> 16);
+ *d_ptr++ = (uint8_t)(s >> 8);
+ *d_ptr++ = (uint8_t)(s >> 0);
+ d_len -= 3;
+ }
+
+ if (!src_closed) {
+ o.status.repr = wuffs_base__suspension__short_read;
+ goto done;
+ }
+
+ if (s_len == 0) {
+ o.status.repr = NULL;
+ goto done;
+ } else if (s_len == 1) {
+ o.status.repr = wuffs_base__error__bad_data;
+ goto done;
+ } else if (s_len == 2) {
+ goto src2;
+ }
+
+src3:
+ do {
+ uint32_t s = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
+ uint32_t s0 = alphabet[0xFF & (s >> 0)];
+ uint32_t s1 = alphabet[0xFF & (s >> 8)];
+ uint32_t s2 = alphabet[0xFF & (s >> 16)];
+ if ((s0 & 0xC0) || (s1 & 0xC0) || (s2 & 0xC3)) {
+ o.status.repr = wuffs_base__error__bad_data;
+ goto done;
+ }
+ if (d_len < 2) {
+ o.status.repr = wuffs_base__suspension__short_write;
+ goto done;
+ }
+ s_ptr += pad ? 4 : 3;
+ s = (s0 << 18) | (s1 << 12) | (s2 << 6);
+ *d_ptr++ = (uint8_t)(s >> 16);
+ *d_ptr++ = (uint8_t)(s >> 8);
+ o.status.repr = NULL;
+ goto done;
+ } while (0);
+
+src2:
+ do {
+ uint32_t s = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
+ uint32_t s0 = alphabet[0xFF & (s >> 0)];
+ uint32_t s1 = alphabet[0xFF & (s >> 8)];
+ if ((s0 & 0xC0) || (s1 & 0xCF)) {
+ o.status.repr = wuffs_base__error__bad_data;
+ goto done;
+ }
+ if (d_len < 1) {
+ o.status.repr = wuffs_base__suspension__short_write;
+ goto done;
+ }
+ s_ptr += pad ? 4 : 2;
+ s = (s0 << 18) | (s1 << 12);
+ *d_ptr++ = (uint8_t)(s >> 16);
+ o.status.repr = NULL;
+ goto done;
+ } while (0);
+
+done:
+ o.num_dst = (size_t)(d_ptr - dst.ptr);
+ o.num_src = (size_t)(s_ptr - src.ptr);
+ return o;
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__transform__output //
+wuffs_base__base_64__encode(wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 src,
+ bool src_closed,
+ uint32_t options) {
+ const uint8_t* alphabet = (options & WUFFS_BASE__BASE_64__URL_ALPHABET)
+ ? wuffs_base__base_64__encode_url
+ : wuffs_base__base_64__encode_std;
+ wuffs_base__transform__output o;
+ uint8_t* d_ptr = dst.ptr;
+ size_t d_len = dst.len;
+ const uint8_t* s_ptr = src.ptr;
+ size_t s_len = src.len;
+
+ do {
+ while (s_len >= 3) {
+ if (d_len < 4) {
+ o.status.repr = wuffs_base__suspension__short_write;
+ goto done;
+ }
+ uint32_t s = wuffs_base__peek_u24be__no_bounds_check(s_ptr);
+ s_ptr += 3;
+ s_len -= 3;
+ *d_ptr++ = alphabet[0x3F & (s >> 18)];
+ *d_ptr++ = alphabet[0x3F & (s >> 12)];
+ *d_ptr++ = alphabet[0x3F & (s >> 6)];
+ *d_ptr++ = alphabet[0x3F & (s >> 0)];
+ d_len -= 4;
+ }
+
+ if (!src_closed) {
+ o.status.repr = wuffs_base__suspension__short_read;
+ goto done;
+ }
+
+ if (s_len == 2) {
+ if (d_len <
+ ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 3)) {
+ o.status.repr = wuffs_base__suspension__short_write;
+ goto done;
+ }
+ uint32_t s = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(s_ptr)))
+ << 8;
+ s_ptr += 2;
+ *d_ptr++ = alphabet[0x3F & (s >> 18)];
+ *d_ptr++ = alphabet[0x3F & (s >> 12)];
+ *d_ptr++ = alphabet[0x3F & (s >> 6)];
+ if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
+ *d_ptr++ = '=';
+ }
+ o.status.repr = NULL;
+ goto done;
+
+ } else if (s_len == 1) {
+ if (d_len <
+ ((options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) ? 4 : 2)) {
+ o.status.repr = wuffs_base__suspension__short_write;
+ goto done;
+ }
+ uint32_t s = ((uint32_t)(wuffs_base__peek_u8__no_bounds_check(s_ptr)))
+ << 16;
+ s_ptr += 1;
+ *d_ptr++ = alphabet[0x3F & (s >> 18)];
+ *d_ptr++ = alphabet[0x3F & (s >> 12)];
+ if (options & WUFFS_BASE__BASE_64__ENCODE_EMIT_PADDING) {
+ *d_ptr++ = '=';
+ *d_ptr++ = '=';
+ }
+ o.status.repr = NULL;
+ goto done;
+
+ } else {
+ o.status.repr = NULL;
+ goto done;
+ }
+ } while (0);
+
+done:
+ o.num_dst = (size_t)(d_ptr - dst.ptr);
+ o.num_src = (size_t)(s_ptr - src.ptr);
+ return o;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE__INTCONV)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+ defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
+
+// ---------------- Magic Numbers
+
+// ICO doesn't start with a magic identifier. Instead, see if the opening bytes
+// are plausibly ICO.
+//
+// Callers should have already verified that (prefix_data.len >= 2) and the
+// first two bytes are 0x00.
+//
+// See:
+// - https://docs.fileformat.com/image/ico/
+static int32_t //
+wuffs_base__magic_number_guess_fourcc__maybe_ico(
+ wuffs_base__slice_u8 prefix_data,
+ bool prefix_closed) {
+ // Allow-list for the Image Type field.
+ if (prefix_data.len < 4) {
+ return prefix_closed ? 0 : -1;
+ } else if (prefix_data.ptr[3] != 0) {
+ return 0;
+ }
+ switch (prefix_data.ptr[2]) {
+ case 0x01: // ICO
+ case 0x02: // CUR
+ break;
+ default:
+ return 0;
+ }
+
+ // The Number Of Images should be positive.
+ if (prefix_data.len < 6) {
+ return prefix_closed ? 0 : -1;
+ } else if ((prefix_data.ptr[4] == 0) && (prefix_data.ptr[5] == 0)) {
+ return 0;
+ }
+
+ // The first ICONDIRENTRY's fourth byte should be zero.
+ if (prefix_data.len < 10) {
+ return prefix_closed ? 0 : -1;
+ } else if (prefix_data.ptr[9] != 0) {
+ return 0;
+ }
+
+ // TODO: have a separate FourCC for CUR?
+ return 0x49434F20; // 'ICO 'be
+}
+
+// TGA doesn't start with a magic identifier. Instead, see if the opening bytes
+// are plausibly TGA.
+//
+// Callers should have already verified that (prefix_data.len >= 2) and the
+// second byte (prefix_data.ptr[1], the Color Map Type byte), is either 0x00 or
+// 0x01.
+//
+// See:
+// - https://docs.fileformat.com/image/tga/
+// - https://www.dca.fee.unicamp.br/~martino/disciplinas/ea978/tgaffs.pdf
+static int32_t //
+wuffs_base__magic_number_guess_fourcc__maybe_tga(
+ wuffs_base__slice_u8 prefix_data,
+ bool prefix_closed) {
+ // Allow-list for the Image Type field.
+ if (prefix_data.len < 3) {
+ return prefix_closed ? 0 : -1;
+ }
+ switch (prefix_data.ptr[2]) {
+ case 0x01:
+ case 0x02:
+ case 0x03:
+ case 0x09:
+ case 0x0A:
+ case 0x0B:
+ break;
+ default:
+ // TODO: 0x20 and 0x21 are invalid, according to the spec, but are
+ // apparently unofficial extensions.
+ return 0;
+ }
+
+ // Allow-list for the Color Map Entry Size field (if the Color Map Type field
+ // is non-zero) or else all the Color Map fields should be zero.
+ if (prefix_data.len < 8) {
+ return prefix_closed ? 0 : -1;
+ } else if (prefix_data.ptr[1] != 0x00) {
+ switch (prefix_data.ptr[7]) {
+ case 0x0F:
+ case 0x10:
+ case 0x18:
+ case 0x20:
+ break;
+ default:
+ return 0;
+ }
+ } else if ((prefix_data.ptr[3] | prefix_data.ptr[4] | prefix_data.ptr[5] |
+ prefix_data.ptr[6] | prefix_data.ptr[7]) != 0x00) {
+ return 0;
+ }
+
+ // Allow-list for the Pixel Depth field.
+ if (prefix_data.len < 17) {
+ return prefix_closed ? 0 : -1;
+ }
+ switch (prefix_data.ptr[16]) {
+ case 0x01:
+ case 0x08:
+ case 0x0F:
+ case 0x10:
+ case 0x18:
+ case 0x20:
+ break;
+ default:
+ return 0;
+ }
+
+ return 0x54474120; // 'TGA 'be
+}
+
+WUFFS_BASE__MAYBE_STATIC int32_t //
+wuffs_base__magic_number_guess_fourcc(wuffs_base__slice_u8 prefix_data,
+ bool prefix_closed) {
+ // This is similar to (but different from):
+ // - the magic/Magdir tables under https://github.com/file/file
+ // - the MIME Sniffing algorithm at https://mimesniff.spec.whatwg.org/
+
+ // table holds the 'magic numbers' (which are actually variable length
+ // strings). The strings may contain NUL bytes, so the "const char* magic"
+ // value starts with the length-minus-1 of the 'magic number'.
+ //
+ // Keep it sorted by magic[1], then magic[0] descending (prioritizing longer
+ // matches) and finally by magic[2:]. When multiple entries match, the
+ // longest one wins.
+ //
+ // The fourcc field might be negated, in which case there's further
+ // specialization (see § below).
+ static struct {
+ int32_t fourcc;
+ const char* magic;
+ } table[] = {
+ {-0x30302020, "\x01\x00\x00"}, // '00 'be
+ {+0x475A2020, "\x02\x1F\x8B\x08"}, // GZ
+ {+0x5A535444, "\x03\x28\xB5\x2F\xFD"}, // ZSTD
+ {+0x425A3220, "\x02\x42\x5A\x68"}, // BZ2
+ {+0x424D5020, "\x01\x42\x4D"}, // BMP
+ {+0x47494620, "\x03\x47\x49\x46\x38"}, // GIF
+ {+0x54494646, "\x03\x49\x49\x2A\x00"}, // TIFF (little-endian)
+ {+0x54494646, "\x03\x4D\x4D\x00\x2A"}, // TIFF (big-endian)
+ {+0x4E50424D, "\x02\x50\x35\x0A"}, // NPBM (P5; *.pgm)
+ {+0x4E50424D, "\x02\x50\x36\x0A"}, // NPBM (P6; *.ppm)
+ {-0x52494646, "\x03\x52\x49\x46\x46"}, // RIFF
+ {+0x4C5A4D41, "\x04\x5D\x00\x10\x00\x00"}, // LZMA
+ {+0x4C5A4D41, "\x02\x5D\x00\x00"}, // LZMA
+ {+0x4E494520, "\x02\x6E\xC3\xAF"}, // NIE
+ {+0x514F4920, "\x03\x71\x6F\x69\x66"}, // QOI
+ {+0x5A4C4942, "\x01\x78\x9C"}, // ZLIB
+ {+0x504E4720, "\x03\x89\x50\x4E\x47"}, // PNG
+ {+0x585A2020, "\x04\xFD\x37\x7A\x58\x5A"}, // XZ
+ {+0x4A504547, "\x01\xFF\xD8"}, // JPEG
+ };
+ static const size_t table_len = sizeof(table) / sizeof(table[0]);
+
+ if (prefix_data.len == 0) {
+ return prefix_closed ? 0 : -1;
+ }
+ uint8_t pre_first_byte = prefix_data.ptr[0];
+
+ int32_t fourcc = 0;
+ size_t i;
+ for (i = 0; i < table_len; i++) {
+ uint8_t mag_first_byte = ((uint8_t)(table[i].magic[1]));
+ if (pre_first_byte < mag_first_byte) {
+ break;
+ } else if (pre_first_byte > mag_first_byte) {
+ continue;
+ }
+ fourcc = table[i].fourcc;
+
+ uint8_t mag_remaining_len = ((uint8_t)(table[i].magic[0]));
+ if (mag_remaining_len == 0) {
+ goto match;
+ }
+
+ const char* mag_remaining_ptr = table[i].magic + 2;
+ uint8_t* pre_remaining_ptr = prefix_data.ptr + 1;
+ size_t pre_remaining_len = prefix_data.len - 1;
+ if (pre_remaining_len < mag_remaining_len) {
+ if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, pre_remaining_len)) {
+ return prefix_closed ? 0 : -1;
+ }
+ } else {
+ if (!memcmp(pre_remaining_ptr, mag_remaining_ptr, mag_remaining_len)) {
+ goto match;
+ }
+ }
+ }
+
+ if (prefix_data.len < 2) {
+ return prefix_closed ? 0 : -1;
+ } else if ((prefix_data.ptr[1] == 0x00) || (prefix_data.ptr[1] == 0x01)) {
+ return wuffs_base__magic_number_guess_fourcc__maybe_tga(prefix_data,
+ prefix_closed);
+ }
+
+ return 0;
+
+match:
+ // Negative FourCC values (see § above) are further specialized.
+ if (fourcc < 0) {
+ fourcc = -fourcc;
+
+ if (fourcc == 0x52494646) { // 'RIFF'be
+ if (prefix_data.len < 12) {
+ return prefix_closed ? 0 : -1;
+ }
+ uint32_t x = wuffs_base__peek_u32be__no_bounds_check(prefix_data.ptr + 8);
+ if (x == 0x57454250) { // 'WEBP'be
+ return 0x57454250; // 'WEBP'be
+ }
+
+ } else if (fourcc == 0x30302020) { // '00 'be
+ // Binary data starting with multiple 0x00 NUL bytes is quite common.
+ // Unfortunately, some file formats also don't start with a magic
+ // identifier, so we have to use heuristics (where the order matters, the
+ // same as /usr/bin/file's magic/Magdir tables) as best we can. Maybe
+ // it's TGA, ICO/CUR, etc. Maybe it's something else.
+ int32_t tga = wuffs_base__magic_number_guess_fourcc__maybe_tga(
+ prefix_data, prefix_closed);
+ if (tga != 0) {
+ return tga;
+ }
+ int32_t ico = wuffs_base__magic_number_guess_fourcc__maybe_ico(
+ prefix_data, prefix_closed);
+ if (ico != 0) {
+ return ico;
+ }
+ if (prefix_data.len < 4) {
+ return prefix_closed ? 0 : -1;
+ } else if ((prefix_data.ptr[2] != 0x00) &&
+ ((prefix_data.ptr[2] >= 0x80) ||
+ (prefix_data.ptr[3] != 0x00))) {
+ // Roughly speaking, this could be a non-degenerate (non-0-width and
+ // non-0-height) WBMP image.
+ return 0x57424D50; // 'WBMP'be
+ }
+ return 0;
+ }
+ }
+ return fourcc;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE__MAGIC)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+ defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
+
+// ---------------- Pixel Swizzler
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len);
+
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+static uint64_t //
+wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len);
+
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxx__y__x86_sse42(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+
+// --------
+
+static inline uint32_t //
+wuffs_base__swap_u32_argb_abgr(uint32_t u) {
+ uint32_t o = u & 0xFF00FF00ul;
+ uint32_t r = u & 0x00FF0000ul;
+ uint32_t b = u & 0x000000FFul;
+ return o | (r >> 16) | (b << 16);
+}
+
+static inline uint64_t //
+wuffs_base__swap_u64_argb_abgr(uint64_t u) {
+ uint64_t o = u & 0xFFFF0000FFFF0000ull;
+ uint64_t r = u & 0x0000FFFF00000000ull;
+ uint64_t b = u & 0x000000000000FFFFull;
+ return o | (r >> 32) | (b << 32);
+}
+
+static inline uint32_t //
+wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(uint64_t c) {
+ uint32_t a = ((uint32_t)(0xFF & (c >> 56)));
+ uint32_t r = ((uint32_t)(0xFF & (c >> 40)));
+ uint32_t g = ((uint32_t)(0xFF & (c >> 24)));
+ uint32_t b = ((uint32_t)(0xFF & (c >> 8)));
+ return (a << 24) | (b << 16) | (g << 8) | (r << 0);
+}
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__color_u32_argb_premul //
+wuffs_base__pixel_buffer__color_u32_at(const wuffs_base__pixel_buffer* pb,
+ uint32_t x,
+ uint32_t y) {
+ if (!pb || (x >= pb->pixcfg.private_impl.width) ||
+ (y >= pb->pixcfg.private_impl.height)) {
+ return 0;
+ }
+
+ if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
+ // TODO: support planar formats.
+ return 0;
+ }
+
+ size_t stride = pb->private_impl.planes[0].stride;
+ const uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
+
+ switch (pb->pixcfg.private_impl.pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ return wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
+
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
+ uint8_t* palette = pb->private_impl.planes[3].ptr;
+ return wuffs_base__peek_u32le__no_bounds_check(palette +
+ (4 * ((size_t)row[x])));
+ }
+
+ // Common formats above. Rarer formats below.
+
+ case WUFFS_BASE__PIXEL_FORMAT__Y:
+ return 0xFF000000 | (0x00010101 * ((uint32_t)(row[x])));
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
+ return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 1])));
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
+ return 0xFF000000 | (0x00010101 * ((uint32_t)(row[(2 * x) + 0])));
+
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL: {
+ uint8_t* palette = pb->private_impl.planes[3].ptr;
+ return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u32le__no_bounds_check(palette +
+ (4 * ((size_t)row[x]))));
+ }
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ return wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
+ wuffs_base__peek_u16le__no_bounds_check(row + (2 * ((size_t)x))));
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ return 0xFF000000 |
+ wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x)));
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ return wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ return wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u64le__no_bounds_check(row + (8 * ((size_t)x))));
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ return 0xFF000000 |
+ wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x)));
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ return wuffs_base__swap_u32_argb_abgr(
+ 0xFF000000 |
+ wuffs_base__peek_u24le__no_bounds_check(row + (3 * ((size_t)x))));
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ return wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u32le__no_bounds_check(row +
+ (4 * ((size_t)x)))));
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ return wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ return wuffs_base__swap_u32_argb_abgr(
+ 0xFF000000 |
+ wuffs_base__peek_u32le__no_bounds_check(row + (4 * ((size_t)x))));
+
+ default:
+ // TODO: support more formats.
+ break;
+ }
+
+ return 0;
+}
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__pixel_buffer__set_color_u32_at(
+ wuffs_base__pixel_buffer* pb,
+ uint32_t x,
+ uint32_t y,
+ wuffs_base__color_u32_argb_premul color) {
+ if (!pb) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if ((x >= pb->pixcfg.private_impl.width) ||
+ (y >= pb->pixcfg.private_impl.height)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+
+ if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
+ // TODO: support planar formats.
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ }
+
+ size_t stride = pb->private_impl.planes[0].stride;
+ uint8_t* row = pb->private_impl.planes[0].ptr + (stride * ((size_t)y));
+
+ switch (pb->pixcfg.private_impl.pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ wuffs_base__poke_u32le__no_bounds_check(row + (4 * ((size_t)x)), color);
+ break;
+
+ // Common formats above. Rarer formats below.
+
+ case WUFFS_BASE__PIXEL_FORMAT__Y:
+ wuffs_base__poke_u8__no_bounds_check(
+ row + ((size_t)x),
+ wuffs_base__color_u32_argb_premul__as__color_u8_gray(color));
+ break;
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
+ wuffs_base__poke_u16le__no_bounds_check(
+ row + (2 * ((size_t)x)),
+ wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
+ break;
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
+ wuffs_base__poke_u16be__no_bounds_check(
+ row + (2 * ((size_t)x)),
+ wuffs_base__color_u32_argb_premul__as__color_u16_gray(color));
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
+ wuffs_base__poke_u8__no_bounds_check(
+ row + ((size_t)x), wuffs_base__pixel_palette__closest_element(
+ wuffs_base__pixel_buffer__palette(pb),
+ pb->pixcfg.private_impl.pixfmt, color));
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ wuffs_base__poke_u16le__no_bounds_check(
+ row + (2 * ((size_t)x)),
+ wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
+ break;
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ wuffs_base__poke_u24le__no_bounds_check(row + (3 * ((size_t)x)), color);
+ break;
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ wuffs_base__poke_u32le__no_bounds_check(
+ row + (4 * ((size_t)x)),
+ wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
+ color));
+ break;
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ wuffs_base__poke_u64le__no_bounds_check(
+ row + (8 * ((size_t)x)),
+ wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
+ color));
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ wuffs_base__poke_u24le__no_bounds_check(
+ row + (3 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
+ break;
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ wuffs_base__poke_u32le__no_bounds_check(
+ row + (4 * ((size_t)x)),
+ wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
+ wuffs_base__swap_u32_argb_abgr(color)));
+ break;
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ wuffs_base__poke_u32le__no_bounds_check(
+ row + (4 * ((size_t)x)), wuffs_base__swap_u32_argb_abgr(color));
+ break;
+
+ default:
+ // TODO: support more formats.
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ }
+
+ return wuffs_base__make_status(NULL);
+}
+
+// --------
+
+static inline void //
+wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
+ wuffs_base__pixel_buffer* pb,
+ wuffs_base__rect_ie_u32 rect,
+ uint16_t color) {
+ size_t stride = pb->private_impl.planes[0].stride;
+ uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
+ if ((stride == (2 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
+ uint8_t* ptr =
+ pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
+ uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
+ size_t n;
+ for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
+ wuffs_base__poke_u16le__no_bounds_check(ptr, color);
+ ptr += 2;
+ }
+ return;
+ }
+
+ uint32_t y;
+ for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
+ uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
+ (2 * ((size_t)rect.min_incl_x));
+ uint32_t n;
+ for (n = width; n > 0; n--) {
+ wuffs_base__poke_u16le__no_bounds_check(ptr, color);
+ ptr += 2;
+ }
+ }
+}
+
+static inline void //
+wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(
+ wuffs_base__pixel_buffer* pb,
+ wuffs_base__rect_ie_u32 rect,
+ uint32_t color) {
+ size_t stride = pb->private_impl.planes[0].stride;
+ uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
+ if ((stride == (3 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
+ uint8_t* ptr =
+ pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
+ uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
+ size_t n;
+ for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
+ wuffs_base__poke_u24le__no_bounds_check(ptr, color);
+ ptr += 3;
+ }
+ return;
+ }
+
+ uint32_t y;
+ for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
+ uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
+ (3 * ((size_t)rect.min_incl_x));
+ uint32_t n;
+ for (n = width; n > 0; n--) {
+ wuffs_base__poke_u24le__no_bounds_check(ptr, color);
+ ptr += 3;
+ }
+ }
+}
+
+static inline void //
+wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
+ wuffs_base__pixel_buffer* pb,
+ wuffs_base__rect_ie_u32 rect,
+ uint32_t color) {
+ size_t stride = pb->private_impl.planes[0].stride;
+ uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
+ if ((stride == (4 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
+ uint8_t* ptr =
+ pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
+ uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
+ size_t n;
+ for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
+ wuffs_base__poke_u32le__no_bounds_check(ptr, color);
+ ptr += 4;
+ }
+ return;
+ }
+
+ uint32_t y;
+ for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
+ uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
+ (4 * ((size_t)rect.min_incl_x));
+ uint32_t n;
+ for (n = width; n > 0; n--) {
+ wuffs_base__poke_u32le__no_bounds_check(ptr, color);
+ ptr += 4;
+ }
+ }
+}
+
+static inline void //
+wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
+ wuffs_base__pixel_buffer* pb,
+ wuffs_base__rect_ie_u32 rect,
+ uint64_t color) {
+ size_t stride = pb->private_impl.planes[0].stride;
+ uint32_t width = wuffs_base__rect_ie_u32__width(&rect);
+ if ((stride == (8 * ((uint64_t)width))) && (rect.min_incl_x == 0)) {
+ uint8_t* ptr =
+ pb->private_impl.planes[0].ptr + (stride * ((size_t)rect.min_incl_y));
+ uint32_t height = wuffs_base__rect_ie_u32__height(&rect);
+ size_t n;
+ for (n = ((size_t)width) * ((size_t)height); n > 0; n--) {
+ wuffs_base__poke_u64le__no_bounds_check(ptr, color);
+ ptr += 8;
+ }
+ return;
+ }
+
+ uint32_t y;
+ for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
+ uint8_t* ptr = pb->private_impl.planes[0].ptr + (stride * ((size_t)y)) +
+ (8 * ((size_t)rect.min_incl_x));
+ uint32_t n;
+ for (n = width; n > 0; n--) {
+ wuffs_base__poke_u64le__no_bounds_check(ptr, color);
+ ptr += 8;
+ }
+ }
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__pixel_buffer__set_color_u32_fill_rect(
+ wuffs_base__pixel_buffer* pb,
+ wuffs_base__rect_ie_u32 rect,
+ wuffs_base__color_u32_argb_premul color) {
+ if (!pb) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ } else if (wuffs_base__rect_ie_u32__is_empty(&rect)) {
+ return wuffs_base__make_status(NULL);
+ }
+ wuffs_base__rect_ie_u32 bounds =
+ wuffs_base__pixel_config__bounds(&pb->pixcfg);
+ if (!wuffs_base__rect_ie_u32__contains_rect(&bounds, rect)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+
+ if (wuffs_base__pixel_format__is_planar(&pb->pixcfg.private_impl.pixfmt)) {
+ // TODO: support planar formats.
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ }
+
+ switch (pb->pixcfg.private_impl.pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(pb, rect, color);
+ return wuffs_base__make_status(NULL);
+
+ // Common formats above. Rarer formats below.
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ wuffs_base__pixel_buffer__set_color_u32_fill_rect__xx(
+ pb, rect,
+ wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(color));
+ return wuffs_base__make_status(NULL);
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxx(pb, rect, color);
+ return wuffs_base__make_status(NULL);
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
+ pb, rect,
+ wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
+ color));
+ return wuffs_base__make_status(NULL);
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxxxxxx(
+ pb, rect,
+ wuffs_base__color_u32_argb_premul__as__color_u64_argb_nonpremul(
+ color));
+ return wuffs_base__make_status(NULL);
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
+ pb, rect,
+ wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
+ wuffs_base__swap_u32_argb_abgr(color)));
+ return wuffs_base__make_status(NULL);
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ wuffs_base__pixel_buffer__set_color_u32_fill_rect__xxxx(
+ pb, rect, wuffs_base__swap_u32_argb_abgr(color));
+ return wuffs_base__make_status(NULL);
+ }
+
+ uint32_t y;
+ for (y = rect.min_incl_y; y < rect.max_excl_y; y++) {
+ uint32_t x;
+ for (x = rect.min_incl_x; x < rect.max_excl_x; x++) {
+ wuffs_base__pixel_buffer__set_color_u32_at(pb, x, y, color);
+ }
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC uint8_t //
+wuffs_base__pixel_palette__closest_element(
+ wuffs_base__slice_u8 palette_slice,
+ wuffs_base__pixel_format palette_format,
+ wuffs_base__color_u32_argb_premul c) {
+ size_t n = palette_slice.len / 4;
+ if (n > (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ n = (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4);
+ }
+ size_t best_index = 0;
+ uint64_t best_score = 0xFFFFFFFFFFFFFFFF;
+
+ // Work in 16-bit color.
+ uint32_t ca = 0x101 * (0xFF & (c >> 24));
+ uint32_t cr = 0x101 * (0xFF & (c >> 16));
+ uint32_t cg = 0x101 * (0xFF & (c >> 8));
+ uint32_t cb = 0x101 * (0xFF & (c >> 0));
+
+ switch (palette_format.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY: {
+ bool nonpremul = palette_format.repr ==
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL;
+
+ size_t i;
+ for (i = 0; i < n; i++) {
+ // Work in 16-bit color.
+ uint32_t pb = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 0]));
+ uint32_t pg = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 1]));
+ uint32_t pr = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 2]));
+ uint32_t pa = 0x101 * ((uint32_t)(palette_slice.ptr[(4 * i) + 3]));
+
+ // Convert to premultiplied alpha.
+ if (nonpremul && (pa != 0xFFFF)) {
+ pb = (pb * pa) / 0xFFFF;
+ pg = (pg * pa) / 0xFFFF;
+ pr = (pr * pa) / 0xFFFF;
+ }
+
+ // These deltas are conceptually int32_t (signed) but after squaring,
+ // it's equivalent to work in uint32_t (unsigned).
+ pb -= cb;
+ pg -= cg;
+ pr -= cr;
+ pa -= ca;
+ uint64_t score = ((uint64_t)(pb * pb)) + ((uint64_t)(pg * pg)) +
+ ((uint64_t)(pr * pr)) + ((uint64_t)(pa * pa));
+ if (best_score > score) {
+ best_score = score;
+ best_index = i;
+ }
+ }
+ break;
+ }
+ }
+
+ return (uint8_t)best_index;
+}
+
+// --------
+
+static inline uint32_t //
+wuffs_base__composite_nonpremul_nonpremul_u32_axxx(uint32_t dst_nonpremul,
+ uint32_t src_nonpremul) {
+ // Extract 16-bit color components.
+ //
+ // If the destination is transparent then SRC_OVER is equivalent to SRC: just
+ // return src_nonpremul. This isn't just an optimization (skipping the rest
+ // of the function's computation). It also preserves the nonpremul
+ // distinction between e.g. transparent red and transparent blue that would
+ // otherwise be lost by converting from nonpremul to premul and back.
+ uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
+ if (da == 0) {
+ return src_nonpremul;
+ }
+ uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
+ uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
+ uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
+ uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
+ uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
+ uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
+ uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
+
+ // Convert dst from nonpremul to premul.
+ dr = (dr * da) / 0xFFFF;
+ dg = (dg * da) / 0xFFFF;
+ db = (db * da) / 0xFFFF;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ da = sa + ((da * ia) / 0xFFFF);
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert dst from premul to nonpremul.
+ if (da != 0) {
+ dr = (dr * 0xFFFF) / da;
+ dg = (dg * 0xFFFF) / da;
+ db = (db * 0xFFFF) / da;
+ }
+
+ // Convert from 16-bit color to 8-bit color.
+ da >>= 8;
+ dr >>= 8;
+ dg >>= 8;
+ db >>= 8;
+
+ // Combine components.
+ return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
+}
+
+static inline uint64_t //
+wuffs_base__composite_nonpremul_nonpremul_u64_axxx(uint64_t dst_nonpremul,
+ uint64_t src_nonpremul) {
+ // Extract components.
+ //
+ // If the destination is transparent then SRC_OVER is equivalent to SRC: just
+ // return src_nonpremul. This isn't just an optimization (skipping the rest
+ // of the function's computation). It also preserves the nonpremul
+ // distinction between e.g. transparent red and transparent blue that would
+ // otherwise be lost by converting from nonpremul to premul and back.
+ uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
+ if (da == 0) {
+ return src_nonpremul;
+ }
+ uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
+ uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
+ uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
+ uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
+ uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
+ uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
+ uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
+
+ // Convert dst from nonpremul to premul.
+ dr = (dr * da) / 0xFFFF;
+ dg = (dg * da) / 0xFFFF;
+ db = (db * da) / 0xFFFF;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint64_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ da = sa + ((da * ia) / 0xFFFF);
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert dst from premul to nonpremul.
+ if (da != 0) {
+ dr = (dr * 0xFFFF) / da;
+ dg = (dg * 0xFFFF) / da;
+ db = (db * 0xFFFF) / da;
+ }
+
+ // Combine components.
+ return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
+}
+
+static inline uint32_t //
+wuffs_base__composite_nonpremul_premul_u32_axxx(uint32_t dst_nonpremul,
+ uint32_t src_premul) {
+ // Extract 16-bit color components.
+ uint32_t da = 0x101 * (0xFF & (dst_nonpremul >> 24));
+ uint32_t dr = 0x101 * (0xFF & (dst_nonpremul >> 16));
+ uint32_t dg = 0x101 * (0xFF & (dst_nonpremul >> 8));
+ uint32_t db = 0x101 * (0xFF & (dst_nonpremul >> 0));
+ uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
+ uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
+ uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
+ uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
+
+ // Convert dst from nonpremul to premul.
+ dr = (dr * da) / 0xFFFF;
+ dg = (dg * da) / 0xFFFF;
+ db = (db * da) / 0xFFFF;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (premul) over dst (premul).
+ da = sa + ((da * ia) / 0xFFFF);
+ dr = sr + ((dr * ia) / 0xFFFF);
+ dg = sg + ((dg * ia) / 0xFFFF);
+ db = sb + ((db * ia) / 0xFFFF);
+
+ // Convert dst from premul to nonpremul.
+ if (da != 0) {
+ dr = (dr * 0xFFFF) / da;
+ dg = (dg * 0xFFFF) / da;
+ db = (db * 0xFFFF) / da;
+ }
+
+ // Convert from 16-bit color to 8-bit color.
+ da >>= 8;
+ dr >>= 8;
+ dg >>= 8;
+ db >>= 8;
+
+ // Combine components.
+ return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
+}
+
+static inline uint64_t //
+wuffs_base__composite_nonpremul_premul_u64_axxx(uint64_t dst_nonpremul,
+ uint64_t src_premul) {
+ // Extract components.
+ uint64_t da = 0xFFFF & (dst_nonpremul >> 48);
+ uint64_t dr = 0xFFFF & (dst_nonpremul >> 32);
+ uint64_t dg = 0xFFFF & (dst_nonpremul >> 16);
+ uint64_t db = 0xFFFF & (dst_nonpremul >> 0);
+ uint64_t sa = 0xFFFF & (src_premul >> 48);
+ uint64_t sr = 0xFFFF & (src_premul >> 32);
+ uint64_t sg = 0xFFFF & (src_premul >> 16);
+ uint64_t sb = 0xFFFF & (src_premul >> 0);
+
+ // Convert dst from nonpremul to premul.
+ dr = (dr * da) / 0xFFFF;
+ dg = (dg * da) / 0xFFFF;
+ db = (db * da) / 0xFFFF;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint64_t ia = 0xFFFF - sa;
+
+ // Composite src (premul) over dst (premul).
+ da = sa + ((da * ia) / 0xFFFF);
+ dr = sr + ((dr * ia) / 0xFFFF);
+ dg = sg + ((dg * ia) / 0xFFFF);
+ db = sb + ((db * ia) / 0xFFFF);
+
+ // Convert dst from premul to nonpremul.
+ if (da != 0) {
+ dr = (dr * 0xFFFF) / da;
+ dg = (dg * 0xFFFF) / da;
+ db = (db * 0xFFFF) / da;
+ }
+
+ // Combine components.
+ return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
+}
+
+static inline uint32_t //
+wuffs_base__composite_premul_nonpremul_u32_axxx(uint32_t dst_premul,
+ uint32_t src_nonpremul) {
+ // Extract 16-bit color components.
+ uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
+ uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
+ uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
+ uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
+ uint32_t sa = 0x101 * (0xFF & (src_nonpremul >> 24));
+ uint32_t sr = 0x101 * (0xFF & (src_nonpremul >> 16));
+ uint32_t sg = 0x101 * (0xFF & (src_nonpremul >> 8));
+ uint32_t sb = 0x101 * (0xFF & (src_nonpremul >> 0));
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ da = sa + ((da * ia) / 0xFFFF);
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert from 16-bit color to 8-bit color.
+ da >>= 8;
+ dr >>= 8;
+ dg >>= 8;
+ db >>= 8;
+
+ // Combine components.
+ return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
+}
+
+static inline uint64_t //
+wuffs_base__composite_premul_nonpremul_u64_axxx(uint64_t dst_premul,
+ uint64_t src_nonpremul) {
+ // Extract components.
+ uint64_t da = 0xFFFF & (dst_premul >> 48);
+ uint64_t dr = 0xFFFF & (dst_premul >> 32);
+ uint64_t dg = 0xFFFF & (dst_premul >> 16);
+ uint64_t db = 0xFFFF & (dst_premul >> 0);
+ uint64_t sa = 0xFFFF & (src_nonpremul >> 48);
+ uint64_t sr = 0xFFFF & (src_nonpremul >> 32);
+ uint64_t sg = 0xFFFF & (src_nonpremul >> 16);
+ uint64_t sb = 0xFFFF & (src_nonpremul >> 0);
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint64_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ da = sa + ((da * ia) / 0xFFFF);
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Combine components.
+ return (db << 0) | (dg << 16) | (dr << 32) | (da << 48);
+}
+
+static inline uint32_t //
+wuffs_base__composite_premul_premul_u32_axxx(uint32_t dst_premul,
+ uint32_t src_premul) {
+ // Extract 16-bit color components.
+ uint32_t da = 0x101 * (0xFF & (dst_premul >> 24));
+ uint32_t dr = 0x101 * (0xFF & (dst_premul >> 16));
+ uint32_t dg = 0x101 * (0xFF & (dst_premul >> 8));
+ uint32_t db = 0x101 * (0xFF & (dst_premul >> 0));
+ uint32_t sa = 0x101 * (0xFF & (src_premul >> 24));
+ uint32_t sr = 0x101 * (0xFF & (src_premul >> 16));
+ uint32_t sg = 0x101 * (0xFF & (src_premul >> 8));
+ uint32_t sb = 0x101 * (0xFF & (src_premul >> 0));
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (premul) over dst (premul).
+ da = sa + ((da * ia) / 0xFFFF);
+ dr = sr + ((dr * ia) / 0xFFFF);
+ dg = sg + ((dg * ia) / 0xFFFF);
+ db = sb + ((db * ia) / 0xFFFF);
+
+ // Convert from 16-bit color to 8-bit color.
+ da >>= 8;
+ dr >>= 8;
+ dg >>= 8;
+ db >>= 8;
+
+ // Combine components.
+ return (db << 0) | (dg << 8) | (dr << 16) | (da << 24);
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(uint8_t* dst_ptr,
+ size_t dst_len,
+ const uint8_t* src_ptr,
+ size_t src_len,
+ bool nonpremul) {
+ size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n--) {
+ uint32_t argb = wuffs_base__peek_u32le__no_bounds_check(s);
+ if (nonpremul) {
+ argb =
+ wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(argb);
+ }
+ uint32_t b5 = 0x1F & (argb >> (8 - 5));
+ uint32_t g6 = 0x3F & (argb >> (16 - 6));
+ uint32_t r5 = 0x1F & (argb >> (24 - 5));
+ uint32_t alpha = argb & 0xFF000000;
+ wuffs_base__poke_u32le__no_bounds_check(
+ d, alpha | (r5 << 11) | (g6 << 5) | (b5 << 0));
+ s += 4;
+ d += 4;
+ }
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__swap_rgb_bgr(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t len = (dst_len < src_len ? dst_len : src_len) / 3;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n--) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ d[0] = s2;
+ d[1] = s1;
+ d[2] = s0;
+ s += 3;
+ d += 3;
+ }
+ return len;
+}
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+static uint64_t //
+wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ __m128i shuffle = _mm_set_epi8(+0x0F, +0x0C, +0x0D, +0x0E, //
+ +0x0B, +0x08, +0x09, +0x0A, //
+ +0x07, +0x04, +0x05, +0x06, //
+ +0x03, +0x00, +0x01, +0x02);
+
+ while (n >= 4) {
+ __m128i x;
+ x = _mm_lddqu_si128((const __m128i*)(const void*)s);
+ x = _mm_shuffle_epi8(x, shuffle);
+ _mm_storeu_si128((__m128i*)(void*)d, x);
+
+ s += 4 * 4;
+ d += 4 * 4;
+ n -= 4;
+ }
+
+ while (n--) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ uint8_t s3 = s[3];
+ d[0] = s2;
+ d[1] = s1;
+ d[2] = s0;
+ d[3] = s3;
+ s += 4;
+ d += 4;
+ }
+ return len;
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+static uint64_t //
+wuffs_base__pixel_swizzler__swap_rgbx_bgrx(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t len = (dst_len < src_len ? dst_len : src_len) / 4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n--) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ uint8_t s3 = s[3];
+ d[0] = s2;
+ d[1] = s1;
+ d[2] = s0;
+ d[3] = s3;
+ s += 4;
+ d += 4;
+ }
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__copy_1_1(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t len = (dst_len < src_len) ? dst_len : src_len;
+ if (len > 0) {
+ memmove(dst_ptr, src_ptr, len);
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__copy_2_2(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
+ if (len > 0) {
+ memmove(dst_ptr, src_ptr, len * 2);
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__copy_3_3(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len3 = src_len / 3;
+ size_t len = (dst_len3 < src_len3) ? dst_len3 : src_len3;
+ if (len > 0) {
+ memmove(dst_ptr, src_ptr, len * 3);
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__copy_4_4(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ if (len > 0) {
+ memmove(dst_ptr, src_ptr, len * 4);
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__copy_8_8(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
+ if (len > 0) {
+ memmove(dst_ptr, src_ptr, len * 8);
+ }
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__bgr(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len3 = src_len / 3;
+ size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t b5 = s[0] >> 3;
+ uint32_t g6 = s[1] >> 2;
+ uint32_t r5 = s[2] >> 3;
+ uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
+
+ s += 1 * 3;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__bgrx(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t b5 = s[0] >> 3;
+ uint32_t g6 = s[1] >> 2;
+ uint32_t r5 = s[2] >> 3;
+ uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (0 * 2),
+ wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
+ wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (0 * 2),
+ wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
+ wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)))));
+
+ s += 1 * 8;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t sa = 0x101 * ((uint32_t)s[3]);
+ uint32_t sr = 0x101 * ((uint32_t)s[2]);
+ uint32_t sg = 0x101 * ((uint32_t)s[1]);
+ uint32_t sb = 0x101 * ((uint32_t)s[0]);
+
+ // Convert from 565 color to 16-bit color.
+ uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
+ uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
+ uint32_t dr = (0x8421 * old_r5) >> 4;
+ uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
+ uint32_t dg = (0x1041 * old_g6) >> 2;
+ uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
+ uint32_t db = (0x8421 * old_b5) >> 4;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert from 16-bit color to 565 color and combine the components.
+ uint32_t new_r5 = 0x1F & (dr >> 11);
+ uint32_t new_g6 = 0x3F & (dg >> 10);
+ uint32_t new_b5 = 0x1F & (db >> 11);
+ uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len2 < src_len8) ? dst_len2 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
+ uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
+ uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
+ uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
+
+ // Convert from 565 color to 16-bit color.
+ uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
+ uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
+ uint32_t dr = (0x8421 * old_r5) >> 4;
+ uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
+ uint32_t dg = (0x1041 * old_g6) >> 2;
+ uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
+ uint32_t db = (0x8421 * old_b5) >> 4;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert from 16-bit color to 565 color and combine the components.
+ uint32_t new_r5 = 0x1F & (dr >> 11);
+ uint32_t new_g6 = 0x3F & (dg >> 10);
+ uint32_t new_b5 = 0x1F & (db >> 11);
+ uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
+
+ s += 1 * 8;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (0 * 2), wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t sa = 0x101 * ((uint32_t)s[3]);
+ uint32_t sr = 0x101 * ((uint32_t)s[2]);
+ uint32_t sg = 0x101 * ((uint32_t)s[1]);
+ uint32_t sb = 0x101 * ((uint32_t)s[0]);
+
+ // Convert from 565 color to 16-bit color.
+ uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
+ uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
+ uint32_t dr = (0x8421 * old_r5) >> 4;
+ uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
+ uint32_t dg = (0x1041 * old_g6) >> 2;
+ uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
+ uint32_t db = (0x8421 * old_b5) >> 4;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (premul) over dst (premul).
+ dr = sr + ((dr * ia) / 0xFFFF);
+ dg = sg + ((dg * ia) / 0xFFFF);
+ db = sb + ((db * ia) / 0xFFFF);
+
+ // Convert from 16-bit color to 565 color and combine the components.
+ uint32_t new_r5 = 0x1F & (dr >> 11);
+ uint32_t new_g6 = 0x3F & (dg >> 10);
+ uint32_t new_b5 = 0x1F & (db >> 11);
+ uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__rgb(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len3 = src_len / 3;
+ size_t len = (dst_len2 < src_len3) ? dst_len2 : src_len3;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t r5 = s[0] >> 3;
+ uint32_t g6 = s[1] >> 2;
+ uint32_t b5 = s[2] >> 3;
+ uint32_t rgb_565 = (r5 << 11) | (g6 << 5) | (b5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
+
+ s += 1 * 3;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (0 * 2),
+ wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
+ wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))))));
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t sa = 0x101 * ((uint32_t)s[3]);
+ uint32_t sb = 0x101 * ((uint32_t)s[2]);
+ uint32_t sg = 0x101 * ((uint32_t)s[1]);
+ uint32_t sr = 0x101 * ((uint32_t)s[0]);
+
+ // Convert from 565 color to 16-bit color.
+ uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
+ uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
+ uint32_t dr = (0x8421 * old_r5) >> 4;
+ uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
+ uint32_t dg = (0x1041 * old_g6) >> 2;
+ uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
+ uint32_t db = (0x8421 * old_b5) >> 4;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert from 16-bit color to 565 color and combine the components.
+ uint32_t new_r5 = 0x1F & (dr >> 11);
+ uint32_t new_g6 = 0x3F & (dg >> 10);
+ uint32_t new_b5 = 0x1F & (db >> 11);
+ uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (0 * 2),
+ wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
+ wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len2 < src_len4) ? dst_len2 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t sa = 0x101 * ((uint32_t)s[3]);
+ uint32_t sb = 0x101 * ((uint32_t)s[2]);
+ uint32_t sg = 0x101 * ((uint32_t)s[1]);
+ uint32_t sr = 0x101 * ((uint32_t)s[0]);
+
+ // Convert from 565 color to 16-bit color.
+ uint32_t old_rgb_565 = wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2));
+ uint32_t old_r5 = 0x1F & (old_rgb_565 >> 11);
+ uint32_t dr = (0x8421 * old_r5) >> 4;
+ uint32_t old_g6 = 0x3F & (old_rgb_565 >> 5);
+ uint32_t dg = (0x1041 * old_g6) >> 2;
+ uint32_t old_b5 = 0x1F & (old_rgb_565 >> 0);
+ uint32_t db = (0x8421 * old_b5) >> 4;
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (premul) over dst (premul).
+ dr = sr + ((dr * ia) / 0xFFFF);
+ dg = sg + ((dg * ia) / 0xFFFF);
+ db = sb + ((db * ia) / 0xFFFF);
+
+ // Convert from 16-bit color to 565 color and combine the components.
+ uint32_t new_r5 = 0x1F & (dr >> 11);
+ uint32_t new_g6 = 0x3F & (dg >> 10);
+ uint32_t new_b5 = 0x1F & (db >> 11);
+ uint32_t new_rgb_565 = (new_r5 << 11) | (new_g6 << 5) | (new_b5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)new_rgb_565);
+
+ s += 1 * 4;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__y(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t y5 = s[0] >> 3;
+ uint32_t y6 = s[0] >> 2;
+ uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
+
+ s += 1 * 1;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__y_16be(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t y5 = s[0] >> 3;
+ uint32_t y6 = s[0] >> 2;
+ uint32_t rgb_565 = (y5 << 11) | (y6 << 5) | (y5 << 0);
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)rgb_565);
+
+ s += 1 * 2;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__index__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len2 = dst_len / 2;
+ size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ const size_t loop_unroll_count = 4;
+
+ while (n >= loop_unroll_count) {
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[0] * 4)));
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (1 * 2), wuffs_base__peek_u16le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[1] * 4)));
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (2 * 2), wuffs_base__peek_u16le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[2] * 4)));
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (3 * 2), wuffs_base__peek_u16le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[3] * 4)));
+
+ s += loop_unroll_count * 1;
+ d += loop_unroll_count * 2;
+ n -= loop_unroll_count;
+ }
+
+ while (n >= 1) {
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (0 * 2), wuffs_base__peek_u16le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[0] * 4)));
+
+ s += 1 * 1;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len2 = dst_len / 2;
+ size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
+ wuffs_base__peek_u16le__no_bounds_check(d + (0 * 2)));
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ wuffs_base__poke_u16le__no_bounds_check(
+ d + (0 * 2),
+ wuffs_base__color_u32_argb_premul__as__color_u16_rgb_565(
+ wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0)));
+
+ s += 1 * 1;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len2 = dst_len / 2;
+ size_t len = (dst_len2 < src_len) ? dst_len2 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ if (s0) {
+ wuffs_base__poke_u16le__no_bounds_check(d + (0 * 2), (uint16_t)s0);
+ }
+
+ s += 1 * 1;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__bgr_565(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
+ wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)));
+ wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
+
+ s += 1 * 2;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t s0 =
+ wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t s0 =
+ wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
+ wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
+
+ s += 1 * 8;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t dr = 0x101 * ((uint32_t)d[2]);
+ uint32_t dg = 0x101 * ((uint32_t)d[1]);
+ uint32_t db = 0x101 * ((uint32_t)d[0]);
+ uint32_t sa = 0x101 * ((uint32_t)s[3]);
+ uint32_t sr = 0x101 * ((uint32_t)s[2]);
+ uint32_t sg = 0x101 * ((uint32_t)s[1]);
+ uint32_t sb = 0x101 * ((uint32_t)s[0]);
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert from 16-bit color to 8-bit color.
+ d[0] = (uint8_t)(db >> 8);
+ d[1] = (uint8_t)(dg >> 8);
+ d[2] = (uint8_t)(dr >> 8);
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t dr = 0x101 * ((uint32_t)d[2]);
+ uint32_t dg = 0x101 * ((uint32_t)d[1]);
+ uint32_t db = 0x101 * ((uint32_t)d[0]);
+ uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
+ uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
+ uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
+ uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert from 16-bit color to 8-bit color.
+ d[0] = (uint8_t)(db >> 8);
+ d[1] = (uint8_t)(dg >> 8);
+ d[2] = (uint8_t)(dr >> 8);
+
+ s += 1 * 8;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__bgra_premul__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ d[0] = s0;
+ d[1] = s1;
+ d[2] = s2;
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t dr = 0x101 * ((uint32_t)d[2]);
+ uint32_t dg = 0x101 * ((uint32_t)d[1]);
+ uint32_t db = 0x101 * ((uint32_t)d[0]);
+ uint32_t sa = 0x101 * ((uint32_t)s[3]);
+ uint32_t sr = 0x101 * ((uint32_t)s[2]);
+ uint32_t sg = 0x101 * ((uint32_t)s[1]);
+ uint32_t sb = 0x101 * ((uint32_t)s[0]);
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (premul) over dst (premul).
+ dr = sr + ((dr * ia) / 0xFFFF);
+ dg = sg + ((dg * ia) / 0xFFFF);
+ db = sb + ((db * ia) / 0xFFFF);
+
+ // Convert from 16-bit color to 8-bit color.
+ d[0] = (uint8_t)(db >> 8);
+ d[1] = (uint8_t)(dg >> 8);
+ d[2] = (uint8_t)(dr >> 8);
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
+ wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
+ wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
+ wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
+
+ s += 1 * 8;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t dr = 0x101 * ((uint32_t)d[2]);
+ uint32_t dg = 0x101 * ((uint32_t)d[1]);
+ uint32_t db = 0x101 * ((uint32_t)d[0]);
+ uint32_t sa = 0x101 * ((uint32_t)s[3]);
+ uint32_t sb = 0x101 * ((uint32_t)s[2]);
+ uint32_t sg = 0x101 * ((uint32_t)s[1]);
+ uint32_t sr = 0x101 * ((uint32_t)s[0]);
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert from 16-bit color to 8-bit color.
+ d[0] = (uint8_t)(db >> 8);
+ d[1] = (uint8_t)(dg >> 8);
+ d[2] = (uint8_t)(dr >> 8);
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len3 < src_len8) ? dst_len3 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t dr = 0x101 * ((uint32_t)d[2]);
+ uint32_t dg = 0x101 * ((uint32_t)d[1]);
+ uint32_t db = 0x101 * ((uint32_t)d[0]);
+ uint32_t sa = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 6));
+ uint32_t sb = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 4));
+ uint32_t sg = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 2));
+ uint32_t sr = ((uint32_t)wuffs_base__peek_u16le__no_bounds_check(s + 0));
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (nonpremul) over dst (premul).
+ dr = ((sr * sa) + (dr * ia)) / 0xFFFF;
+ dg = ((sg * sa) + (dg * ia)) / 0xFFFF;
+ db = ((sb * sa) + (db * ia)) / 0xFFFF;
+
+ // Convert from 16-bit color to 8-bit color.
+ d[0] = (uint8_t)(db >> 8);
+ d[1] = (uint8_t)(dg >> 8);
+ d[2] = (uint8_t)(dr >> 8);
+
+ s += 1 * 8;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__rgba_premul__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ d[0] = s2;
+ d[1] = s1;
+ d[2] = s0;
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ // Extract 16-bit color components.
+ uint32_t dr = 0x101 * ((uint32_t)d[2]);
+ uint32_t dg = 0x101 * ((uint32_t)d[1]);
+ uint32_t db = 0x101 * ((uint32_t)d[0]);
+ uint32_t sa = 0x101 * ((uint32_t)s[3]);
+ uint32_t sb = 0x101 * ((uint32_t)s[2]);
+ uint32_t sg = 0x101 * ((uint32_t)s[1]);
+ uint32_t sr = 0x101 * ((uint32_t)s[0]);
+
+ // Calculate the inverse of the src-alpha: how much of the dst to keep.
+ uint32_t ia = 0xFFFF - sa;
+
+ // Composite src (premul) over dst (premul).
+ dr = sr + ((dr * ia) / 0xFFFF);
+ dg = sg + ((dg * ia) / 0xFFFF);
+ db = sb + ((db * ia) / 0xFFFF);
+
+ // Convert from 16-bit color to 8-bit color.
+ d[0] = (uint8_t)(db >> 8);
+ d[1] = (uint8_t)(dg >> 8);
+ d[2] = (uint8_t)(dr >> 8);
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgr__rgbx(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint8_t b0 = s[0];
+ uint8_t b1 = s[1];
+ uint8_t b2 = s[2];
+ d[0] = b2;
+ d[1] = b1;
+ d[2] = b0;
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__color_u64__as__color_u32(
+ wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
+
+ s += 1 * 8;
+ d += 1 * 4;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
+ uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u64__as__color_u32(
+ wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
+
+ s += 1 * 8;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len4 = dst_len / 4;
+ size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
+
+ s += 1 * 1;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__composite_nonpremul_nonpremul_u32_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__composite_nonpremul_premul_u32_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ uint8_t s3 = s[3];
+ d[0] = s0;
+ d[1] = s0;
+ d[2] = s1;
+ d[3] = s1;
+ d[4] = s2;
+ d[5] = s2;
+ d[6] = s3;
+ d[7] = s3;
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
+ uint64_t s0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8),
+ wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len8 < src_len8) ? dst_len8 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
+ uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8),
+ wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
+
+ s += 1 * 8;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint64_t s0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
+ wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
+ uint64_t s0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len8 = dst_len / 8;
+ size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
+ uint64_t s0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4)));
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8),
+ wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
+
+ s += 1 * 1;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ uint8_t s3 = s[3];
+ d[0] = s2;
+ d[1] = s2;
+ d[2] = s1;
+ d[3] = s1;
+ d[4] = s0;
+ d[5] = s0;
+ d[6] = s3;
+ d[7] = s3;
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
+ uint64_t s0 =
+ wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8),
+ wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint64_t s0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__color_u32_argb_premul__as__color_u32_argb_nonpremul(
+ wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)))));
+ wuffs_base__poke_u64le__no_bounds_check(d + (0 * 8), s0);
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__peek_u64le__no_bounds_check(d + (0 * 8));
+ uint64_t s0 =
+ wuffs_base__color_u32__as__color_u64(wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4))));
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8), wuffs_base__composite_nonpremul_premul_u64_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(s0));
+
+ s += 1 * 8;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
+ uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u64__as__color_u32(
+ wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
+
+ s += 1 * 8;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len4 = dst_len / 4;
+ size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
+
+ s += 1 * 1;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u32_argb_nonpremul__as__color_u32_argb_premul(s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint64_t s0 = wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__color_u64_argb_nonpremul__as__color_u32_argb_premul(
+ s0)));
+
+ s += 1 * 8;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
+ uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
+ wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u64__as__color_u32(
+ wuffs_base__composite_premul_nonpremul_u64_axxx(d0, s0)));
+
+ s += 1 * 8;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint32_t d0 = wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4));
+ uint32_t s0 = wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__composite_premul_premul_u32_axxx(d0, s0));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw__bgr(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len3 = src_len / 3;
+ size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ 0xFF000000 | wuffs_base__peek_u24le__no_bounds_check(s + (0 * 3)));
+
+ s += 1 * 3;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw__bgr_565(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
+ wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2))));
+
+ s += 1 * 2;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw__bgrx(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ 0xFF000000 | wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len3 = src_len / 3;
+ size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ __m128i shuffle = _mm_set_epi8(+0x00, +0x09, +0x0A, +0x0B, //
+ +0x00, +0x06, +0x07, +0x08, //
+ +0x00, +0x03, +0x04, +0x05, //
+ +0x00, +0x00, +0x01, +0x02);
+ __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, //
+ -0x01, +0x00, +0x00, +0x00, //
+ -0x01, +0x00, +0x00, +0x00, //
+ -0x01, +0x00, +0x00, +0x00);
+
+ while (n >= 6) {
+ __m128i x;
+ x = _mm_lddqu_si128((const __m128i*)(const void*)s);
+ x = _mm_shuffle_epi8(x, shuffle);
+ x = _mm_or_si128(x, or_ff);
+ _mm_storeu_si128((__m128i*)(void*)d, x);
+
+ s += 4 * 3;
+ d += 4 * 4;
+ n -= 4;
+ }
+
+ while (n >= 1) {
+ uint8_t b0 = s[0];
+ uint8_t b1 = s[1];
+ uint8_t b2 = s[2];
+ d[0] = b2;
+ d[1] = b1;
+ d[2] = b0;
+ d[3] = 0xFF;
+
+ s += 1 * 3;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw__rgb(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len3 = src_len / 3;
+ size_t len = (dst_len4 < src_len3) ? dst_len4 : src_len3;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint8_t b0 = s[0];
+ uint8_t b1 = s[1];
+ uint8_t b2 = s[2];
+ d[0] = b2;
+ d[1] = b1;
+ d[2] = b0;
+ d[3] = 0xFF;
+
+ s += 1 * 3;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw__rgbx(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len4 < src_len4) ? dst_len4 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint8_t b0 = s[0];
+ uint8_t b1 = s[1];
+ uint8_t b2 = s[2];
+ d[0] = b2;
+ d[1] = b1;
+ d[2] = b0;
+ d[3] = 0xFF;
+
+ s += 1 * 4;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw_4x16le__bgr(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len3 = src_len / 3;
+ size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ d[0] = s0;
+ d[1] = s0;
+ d[2] = s1;
+ d[3] = s1;
+ d[4] = s2;
+ d[5] = s2;
+ d[6] = 0xFF;
+ d[7] = 0xFF;
+
+ s += 1 * 3;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8),
+ wuffs_base__color_u32__as__color_u64(
+ wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
+ wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
+
+ s += 1 * 2;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len8 < src_len4) ? dst_len8 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ d[0] = s0;
+ d[1] = s0;
+ d[2] = s1;
+ d[3] = s1;
+ d[4] = s2;
+ d[5] = s2;
+ d[6] = 0xFF;
+ d[7] = 0xFF;
+
+ s += 1 * 4;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__bgrw_4x16le__rgb(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len3 = src_len / 3;
+ size_t len = (dst_len8 < src_len3) ? dst_len8 : src_len3;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ uint8_t s2 = s[2];
+ d[0] = s2;
+ d[1] = s2;
+ d[2] = s1;
+ d[3] = s1;
+ d[4] = s0;
+ d[5] = s0;
+ d[6] = 0xFF;
+ d[7] = 0xFF;
+
+ s += 1 * 3;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__rgb__bgr_565(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u24le__no_bounds_check(
+ d + (0 * 3),
+ wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
+ wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
+
+ s += 1 * 2;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+
+ size_t n = len;
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__color_u64__as__color_u32__swap_u32_argb_abgr(
+ wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8))));
+
+ s += 1 * 8;
+ d += 1 * 4;
+ n -= 1;
+ }
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len8 = src_len / 8;
+ size_t len = (dst_len4 < src_len8) ? dst_len4 : src_len8;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint64_t d0 = wuffs_base__color_u32__as__color_u64(
+ wuffs_base__peek_u32le__no_bounds_check(d + (0 * 4)));
+ uint64_t s0 = wuffs_base__swap_u64_argb_abgr(
+ wuffs_base__peek_u64le__no_bounds_check(s + (0 * 8)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__color_u64__as__color_u32(
+ wuffs_base__composite_nonpremul_nonpremul_u64_axxx(d0, s0)));
+
+ s += 1 * 8;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__rgbw__bgr_565(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4),
+ wuffs_base__swap_u32_argb_abgr(
+ wuffs_base__color_u16_rgb_565__as__color_u32_argb_premul(
+ wuffs_base__peek_u16le__no_bounds_check(s + (0 * 2)))));
+
+ s += 1 * 2;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxx__index__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len3 = dst_len / 3;
+ size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ const size_t loop_unroll_count = 4;
+
+ // The comparison in the while condition is ">", not ">=", because with
+ // ">=", the last 4-byte store could write past the end of the dst slice.
+ //
+ // Each 4-byte store writes one too many bytes, but a subsequent store
+ // will overwrite that with the correct byte. There is always another
+ // store, whether a 4-byte store in this loop or a 1-byte store in the
+ // next loop.
+ while (n > loop_unroll_count) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[0] * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (1 * 3), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[1] * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (2 * 3), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[2] * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (3 * 3), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[3] * 4)));
+
+ s += loop_unroll_count * 1;
+ d += loop_unroll_count * 3;
+ n -= loop_unroll_count;
+ }
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
+
+ s += 1 * 1;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len3 = dst_len / 3;
+ size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint32_t d0 =
+ wuffs_base__peek_u24le__no_bounds_check(d + (0 * 3)) | 0xFF000000;
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ wuffs_base__poke_u24le__no_bounds_check(
+ d + (0 * 3), wuffs_base__composite_premul_nonpremul_u32_axxx(d0, s0));
+
+ s += 1 * 1;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len3 = dst_len / 3;
+ size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ const size_t loop_unroll_count = 4;
+
+ while (n >= loop_unroll_count) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ if (s0) {
+ wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
+ }
+ uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[1] * 4));
+ if (s1) {
+ wuffs_base__poke_u24le__no_bounds_check(d + (1 * 3), s1);
+ }
+ uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[2] * 4));
+ if (s2) {
+ wuffs_base__poke_u24le__no_bounds_check(d + (2 * 3), s2);
+ }
+ uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[3] * 4));
+ if (s3) {
+ wuffs_base__poke_u24le__no_bounds_check(d + (3 * 3), s3);
+ }
+
+ s += loop_unroll_count * 1;
+ d += loop_unroll_count * 3;
+ n -= loop_unroll_count;
+ }
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ if (s0) {
+ wuffs_base__poke_u24le__no_bounds_check(d + (0 * 3), s0);
+ }
+
+ s += 1 * 1;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxx__xxxx(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len4 = src_len / 4;
+ size_t len = (dst_len3 < src_len4) ? dst_len3 : src_len4;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ wuffs_base__poke_u24le__no_bounds_check(
+ d + (0 * 3), wuffs_base__peek_u32le__no_bounds_check(s + (0 * 4)));
+
+ s += 1 * 4;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxx__y(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t len = (dst_len3 < src_len) ? dst_len3 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ d[0] = s0;
+ d[1] = s0;
+ d[2] = s0;
+
+ s += 1 * 1;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxx__y_16be(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len3 = dst_len / 3;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len3 < src_len2) ? dst_len3 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ // TODO: unroll.
+
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ d[0] = s0;
+ d[1] = s0;
+ d[2] = s0;
+
+ s += 1 * 2;
+ d += 1 * 3;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxx__index__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len4 = dst_len / 4;
+ size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ const size_t loop_unroll_count = 4;
+
+ while (n >= loop_unroll_count) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[0] * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (1 * 4), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[1] * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (2 * 4), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[2] * 4)));
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (3 * 4), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[3] * 4)));
+
+ s += loop_unroll_count * 1;
+ d += loop_unroll_count * 4;
+ n -= loop_unroll_count;
+ }
+
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[0] * 4)));
+
+ s += 1 * 1;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len4 = dst_len / 4;
+ size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ const size_t loop_unroll_count = 4;
+
+ while (n >= loop_unroll_count) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ if (s0) {
+ wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
+ }
+ uint32_t s1 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[1] * 4));
+ if (s1) {
+ wuffs_base__poke_u32le__no_bounds_check(d + (1 * 4), s1);
+ }
+ uint32_t s2 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[2] * 4));
+ if (s2) {
+ wuffs_base__poke_u32le__no_bounds_check(d + (2 * 4), s2);
+ }
+ uint32_t s3 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[3] * 4));
+ if (s3) {
+ wuffs_base__poke_u32le__no_bounds_check(d + (3 * 4), s3);
+ }
+
+ s += loop_unroll_count * 1;
+ d += loop_unroll_count * 4;
+ n -= loop_unroll_count;
+ }
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ if (s0) {
+ wuffs_base__poke_u32le__no_bounds_check(d + (0 * 4), s0);
+ }
+
+ s += 1 * 1;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxx__y__x86_sse42(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ __m128i shuffle = _mm_set_epi8(+0x03, +0x03, +0x03, +0x03, //
+ +0x02, +0x02, +0x02, +0x02, //
+ +0x01, +0x01, +0x01, +0x01, //
+ +0x00, +0x00, +0x00, +0x00);
+ __m128i or_ff = _mm_set_epi8(-0x01, +0x00, +0x00, +0x00, //
+ -0x01, +0x00, +0x00, +0x00, //
+ -0x01, +0x00, +0x00, +0x00, //
+ -0x01, +0x00, +0x00, +0x00);
+
+ while (n >= 4) {
+ __m128i x;
+ x = _mm_cvtsi32_si128((int)(wuffs_base__peek_u32le__no_bounds_check(s)));
+ x = _mm_shuffle_epi8(x, shuffle);
+ x = _mm_or_si128(x, or_ff);
+ _mm_storeu_si128((__m128i*)(void*)d, x);
+
+ s += 4 * 1;
+ d += 4 * 4;
+ n -= 4;
+ }
+
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
+
+ s += 1 * 1;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxx__y(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t len = (dst_len4 < src_len) ? dst_len4 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
+
+ s += 1 * 1;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxx__y_16be(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len4 = dst_len / 4;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len4 < src_len2) ? dst_len4 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ wuffs_base__poke_u32le__no_bounds_check(
+ d + (0 * 4), 0xFF000000 | (0x010101 * (uint32_t)s[0]));
+
+ s += 1 * 2;
+ d += 1 * 4;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxxxxxx__index__src(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len8 = dst_len / 8;
+ size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8), wuffs_base__color_u32__as__color_u64(
+ wuffs_base__peek_u32le__no_bounds_check(
+ dst_palette_ptr + ((size_t)s[0] * 4))));
+
+ s += 1 * 1;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ if (dst_palette_len !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return 0;
+ }
+ size_t dst_len8 = dst_len / 8;
+ size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint32_t s0 = wuffs_base__peek_u32le__no_bounds_check(dst_palette_ptr +
+ ((size_t)s[0] * 4));
+ if (s0) {
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8), wuffs_base__color_u32__as__color_u64(s0));
+ }
+
+ s += 1 * 1;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxxxxxx__y(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t len = (dst_len8 < src_len) ? dst_len8 : src_len;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8), 0xFFFF000000000000 | (0x010101010101 * (uint64_t)s[0]));
+
+ s += 1 * 1;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__xxxxxxxx__y_16be(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len8 = dst_len / 8;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len8 < src_len2) ? dst_len8 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint64_t s0 =
+ ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(s + (0 * 2))));
+ wuffs_base__poke_u64le__no_bounds_check(
+ d + (0 * 8), 0xFFFF000000000000 | (0x000100010001 * s0));
+
+ s += 1 * 2;
+ d += 1 * 8;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__y__y_16be(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len < src_len2) ? dst_len : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ d[0] = s[0];
+
+ s += 1 * 2;
+ d += 1 * 1;
+ n -= 1;
+ }
+
+ return len;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__y_16le__y_16be(uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ const uint8_t* src_ptr,
+ size_t src_len) {
+ size_t dst_len2 = dst_len / 2;
+ size_t src_len2 = src_len / 2;
+ size_t len = (dst_len2 < src_len2) ? dst_len2 : src_len2;
+ uint8_t* d = dst_ptr;
+ const uint8_t* s = src_ptr;
+ size_t n = len;
+
+ while (n >= 1) {
+ uint8_t s0 = s[0];
+ uint8_t s1 = s[1];
+ d[0] = s1;
+ d[1] = s0;
+
+ s += 1 * 2;
+ d += 1 * 2;
+ n -= 1;
+ }
+
+ return len;
+}
+
+// --------
+
+static uint64_t //
+wuffs_base__pixel_swizzler__transparent_black_src(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ uint64_t num_pixels,
+ uint32_t dst_pixfmt_bytes_per_pixel) {
+ uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
+ if (n > num_pixels) {
+ n = num_pixels;
+ }
+ memset(dst_ptr, 0, ((size_t)(n * dst_pixfmt_bytes_per_pixel)));
+ return n;
+}
+
+static uint64_t //
+wuffs_base__pixel_swizzler__transparent_black_src_over(
+ uint8_t* dst_ptr,
+ size_t dst_len,
+ uint8_t* dst_palette_ptr,
+ size_t dst_palette_len,
+ uint64_t num_pixels,
+ uint32_t dst_pixfmt_bytes_per_pixel) {
+ uint64_t n = ((uint64_t)dst_len) / dst_pixfmt_bytes_per_pixel;
+ if (n > num_pixels) {
+ n = num_pixels;
+ }
+ return n;
+}
+
+// --------
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__y(wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__Y:
+ return wuffs_base__pixel_swizzler__copy_1_1;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ return wuffs_base__pixel_swizzler__bgr_565__y;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ return wuffs_base__pixel_swizzler__xxx__y;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ if (wuffs_base__cpu_arch__have_x86_sse42()) {
+ return wuffs_base__pixel_swizzler__xxxx__y__x86_sse42;
+ }
+#endif
+ return wuffs_base__pixel_swizzler__xxxx__y;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
+ return wuffs_base__pixel_swizzler__xxxxxxxx__y;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__y_16be(wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__Y:
+ return wuffs_base__pixel_swizzler__y__y_16be;
+
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
+ return wuffs_base__pixel_swizzler__y_16le__y_16be;
+
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
+ return wuffs_base__pixel_swizzler__copy_2_2;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ return wuffs_base__pixel_swizzler__bgr_565__y_16be;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ return wuffs_base__pixel_swizzler__xxx__y_16be;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ return wuffs_base__pixel_swizzler__xxxx__y_16be;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL_4X16LE:
+ return wuffs_base__pixel_swizzler__xxxxxxxx__y_16be;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
+ wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__copy_1_1;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
+ dst_palette.ptr, dst_palette.len, src_palette.ptr,
+ src_palette.len, true) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__bgr_565__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__bgr_565__index_bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__xxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__xxxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__index_bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ if (wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__xxxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__xxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__xxx__index_bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__xxxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__index_bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ if (wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__xxxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ return wuffs_base__pixel_swizzler__bgra_premul__index_bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ // TODO.
+ break;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
+ wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__copy_1_1;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ if (wuffs_base__pixel_swizzler__squash_align4_bgr_565_8888(
+ dst_palette.ptr, dst_palette.len, src_palette.ptr,
+ src_palette.len, false) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr_565__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr_565__index_binary_alpha__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__xxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__xxxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
+ if (wuffs_base__slice_u8__copy_from_slice(dst_palette, src_palette) !=
+ WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__xxxxxxxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__xxxxxxxx__index_binary_alpha__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__xxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__xxx__index_binary_alpha__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ if (wuffs_base__pixel_swizzler__swap_rgbx_bgrx(
+ dst_palette.ptr, dst_palette.len, NULL, 0, src_palette.ptr,
+ src_palette.len) !=
+ (WUFFS_BASE__PIXEL_FORMAT__INDEXED__PALETTE_BYTE_LENGTH / 4)) {
+ return NULL;
+ }
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__xxxx__index__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__xxxx__index_binary_alpha__src_over;
+ }
+ return NULL;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__bgr_565(
+ wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ return wuffs_base__pixel_swizzler__copy_2_2;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ return wuffs_base__pixel_swizzler__bgr__bgr_565;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ return wuffs_base__pixel_swizzler__bgrw__bgr_565;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
+ return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr_565;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ return wuffs_base__pixel_swizzler__rgb__bgr_565;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ return wuffs_base__pixel_swizzler__rgbw__bgr_565;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__bgr(wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ return wuffs_base__pixel_swizzler__bgr_565__bgr;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ return wuffs_base__pixel_swizzler__copy_3_3;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ return wuffs_base__pixel_swizzler__bgrw__bgr;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL_4X16LE:
+ return wuffs_base__pixel_swizzler__bgrw_4x16le__bgr;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ return wuffs_base__pixel_swizzler__swap_rgb_bgr;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ if (wuffs_base__cpu_arch__have_x86_sse42()) {
+ return wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42;
+ }
+#endif
+ return wuffs_base__pixel_swizzler__bgrw__rgb;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
+ wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__copy_4_4;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ // TODO.
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ if (wuffs_base__cpu_arch__have_x86_sse42()) {
+ return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42;
+ }
+#endif
+ return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ // TODO.
+ break;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
+ wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr_565__bgra_nonpremul_4x16le__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul_4x16le__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul_4x16le__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__copy_8_8;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_nonpremul_4x16le__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul_4x16le__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ // TODO.
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul_4x16le__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__rgba_nonpremul__bgra_nonpremul_4x16le__src_over;
+ }
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul_4x16le__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ // TODO.
+ break;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__bgra_premul(
+ wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr_565__bgra_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__bgra_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__bgra_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__copy_4_4;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__rgba_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ if (wuffs_base__cpu_arch__have_x86_sse42()) {
+ return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42;
+ }
+#endif
+ return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
+ }
+ return NULL;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__bgrx(wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ return wuffs_base__pixel_swizzler__bgr_565__bgrx;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ return wuffs_base__pixel_swizzler__xxx__xxxx;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ return wuffs_base__pixel_swizzler__bgrw__bgrx;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ return wuffs_base__pixel_swizzler__bgrw_4x16le__bgrx;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ return wuffs_base__pixel_swizzler__copy_4_4;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ return wuffs_base__pixel_swizzler__bgr__rgbx;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ return wuffs_base__pixel_swizzler__bgrw__rgbx;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__rgb(wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ return wuffs_base__pixel_swizzler__bgr_565__rgb;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ return wuffs_base__pixel_swizzler__swap_rgb_bgr;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ if (wuffs_base__cpu_arch__have_x86_sse42()) {
+ return wuffs_base__pixel_swizzler__bgrw__rgb__x86_sse42;
+ }
+#endif
+ return wuffs_base__pixel_swizzler__bgrw__rgb;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ return wuffs_base__pixel_swizzler__bgrw_4x16le__rgb;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ return wuffs_base__pixel_swizzler__copy_3_3;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ return wuffs_base__pixel_swizzler__bgrw__bgr;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
+ wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr_565__rgba_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__rgba_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ if (wuffs_base__cpu_arch__have_x86_sse42()) {
+ return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42;
+ }
+#endif
+ return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__rgba_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ // TODO.
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__copy_4_4;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__bgra_nonpremul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ // TODO.
+ break;
+ }
+ return NULL;
+}
+
+static wuffs_base__pixel_swizzler__func //
+wuffs_base__pixel_swizzler__prepare__rgba_premul(
+ wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ switch (dst_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr_565__rgba_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__rgba_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__rgba_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__rgba_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul_4x16le__rgba_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ if (wuffs_base__cpu_arch__have_x86_sse42()) {
+ return wuffs_base__pixel_swizzler__swap_rgbx_bgrx__x86_sse42;
+ }
+#endif
+ return wuffs_base__pixel_swizzler__swap_rgbx_bgrx;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__rgba_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgr__bgra_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgr__bgra_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_nonpremul__bgra_premul__src_over;
+ }
+ return NULL;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ return wuffs_base__pixel_swizzler__copy_4_4;
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ return wuffs_base__pixel_swizzler__bgra_premul__bgra_premul__src_over;
+ }
+ return NULL;
+ }
+ return NULL;
+}
+
+// --------
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__pixel_swizzler__prepare(wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_format dst_pixfmt,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__pixel_format src_pixfmt,
+ wuffs_base__slice_u8 src_palette,
+ wuffs_base__pixel_blend blend) {
+ if (!p) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ p->private_impl.func = NULL;
+ p->private_impl.transparent_black_func = NULL;
+ p->private_impl.dst_pixfmt_bytes_per_pixel = 0;
+ p->private_impl.src_pixfmt_bytes_per_pixel = 0;
+
+ wuffs_base__pixel_swizzler__func func = NULL;
+ wuffs_base__pixel_swizzler__transparent_black_func transparent_black_func =
+ NULL;
+
+ uint32_t dst_pixfmt_bits_per_pixel =
+ wuffs_base__pixel_format__bits_per_pixel(&dst_pixfmt);
+ if ((dst_pixfmt_bits_per_pixel == 0) ||
+ ((dst_pixfmt_bits_per_pixel & 7) != 0)) {
+ return wuffs_base__make_status(
+ wuffs_base__error__unsupported_pixel_swizzler_option);
+ }
+
+ uint32_t src_pixfmt_bits_per_pixel =
+ wuffs_base__pixel_format__bits_per_pixel(&src_pixfmt);
+ if ((src_pixfmt_bits_per_pixel == 0) ||
+ ((src_pixfmt_bits_per_pixel & 7) != 0)) {
+ return wuffs_base__make_status(
+ wuffs_base__error__unsupported_pixel_swizzler_option);
+ }
+
+ // TODO: support many more formats.
+
+ switch (blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ transparent_black_func =
+ wuffs_base__pixel_swizzler__transparent_black_src;
+ break;
+
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ transparent_black_func =
+ wuffs_base__pixel_swizzler__transparent_black_src_over;
+ break;
+ }
+
+ switch (src_pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__Y:
+ func = wuffs_base__pixel_swizzler__prepare__y(p, dst_pixfmt, dst_palette,
+ src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
+ func = wuffs_base__pixel_swizzler__prepare__y_16be(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
+ func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_nonpremul(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
+ func = wuffs_base__pixel_swizzler__prepare__indexed__bgra_binary(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ func = wuffs_base__pixel_swizzler__prepare__bgr_565(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ func = wuffs_base__pixel_swizzler__prepare__bgr(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ func = wuffs_base__pixel_swizzler__prepare__bgra_nonpremul_4x16le(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ func = wuffs_base__pixel_swizzler__prepare__bgra_premul(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ func = wuffs_base__pixel_swizzler__prepare__bgrx(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ func = wuffs_base__pixel_swizzler__prepare__rgb(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ func = wuffs_base__pixel_swizzler__prepare__rgba_nonpremul(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ func = wuffs_base__pixel_swizzler__prepare__rgba_premul(
+ p, dst_pixfmt, dst_palette, src_palette, blend);
+ break;
+ }
+
+ p->private_impl.func = func;
+ p->private_impl.transparent_black_func = transparent_black_func;
+ p->private_impl.dst_pixfmt_bytes_per_pixel = dst_pixfmt_bits_per_pixel / 8;
+ p->private_impl.src_pixfmt_bytes_per_pixel = src_pixfmt_bits_per_pixel / 8;
+ return wuffs_base__make_status(
+ func ? NULL : wuffs_base__error__unsupported_pixel_swizzler_option);
+}
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
+ const wuffs_base__pixel_swizzler* p,
+ uint32_t up_to_num_pixels,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r) {
+ if (p && p->private_impl.func) {
+ const uint8_t* iop_r = *ptr_iop_r;
+ uint64_t src_len = wuffs_base__u64__min(
+ ((uint64_t)up_to_num_pixels) *
+ ((uint64_t)p->private_impl.src_pixfmt_bytes_per_pixel),
+ ((uint64_t)(io2_r - iop_r)));
+ uint64_t n =
+ (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
+ dst_palette.len, iop_r, (size_t)src_len);
+ *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
+ return n;
+ }
+ return 0;
+}
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
+ const wuffs_base__pixel_swizzler* p,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ const uint8_t** ptr_iop_r,
+ const uint8_t* io2_r) {
+ if (p && p->private_impl.func) {
+ const uint8_t* iop_r = *ptr_iop_r;
+ uint64_t src_len = ((uint64_t)(io2_r - iop_r));
+ uint64_t n =
+ (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
+ dst_palette.len, iop_r, (size_t)src_len);
+ *ptr_iop_r += n * p->private_impl.src_pixfmt_bytes_per_pixel;
+ return n;
+ }
+ return 0;
+}
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(
+ const wuffs_base__pixel_swizzler* p,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ wuffs_base__slice_u8 src) {
+ if (p && p->private_impl.func) {
+ return (*p->private_impl.func)(dst.ptr, dst.len, dst_palette.ptr,
+ dst_palette.len, src.ptr, src.len);
+ }
+ return 0;
+}
+
+WUFFS_BASE__MAYBE_STATIC uint64_t //
+wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(
+ const wuffs_base__pixel_swizzler* p,
+ wuffs_base__slice_u8 dst,
+ wuffs_base__slice_u8 dst_palette,
+ uint64_t num_pixels) {
+ if (p && p->private_impl.transparent_black_func) {
+ return (*p->private_impl.transparent_black_func)(
+ dst.ptr, dst.len, dst_palette.ptr, dst_palette.len, num_pixels,
+ p->private_impl.dst_pixfmt_bytes_per_pixel);
+ }
+ return 0;
+}
+
+// --------
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2);
+
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2);
+
+#if defined(__GNUC__) && !defined(__clang__)
+// No-op.
+#else
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor,
+ size_t src_len,
+ uint32_t h1v2_bias_ignored,
+ bool first_column,
+ bool last_column);
+#endif
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64)
+
+// --------
+
+static inline uint32_t //
+wuffs_base__u32__max_of_4(uint32_t a, uint32_t b, uint32_t c, uint32_t d) {
+ return wuffs_base__u32__max( //
+ wuffs_base__u32__max(a, b), //
+ wuffs_base__u32__max(c, d));
+}
+
+static inline uint32_t //
+wuffs_base__u32__min_of_5(uint32_t a,
+ uint32_t b,
+ uint32_t c,
+ uint32_t d,
+ uint32_t e) {
+ return wuffs_base__u32__min( //
+ wuffs_base__u32__min( //
+ wuffs_base__u32__min(a, b), //
+ wuffs_base__u32__min(c, d)), //
+ e);
+}
+
+// --------
+
+typedef void (*wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func)(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2,
+ const uint8_t* up3);
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_cmyk__convert_4_general(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2,
+ const uint8_t* up3) {
+ for (; x < x_end; x++) {
+ // It's called CMYK but, but for Adobe CMYK JPEG images in practice, it's
+ // RGBW: 0xFFu means no ink instead of full ink. Note that a double
+ // inversion is a no-op, so inversions might be implicit in the code below.
+ uint32_t r = ((uint32_t)(*up0++));
+ uint32_t g = ((uint32_t)(*up1++));
+ uint32_t b = ((uint32_t)(*up2++));
+ uint32_t w = ((uint32_t)(*up3++));
+ r = ((r * w) + 0x7Fu) / 0xFFu;
+ g = ((g * w) + 0x7Fu) / 0xFFu;
+ b = ((b * w) + 0x7Fu) / 0xFFu;
+ wuffs_base__pixel_buffer__set_color_u32_at(
+ dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u));
+ }
+}
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycck__convert_4_general(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2,
+ const uint8_t* up3) {
+ for (; x < x_end; x++) {
+ // We invert once again: 0xFFu means no ink instead of full ink.
+ uint32_t color = //
+ wuffs_base__color_ycc__as__color_u32( //
+ *up0++, *up1++, *up2++);
+ uint32_t r = 0xFFu - (0xFFu & (color >> 16u));
+ uint32_t g = 0xFFu - (0xFFu & (color >> 8u));
+ uint32_t b = 0xFFu - (0xFFu & (color >> 0u));
+ uint32_t w = ((uint32_t)(*up3++));
+ r = ((r * w) + 0x7Fu) / 0xFFu;
+ g = ((g * w) + 0x7Fu) / 0xFFu;
+ b = ((b * w) + 0x7Fu) / 0xFFu;
+ wuffs_base__pixel_buffer__set_color_u32_at(
+ dst, x, y, 0xFF000000u | (r << 16u) | (g << 8u) | (b << 0u));
+ }
+}
+
+// --------
+
+typedef void (*wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func)(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2);
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_rgb__convert_3_general(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2) {
+ for (; x < x_end; x++) {
+ uint32_t color = 0xFF000000u | //
+ (((uint32_t)(*up0++)) << 16u) | //
+ (((uint32_t)(*up1++)) << 8u) | //
+ (((uint32_t)(*up2++)) << 0u);
+ wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
+ }
+}
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_general(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2) {
+ for (; x < x_end; x++) {
+ uint32_t color = //
+ wuffs_base__color_ycc__as__color_u32( //
+ *up0++, *up1++, *up2++);
+ wuffs_base__pixel_buffer__set_color_u32_at(dst, x, y, color);
+ }
+}
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2) {
+ size_t dst_stride = dst->private_impl.planes[0].stride;
+ uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
+ (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
+
+ for (; x < x_end; x++) {
+ uint32_t color = //
+ wuffs_base__color_ycc__as__color_u32( //
+ *up0++, *up1++, *up2++);
+ wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
+ dst_iter += 4u;
+ }
+}
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2) {
+ size_t dst_stride = dst->private_impl.planes[0].stride;
+ uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
+ (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
+
+ for (; x < x_end; x++) {
+ uint32_t color = //
+ wuffs_base__color_ycc__as__color_u32_abgr( //
+ *up0++, *up1++, *up2++);
+ wuffs_base__poke_u32le__no_bounds_check(dst_iter, color);
+ dst_iter += 4u;
+ }
+}
+
+// --------
+
+// wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upsamples to a
+// destination slice at least 480 (YCCK) or 672 (YCC) bytes long and whose
+// src_len (multiplied by 1, 2, 3 or 4) is positive but no more than that. This
+// 480 or 672 length is just under 1/4 or 1/3 of the scratch_buffer_2k slice
+// length. Both (480 * 4) = 1920 and (672 * 3) = 2016 are less than 2048.
+//
+// 480 and 672 are nice round numbers because a JPEG MCU is 1, 2, 3 or 4 blocks
+// wide and each block is 8 pixels wide. We have:
+// 480 = 1 * 8 * 60, 672 = 1 * 8 * 84
+// 480 = 2 * 8 * 30, 672 = 2 * 8 * 42
+// 480 = 3 * 8 * 20, 672 = 3 * 8 * 28
+// 480 = 4 * 8 * 15, 672 = 4 * 8 * 21
+//
+// Box filters are equivalent to nearest neighbor upsampling. These ignore the
+// src_ptr_minor, h1v2_bias, first_column and last_column arguments.
+//
+// Triangle filters use a 3:1 ratio (in 1 dimension), or 9:3:3:1 (in 2
+// dimensions), which is higher quality (less blocky) but also higher
+// computational effort.
+//
+// In theory, we could use triangle filters for any (inv_h, inv_v) combination.
+// In practice, matching libjpeg-turbo, we only implement it for the common
+// chroma subsampling ratios (YCC420, YCC422 or YCC440), corresponding to an
+// (inv_h, inv_v) pair of (2, 2), (2, 1) or (1, 2).
+typedef const uint8_t* (
+ *wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func)(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major, // Nearest row.
+ const uint8_t* src_ptr_minor, // Adjacent row, alternating above or below.
+ size_t src_len,
+ uint32_t h1v2_bias,
+ bool first_column,
+ bool last_column);
+
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor_ignored,
+ size_t src_len,
+ uint32_t h1v2_bias_ignored,
+ bool first_column_ignored,
+ bool last_column_ignored) {
+ return src_ptr_major;
+}
+
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor_ignored,
+ size_t src_len,
+ uint32_t h1v2_bias_ignored,
+ bool first_column_ignored,
+ bool last_column_ignored) {
+ uint8_t* dp = dst_ptr;
+ const uint8_t* sp = src_ptr_major;
+ while (src_len--) {
+ uint8_t sv = *sp++;
+ *dp++ = sv;
+ *dp++ = sv;
+ }
+ return dst_ptr;
+}
+
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor_ignored,
+ size_t src_len,
+ uint32_t h1v2_bias_ignored,
+ bool first_column_ignored,
+ bool last_column_ignored) {
+ uint8_t* dp = dst_ptr;
+ const uint8_t* sp = src_ptr_major;
+ while (src_len--) {
+ uint8_t sv = *sp++;
+ *dp++ = sv;
+ *dp++ = sv;
+ *dp++ = sv;
+ }
+ return dst_ptr;
+}
+
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor_ignored,
+ size_t src_len,
+ uint32_t h1v2_bias_ignored,
+ bool first_column_ignored,
+ bool last_column_ignored) {
+ uint8_t* dp = dst_ptr;
+ const uint8_t* sp = src_ptr_major;
+ while (src_len--) {
+ uint8_t sv = *sp++;
+ *dp++ = sv;
+ *dp++ = sv;
+ *dp++ = sv;
+ *dp++ = sv;
+ }
+ return dst_ptr;
+}
+
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1v2_triangle(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor,
+ size_t src_len,
+ uint32_t h1v2_bias,
+ bool first_column,
+ bool last_column) {
+ uint8_t* dp = dst_ptr;
+ const uint8_t* sp_major = src_ptr_major;
+ const uint8_t* sp_minor = src_ptr_minor;
+ while (src_len--) {
+ *dp++ = (uint8_t)(((3u * ((uint32_t)(*sp_major++))) + //
+ (1u * ((uint32_t)(*sp_minor++))) + //
+ h1v2_bias) >>
+ 2u);
+ }
+ return dst_ptr;
+}
+
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v1_triangle(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor,
+ size_t src_len,
+ uint32_t h1v2_bias_ignored,
+ bool first_column,
+ bool last_column) {
+ uint8_t* dp = dst_ptr;
+ const uint8_t* sp = src_ptr_major;
+
+ if (first_column) {
+ src_len--;
+ if ((src_len <= 0u) && last_column) {
+ uint8_t sv = *sp++;
+ *dp++ = sv;
+ *dp++ = sv;
+ return dst_ptr;
+ }
+ uint32_t svp1 = sp[+1];
+ uint8_t sv = *sp++;
+ *dp++ = sv;
+ *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svp1 + 2u) >> 2u);
+ if (src_len <= 0u) {
+ return dst_ptr;
+ }
+ }
+
+ if (last_column) {
+ src_len--;
+ }
+
+ for (; src_len > 0u; src_len--) {
+ uint32_t svm1 = sp[-1];
+ uint32_t svp1 = sp[+1];
+ uint32_t sv3 = 3u * (uint32_t)(*sp++);
+ *dp++ = (uint8_t)((sv3 + svm1 + 1u) >> 2u);
+ *dp++ = (uint8_t)((sv3 + svp1 + 2u) >> 2u);
+ }
+
+ if (last_column) {
+ uint32_t svm1 = sp[-1];
+ uint8_t sv = *sp++;
+ *dp++ = (uint8_t)(((3u * (uint32_t)sv) + svm1 + 1u) >> 2u);
+ *dp++ = sv;
+ }
+
+ return dst_ptr;
+}
+
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor,
+ size_t src_len,
+ uint32_t h1v2_bias_ignored,
+ bool first_column,
+ bool last_column) {
+ uint8_t* dp = dst_ptr;
+ const uint8_t* sp_major = src_ptr_major;
+ const uint8_t* sp_minor = src_ptr_minor;
+
+ if (first_column) {
+ src_len--;
+ if ((src_len <= 0u) && last_column) {
+ uint32_t sv = (12u * ((uint32_t)(*sp_major++))) + //
+ (4u * ((uint32_t)(*sp_minor++)));
+ *dp++ = (uint8_t)((sv + 8u) >> 4u);
+ *dp++ = (uint8_t)((sv + 7u) >> 4u);
+ return dst_ptr;
+ }
+
+ uint32_t sv_major_m1 = sp_major[-0]; // Clamp offset to zero.
+ uint32_t sv_minor_m1 = sp_minor[-0]; // Clamp offset to zero.
+ uint32_t sv_major_p1 = sp_major[+1];
+ uint32_t sv_minor_p1 = sp_minor[+1];
+
+ uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
+ (3u * ((uint32_t)(*sp_minor++)));
+ *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
+ *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
+ if (src_len <= 0u) {
+ return dst_ptr;
+ }
+ }
+
+ if (last_column) {
+ src_len--;
+ }
+
+ for (; src_len > 0u; src_len--) {
+ uint32_t sv_major_m1 = sp_major[-1];
+ uint32_t sv_minor_m1 = sp_minor[-1];
+ uint32_t sv_major_p1 = sp_major[+1];
+ uint32_t sv_minor_p1 = sp_minor[+1];
+
+ uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
+ (3u * ((uint32_t)(*sp_minor++)));
+ *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
+ *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
+ }
+
+ if (last_column) {
+ uint32_t sv_major_m1 = sp_major[-1];
+ uint32_t sv_minor_m1 = sp_minor[-1];
+ uint32_t sv_major_p1 = sp_major[+0]; // Clamp offset to zero.
+ uint32_t sv_minor_p1 = sp_minor[+0]; // Clamp offset to zero.
+
+ uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
+ (3u * ((uint32_t)(*sp_minor++)));
+ *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
+ *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
+ }
+
+ return dst_ptr;
+}
+
+// wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs is indexed by inv_h
+// and then inv_v.
+static const wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs[4][4] = {
+ {
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1vn_box,
+ },
+ {
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2vn_box,
+ },
+ {
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h3vn_box,
+ },
+ {
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h4vn_box,
+ },
+};
+
+static inline uint32_t //
+wuffs_base__pixel_swizzler__has_triangle_upsampler(uint32_t inv_h,
+ uint32_t inv_v) {
+ if (inv_h == 1u) {
+ return inv_v == 2u;
+ } else if (inv_h == 2u) {
+ return (inv_v == 1u) || (inv_v == 2u);
+ }
+ return false;
+}
+
+// --------
+
+// All of the wuffs_base__pixel_swizzler__swizzle_ycc__etc functions have
+// preconditions. See all of the checks made in
+// wuffs_base__pixel_swizzler__swizzle_ycck before calling these functions. For
+// example, (width > 0) is a precondition, but there are many more.
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t width,
+ uint32_t y,
+ const uint8_t* src_ptr0,
+ const uint8_t* src_ptr1,
+ const uint8_t* src_ptr2,
+ const uint8_t* src_ptr3,
+ uint32_t stride0,
+ uint32_t stride1,
+ uint32_t stride2,
+ uint32_t stride3,
+ uint32_t inv_h0,
+ uint32_t inv_h1,
+ uint32_t inv_h2,
+ uint32_t inv_h3,
+ uint32_t inv_v0,
+ uint32_t inv_v1,
+ uint32_t inv_v2,
+ uint32_t inv_v3,
+ uint32_t half_width_for_2to1,
+ uint32_t h1v2_bias,
+ uint8_t* scratch_buffer_2k_ptr,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc3,
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func) {
+ const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
+ const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
+ const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
+ const uint8_t* src3 = src_ptr3 + ((y / inv_v3) * (size_t)stride3);
+ uint32_t total_src_len0 = 0u;
+ uint32_t total_src_len1 = 0u;
+ uint32_t total_src_len2 = 0u;
+ uint32_t total_src_len3 = 0u;
+
+ uint32_t x = 0u;
+ while (x < width) {
+ bool first_column = x == 0u;
+ uint32_t end = x + 480u;
+ if (end > width) {
+ end = width;
+ }
+
+ uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
+ uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
+ uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
+ uint32_t src_len3 = ((end - x) + inv_h3 - 1u) / inv_h3;
+ total_src_len0 += src_len0;
+ total_src_len1 += src_len1;
+ total_src_len2 += src_len2;
+ total_src_len3 += src_len3;
+
+ const uint8_t* src_ptr_x0 = src0 + (x / inv_h0);
+ const uint8_t* up0 = (*upfunc0)( //
+ scratch_buffer_2k_ptr + (0u * 480u), //
+ src_ptr_x0, //
+ src_ptr_x0, //
+ src_len0, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len0 >= half_width_for_2to1));
+
+ const uint8_t* src_ptr_x1 = src1 + (x / inv_h1);
+ const uint8_t* up1 = (*upfunc1)( //
+ scratch_buffer_2k_ptr + (1u * 480u), //
+ src_ptr_x1, //
+ src_ptr_x1, //
+ src_len1, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len1 >= half_width_for_2to1));
+
+ const uint8_t* src_ptr_x2 = src2 + (x / inv_h2);
+ const uint8_t* up2 = (*upfunc2)( //
+ scratch_buffer_2k_ptr + (2u * 480u), //
+ src_ptr_x2, //
+ src_ptr_x2, //
+ src_len2, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len2 >= half_width_for_2to1));
+
+ const uint8_t* src_ptr_x3 = src3 + (x / inv_h3);
+ const uint8_t* up3 = (*upfunc3)( //
+ scratch_buffer_2k_ptr + (3u * 480u), //
+ src_ptr_x3, //
+ src_ptr_x3, //
+ src_len3, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len3 >= half_width_for_2to1));
+
+ (*conv4func)(dst, x, end, y, up0, up1, up2, up3);
+ x = end;
+ }
+}
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t width,
+ uint32_t height,
+ const uint8_t* src_ptr0,
+ const uint8_t* src_ptr1,
+ const uint8_t* src_ptr2,
+ const uint8_t* src_ptr3,
+ uint32_t stride0,
+ uint32_t stride1,
+ uint32_t stride2,
+ uint32_t stride3,
+ uint32_t inv_h0,
+ uint32_t inv_h1,
+ uint32_t inv_h2,
+ uint32_t inv_h3,
+ uint32_t inv_v0,
+ uint32_t inv_v1,
+ uint32_t inv_v2,
+ uint32_t inv_v3,
+ uint32_t half_width_for_2to1,
+ uint32_t half_height_for_2to1,
+ uint8_t* scratch_buffer_2k_ptr,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4],
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func) {
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 =
+ (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 =
+ (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 =
+ (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc3 =
+ (*upfuncs)[(inv_h3 - 1u) & 3u][(inv_v3 - 1u) & 3u];
+
+ // First row.
+ uint32_t h1v2_bias = 1u;
+ wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row(
+ dst, width, 0u, //
+ src_ptr0, src_ptr1, src_ptr2, src_ptr3, //
+ stride0, stride1, stride2, stride3, //
+ inv_h0, inv_h1, inv_h2, inv_h3, //
+ inv_v0, inv_v1, inv_v2, inv_v3, //
+ half_width_for_2to1, //
+ h1v2_bias, //
+ scratch_buffer_2k_ptr, //
+ upfunc0, upfunc1, upfunc2, upfunc3, conv4func);
+ h1v2_bias = 2u;
+
+ // Middle rows.
+ bool last_row = height == 2u * half_height_for_2to1;
+ uint32_t y_max_excl = last_row ? (height - 1u) : height;
+ uint32_t y;
+ for (y = 1u; y < y_max_excl; y++) {
+ const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
+ const uint8_t* src0_minor =
+ (inv_v0 != 2u)
+ ? src0_major
+ : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0));
+ const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
+ const uint8_t* src1_minor =
+ (inv_v1 != 2u)
+ ? src1_major
+ : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1));
+ const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
+ const uint8_t* src2_minor =
+ (inv_v2 != 2u)
+ ? src2_major
+ : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2));
+ const uint8_t* src3_major = src_ptr3 + ((y / inv_v3) * (size_t)stride3);
+ const uint8_t* src3_minor =
+ (inv_v3 != 2u)
+ ? src3_major
+ : ((y & 1u) ? (src3_major + stride3) : (src3_major - stride3));
+ uint32_t total_src_len0 = 0u;
+ uint32_t total_src_len1 = 0u;
+ uint32_t total_src_len2 = 0u;
+ uint32_t total_src_len3 = 0u;
+
+ uint32_t x = 0u;
+ while (x < width) {
+ bool first_column = x == 0u;
+ uint32_t end = x + 480u;
+ if (end > width) {
+ end = width;
+ }
+
+ uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
+ uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
+ uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
+ uint32_t src_len3 = ((end - x) + inv_h3 - 1u) / inv_h3;
+ total_src_len0 += src_len0;
+ total_src_len1 += src_len1;
+ total_src_len2 += src_len2;
+ total_src_len3 += src_len3;
+
+ const uint8_t* up0 = (*upfunc0)( //
+ scratch_buffer_2k_ptr + (0u * 480u), //
+ src0_major + (x / inv_h0), //
+ src0_minor + (x / inv_h0), //
+ src_len0, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len0 >= half_width_for_2to1));
+
+ const uint8_t* up1 = (*upfunc1)( //
+ scratch_buffer_2k_ptr + (1u * 480u), //
+ src1_major + (x / inv_h1), //
+ src1_minor + (x / inv_h1), //
+ src_len1, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len1 >= half_width_for_2to1));
+
+ const uint8_t* up2 = (*upfunc2)( //
+ scratch_buffer_2k_ptr + (2u * 480u), //
+ src2_major + (x / inv_h2), //
+ src2_minor + (x / inv_h2), //
+ src_len2, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len2 >= half_width_for_2to1));
+
+ const uint8_t* up3 = (*upfunc3)( //
+ scratch_buffer_2k_ptr + (3u * 480u), //
+ src3_major + (x / inv_h3), //
+ src3_minor + (x / inv_h3), //
+ src_len3, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len3 >= half_width_for_2to1));
+
+ (*conv4func)(dst, x, end, y, up0, up1, up2, up3);
+ x = end;
+ }
+
+ h1v2_bias ^= 3u;
+ }
+
+ // Last row.
+ if (y_max_excl != height) {
+ wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter_edge_row(
+ dst, width, height - 1u, //
+ src_ptr0, src_ptr1, src_ptr2, src_ptr3, //
+ stride0, stride1, stride2, stride3, //
+ inv_h0, inv_h1, inv_h2, inv_h3, //
+ inv_v0, inv_v1, inv_v2, inv_v3, //
+ half_width_for_2to1, //
+ h1v2_bias, //
+ scratch_buffer_2k_ptr, //
+ upfunc0, upfunc1, upfunc2, upfunc3, conv4func);
+ }
+}
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t width,
+ uint32_t y,
+ const uint8_t* src_ptr0,
+ const uint8_t* src_ptr1,
+ const uint8_t* src_ptr2,
+ uint32_t stride0,
+ uint32_t stride1,
+ uint32_t stride2,
+ uint32_t inv_h0,
+ uint32_t inv_h1,
+ uint32_t inv_h2,
+ uint32_t inv_v0,
+ uint32_t inv_v1,
+ uint32_t inv_v2,
+ uint32_t half_width_for_2to1,
+ uint32_t h1v2_bias,
+ uint8_t* scratch_buffer_2k_ptr,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2,
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) {
+ const uint8_t* src0 = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
+ const uint8_t* src1 = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
+ const uint8_t* src2 = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
+ uint32_t total_src_len0 = 0u;
+ uint32_t total_src_len1 = 0u;
+ uint32_t total_src_len2 = 0u;
+
+ uint32_t x = 0u;
+ while (x < width) {
+ bool first_column = x == 0u;
+ uint32_t end = x + 672u;
+ if (end > width) {
+ end = width;
+ }
+
+ uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
+ uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
+ uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
+ total_src_len0 += src_len0;
+ total_src_len1 += src_len1;
+ total_src_len2 += src_len2;
+
+ const uint8_t* src_ptr_x0 = src0 + (x / inv_h0);
+ const uint8_t* up0 = (*upfunc0)( //
+ scratch_buffer_2k_ptr + (0u * 672u), //
+ src_ptr_x0, //
+ src_ptr_x0, //
+ src_len0, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len0 >= half_width_for_2to1));
+
+ const uint8_t* src_ptr_x1 = src1 + (x / inv_h1);
+ const uint8_t* up1 = (*upfunc1)( //
+ scratch_buffer_2k_ptr + (1u * 672u), //
+ src_ptr_x1, //
+ src_ptr_x1, //
+ src_len1, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len1 >= half_width_for_2to1));
+
+ const uint8_t* src_ptr_x2 = src2 + (x / inv_h2);
+ const uint8_t* up2 = (*upfunc2)( //
+ scratch_buffer_2k_ptr + (2u * 672u), //
+ src_ptr_x2, //
+ src_ptr_x2, //
+ src_len2, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len2 >= half_width_for_2to1));
+
+ (*conv3func)(dst, x, end, y, up0, up1, up2);
+ x = end;
+ }
+}
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t width,
+ uint32_t height,
+ const uint8_t* src_ptr0,
+ const uint8_t* src_ptr1,
+ const uint8_t* src_ptr2,
+ uint32_t stride0,
+ uint32_t stride1,
+ uint32_t stride2,
+ uint32_t inv_h0,
+ uint32_t inv_h1,
+ uint32_t inv_h2,
+ uint32_t inv_v0,
+ uint32_t inv_v1,
+ uint32_t inv_v2,
+ uint32_t half_width_for_2to1,
+ uint32_t half_height_for_2to1,
+ uint8_t* scratch_buffer_2k_ptr,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4],
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) {
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 =
+ (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 =
+ (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 =
+ (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
+
+ // First row.
+ uint32_t h1v2_bias = 1u;
+ wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row(
+ dst, width, 0u, //
+ src_ptr0, src_ptr1, src_ptr2, //
+ stride0, stride1, stride2, //
+ inv_h0, inv_h1, inv_h2, //
+ inv_v0, inv_v1, inv_v2, //
+ half_width_for_2to1, //
+ h1v2_bias, //
+ scratch_buffer_2k_ptr, //
+ upfunc0, upfunc1, upfunc2, conv3func);
+ h1v2_bias = 2u;
+
+ // Middle rows.
+ bool last_row = height == 2u * half_height_for_2to1;
+ uint32_t y_max_excl = last_row ? (height - 1u) : height;
+ uint32_t y;
+ for (y = 1u; y < y_max_excl; y++) {
+ const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
+ const uint8_t* src0_minor =
+ (inv_v0 != 2u)
+ ? src0_major
+ : ((y & 1u) ? (src0_major + stride0) : (src0_major - stride0));
+ const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
+ const uint8_t* src1_minor =
+ (inv_v1 != 2u)
+ ? src1_major
+ : ((y & 1u) ? (src1_major + stride1) : (src1_major - stride1));
+ const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
+ const uint8_t* src2_minor =
+ (inv_v2 != 2u)
+ ? src2_major
+ : ((y & 1u) ? (src2_major + stride2) : (src2_major - stride2));
+ uint32_t total_src_len0 = 0u;
+ uint32_t total_src_len1 = 0u;
+ uint32_t total_src_len2 = 0u;
+
+ uint32_t x = 0u;
+ while (x < width) {
+ bool first_column = x == 0u;
+ uint32_t end = x + 672u;
+ if (end > width) {
+ end = width;
+ }
+
+ uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
+ uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
+ uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
+ total_src_len0 += src_len0;
+ total_src_len1 += src_len1;
+ total_src_len2 += src_len2;
+
+ const uint8_t* up0 = (*upfunc0)( //
+ scratch_buffer_2k_ptr + (0u * 672u), //
+ src0_major + (x / inv_h0), //
+ src0_minor + (x / inv_h0), //
+ src_len0, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len0 >= half_width_for_2to1));
+
+ const uint8_t* up1 = (*upfunc1)( //
+ scratch_buffer_2k_ptr + (1u * 672u), //
+ src1_major + (x / inv_h1), //
+ src1_minor + (x / inv_h1), //
+ src_len1, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len1 >= half_width_for_2to1));
+
+ const uint8_t* up2 = (*upfunc2)( //
+ scratch_buffer_2k_ptr + (2u * 672u), //
+ src2_major + (x / inv_h2), //
+ src2_minor + (x / inv_h2), //
+ src_len2, //
+ h1v2_bias, //
+ first_column, //
+ (total_src_len2 >= half_width_for_2to1));
+
+ (*conv3func)(dst, x, end, y, up0, up1, up2);
+ x = end;
+ }
+
+ h1v2_bias ^= 3u;
+ }
+
+ // Last row.
+ if (y_max_excl != height) {
+ wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter_edge_row(
+ dst, width, height - 1u, //
+ src_ptr0, src_ptr1, src_ptr2, //
+ stride0, stride1, stride2, //
+ inv_h0, inv_h1, inv_h2, //
+ inv_v0, inv_v1, inv_v2, //
+ half_width_for_2to1, //
+ h1v2_bias, //
+ scratch_buffer_2k_ptr, //
+ upfunc0, upfunc1, upfunc2, conv3func);
+ }
+}
+
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__general__box_filter(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t width,
+ uint32_t height,
+ const uint8_t* src_ptr0,
+ const uint8_t* src_ptr1,
+ const uint8_t* src_ptr2,
+ uint32_t stride0,
+ uint32_t stride1,
+ uint32_t stride2,
+ uint32_t inv_h0,
+ uint32_t inv_h1,
+ uint32_t inv_h2,
+ uint32_t inv_v0,
+ uint32_t inv_v1,
+ uint32_t inv_v2,
+ uint32_t half_width_for_2to1,
+ uint32_t half_height_for_2to1,
+ uint8_t* scratch_buffer_2k_ptr,
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func (*upfuncs)[4][4],
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) {
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc0 =
+ (*upfuncs)[(inv_h0 - 1u) & 3u][(inv_v0 - 1u) & 3u];
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc1 =
+ (*upfuncs)[(inv_h1 - 1u) & 3u][(inv_v1 - 1u) & 3u];
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfunc2 =
+ (*upfuncs)[(inv_h2 - 1u) & 3u][(inv_v2 - 1u) & 3u];
+
+ uint32_t y;
+ for (y = 0u; y < height; y++) {
+ const uint8_t* src0_major = src_ptr0 + ((y / inv_v0) * (size_t)stride0);
+ const uint8_t* src1_major = src_ptr1 + ((y / inv_v1) * (size_t)stride1);
+ const uint8_t* src2_major = src_ptr2 + ((y / inv_v2) * (size_t)stride2);
+
+ uint32_t x = 0u;
+ while (x < width) {
+ uint32_t end = x + 672u;
+ if (end > width) {
+ end = width;
+ }
+
+ uint32_t src_len0 = ((end - x) + inv_h0 - 1u) / inv_h0;
+ uint32_t src_len1 = ((end - x) + inv_h1 - 1u) / inv_h1;
+ uint32_t src_len2 = ((end - x) + inv_h2 - 1u) / inv_h2;
+
+ const uint8_t* up0 = (*upfunc0)( //
+ scratch_buffer_2k_ptr + (0u * 672u), //
+ src0_major + (x / inv_h0), //
+ src0_major + (x / inv_h0), //
+ src_len0, //
+ 0u, false, false);
+
+ const uint8_t* up1 = (*upfunc1)( //
+ scratch_buffer_2k_ptr + (1u * 672u), //
+ src1_major + (x / inv_h1), //
+ src1_major + (x / inv_h1), //
+ src_len1, //
+ 0u, false, false);
+
+ const uint8_t* up2 = (*upfunc2)( //
+ scratch_buffer_2k_ptr + (2u * 672u), //
+ src2_major + (x / inv_h2), //
+ src2_major + (x / inv_h2), //
+ src_len2, //
+ 0u, false, false);
+
+ (*conv3func)(dst, x, end, y, up0, up1, up2);
+ x = end;
+ }
+ }
+}
+
+// --------
+
+// wuffs_base__pixel_swizzler__flattened_length is like
+// wuffs_base__table__flattened_length but returns uint64_t (not size_t) and
+// also accounts for subsampling.
+static uint64_t //
+wuffs_base__pixel_swizzler__flattened_length(uint32_t width,
+ uint32_t height,
+ uint32_t stride,
+ uint32_t inv_h,
+ uint32_t inv_v) {
+ uint64_t scaled_width = (((uint64_t)width) + (inv_h - 1u)) / inv_h;
+ uint64_t scaled_height = (((uint64_t)height) + (inv_v - 1u)) / inv_v;
+ if (scaled_height <= 0u) {
+ return 0u;
+ }
+ return ((scaled_height - 1u) * stride) + scaled_width;
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status //
+wuffs_base__pixel_swizzler__swizzle_ycck(
+ const wuffs_base__pixel_swizzler* p,
+ wuffs_base__pixel_buffer* dst,
+ wuffs_base__slice_u8 dst_palette,
+ uint32_t width,
+ uint32_t height,
+ wuffs_base__slice_u8 src0,
+ wuffs_base__slice_u8 src1,
+ wuffs_base__slice_u8 src2,
+ wuffs_base__slice_u8 src3,
+ uint32_t width0,
+ uint32_t width1,
+ uint32_t width2,
+ uint32_t width3,
+ uint32_t height0,
+ uint32_t height1,
+ uint32_t height2,
+ uint32_t height3,
+ uint32_t stride0,
+ uint32_t stride1,
+ uint32_t stride2,
+ uint32_t stride3,
+ uint8_t h0,
+ uint8_t h1,
+ uint8_t h2,
+ uint8_t h3,
+ uint8_t v0,
+ uint8_t v1,
+ uint8_t v2,
+ uint8_t v3,
+ bool is_rgb_or_cmyk,
+ bool triangle_filter_for_2to1,
+ wuffs_base__slice_u8 scratch_buffer_2k) {
+ if (!p) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ } else if (!dst || (width > 0xFFFFu) || (height > 0xFFFFu) || //
+ (4u <= ((unsigned int)h0 - 1u)) || //
+ (4u <= ((unsigned int)h1 - 1u)) || //
+ (4u <= ((unsigned int)h2 - 1u)) || //
+ (4u <= ((unsigned int)v0 - 1u)) || //
+ (4u <= ((unsigned int)v1 - 1u)) || //
+ (4u <= ((unsigned int)v2 - 1u)) || //
+ (scratch_buffer_2k.len < 2048u)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((h3 != 0u) || (v3 != 0u)) {
+ if ((4u <= ((unsigned int)h3 - 1u)) || //
+ (4u <= ((unsigned int)v3 - 1u))) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ }
+
+ uint32_t max_incl_h = wuffs_base__u32__max_of_4(h0, h1, h2, h3);
+ uint32_t max_incl_v = wuffs_base__u32__max_of_4(v0, v1, v2, v3);
+
+ // Calculate the inverse h and v ratios.
+ //
+ // It also canonicalizes (h=2 and max_incl_h=4) as equivalent to (h=1 and
+ // max_incl_h=2). In both cases, the inv_h value is 2.
+ uint32_t inv_h0 = max_incl_h / h0;
+ uint32_t inv_h1 = max_incl_h / h1;
+ uint32_t inv_h2 = max_incl_h / h2;
+ uint32_t inv_h3 = h3 ? (max_incl_h / h3) : 0u;
+ uint32_t inv_v0 = max_incl_v / v0;
+ uint32_t inv_v1 = max_incl_v / v1;
+ uint32_t inv_v2 = max_incl_v / v2;
+ uint32_t inv_v3 = v3 ? (max_incl_v / v3) : 0u;
+
+ uint32_t half_width_for_2to1 = (width + 1u) / 2u;
+ uint32_t half_height_for_2to1 = (height + 1u) / 2u;
+
+ width = wuffs_base__u32__min_of_5( //
+ width, //
+ width0 * inv_h0, //
+ width1 * inv_h1, //
+ width2 * inv_h2, //
+ wuffs_base__pixel_config__width(&dst->pixcfg));
+ height = wuffs_base__u32__min_of_5( //
+ height, //
+ height0 * inv_v0, //
+ height1 * inv_v1, //
+ height2 * inv_v2, //
+ wuffs_base__pixel_config__height(&dst->pixcfg));
+
+ if (((h0 * inv_h0) != max_incl_h) || //
+ ((h1 * inv_h1) != max_incl_h) || //
+ ((h2 * inv_h2) != max_incl_h) || //
+ ((v0 * inv_v0) != max_incl_v) || //
+ ((v1 * inv_v1) != max_incl_v) || //
+ ((v2 * inv_v2) != max_incl_v) || //
+ (src0.len < wuffs_base__pixel_swizzler__flattened_length(
+ width, height, stride0, inv_h0, inv_v0)) ||
+ (src1.len < wuffs_base__pixel_swizzler__flattened_length(
+ width, height, stride1, inv_h1, inv_v1)) ||
+ (src2.len < wuffs_base__pixel_swizzler__flattened_length(
+ width, height, stride2, inv_h2, inv_v2))) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((h3 != 0u) || (v3 != 0u)) {
+ if (((h3 * inv_h3) != max_incl_h) || //
+ ((v3 * inv_v3) != max_incl_v) || //
+ (src3.len < wuffs_base__pixel_swizzler__flattened_length(
+ width, height, stride3, inv_h3, inv_v3))) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ }
+
+ if (wuffs_base__pixel_format__is_planar(&dst->pixcfg.private_impl.pixfmt)) {
+ // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO.
+ return wuffs_base__make_status(
+ wuffs_base__error__unsupported_pixel_swizzler_option);
+ }
+
+ switch (dst->pixcfg.private_impl.pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__Y:
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__Y_16BE:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__INDEXED__BGRA_BINARY:
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+ break;
+
+ default:
+ // TODO: see wuffs_base__pixel_buffer__set_color_u32_at's TODO.
+ return wuffs_base__make_status(
+ wuffs_base__error__unsupported_pixel_swizzler_option);
+ }
+
+ if ((width <= 0u) || (height <= 0u)) {
+ return wuffs_base__make_status(NULL);
+ }
+
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func = NULL;
+
+ if (is_rgb_or_cmyk) {
+ conv3func = &wuffs_base__pixel_swizzler__swizzle_rgb__convert_3_general;
+ } else {
+ switch (dst->pixcfg.private_impl.pixfmt.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRX:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+ if (wuffs_base__cpu_arch__have_x86_avx2()) {
+ conv3func =
+ &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2;
+ break;
+ }
+#endif
+ conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx;
+ break;
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBX:
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+ if (wuffs_base__cpu_arch__have_x86_avx2()) {
+ conv3func =
+ &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2;
+ break;
+ }
+#endif
+ conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx;
+ break;
+ default:
+ conv3func = &wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_general;
+ break;
+ }
+ }
+
+ void (*func)(
+ wuffs_base__pixel_buffer * dst, //
+ uint32_t width, //
+ uint32_t height, //
+ const uint8_t* src_ptr0, //
+ const uint8_t* src_ptr1, //
+ const uint8_t* src_ptr2, //
+ uint32_t stride0, //
+ uint32_t stride1, //
+ uint32_t stride2, //
+ uint32_t inv_h0, //
+ uint32_t inv_h1, //
+ uint32_t inv_h2, //
+ uint32_t inv_v0, //
+ uint32_t inv_v1, //
+ uint32_t inv_v2, //
+ uint32_t half_width_for_2to1, //
+ uint32_t half_height_for_2to1, //
+ uint8_t* scratch_buffer_2k_ptr, //
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func(*upfuncs)[4][4],
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_func conv3func) =
+ &wuffs_base__pixel_swizzler__swizzle_ycc__general__box_filter;
+
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_func upfuncs[4][4];
+ memcpy(&upfuncs, &wuffs_base__pixel_swizzler__swizzle_ycc__upsample_funcs,
+ sizeof upfuncs);
+
+ if (triangle_filter_for_2to1 &&
+ (wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h0, inv_v0) ||
+ wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h1, inv_v1) ||
+ wuffs_base__pixel_swizzler__has_triangle_upsampler(inv_h2, inv_v2))) {
+ func = &wuffs_base__pixel_swizzler__swizzle_ycc__general__triangle_filter;
+
+ upfuncs[0][1] =
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h1v2_triangle;
+ upfuncs[1][0] =
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v1_triangle;
+ upfuncs[1][1] =
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle;
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+#if defined(__GNUC__) && !defined(__clang__)
+ // Don't use our AVX2 implementation for GCC (but do use it for clang). For
+ // some unknown reason, GCC performs noticably better on the non-SIMD
+ // version. Possibly because GCC's auto-vectorizer is smarter (just with
+ // SSE2, not AVX2) than our hand-written code, but that's just a guess.
+ //
+ // See commits 51bc60ef9298cb2efc1b29a9681191f66d49820d and
+ // cd769a0cdf1b5affee13f6089b995f3d39569cb4 for benchmark numbers.
+ //
+ // See also https://godbolt.org/z/MbhbPGEz4 for Debian Bullseye's clang 11
+ // versus gcc 10, where only gcc auto-vectorizes, although later clang
+ // versions will also auto-vectorize.
+#else
+ if (wuffs_base__cpu_arch__have_x86_avx2()) {
+ upfuncs[1][1] =
+ wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2;
+ }
+#endif
+#endif
+ }
+
+ if ((h3 != 0u) || (v3 != 0u)) {
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_4_func conv4func =
+ is_rgb_or_cmyk
+ ? &wuffs_base__pixel_swizzler__swizzle_cmyk__convert_4_general
+ : &wuffs_base__pixel_swizzler__swizzle_ycck__convert_4_general;
+ wuffs_base__pixel_swizzler__swizzle_ycck__general__triangle_filter( //
+ dst, width, height, //
+ src0.ptr, src1.ptr, src2.ptr, src3.ptr, //
+ stride0, stride1, stride2, stride3, //
+ inv_h0, inv_h1, inv_h2, inv_h3, //
+ inv_v0, inv_v1, inv_v2, inv_v3, //
+ half_width_for_2to1, half_height_for_2to1, //
+ scratch_buffer_2k.ptr, &upfuncs, conv4func);
+
+ } else {
+ (*func)( //
+ dst, width, height, //
+ src0.ptr, src1.ptr, src2.ptr, //
+ stride0, stride1, stride2, //
+ inv_h0, inv_h1, inv_h2, //
+ inv_v0, inv_v1, inv_v2, //
+ half_width_for_2to1, half_height_for_2to1, //
+ scratch_buffer_2k.ptr, &upfuncs, conv3func);
+ }
+
+ return wuffs_base__make_status(NULL);
+}
+
+// --------
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_avx2
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx_x86_avx2(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2) {
+ if ((x + 32u) > x_end) {
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx( //
+ dst, x, x_end, y, up0, up1, up2);
+ return;
+ }
+
+ size_t dst_stride = dst->private_impl.planes[0].stride;
+ uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
+ (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
+
+ // u0001 = u16x16 [0x0001 .. 0x0001]
+ // u00FF = u16x16 [0x00FF .. 0x00FF]
+ // uFF80 = u16x16 [0xFF80 .. 0xFF80]
+ // uFFFF = u16x16 [0xFFFF .. 0xFFFF]
+ const __m256i u0001 = _mm256_set1_epi16(+0x0001);
+ const __m256i u00FF = _mm256_set1_epi16(+0x00FF);
+ const __m256i uFF80 = _mm256_set1_epi16(-0x0080);
+ const __m256i uFFFF = _mm256_set1_epi16(-0x0001);
+
+ // p8000_p0000 = u16x16 [0x8000 0x0000 .. 0x8000 0x0000]
+ const __m256i p8000_p0000 = _mm256_set_epi16( //
+ +0x0000, -0x8000, +0x0000, -0x8000, //
+ +0x0000, -0x8000, +0x0000, -0x8000, //
+ +0x0000, -0x8000, +0x0000, -0x8000, //
+ +0x0000, -0x8000, +0x0000, -0x8000);
+
+ // Per wuffs_base__color_ycc__as__color_u32, the formulae:
+ //
+ // R = Y + 1.40200 * Cr
+ // G = Y - 0.34414 * Cb - 0.71414 * Cr
+ // B = Y + 1.77200 * Cb
+ //
+ // When scaled by 1<<16:
+ //
+ // 0.34414 becomes 0x0581A = 22554.
+ // 0.71414 becomes 0x0B6D2 = 46802.
+ // 1.40200 becomes 0x166E9 = 91881.
+ // 1.77200 becomes 0x1C5A2 = 116130.
+ //
+ // Separate the integer and fractional parts, since we work with signed
+ // 16-bit SIMD lanes. The fractional parts range from -0.5 .. +0.5 (as
+ // floating-point) which is from -0x8000 .. +0x8000 (as fixed-point).
+ //
+ // -0x3A5E = -0x20000 + 0x1C5A2 The B:Cb factor.
+ // +0x66E9 = -0x10000 + 0x166E9 The R:Cr factor.
+ // -0x581A = +0x00000 - 0x0581A The G:Cb factor.
+ // +0x492E = +0x10000 - 0x0B6D2 The G:Cr factor.
+ const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E);
+ const __m256i p66E9 = _mm256_set1_epi16(+0x66E9);
+ const __m256i m581A_p492E = _mm256_set_epi16( //
+ +0x492E, -0x581A, +0x492E, -0x581A, //
+ +0x492E, -0x581A, +0x492E, -0x581A, //
+ +0x492E, -0x581A, +0x492E, -0x581A, //
+ +0x492E, -0x581A, +0x492E, -0x581A);
+
+ while (x < x_end) {
+ // Load chroma values in even and odd columns (the high 8 bits of each
+ // u16x16 element are zero) and then subtract 0x0080.
+ //
+ // cb_all = u8x32 [cb.00 cb.01 cb.02 cb.03 .. cb.1C cb.1D cb.1E cb.1F]
+ // cb_eve = i16x16 [cb.00-0x80 cb.02-0x80 .. cb.1C-0x80 cb.1E-0x80 ]
+ // cb_odd = i16x16 [cb.01-0x80 cb.03-0x80 .. cb.1D-0x80 cb.1F-0x80 ]
+ //
+ // Ditto for the cr_xxx Chroma-Red values.
+ __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1);
+ __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2);
+ __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF));
+ __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF));
+ __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8));
+ __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8));
+
+ // ----
+
+ // Calculate:
+ //
+ // B-Y = (+1.77200 * Cb) as floating-point
+ // R-Y = (+1.40200 * Cr) as floating-point
+ //
+ // B-Y = ((0x2_0000 - 0x3A5E) * Cb) as fixed-point
+ // R-Y = ((0x1_0000 + 0x66E9) * Cr) as fixed-point
+ //
+ // B-Y = ((-0x3A5E * Cb) + ("2.0" * Cb))
+ // R-Y = ((+0x66E9 * Cr) + ("1.0" * Cr))
+
+ // Multiply by m3A5E or p66E9, taking the high 16 bits. There's also a
+ // doubling (add x to itself), adding-of-1 and halving (shift right by 1).
+ // That makes multiply-and-take-high round to nearest (instead of down).
+ __m256i tmp_by_eve = _mm256_srai_epi16(
+ _mm256_add_epi16(
+ _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001),
+ 1);
+ __m256i tmp_by_odd = _mm256_srai_epi16(
+ _mm256_add_epi16(
+ _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001),
+ 1);
+ __m256i tmp_ry_eve = _mm256_srai_epi16(
+ _mm256_add_epi16(
+ _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001),
+ 1);
+ __m256i tmp_ry_odd = _mm256_srai_epi16(
+ _mm256_add_epi16(
+ _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001),
+ 1);
+
+ // Add (2 * Cb) and (1 * Cr).
+ __m256i by_eve =
+ _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve));
+ __m256i by_odd =
+ _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd));
+ __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve);
+ __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd);
+
+ // ----
+
+ // Calculate:
+ //
+ // G-Y = (-0.34414 * Cb) +
+ // (-0.71414 * Cr) as floating-point
+ //
+ // G-Y = ((+0x0_0000 - 0x581A) * Cb) +
+ // ((-0x1_0000 + 0x492E) * Cr) as fixed-point
+ //
+ // G-Y = (-0x581A * Cb) +
+ // (+0x492E * Cr) - ("1.0" * Cr)
+
+ // Multiply-add to get ((-0x581A * Cb) + (+0x492E * Cr)).
+ __m256i tmp0_gy_eve_lo = _mm256_madd_epi16( //
+ _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E);
+ __m256i tmp0_gy_eve_hi = _mm256_madd_epi16( //
+ _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E);
+ __m256i tmp0_gy_odd_lo = _mm256_madd_epi16( //
+ _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E);
+ __m256i tmp0_gy_odd_hi = _mm256_madd_epi16( //
+ _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E);
+
+ // Divide the i32x8 vectors by (1 << 16), rounding to nearest.
+ __m256i tmp1_gy_eve_lo =
+ _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16);
+ __m256i tmp1_gy_eve_hi =
+ _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16);
+ __m256i tmp1_gy_odd_lo =
+ _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16);
+ __m256i tmp1_gy_odd_hi =
+ _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16);
+
+ // Pack the ((-0x581A * Cb) + (+0x492E * Cr)) as i16x16 and subtract Cr.
+ __m256i gy_eve = _mm256_sub_epi16(
+ _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve);
+ __m256i gy_odd = _mm256_sub_epi16(
+ _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd);
+
+ // ----
+
+ // Add Y to (B-Y), (G-Y) and (R-Y) to produce B, G and R.
+ //
+ // For the resultant packed_x_xxx vectors, only elements 0 ..= 7 and 16 ..=
+ // 23 of the 32-element vectors matter (since we'll unpacklo but not
+ // unpackhi them). Let … denote 8 ignored consecutive u8 values and let %
+ // denote 0xFF. We'll end this section with:
+ //
+ // packed_b_eve = u8x32 [b00 b02 .. b0C b0E … b10 b12 .. b1C b1E …]
+ // packed_b_odd = u8x32 [b01 b03 .. b0D b0F … b11 b13 .. b1D b1F …]
+ // packed_g_eve = u8x32 [g00 g02 .. g0C g0E … g10 g12 .. g1C g1E …]
+ // packed_g_odd = u8x32 [g01 g03 .. g0D g0F … g11 g13 .. g1D g1F …]
+ // packed_r_eve = u8x32 [r00 r02 .. r0C r0E … r10 r12 .. r1C r1E …]
+ // packed_r_odd = u8x32 [r01 r03 .. r0D r0F … r11 r13 .. r1D r1F …]
+ // uFFFF = u8x32 [ % % .. % % … % % .. % % …]
+
+ __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0);
+ __m256i yy_eve = _mm256_and_si256(yy_all, u00FF);
+ __m256i yy_odd = _mm256_srli_epi16(yy_all, 8);
+
+ __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve);
+ __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd);
+ __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve);
+ __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd);
+
+ __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve);
+ __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd);
+ __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve);
+ __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd);
+
+ __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve);
+ __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd);
+ __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve);
+ __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd);
+
+ // ----
+
+ // Mix those values (unpacking in 8, 16 and then 32 bit units) to get the
+ // desired BGRX/RGBX order.
+ //
+ // From here onwards, all of our __m256i registers are u8x32.
+
+ // mix00 = [b00 g00 b02 g02 .. b0E g0E b10 g10 .. b1C g1C b1E g1E]
+ // mix01 = [b01 g01 b03 g03 .. b0F g0F b11 g11 .. b1D g1D b1F g1F]
+ // mix02 = [r00 % r02 % .. r0E % r10 % .. r1C % r1E %]
+ // mix03 = [r01 % r03 % .. r0F % r11 % .. r1D % r1F %]
+ //
+ // See also § below.
+ __m256i mix00 = _mm256_unpacklo_epi8(packed_b_eve, packed_g_eve);
+ __m256i mix01 = _mm256_unpacklo_epi8(packed_b_odd, packed_g_odd);
+ __m256i mix02 = _mm256_unpacklo_epi8(packed_r_eve, uFFFF);
+ __m256i mix03 = _mm256_unpacklo_epi8(packed_r_odd, uFFFF);
+
+ // mix10 = [b00 g00 r00 % b02 g02 r02 % b04 g04 r04 % b06 g06 r06 %
+ // b10 g10 r10 % b12 g12 r12 % b14 g14 r14 % b16 g16 r16 %]
+ // mix11 = [b01 g01 r01 % b03 g03 r03 % b05 g05 r05 % b07 g07 r07 %
+ // b11 g11 r11 % b13 g13 r13 % b15 g15 r15 % b17 g17 r17 %]
+ // mix12 = [b08 g08 r08 % b0A g0A r0A % b0C g0C r0C % b0E g0E r0E %
+ // b18 g18 r18 % b1A g1A r1A % b1C g1C r1C % b1E g1E r1E %]
+ // mix13 = [b09 g09 r09 % b0B g0B r0B % b0D g0D r0D % b0F g0F r0F %
+ // b19 g19 r19 % b1B g1B r1B % b1D g1D r1D % b1F g1F r1F %]
+ __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02);
+ __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03);
+ __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02);
+ __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03);
+
+ // mix20 = [b00 g00 r00 % b01 g01 r01 % b02 g02 r02 % b03 g03 r03 %
+ // b10 g10 r10 % b11 g11 r11 % b12 g12 r12 % b13 g13 r13 %]
+ // mix21 = [b04 g04 r04 % b05 g05 r05 % b06 g06 r06 % b07 g07 r07 %
+ // b14 g14 r14 % b15 g15 r15 % b16 g16 r16 % b17 g17 r17 %]
+ // mix22 = [b08 g08 r08 % b09 g09 r09 % b0A g0A r0A % b0B g0B r0B %
+ // b18 g18 r18 % b19 g19 r19 % b1A g1A r1A % b1B g1B r1B %]
+ // mix23 = [b0C g0C r0C % b0D g0D r0D % b0E g0E r0E % b0F g0F r0F %
+ // b1C g1C r1C % b1D g1D r1D % b1E g1E r1E % b1F g1F r1F %]
+ __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11);
+ __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11);
+ __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13);
+ __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13);
+
+ // mix30 = [b00 g00 r00 % b01 g01 r01 % b02 g02 r02 % b03 g03 r03 %
+ // b04 g04 r04 % b05 g05 r05 % b06 g06 r06 % b07 g07 r07 %]
+ // mix31 = [b08 g08 r08 % b09 g09 r09 % b0A g0A r0A % b0B g0B r0B %
+ // b0C g0C r0C % b0D g0D r0D % b0E g0E r0E % b0F g0F r0F %]
+ // mix32 = [b10 g10 r10 % b11 g11 r11 % b12 g12 r12 % b13 g13 r13 %
+ // b14 g14 r14 % b15 g15 r15 % b16 g16 r16 % b17 g17 r17 %]
+ // mix33 = [b18 g18 r18 % b19 g19 r19 % b1A g1A r1A % b1B g1B r1B %
+ // b1C g1C r1C % b1D g1D r1D % b1E g1E r1E % b1F g1F r1F %]
+ __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20);
+ __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20);
+ __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31);
+ __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31);
+
+ // Write out four u8x32 SIMD registers (128 bytes, 32 BGRX/RGBX pixels).
+ _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30);
+ _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31);
+ _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32);
+ _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33);
+
+ // Advance by up to 32 pixels. The first iteration might be smaller than 32
+ // so that all of the remaining steps are exactly 32.
+ uint32_t n = 32u - (31u & (x - x_end));
+ dst_iter += 4u * n;
+ up0 += n;
+ up1 += n;
+ up2 += n;
+ x += n;
+ }
+}
+
+// The rgbx flavor (below) is exactly the same as the bgrx flavor (above)
+// except for the lines marked with a § and that comments were stripped.
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
+static void //
+wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_rgbx_x86_avx2(
+ wuffs_base__pixel_buffer* dst,
+ uint32_t x,
+ uint32_t x_end,
+ uint32_t y,
+ const uint8_t* up0,
+ const uint8_t* up1,
+ const uint8_t* up2) {
+ if ((x + 32u) > x_end) {
+ wuffs_base__pixel_swizzler__swizzle_ycc__convert_3_bgrx( //
+ dst, x, x_end, y, up0, up1, up2);
+ return;
+ }
+
+ size_t dst_stride = dst->private_impl.planes[0].stride;
+ uint8_t* dst_iter = dst->private_impl.planes[0].ptr +
+ (dst_stride * ((size_t)y)) + (4u * ((size_t)x));
+
+ const __m256i u0001 = _mm256_set1_epi16(+0x0001);
+ const __m256i u00FF = _mm256_set1_epi16(+0x00FF);
+ const __m256i uFF80 = _mm256_set1_epi16(-0x0080);
+ const __m256i uFFFF = _mm256_set1_epi16(-0x0001);
+
+ const __m256i p8000_p0000 = _mm256_set_epi16( //
+ +0x0000, -0x8000, +0x0000, -0x8000, //
+ +0x0000, -0x8000, +0x0000, -0x8000, //
+ +0x0000, -0x8000, +0x0000, -0x8000, //
+ +0x0000, -0x8000, +0x0000, -0x8000);
+
+ const __m256i m3A5E = _mm256_set1_epi16(-0x3A5E);
+ const __m256i p66E9 = _mm256_set1_epi16(+0x66E9);
+ const __m256i m581A_p492E = _mm256_set_epi16( //
+ +0x492E, -0x581A, +0x492E, -0x581A, //
+ +0x492E, -0x581A, +0x492E, -0x581A, //
+ +0x492E, -0x581A, +0x492E, -0x581A, //
+ +0x492E, -0x581A, +0x492E, -0x581A);
+
+ while (x < x_end) {
+ __m256i cb_all = _mm256_lddqu_si256((const __m256i*)(const void*)up1);
+ __m256i cr_all = _mm256_lddqu_si256((const __m256i*)(const void*)up2);
+ __m256i cb_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cb_all, u00FF));
+ __m256i cr_eve = _mm256_add_epi16(uFF80, _mm256_and_si256(cr_all, u00FF));
+ __m256i cb_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cb_all, 8));
+ __m256i cr_odd = _mm256_add_epi16(uFF80, _mm256_srli_epi16(cr_all, 8));
+
+ __m256i tmp_by_eve = _mm256_srai_epi16(
+ _mm256_add_epi16(
+ _mm256_mulhi_epi16(_mm256_add_epi16(cb_eve, cb_eve), m3A5E), u0001),
+ 1);
+ __m256i tmp_by_odd = _mm256_srai_epi16(
+ _mm256_add_epi16(
+ _mm256_mulhi_epi16(_mm256_add_epi16(cb_odd, cb_odd), m3A5E), u0001),
+ 1);
+ __m256i tmp_ry_eve = _mm256_srai_epi16(
+ _mm256_add_epi16(
+ _mm256_mulhi_epi16(_mm256_add_epi16(cr_eve, cr_eve), p66E9), u0001),
+ 1);
+ __m256i tmp_ry_odd = _mm256_srai_epi16(
+ _mm256_add_epi16(
+ _mm256_mulhi_epi16(_mm256_add_epi16(cr_odd, cr_odd), p66E9), u0001),
+ 1);
+
+ __m256i by_eve =
+ _mm256_add_epi16(tmp_by_eve, _mm256_add_epi16(cb_eve, cb_eve));
+ __m256i by_odd =
+ _mm256_add_epi16(tmp_by_odd, _mm256_add_epi16(cb_odd, cb_odd));
+ __m256i ry_eve = _mm256_add_epi16(tmp_ry_eve, cr_eve);
+ __m256i ry_odd = _mm256_add_epi16(tmp_ry_odd, cr_odd);
+
+ __m256i tmp0_gy_eve_lo = _mm256_madd_epi16( //
+ _mm256_unpacklo_epi16(cb_eve, cr_eve), m581A_p492E);
+ __m256i tmp0_gy_eve_hi = _mm256_madd_epi16( //
+ _mm256_unpackhi_epi16(cb_eve, cr_eve), m581A_p492E);
+ __m256i tmp0_gy_odd_lo = _mm256_madd_epi16( //
+ _mm256_unpacklo_epi16(cb_odd, cr_odd), m581A_p492E);
+ __m256i tmp0_gy_odd_hi = _mm256_madd_epi16( //
+ _mm256_unpackhi_epi16(cb_odd, cr_odd), m581A_p492E);
+
+ __m256i tmp1_gy_eve_lo =
+ _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_lo, p8000_p0000), 16);
+ __m256i tmp1_gy_eve_hi =
+ _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_eve_hi, p8000_p0000), 16);
+ __m256i tmp1_gy_odd_lo =
+ _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_lo, p8000_p0000), 16);
+ __m256i tmp1_gy_odd_hi =
+ _mm256_srai_epi32(_mm256_add_epi32(tmp0_gy_odd_hi, p8000_p0000), 16);
+
+ __m256i gy_eve = _mm256_sub_epi16(
+ _mm256_packs_epi32(tmp1_gy_eve_lo, tmp1_gy_eve_hi), cr_eve);
+ __m256i gy_odd = _mm256_sub_epi16(
+ _mm256_packs_epi32(tmp1_gy_odd_lo, tmp1_gy_odd_hi), cr_odd);
+
+ __m256i yy_all = _mm256_lddqu_si256((const __m256i*)(const void*)up0);
+ __m256i yy_eve = _mm256_and_si256(yy_all, u00FF);
+ __m256i yy_odd = _mm256_srli_epi16(yy_all, 8);
+
+ __m256i loose_b_eve = _mm256_add_epi16(by_eve, yy_eve);
+ __m256i loose_b_odd = _mm256_add_epi16(by_odd, yy_odd);
+ __m256i packed_b_eve = _mm256_packus_epi16(loose_b_eve, loose_b_eve);
+ __m256i packed_b_odd = _mm256_packus_epi16(loose_b_odd, loose_b_odd);
+
+ __m256i loose_g_eve = _mm256_add_epi16(gy_eve, yy_eve);
+ __m256i loose_g_odd = _mm256_add_epi16(gy_odd, yy_odd);
+ __m256i packed_g_eve = _mm256_packus_epi16(loose_g_eve, loose_g_eve);
+ __m256i packed_g_odd = _mm256_packus_epi16(loose_g_odd, loose_g_odd);
+
+ __m256i loose_r_eve = _mm256_add_epi16(ry_eve, yy_eve);
+ __m256i loose_r_odd = _mm256_add_epi16(ry_odd, yy_odd);
+ __m256i packed_r_eve = _mm256_packus_epi16(loose_r_eve, loose_r_eve);
+ __m256i packed_r_odd = _mm256_packus_epi16(loose_r_odd, loose_r_odd);
+
+ // § Note the swapped B and R channels.
+ __m256i mix00 = _mm256_unpacklo_epi8(packed_r_eve, packed_g_eve);
+ __m256i mix01 = _mm256_unpacklo_epi8(packed_r_odd, packed_g_odd);
+ __m256i mix02 = _mm256_unpacklo_epi8(packed_b_eve, uFFFF);
+ __m256i mix03 = _mm256_unpacklo_epi8(packed_b_odd, uFFFF);
+
+ __m256i mix10 = _mm256_unpacklo_epi16(mix00, mix02);
+ __m256i mix11 = _mm256_unpacklo_epi16(mix01, mix03);
+ __m256i mix12 = _mm256_unpackhi_epi16(mix00, mix02);
+ __m256i mix13 = _mm256_unpackhi_epi16(mix01, mix03);
+
+ __m256i mix20 = _mm256_unpacklo_epi32(mix10, mix11);
+ __m256i mix21 = _mm256_unpackhi_epi32(mix10, mix11);
+ __m256i mix22 = _mm256_unpacklo_epi32(mix12, mix13);
+ __m256i mix23 = _mm256_unpackhi_epi32(mix12, mix13);
+
+ __m256i mix30 = _mm256_permute2x128_si256(mix20, mix21, 0x20);
+ __m256i mix31 = _mm256_permute2x128_si256(mix22, mix23, 0x20);
+ __m256i mix32 = _mm256_permute2x128_si256(mix20, mix21, 0x31);
+ __m256i mix33 = _mm256_permute2x128_si256(mix22, mix23, 0x31);
+
+ _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x00), mix30);
+ _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x20), mix31);
+ _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x40), mix32);
+ _mm256_storeu_si256((__m256i*)(void*)(dst_iter + 0x60), mix33);
+
+ uint32_t n = 32u - (31u & (x - x_end));
+ dst_iter += 4u * n;
+ up0 += n;
+ up1 += n;
+ up2 += n;
+ x += n;
+ }
+}
+
+#if defined(__GNUC__) && !defined(__clang__)
+// No-op.
+#else
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
+static const uint8_t* //
+wuffs_base__pixel_swizzler__swizzle_ycc__upsample_inv_h2v2_triangle_x86_avx2(
+ uint8_t* dst_ptr,
+ const uint8_t* src_ptr_major,
+ const uint8_t* src_ptr_minor,
+ size_t src_len,
+ uint32_t h1v2_bias_ignored,
+ bool first_column,
+ bool last_column) {
+ uint8_t* dp = dst_ptr;
+ const uint8_t* sp_major = src_ptr_major;
+ const uint8_t* sp_minor = src_ptr_minor;
+
+ if (first_column) {
+ src_len--;
+ if ((src_len <= 0u) && last_column) {
+ uint32_t sv = (12u * ((uint32_t)(*sp_major++))) + //
+ (4u * ((uint32_t)(*sp_minor++)));
+ *dp++ = (uint8_t)((sv + 8u) >> 4u);
+ *dp++ = (uint8_t)((sv + 7u) >> 4u);
+ return dst_ptr;
+ }
+
+ uint32_t sv_major_m1 = sp_major[-0]; // Clamp offset to zero.
+ uint32_t sv_minor_m1 = sp_minor[-0]; // Clamp offset to zero.
+ uint32_t sv_major_p1 = sp_major[+1];
+ uint32_t sv_minor_p1 = sp_minor[+1];
+
+ uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
+ (3u * ((uint32_t)(*sp_minor++)));
+ *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
+ *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
+ if (src_len <= 0u) {
+ return dst_ptr;
+ }
+ }
+
+ if (last_column) {
+ src_len--;
+ }
+
+ if (src_len < 32) {
+ // This fallback is the same as the non-SIMD-capable code path.
+ for (; src_len > 0u; src_len--) {
+ uint32_t sv_major_m1 = sp_major[-1];
+ uint32_t sv_minor_m1 = sp_minor[-1];
+ uint32_t sv_major_p1 = sp_major[+1];
+ uint32_t sv_minor_p1 = sp_minor[+1];
+
+ uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
+ (3u * ((uint32_t)(*sp_minor++)));
+ *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
+ *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
+ }
+
+ } else {
+ while (src_len > 0u) {
+ // Load 1+32+1 samples (six u8x32 vectors) from the major (jxx) and minor
+ // (nxx) rows.
+ //
+ // major_p0 = [j00 j01 j02 j03 .. j28 j29 j30 j31] // p0 = "plus 0"
+ // minor_p0 = [n00 n01 n02 n03 .. n28 n29 n30 n31] // p0 = "plus 0"
+ // major_m1 = [jm1 j00 j01 j02 .. j27 j28 j29 j30] // m1 = "minus 1"
+ // minor_m1 = [nm1 n00 n01 n02 .. n27 n28 n29 n30] // m1 = "minus 1"
+ // major_p1 = [j01 j02 j03 j04 .. j29 j30 j31 j32] // p1 = "plus 1"
+ // minor_p1 = [n01 n02 n03 n04 .. n29 n30 n31 n32] // p1 = "plus 1"
+ __m256i major_p0 =
+ _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 0));
+ __m256i minor_p0 =
+ _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 0));
+ __m256i major_m1 =
+ _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major - 1));
+ __m256i minor_m1 =
+ _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor - 1));
+ __m256i major_p1 =
+ _mm256_lddqu_si256((const __m256i*)(const void*)(sp_major + 1));
+ __m256i minor_p1 =
+ _mm256_lddqu_si256((const __m256i*)(const void*)(sp_minor + 1));
+
+ // Unpack, staying with u8x32 vectors.
+ //
+ // step1_p0_lo = [j00 n00 j01 n01 .. j07 n07 j16 n16 j17 n17 .. j23 n23]
+ // step1_p0_hi = [j08 n08 j09 n09 .. j15 n15 j24 n24 j25 n25 .. j31 n31]
+ // step1_m1_lo = [jm1 nm1 j00 n00 .. j06 n06 j15 n15 j16 n16 .. j22 n22]
+ // step1_m1_hi = [j07 n07 j08 n08 .. j14 n14 j23 n23 j24 n24 .. j30 n30]
+ // step1_p1_lo = [j01 n01 j02 n02 .. j08 n08 j17 n17 j18 n18 .. j24 n24]
+ // step1_p1_hi = [j09 n09 j10 n10 .. j16 n16 j25 n25 j26 n26 .. j32 n32]
+ __m256i step1_p0_lo = _mm256_unpacklo_epi8(major_p0, minor_p0);
+ __m256i step1_p0_hi = _mm256_unpackhi_epi8(major_p0, minor_p0);
+ __m256i step1_m1_lo = _mm256_unpacklo_epi8(major_m1, minor_m1);
+ __m256i step1_m1_hi = _mm256_unpackhi_epi8(major_m1, minor_m1);
+ __m256i step1_p1_lo = _mm256_unpacklo_epi8(major_p1, minor_p1);
+ __m256i step1_p1_hi = _mm256_unpackhi_epi8(major_p1, minor_p1);
+
+ // Multiply-add to get u16x16 vectors.
+ //
+ // step2_p0_lo = [9*j00+3*n00 9*j01+3*n01 .. 9*j23+3*n23]
+ // step2_p0_hi = [9*j08+3*n08 9*j09+3*n09 .. 9*j31+3*n31]
+ // step2_m1_lo = [3*jm1+1*nm1 3*j00+1*n00 .. 3*j22+1*n22]
+ // step2_m1_hi = [3*j07+1*n07 3*j08+1*n08 .. 3*j30+1*n30]
+ // step2_p1_lo = [3*j01+1*n01 3*j02+1*n02 .. 3*j24+1*n24]
+ // step2_p1_hi = [3*j09+1*n09 3*j10+1*n10 .. 3*j32+1*n32]
+ const __m256i k0309 = _mm256_set1_epi16(0x0309);
+ const __m256i k0103 = _mm256_set1_epi16(0x0103);
+ __m256i step2_p0_lo = _mm256_maddubs_epi16(step1_p0_lo, k0309);
+ __m256i step2_p0_hi = _mm256_maddubs_epi16(step1_p0_hi, k0309);
+ __m256i step2_m1_lo = _mm256_maddubs_epi16(step1_m1_lo, k0103);
+ __m256i step2_m1_hi = _mm256_maddubs_epi16(step1_m1_hi, k0103);
+ __m256i step2_p1_lo = _mm256_maddubs_epi16(step1_p1_lo, k0103);
+ __m256i step2_p1_hi = _mm256_maddubs_epi16(step1_p1_hi, k0103);
+
+ // Compute the weighted sums of (p0, m1) and (p0, p1). For example:
+ //
+ // step3_m1_lo[00] = ((9*j00) + (3*n00) + (3*jm1) + (1*nm1)) as u16
+ // step3_p1_hi[15] = ((9*j31) + (3*n31) + (3*j32) + (1*n32)) as u16
+ __m256i step3_m1_lo = _mm256_add_epi16(step2_p0_lo, step2_m1_lo);
+ __m256i step3_m1_hi = _mm256_add_epi16(step2_p0_hi, step2_m1_hi);
+ __m256i step3_p1_lo = _mm256_add_epi16(step2_p0_lo, step2_p1_lo);
+ __m256i step3_p1_hi = _mm256_add_epi16(step2_p0_hi, step2_p1_hi);
+
+ // Bias by 8 (on the left) or 7 (on the right) and then divide by 16
+ // (which is 9+3+3+1) to get a weighted average. On the left (m1), shift
+ // the u16 right value by 4. On the right (p1), shift right by 4 and then
+ // shift left by 8 so that, when still in the u16x16 little-endian
+ // interpretation, we have:
+ // - m1_element = (etcetera + 8) >> 4
+ // - p1_element = ((etcetera + 7) >> 4) << 8
+ //
+ // step4_m1_lo = [0x00?? 0x00?? ... 0x00?? 0x00??]
+ // step4_p1_lo = [0x??00 0x??00 ... 0x??00 0x??00]
+ // step4_m1_hi = [0x00?? 0x00?? ... 0x00?? 0x00??]
+ // step4_p1_hi = [0x??00 0x??00 ... 0x??00 0x??00]
+ __m256i step4_m1_lo = _mm256_srli_epi16(
+ _mm256_add_epi16(step3_m1_lo, _mm256_set1_epi16(8)), 4);
+ __m256i step4_p1_lo = _mm256_slli_epi16(
+ _mm256_srli_epi16(_mm256_add_epi16(step3_p1_lo, _mm256_set1_epi16(7)),
+ 4),
+ 8);
+ __m256i step4_m1_hi = _mm256_srli_epi16(
+ _mm256_add_epi16(step3_m1_hi, _mm256_set1_epi16(8)), 4);
+ __m256i step4_p1_hi = _mm256_slli_epi16(
+ _mm256_srli_epi16(_mm256_add_epi16(step3_p1_hi, _mm256_set1_epi16(7)),
+ 4),
+ 8);
+
+ // Bitwise-or two "0x00"-rich u16x16 vectors to get a u8x32 vector. Do
+ // that twice. Once for the low columns and once for the high columns.
+ //
+ // In terms of jxx (major row) or nxx (minor row) source samples:
+ // - low columns means ( 0 .. 8; 16 .. 24).
+ // - high columns means ( 8 .. 16; 24 .. 32).
+ //
+ // In terms of dxx destination samples (there are twice as many):
+ // - low columns means ( 0 .. 16; 32 .. 48).
+ // - high columns means (16 .. 32; 48 .. 64).
+ //
+ // step5_lo = [d00 d01 .. d14 d15 d32 d33 .. d46 d47]
+ // step5_hi = [d16 d17 .. d30 d31 d48 d49 .. d62 d63]
+ //
+ // The d00, d02 ... d62 even elements come from (p0, m1) weighted sums.
+ // The d01, d03 ... d63 odd elements come from (p0, p1) weighted sums.
+ __m256i step5_lo = _mm256_or_si256(step4_m1_lo, step4_p1_lo);
+ __m256i step5_hi = _mm256_or_si256(step4_m1_hi, step4_p1_hi);
+
+ // Permute and store.
+ //
+ // step6_00_31 = [d00 d01 .. d14 d15 d16 d17 .. d30 d31]
+ // step6_32_63 = [d32 d33 .. d46 d47 d48 d49 .. d62 d63]
+ __m256i step6_00_31 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x20);
+ __m256i step6_32_63 = _mm256_permute2x128_si256(step5_lo, step5_hi, 0x31);
+ _mm256_storeu_si256((__m256i*)(void*)(dp + 0x00), step6_00_31);
+ _mm256_storeu_si256((__m256i*)(void*)(dp + 0x20), step6_32_63);
+
+ // Advance by up to 32 source samples (64 destination samples). The first
+ // iteration might be smaller than 32 so that all of the remaining steps
+ // are exactly 32.
+ size_t n = 32u - (31u & (0u - src_len));
+ dp += 2u * n;
+ sp_major += n;
+ sp_minor += n;
+ src_len -= n;
+ }
+ }
+
+ if (last_column) {
+ uint32_t sv_major_m1 = sp_major[-1];
+ uint32_t sv_minor_m1 = sp_minor[-1];
+ uint32_t sv_major_p1 = sp_major[+0]; // Clamp offset to zero.
+ uint32_t sv_minor_p1 = sp_minor[+0]; // Clamp offset to zero.
+
+ uint32_t sv = (9u * ((uint32_t)(*sp_major++))) + //
+ (3u * ((uint32_t)(*sp_minor++)));
+ *dp++ = (uint8_t)((sv + (3u * sv_major_m1) + (sv_minor_m1) + 8u) >> 4u);
+ *dp++ = (uint8_t)((sv + (3u * sv_major_p1) + (sv_minor_p1) + 7u) >> 4u);
+ }
+
+ return dst_ptr;
+}
+#endif
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64)
+// ‼ WUFFS MULTI-FILE SECTION -x86_avx2
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE__PIXCONV)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BASE) || \
+ defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
+
+// ---------------- Unicode and UTF-8
+
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__utf_8__encode(wuffs_base__slice_u8 dst, uint32_t code_point) {
+ if (code_point <= 0x7F) {
+ if (dst.len >= 1) {
+ dst.ptr[0] = (uint8_t)(code_point);
+ return 1;
+ }
+
+ } else if (code_point <= 0x07FF) {
+ if (dst.len >= 2) {
+ dst.ptr[0] = (uint8_t)(0xC0 | ((code_point >> 6)));
+ dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
+ return 2;
+ }
+
+ } else if (code_point <= 0xFFFF) {
+ if ((dst.len >= 3) && ((code_point < 0xD800) || (0xDFFF < code_point))) {
+ dst.ptr[0] = (uint8_t)(0xE0 | ((code_point >> 12)));
+ dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
+ dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
+ return 3;
+ }
+
+ } else if (code_point <= 0x10FFFF) {
+ if (dst.len >= 4) {
+ dst.ptr[0] = (uint8_t)(0xF0 | ((code_point >> 18)));
+ dst.ptr[1] = (uint8_t)(0x80 | ((code_point >> 12) & 0x3F));
+ dst.ptr[2] = (uint8_t)(0x80 | ((code_point >> 6) & 0x3F));
+ dst.ptr[3] = (uint8_t)(0x80 | ((code_point >> 0) & 0x3F));
+ return 4;
+ }
+ }
+
+ return 0;
+}
+
+// wuffs_base__utf_8__byte_length_minus_1 is the byte length (minus 1) of a
+// UTF-8 encoded code point, based on the encoding's initial byte.
+// - 0x00 is 1-byte UTF-8 (ASCII).
+// - 0x01 is the start of 2-byte UTF-8.
+// - 0x02 is the start of 3-byte UTF-8.
+// - 0x03 is the start of 4-byte UTF-8.
+// - 0x40 is a UTF-8 tail byte.
+// - 0x80 is invalid UTF-8.
+//
+// RFC 3629 (UTF-8) gives this grammar for valid UTF-8:
+// UTF8-1 = %x00-7F
+// UTF8-2 = %xC2-DF UTF8-tail
+// UTF8-3 = %xE0 %xA0-BF UTF8-tail / %xE1-EC 2( UTF8-tail ) /
+// %xED %x80-9F UTF8-tail / %xEE-EF 2( UTF8-tail )
+// UTF8-4 = %xF0 %x90-BF 2( UTF8-tail ) / %xF1-F3 3( UTF8-tail ) /
+// %xF4 %x80-8F 2( UTF8-tail )
+// UTF8-tail = %x80-BF
+static const uint8_t wuffs_base__utf_8__byte_length_minus_1[256] = {
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x00 ..= 0x07.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x08 ..= 0x0F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x10 ..= 0x17.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 ..= 0x1F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x20 ..= 0x27.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x28 ..= 0x2F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x30 ..= 0x37.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x38 ..= 0x3F.
+
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x40 ..= 0x47.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x48 ..= 0x4F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x50 ..= 0x57.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x58 ..= 0x5F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x60 ..= 0x67.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x68 ..= 0x6F.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x70 ..= 0x77.
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x78 ..= 0x7F.
+
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x80 ..= 0x87.
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x88 ..= 0x8F.
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x90 ..= 0x97.
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0x98 ..= 0x9F.
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA0 ..= 0xA7.
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xA8 ..= 0xAF.
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB0 ..= 0xB7.
+ 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, 0x40, // 0xB8 ..= 0xBF.
+
+ 0x80, 0x80, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC0 ..= 0xC7.
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xC8 ..= 0xCF.
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD0 ..= 0xD7.
+ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, // 0xD8 ..= 0xDF.
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE0 ..= 0xE7.
+ 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, // 0xE8 ..= 0xEF.
+ 0x03, 0x03, 0x03, 0x03, 0x03, 0x80, 0x80, 0x80, // 0xF0 ..= 0xF7.
+ 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, // 0xF8 ..= 0xFF.
+ // 0 1 2 3 4 5 6 7
+ // 8 9 A B C D E F
+};
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
+wuffs_base__utf_8__next(const uint8_t* s_ptr, size_t s_len) {
+ if (s_len == 0) {
+ return wuffs_base__make_utf_8__next__output(0, 0);
+ }
+ uint32_t c = s_ptr[0];
+ switch (wuffs_base__utf_8__byte_length_minus_1[c & 0xFF]) {
+ case 0:
+ return wuffs_base__make_utf_8__next__output(c, 1);
+
+ case 1:
+ if (s_len < 2) {
+ break;
+ }
+ c = wuffs_base__peek_u16le__no_bounds_check(s_ptr);
+ if ((c & 0xC000) != 0x8000) {
+ break;
+ }
+ c = (0x0007C0 & (c << 6)) | (0x00003F & (c >> 8));
+ return wuffs_base__make_utf_8__next__output(c, 2);
+
+ case 2:
+ if (s_len < 3) {
+ break;
+ }
+ c = wuffs_base__peek_u24le__no_bounds_check(s_ptr);
+ if ((c & 0xC0C000) != 0x808000) {
+ break;
+ }
+ c = (0x00F000 & (c << 12)) | (0x000FC0 & (c >> 2)) |
+ (0x00003F & (c >> 16));
+ if ((c <= 0x07FF) || ((0xD800 <= c) && (c <= 0xDFFF))) {
+ break;
+ }
+ return wuffs_base__make_utf_8__next__output(c, 3);
+
+ case 3:
+ if (s_len < 4) {
+ break;
+ }
+ c = wuffs_base__peek_u32le__no_bounds_check(s_ptr);
+ if ((c & 0xC0C0C000) != 0x80808000) {
+ break;
+ }
+ c = (0x1C0000 & (c << 18)) | (0x03F000 & (c << 4)) |
+ (0x000FC0 & (c >> 10)) | (0x00003F & (c >> 24));
+ if ((c <= 0xFFFF) || (0x110000 <= c)) {
+ break;
+ }
+ return wuffs_base__make_utf_8__next__output(c, 4);
+ }
+
+ return wuffs_base__make_utf_8__next__output(
+ WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
+}
+
+WUFFS_BASE__MAYBE_STATIC wuffs_base__utf_8__next__output //
+wuffs_base__utf_8__next_from_end(const uint8_t* s_ptr, size_t s_len) {
+ if (s_len == 0) {
+ return wuffs_base__make_utf_8__next__output(0, 0);
+ }
+ const uint8_t* ptr = &s_ptr[s_len - 1];
+ if (*ptr < 0x80) {
+ return wuffs_base__make_utf_8__next__output(*ptr, 1);
+
+ } else if (*ptr < 0xC0) {
+ const uint8_t* too_far = &s_ptr[(s_len > 4) ? (s_len - 4) : 0];
+ uint32_t n = 1;
+ while (ptr != too_far) {
+ ptr--;
+ n++;
+ if (*ptr < 0x80) {
+ break;
+ } else if (*ptr < 0xC0) {
+ continue;
+ }
+ wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(ptr, n);
+ if (o.byte_length != n) {
+ break;
+ }
+ return o;
+ }
+ }
+
+ return wuffs_base__make_utf_8__next__output(
+ WUFFS_BASE__UNICODE_REPLACEMENT_CHARACTER, 1);
+}
+
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__utf_8__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
+ // TODO: possibly optimize the all-ASCII case (4 or 8 bytes at a time).
+ //
+ // TODO: possibly optimize this by manually inlining the
+ // wuffs_base__utf_8__next calls.
+ size_t original_len = s_len;
+ while (s_len > 0) {
+ wuffs_base__utf_8__next__output o = wuffs_base__utf_8__next(s_ptr, s_len);
+ if ((o.code_point > 0x7F) && (o.byte_length == 1)) {
+ break;
+ }
+ s_ptr += o.byte_length;
+ s_len -= o.byte_length;
+ }
+ return original_len - s_len;
+}
+
+WUFFS_BASE__MAYBE_STATIC size_t //
+wuffs_base__ascii__longest_valid_prefix(const uint8_t* s_ptr, size_t s_len) {
+ // TODO: possibly optimize this by checking 4 or 8 bytes at a time.
+ const uint8_t* original_ptr = s_ptr;
+ const uint8_t* p = s_ptr;
+ const uint8_t* q = s_ptr + s_len;
+ for (; (p != q) && ((*p & 0x80) == 0); p++) {
+ }
+ return (size_t)(p - original_ptr);
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE) ||
+ // defined(WUFFS_CONFIG__MODULE__BASE__UTF8)
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
+
+// ---------------- Status Codes Implementations
+
+// ---------------- Private Consts
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_adler32__hasher__up(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_adler32__hasher__up__choosy_default(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_adler32__hasher__up_arm_neon(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_adler32__hasher__up_x86_sse42(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+
+// ---------------- VTables
+
+const wuffs_base__hasher_u32__func_ptrs
+wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
+ (uint32_t(*)(const void*))(&wuffs_adler32__hasher__checksum_u32),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_adler32__hasher__get_quirk),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_adler32__hasher__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ wuffs_base__slice_u8))(&wuffs_adler32__hasher__update),
+ (uint32_t(*)(void*,
+ wuffs_base__slice_u8))(&wuffs_adler32__hasher__update_u32),
+};
+
+// ---------------- Initializer Implementations
+
+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 options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.choosy_up = &wuffs_adler32__hasher__up__choosy_default;
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
+ wuffs_base__hasher_u32__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
+ (const void*)(&wuffs_adler32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_adler32__hasher*
+wuffs_adler32__hasher__alloc(void) {
+ wuffs_adler32__hasher* x =
+ (wuffs_adler32__hasher*)(calloc(sizeof(wuffs_adler32__hasher), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_adler32__hasher__initialize(
+ x, sizeof(wuffs_adler32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_adler32__hasher(void) {
+ return sizeof(wuffs_adler32__hasher);
+}
+
+// ---------------- Function Implementations
+
+// -------- func adler32.hasher.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_adler32__hasher__get_quirk(
+ const wuffs_adler32__hasher* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func adler32.hasher.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_adler32__hasher__set_quirk(
+ wuffs_adler32__hasher* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func adler32.hasher.update
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_adler32__hasher__update(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ if ( ! self->private_impl.f_started) {
+ self->private_impl.f_started = true;
+ self->private_impl.f_state = 1u;
+ self->private_impl.choosy_up = (
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+ wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_adler32__hasher__up_arm_neon :
+#endif
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_adler32__hasher__up_x86_sse42 :
+#endif
+ self->private_impl.choosy_up);
+ }
+ wuffs_adler32__hasher__up(self, a_x);
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func adler32.hasher.update_u32
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_adler32__hasher__update_u32(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return 0;
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return 0;
+ }
+
+ wuffs_adler32__hasher__update(self, a_x);
+ return self->private_impl.f_state;
+}
+
+// -------- func adler32.hasher.up
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_adler32__hasher__up(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ return (*self->private_impl.choosy_up)(self, a_x);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_adler32__hasher__up__choosy_default(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ uint32_t v_s1 = 0;
+ uint32_t v_s2 = 0;
+ wuffs_base__slice_u8 v_remaining = {0};
+ wuffs_base__slice_u8 v_p = {0};
+
+ v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
+ v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
+ while (((uint64_t)(a_x.len)) > 0u) {
+ v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
+ if (((uint64_t)(a_x.len)) > 5552u) {
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5552u);
+ a_x = wuffs_base__slice_u8__subslice_j(a_x, 5552u);
+ }
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 1;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
+ while (v_p.ptr < i_end0_p) {
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ }
+ v_p.len = 1;
+ uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end1_p) {
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ v_s1 %= 65521u;
+ v_s2 %= 65521u;
+ a_x = v_remaining;
+ }
+ self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func adler32.hasher.checksum_u32
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_adler32__hasher__checksum_u32(
+ const wuffs_adler32__hasher* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return self->private_impl.f_state;
+}
+
+// ‼ WUFFS MULTI-FILE SECTION +arm_neon
+// -------- func adler32.hasher.up_arm_neon
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_adler32__hasher__up_arm_neon(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ uint32_t v_s1 = 0;
+ uint32_t v_s2 = 0;
+ wuffs_base__slice_u8 v_remaining = {0};
+ wuffs_base__slice_u8 v_p = {0};
+ uint8x16_t v_p__left = {0};
+ uint8x16_t v_p_right = {0};
+ uint32x4_t v_v1 = {0};
+ uint32x4_t v_v2 = {0};
+ uint16x8_t v_col0 = {0};
+ uint16x8_t v_col1 = {0};
+ uint16x8_t v_col2 = {0};
+ uint16x8_t v_col3 = {0};
+ uint32x2_t v_sum1 = {0};
+ uint32x2_t v_sum2 = {0};
+ uint32x2_t v_sum12 = {0};
+ uint32_t v_num_iterate_bytes = 0;
+ uint64_t v_tail_index = 0;
+
+ v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
+ v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
+ while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
+ v_s1 += ((uint32_t)(a_x.ptr[0u]));
+ v_s2 += v_s1;
+ a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
+ }
+ v_s1 %= 65521u;
+ v_s2 %= 65521u;
+ while (((uint64_t)(a_x.len)) > 0u) {
+ v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
+ if (((uint64_t)(a_x.len)) > 5536u) {
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u);
+ a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u);
+ }
+ v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u)));
+ v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
+ v_v1 = vdupq_n_u32(0u);
+ v_v2 = vdupq_n_u32(0u);
+ v_col0 = vdupq_n_u16(0u);
+ v_col1 = vdupq_n_u16(0u);
+ v_col2 = vdupq_n_u16(0u);
+ v_col3 = vdupq_n_u16(0u);
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 32;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
+ while (v_p.ptr < i_end0_p) {
+ v_p__left = vld1q_u8(v_p.ptr);
+ v_p_right = vld1q_u8(v_p.ptr + 16u);
+ v_v2 = vaddq_u32(v_v2, v_v1);
+ v_v1 = vpadalq_u16(v_v1, vpadalq_u8(vpaddlq_u8(v_p__left), v_p_right));
+ v_col0 = vaddw_u8(v_col0, vget_low_u8(v_p__left));
+ v_col1 = vaddw_u8(v_col1, vget_high_u8(v_p__left));
+ v_col2 = vaddw_u8(v_col2, vget_low_u8(v_p_right));
+ v_col3 = vaddw_u8(v_col3, vget_high_u8(v_p_right));
+ v_p.ptr += 32;
+ }
+ v_p.len = 0;
+ }
+ v_v2 = vshlq_n_u32(v_v2, 5u);
+ v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col0), ((uint16x4_t){32u, 31u, 30u, 29u}));
+ v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col0), ((uint16x4_t){28u, 27u, 26u, 25u}));
+ v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col1), ((uint16x4_t){24u, 23u, 22u, 21u}));
+ v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col1), ((uint16x4_t){20u, 19u, 18u, 17u}));
+ v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col2), ((uint16x4_t){16u, 15u, 14u, 13u}));
+ v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col2), ((uint16x4_t){12u, 11u, 10u, 9u}));
+ v_v2 = vmlal_u16(v_v2, vget_low_u16(v_col3), ((uint16x4_t){8u, 7u, 6u, 5u}));
+ v_v2 = vmlal_u16(v_v2, vget_high_u16(v_col3), ((uint16x4_t){4u, 3u, 2u, 1u}));
+ v_sum1 = vpadd_u32(vget_low_u32(v_v1), vget_high_u32(v_v1));
+ v_sum2 = vpadd_u32(vget_low_u32(v_v2), vget_high_u32(v_v2));
+ v_sum12 = vpadd_u32(v_sum1, v_sum2);
+ v_s1 += vget_lane_u32(v_sum12, 0u);
+ v_s2 += vget_lane_u32(v_sum12, 1u);
+ v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
+ if (v_tail_index < ((uint64_t)(a_x.len))) {
+ {
+ wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 1;
+ uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end0_p) {
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ }
+ v_s1 %= 65521u;
+ v_s2 %= 65521u;
+ a_x = v_remaining;
+ }
+ self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+// ‼ WUFFS MULTI-FILE SECTION -arm_neon
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+// -------- func adler32.hasher.up_x86_sse42
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_adler32__hasher__up_x86_sse42(
+ wuffs_adler32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ uint32_t v_s1 = 0;
+ uint32_t v_s2 = 0;
+ wuffs_base__slice_u8 v_remaining = {0};
+ wuffs_base__slice_u8 v_p = {0};
+ __m128i v_zeroes = {0};
+ __m128i v_ones = {0};
+ __m128i v_weights__left = {0};
+ __m128i v_weights_right = {0};
+ __m128i v_q__left = {0};
+ __m128i v_q_right = {0};
+ __m128i v_v1 = {0};
+ __m128i v_v2 = {0};
+ __m128i v_v2j = {0};
+ __m128i v_v2k = {0};
+ uint32_t v_num_iterate_bytes = 0;
+ uint64_t v_tail_index = 0;
+
+ v_zeroes = _mm_set1_epi16((int16_t)(0u));
+ v_ones = _mm_set1_epi16((int16_t)(1u));
+ v_weights__left = _mm_set_epi8((int8_t)(17u), (int8_t)(18u), (int8_t)(19u), (int8_t)(20u), (int8_t)(21u), (int8_t)(22u), (int8_t)(23u), (int8_t)(24u), (int8_t)(25u), (int8_t)(26u), (int8_t)(27u), (int8_t)(28u), (int8_t)(29u), (int8_t)(30u), (int8_t)(31u), (int8_t)(32u));
+ v_weights_right = _mm_set_epi8((int8_t)(1u), (int8_t)(2u), (int8_t)(3u), (int8_t)(4u), (int8_t)(5u), (int8_t)(6u), (int8_t)(7u), (int8_t)(8u), (int8_t)(9u), (int8_t)(10u), (int8_t)(11u), (int8_t)(12u), (int8_t)(13u), (int8_t)(14u), (int8_t)(15u), (int8_t)(16u));
+ v_s1 = ((self->private_impl.f_state) & 0xFFFFu);
+ v_s2 = ((self->private_impl.f_state) >> (32u - 16u));
+ while (((uint64_t)(a_x.len)) > 0u) {
+ v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
+ if (((uint64_t)(a_x.len)) > 5536u) {
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 5536u);
+ a_x = wuffs_base__slice_u8__subslice_j(a_x, 5536u);
+ }
+ v_num_iterate_bytes = ((uint32_t)((((uint64_t)(a_x.len)) & 4294967264u)));
+ v_s2 += ((uint32_t)(v_s1 * v_num_iterate_bytes));
+ v_v1 = _mm_setzero_si128();
+ v_v2j = _mm_setzero_si128();
+ v_v2k = _mm_setzero_si128();
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 32;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
+ while (v_p.ptr < i_end0_p) {
+ v_q__left = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr));
+ v_q_right = _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u));
+ v_v2j = _mm_add_epi32(v_v2j, v_v1);
+ v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q__left, v_zeroes));
+ v_v1 = _mm_add_epi32(v_v1, _mm_sad_epu8(v_q_right, v_zeroes));
+ v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q__left, v_weights__left)));
+ v_v2k = _mm_add_epi32(v_v2k, _mm_madd_epi16(v_ones, _mm_maddubs_epi16(v_q_right, v_weights_right)));
+ v_p.ptr += 32;
+ }
+ v_p.len = 0;
+ }
+ v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(177u)));
+ v_v1 = _mm_add_epi32(v_v1, _mm_shuffle_epi32(v_v1, (int32_t)(78u)));
+ v_s1 += ((uint32_t)(_mm_cvtsi128_si32(v_v1)));
+ v_v2 = _mm_add_epi32(v_v2k, _mm_slli_epi32(v_v2j, (int32_t)(5u)));
+ v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(177u)));
+ v_v2 = _mm_add_epi32(v_v2, _mm_shuffle_epi32(v_v2, (int32_t)(78u)));
+ v_s2 += ((uint32_t)(_mm_cvtsi128_si32(v_v2)));
+ v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551584u);
+ if (v_tail_index < ((uint64_t)(a_x.len))) {
+ {
+ wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 1;
+ uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end0_p) {
+ v_s1 += ((uint32_t)(v_p.ptr[0u]));
+ v_s2 += v_s1;
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ }
+ v_s1 %= 65521u;
+ v_s2 %= 65521u;
+ a_x = v_remaining;
+ }
+ self->private_impl.f_state = (((v_s2 & 65535u) << 16u) | (v_s1 & 65535u));
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ADLER32)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_bmp__error__bad_header[] = "#bmp: bad header";
+const char wuffs_bmp__error__bad_rle_compression[] = "#bmp: bad RLE compression";
+const char wuffs_bmp__error__truncated_input[] = "#bmp: truncated input";
+const char wuffs_bmp__error__unsupported_bmp_file[] = "#bmp: unsupported BMP file";
+const char wuffs_bmp__note__internal_note_short_read[] = "@bmp: internal note: short read";
+
+// ---------------- Private Consts
+
+#define WUFFS_BMP__COMPRESSION_NONE 0
+
+#define WUFFS_BMP__COMPRESSION_RLE8 1
+
+#define WUFFS_BMP__COMPRESSION_RLE4 2
+
+#define WUFFS_BMP__COMPRESSION_BITFIELDS 3
+
+#define WUFFS_BMP__COMPRESSION_JPEG 4
+
+#define WUFFS_BMP__COMPRESSION_PNG 5
+
+#define WUFFS_BMP__COMPRESSION_ALPHABITFIELDS 6
+
+#define WUFFS_BMP__COMPRESSION_LOW_BIT_DEPTH 256
+
+#define WUFFS_BMP__RLE_STATE_NEUTRAL 0
+
+#define WUFFS_BMP__RLE_STATE_RUN 1
+
+#define WUFFS_BMP__RLE_STATE_ESCAPE 2
+
+#define WUFFS_BMP__RLE_STATE_LITERAL 3
+
+#define WUFFS_BMP__RLE_STATE_DELTA_X 4
+
+#define WUFFS_BMP__RLE_STATE_DELTA_Y 5
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__do_decode_image_config(
+ wuffs_bmp__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__do_decode_frame_config(
+ wuffs_bmp__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__do_decode_frame(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__swizzle_none(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__swizzle_rle(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__swizzle_bitfields(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__swizzle_low_bit_depth(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__do_tell_me_more(
+ wuffs_bmp__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__read_palette(
+ wuffs_bmp__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__process_masks(
+ wuffs_bmp__decoder* self);
+
+// ---------------- VTables
+
+const wuffs_base__image_decoder__func_ptrs
+wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__pixel_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
+ wuffs_base__slice_u8,
+ wuffs_base__decode_frame_options*))(&wuffs_bmp__decoder__decode_frame),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__frame_config*,
+ wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_frame_config),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__image_config*,
+ wuffs_base__io_buffer*))(&wuffs_bmp__decoder__decode_image_config),
+ (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_bmp__decoder__frame_dirty_rect),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_bmp__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_bmp__decoder__history_retain_length),
+ (uint32_t(*)(const void*))(&wuffs_bmp__decoder__num_animation_loops),
+ (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frame_configs),
+ (uint64_t(*)(const void*))(&wuffs_bmp__decoder__num_decoded_frames),
+ (wuffs_base__status(*)(void*,
+ uint64_t,
+ uint64_t))(&wuffs_bmp__decoder__restart_frame),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_bmp__decoder__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ uint32_t,
+ bool))(&wuffs_bmp__decoder__set_report_metadata),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*))(&wuffs_bmp__decoder__tell_me_more),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bmp__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_bmp__decoder__initialize(
+ wuffs_bmp__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
+ wuffs_base__image_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
+ (const void*)(&wuffs_bmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_bmp__decoder*
+wuffs_bmp__decoder__alloc(void) {
+ wuffs_bmp__decoder* x =
+ (wuffs_bmp__decoder*)(calloc(sizeof(wuffs_bmp__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_bmp__decoder__initialize(
+ x, sizeof(wuffs_bmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_bmp__decoder(void) {
+ return sizeof(wuffs_bmp__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func bmp.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bmp__decoder__get_quirk(
+ const wuffs_bmp__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func bmp.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__set_quirk(
+ wuffs_bmp__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func bmp.decoder.decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__decode_image_config(
+ wuffs_bmp__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_image_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func bmp.decoder.do_decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__do_decode_image_config(
+ wuffs_bmp__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_magic = 0;
+ uint32_t v_width = 0;
+ uint32_t v_height = 0;
+ uint32_t v_planes = 0;
+ uint32_t v_dst_pixfmt = 0;
+ uint32_t v_byte_width = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_call_sequence != 0u) || (self->private_impl.f_io_redirect_fourcc == 1u)) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ } else if (self->private_impl.f_io_redirect_fourcc != 0u) {
+ status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
+ goto ok;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
+ if (num_bits_0 == 8) {
+ t_0 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0)) << 56;
+ }
+ }
+ v_magic = t_0;
+ }
+ if (v_magic != 19778u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ }
+ self->private_data.s_do_decode_image_config[0].scratch = 8u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1)) << 56;
+ }
+ }
+ self->private_impl.f_padding = t_1;
+ }
+ if (self->private_impl.f_padding < 14u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_padding -= 14u;
+ self->private_impl.f_io_redirect_pos = wuffs_base__u64__sat_add(((uint64_t)(self->private_impl.f_padding)), wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))));
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
+ if (num_bits_2 == 24) {
+ t_2 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2)) << 56;
+ }
+ }
+ self->private_impl.f_bitmap_info_len = t_2;
+ }
+ if (self->private_impl.f_padding < self->private_impl.f_bitmap_info_len) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_padding -= self->private_impl.f_bitmap_info_len;
+ if (self->private_impl.f_bitmap_info_len == 12u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ uint32_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
+ if (num_bits_3 == 8) {
+ t_3 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3)) << 56;
+ }
+ }
+ self->private_impl.f_width = t_3;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ uint32_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
+ if (num_bits_4 == 8) {
+ t_4 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4)) << 56;
+ }
+ }
+ self->private_impl.f_height = t_4;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
+ uint32_t t_5;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_5 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_5 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_5;
+ if (num_bits_5 == 8) {
+ t_5 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_5 += 8u;
+ *scratch |= ((uint64_t)(num_bits_5)) << 56;
+ }
+ }
+ v_planes = t_5;
+ }
+ if (v_planes != 1u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
+ uint32_t t_6;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
+ if (num_bits_6 == 8) {
+ t_6 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_6 += 8u;
+ *scratch |= ((uint64_t)(num_bits_6)) << 56;
+ }
+ }
+ self->private_impl.f_bits_per_pixel = t_6;
+ }
+ } else if (self->private_impl.f_bitmap_info_len == 16u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
+ uint32_t t_7;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_7 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
+ if (num_bits_7 == 24) {
+ t_7 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_7 += 8u;
+ *scratch |= ((uint64_t)(num_bits_7)) << 56;
+ }
+ }
+ v_width = t_7;
+ }
+ if (v_width > 2147483647u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ } else if (v_width > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ self->private_impl.f_width = v_width;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
+ uint32_t t_8;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
+ if (num_bits_8 == 24) {
+ t_8 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_8 += 8u;
+ *scratch |= ((uint64_t)(num_bits_8)) << 56;
+ }
+ }
+ v_height = t_8;
+ }
+ if (v_height > 2147483647u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ } else if (v_height > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ self->private_impl.f_height = v_height;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
+ uint32_t t_9;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_9 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
+ if (num_bits_9 == 8) {
+ t_9 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_9 += 8u;
+ *scratch |= ((uint64_t)(num_bits_9)) << 56;
+ }
+ }
+ v_planes = t_9;
+ }
+ if (v_planes != 1u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
+ uint32_t t_10;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_10 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
+ if (num_bits_10 == 8) {
+ t_10 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_10 += 8u;
+ *scratch |= ((uint64_t)(num_bits_10)) << 56;
+ }
+ }
+ self->private_impl.f_bits_per_pixel = t_10;
+ }
+ } else {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
+ uint32_t t_11;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(25);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
+ if (num_bits_11 == 24) {
+ t_11 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_11 += 8u;
+ *scratch |= ((uint64_t)(num_bits_11)) << 56;
+ }
+ }
+ v_width = t_11;
+ }
+ if (v_width > 2147483647u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ } else if (v_width > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ self->private_impl.f_width = v_width;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(26);
+ uint32_t t_12;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_12 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(27);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
+ if (num_bits_12 == 24) {
+ t_12 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_12 += 8u;
+ *scratch |= ((uint64_t)(num_bits_12)) << 56;
+ }
+ }
+ v_height = t_12;
+ }
+ if (v_height == 2147483648u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ } else if (v_height > 2147483648u) {
+ v_height = ((uint32_t)(0u - v_height));
+ if (v_height > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ self->private_impl.f_height = v_height;
+ self->private_impl.f_top_down = true;
+ } else if (v_height > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ } else {
+ self->private_impl.f_height = v_height;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(28);
+ uint32_t t_13;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_13 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(29);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_13 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_13;
+ if (num_bits_13 == 8) {
+ t_13 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_13 += 8u;
+ *scratch |= ((uint64_t)(num_bits_13)) << 56;
+ }
+ }
+ v_planes = t_13;
+ }
+ if (v_planes != 1u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(30);
+ uint32_t t_14;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_14 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(31);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_14 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_14;
+ if (num_bits_14 == 8) {
+ t_14 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_14 += 8u;
+ *scratch |= ((uint64_t)(num_bits_14)) << 56;
+ }
+ }
+ self->private_impl.f_bits_per_pixel = t_14;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(32);
+ uint32_t t_15;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_15 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(33);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_15 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_15;
+ if (num_bits_15 == 24) {
+ t_15 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_15 += 8u;
+ *scratch |= ((uint64_t)(num_bits_15)) << 56;
+ }
+ }
+ self->private_impl.f_compression = t_15;
+ }
+ if (self->private_impl.f_bits_per_pixel == 0u) {
+ if (self->private_impl.f_compression == 4u) {
+ self->private_impl.f_io_redirect_fourcc = 1246774599u;
+ status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
+ goto ok;
+ } else if (self->private_impl.f_compression == 5u) {
+ self->private_impl.f_io_redirect_fourcc = 1347307296u;
+ status = wuffs_base__make_status(wuffs_base__note__i_o_redirect);
+ goto ok;
+ }
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ self->private_data.s_do_decode_image_config[0].scratch = 20u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(34);
+ if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
+ if (self->private_impl.f_bitmap_info_len == 40u) {
+ if (self->private_impl.f_bits_per_pixel >= 16u) {
+ if (self->private_impl.f_padding >= 16u) {
+ self->private_impl.f_bitmap_info_len = 56u;
+ self->private_impl.f_padding -= 16u;
+ } else if (self->private_impl.f_padding >= 12u) {
+ self->private_impl.f_bitmap_info_len = 52u;
+ self->private_impl.f_padding -= 12u;
+ }
+ }
+ } else if ((self->private_impl.f_bitmap_info_len != 52u) &&
+ (self->private_impl.f_bitmap_info_len != 56u) &&
+ (self->private_impl.f_bitmap_info_len != 64u) &&
+ (self->private_impl.f_bitmap_info_len != 108u) &&
+ (self->private_impl.f_bitmap_info_len != 124u)) {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ if (self->private_impl.f_compression == 6u) {
+ self->private_impl.f_compression = 3u;
+ }
+ if (self->private_impl.f_compression == 3u) {
+ if (self->private_impl.f_bitmap_info_len >= 52u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(35);
+ uint32_t t_16;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_16 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(36);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_16 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_16;
+ if (num_bits_16 == 24) {
+ t_16 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_16 += 8u;
+ *scratch |= ((uint64_t)(num_bits_16)) << 56;
+ }
+ }
+ self->private_impl.f_channel_masks[2u] = t_16;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(37);
+ uint32_t t_17;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_17 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(38);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_17 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_17;
+ if (num_bits_17 == 24) {
+ t_17 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_17 += 8u;
+ *scratch |= ((uint64_t)(num_bits_17)) << 56;
+ }
+ }
+ self->private_impl.f_channel_masks[1u] = t_17;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(39);
+ uint32_t t_18;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_18 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(40);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_18 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_18;
+ if (num_bits_18 == 24) {
+ t_18 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_18 += 8u;
+ *scratch |= ((uint64_t)(num_bits_18)) << 56;
+ }
+ }
+ self->private_impl.f_channel_masks[0u] = t_18;
+ }
+ if (self->private_impl.f_bitmap_info_len >= 56u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(41);
+ uint32_t t_19;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_19 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(42);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_19 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_19;
+ if (num_bits_19 == 24) {
+ t_19 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_19 += 8u;
+ *scratch |= ((uint64_t)(num_bits_19)) << 56;
+ }
+ }
+ self->private_impl.f_channel_masks[3u] = t_19;
+ }
+ self->private_data.s_do_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_bitmap_info_len - 56u));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(43);
+ if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
+ }
+ if ((self->private_impl.f_channel_masks[0u] == 255u) && (self->private_impl.f_channel_masks[1u] == 65280u) && (self->private_impl.f_channel_masks[2u] == 16711680u)) {
+ if (self->private_impl.f_bits_per_pixel == 24u) {
+ self->private_impl.f_compression = 0u;
+ } else if (self->private_impl.f_bits_per_pixel == 32u) {
+ if ((self->private_impl.f_channel_masks[3u] == 0u) || (self->private_impl.f_channel_masks[3u] == 4278190080u)) {
+ self->private_impl.f_compression = 0u;
+ }
+ }
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(44);
+ status = wuffs_bmp__decoder__process_masks(self);
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ } else if (self->private_impl.f_bitmap_info_len >= 40u) {
+ self->private_data.s_do_decode_image_config[0].scratch = (self->private_impl.f_bitmap_info_len - 40u);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(45);
+ if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
+ } else {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ }
+ if (self->private_impl.f_compression != 3u) {
+ if (self->private_impl.f_bits_per_pixel < 16u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(46);
+ status = wuffs_bmp__decoder__read_palette(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ }
+ if (self->private_impl.f_compression == 0u) {
+ if ((self->private_impl.f_bits_per_pixel == 1u) || (self->private_impl.f_bits_per_pixel == 2u) || (self->private_impl.f_bits_per_pixel == 4u)) {
+ self->private_impl.f_src_pixfmt = 2198077448u;
+ self->private_impl.f_compression = 256u;
+ } else if (self->private_impl.f_bits_per_pixel == 8u) {
+ self->private_impl.f_src_pixfmt = 2198077448u;
+ } else if (self->private_impl.f_bits_per_pixel == 16u) {
+ self->private_impl.f_compression = 3u;
+ self->private_impl.f_channel_masks[0u] = 31u;
+ self->private_impl.f_channel_masks[1u] = 992u;
+ self->private_impl.f_channel_masks[2u] = 31744u;
+ self->private_impl.f_channel_masks[3u] = 0u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(47);
+ status = wuffs_bmp__decoder__process_masks(self);
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_src_pixfmt = 2164308923u;
+ } else if (self->private_impl.f_bits_per_pixel == 24u) {
+ self->private_impl.f_src_pixfmt = 2147485832u;
+ } else if (self->private_impl.f_bits_per_pixel == 32u) {
+ if (self->private_impl.f_channel_masks[3u] == 0u) {
+ self->private_impl.f_src_pixfmt = 2415954056u;
+ } else {
+ self->private_impl.f_src_pixfmt = 2164295816u;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ } else if (self->private_impl.f_compression == 1u) {
+ if (self->private_impl.f_bits_per_pixel == 8u) {
+ self->private_impl.f_src_pixfmt = 2198077448u;
+ } else {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ } else if (self->private_impl.f_compression == 2u) {
+ if (self->private_impl.f_bits_per_pixel == 4u) {
+ self->private_impl.f_src_pixfmt = 2198077448u;
+ } else {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ } else if (self->private_impl.f_compression == 3u) {
+ if ((self->private_impl.f_bits_per_pixel == 16u) || (self->private_impl.f_bits_per_pixel == 32u)) {
+ self->private_impl.f_src_pixfmt = 2164308923u;
+ } else {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ if (((self->private_impl.f_bitmap_info_len < 40u) || (self->private_impl.f_bitmap_info_len == 64u)) &&
+ (self->private_impl.f_bits_per_pixel != 1u) &&
+ (self->private_impl.f_bits_per_pixel != 4u) &&
+ (self->private_impl.f_bits_per_pixel != 8u) &&
+ (self->private_impl.f_bits_per_pixel != 24u)) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ }
+ if (self->private_impl.f_bits_per_pixel == 1u) {
+ v_byte_width = ((self->private_impl.f_width >> 3u) + (((self->private_impl.f_width & 7u) + 7u) >> 3u));
+ self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
+ } else if (self->private_impl.f_bits_per_pixel == 2u) {
+ v_byte_width = ((self->private_impl.f_width >> 2u) + (((self->private_impl.f_width & 3u) + 3u) >> 2u));
+ self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
+ } else if (self->private_impl.f_bits_per_pixel == 4u) {
+ v_byte_width = ((self->private_impl.f_width >> 1u) + (self->private_impl.f_width & 1u));
+ self->private_impl.f_pad_per_row = ((4u - (v_byte_width & 3u)) & 3u);
+ } else if (self->private_impl.f_bits_per_pixel == 8u) {
+ self->private_impl.f_pad_per_row = ((4u - (self->private_impl.f_width & 3u)) & 3u);
+ } else if (self->private_impl.f_bits_per_pixel == 16u) {
+ self->private_impl.f_pad_per_row = ((self->private_impl.f_width & 1u) * 2u);
+ } else if (self->private_impl.f_bits_per_pixel == 24u) {
+ self->private_impl.f_pad_per_row = (self->private_impl.f_width & 3u);
+ } else if (self->private_impl.f_bits_per_pixel == 32u) {
+ self->private_impl.f_pad_per_row = 0u;
+ }
+ self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ if (a_dst != NULL) {
+ v_dst_pixfmt = 2164295816u;
+ if ((self->private_impl.f_channel_num_bits[0u] > 8u) ||
+ (self->private_impl.f_channel_num_bits[1u] > 8u) ||
+ (self->private_impl.f_channel_num_bits[2u] > 8u) ||
+ (self->private_impl.f_channel_num_bits[3u] > 8u)) {
+ v_dst_pixfmt = 2164308923u;
+ }
+ wuffs_base__image_config__set(
+ a_dst,
+ v_dst_pixfmt,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ self->private_impl.f_frame_config_io_position,
+ (self->private_impl.f_channel_masks[3u] == 0u));
+ }
+ self->private_impl.f_call_sequence = 32u;
+
+ ok:
+ self->private_impl.p_do_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bmp.decoder.decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__decode_frame_config(
+ wuffs_bmp__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 2)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func bmp.decoder.do_decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__do_decode_frame_config(
+ wuffs_bmp__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 32u) {
+ } else if (self->private_impl.f_call_sequence < 32u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_bmp__decoder__do_decode_image_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (self->private_impl.f_call_sequence == 40u) {
+ if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_restart);
+ goto exit;
+ }
+ } else if (self->private_impl.f_call_sequence == 64u) {
+ self->private_impl.f_call_sequence = 96u;
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (a_dst != NULL) {
+ wuffs_base__frame_config__set(
+ a_dst,
+ wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height),
+ ((wuffs_base__flicks)(0u)),
+ 0u,
+ self->private_impl.f_frame_config_io_position,
+ 0u,
+ true,
+ false,
+ 4278190080u);
+ }
+ self->private_impl.f_call_sequence = 64u;
+
+ ok:
+ self->private_impl.p_do_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bmp.decoder.decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__decode_frame(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 3)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_bmp__decoder__do_decode_frame(self,
+ a_dst,
+ a_src,
+ a_blend,
+ a_workbuf,
+ a_opts);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func bmp.decoder.do_decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__do_decode_frame(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 64u) {
+ } else if (self->private_impl.f_call_sequence < 64u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_bmp__decoder__do_decode_frame_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_padding;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
+ if ((self->private_impl.f_width > 0u) && (self->private_impl.f_height > 0u)) {
+ self->private_impl.f_dst_x = 0u;
+ if (self->private_impl.f_top_down) {
+ self->private_impl.f_dst_y = 0u;
+ self->private_impl.f_dst_y_inc = 1u;
+ } else {
+ self->private_impl.f_dst_y = ((uint32_t)(self->private_impl.f_height - 1u));
+ self->private_impl.f_dst_y_inc = 4294967295u;
+ }
+ v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
+ wuffs_base__pixel_buffer__pixel_format(a_dst),
+ wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048)),
+ wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
+ wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
+ a_blend);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ while (true) {
+ if (self->private_impl.f_compression == 0u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_status = wuffs_bmp__decoder__swizzle_none(self, a_dst, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ } else if (self->private_impl.f_compression < 3u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_status = wuffs_bmp__decoder__swizzle_rle(self, a_dst, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ } else if (self->private_impl.f_compression == 3u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_status = wuffs_bmp__decoder__swizzle_bitfields(self, a_dst, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ } else {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_status = wuffs_bmp__decoder__swizzle_low_bit_depth(self, a_dst, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ if (wuffs_base__status__is_ok(&v_status)) {
+ break;
+ } else if (v_status.repr != wuffs_bmp__note__internal_note_short_read) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ }
+ self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_pending_pad;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
+ self->private_impl.f_pending_pad = 0u;
+ }
+ self->private_impl.f_call_sequence = 96u;
+
+ ok:
+ self->private_impl.p_do_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bmp.decoder.swizzle_none
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__swizzle_none(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint32_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_bytes_per_row = 0;
+ uint32_t v_src_bytes_per_pixel = 0;
+ wuffs_base__slice_u8 v_dst_palette = {0};
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint64_t v_i = 0;
+ uint64_t v_j = 0;
+ uint64_t v_n = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ goto exit;
+ }
+ v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
+ v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
+ v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ label__outer__continue:;
+ while (true) {
+ while (self->private_impl.f_pending_pad > 0u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
+ goto ok;
+ }
+ self->private_impl.f_pending_pad -= 1u;
+ iop_a_src += 1u;
+ }
+ while (true) {
+ if (self->private_impl.f_dst_x == self->private_impl.f_width) {
+ self->private_impl.f_dst_x = 0u;
+ self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
+ if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
+ if (self->private_impl.f_height > 0u) {
+ self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
+ }
+ goto label__outer__break;
+ } else if (self->private_impl.f_pad_per_row != 0u) {
+ self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
+ goto label__outer__continue;
+ }
+ }
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
+ }
+ v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
+ if (v_i >= ((uint64_t)(v_dst.len))) {
+ if (self->private_impl.f_bits_per_pixel > 32u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ v_src_bytes_per_pixel = (self->private_impl.f_bits_per_pixel / 8u);
+ if (v_src_bytes_per_pixel == 0u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__unsupported_bmp_file);
+ goto exit;
+ }
+ v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
+ v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
+ v_j = v_n;
+ while (v_j >= 8u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
+ iop_a_src += (v_src_bytes_per_pixel * 8u);
+ }
+ v_j -= 8u;
+ }
+ while (v_j > 0u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
+ iop_a_src += (v_src_bytes_per_pixel * 1u);
+ }
+ v_j -= 1u;
+ }
+ } else {
+ v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
+ &self->private_impl.f_swizzler,
+ wuffs_base__slice_u8__subslice_i(v_dst, v_i),
+ v_dst_palette,
+ &iop_a_src,
+ io2_a_src);
+ }
+ if (v_n == 0u) {
+ status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
+ goto ok;
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
+ }
+ }
+ label__outer__break:;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bmp.decoder.swizzle_rle
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__swizzle_rle(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint32_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_bytes_per_row = 0;
+ wuffs_base__slice_u8 v_dst_palette = {0};
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_row = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint64_t v_i = 0;
+ uint64_t v_n = 0;
+ uint32_t v_p0 = 0;
+ uint8_t v_code = 0;
+ uint8_t v_indexes[2] = {0};
+ uint32_t v_rle_state = 0;
+ uint32_t v_chunk_bits = 0;
+ uint32_t v_chunk_count = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ goto exit;
+ }
+ v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
+ v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
+ v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ v_rle_state = self->private_impl.f_rle_state;
+ label__outer__continue:;
+ while (true) {
+ v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
+ v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
+ }
+ label__middle__continue:;
+ while (true) {
+ v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
+ if (v_i <= ((uint64_t)(v_row.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_row, v_i);
+ } else {
+ v_dst = wuffs_base__utility__empty_slice_u8();
+ }
+ while (true) {
+ while (true) {
+ if (v_rle_state == 0u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
+ goto label__goto_suspend__break;
+ }
+ v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ if (v_code == 0u) {
+ v_rle_state = 2u;
+ continue;
+ }
+ self->private_impl.f_rle_length = ((uint32_t)(v_code));
+ v_rle_state = 1u;
+ continue;
+ } else if (v_rle_state == 1u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
+ goto label__goto_suspend__break;
+ }
+ v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ if (self->private_impl.f_bits_per_pixel == 8u) {
+ v_p0 = 0u;
+ while (v_p0 < self->private_impl.f_rle_length) {
+ self->private_data.f_scratch[v_p0] = v_code;
+ v_p0 += 1u;
+ }
+ } else {
+ v_indexes[0u] = ((uint8_t)((v_code >> 4u)));
+ v_indexes[1u] = (v_code & 15u);
+ v_p0 = 0u;
+ while (v_p0 < self->private_impl.f_rle_length) {
+ self->private_data.f_scratch[(v_p0 + 0u)] = v_indexes[0u];
+ self->private_data.f_scratch[(v_p0 + 1u)] = v_indexes[1u];
+ v_p0 += 2u;
+ }
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_rle_length));
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, self->private_impl.f_rle_length);
+ v_rle_state = 0u;
+ goto label__middle__continue;
+ } else if (v_rle_state == 2u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
+ goto label__goto_suspend__break;
+ }
+ v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ if (v_code < 2u) {
+ if ((self->private_impl.f_dst_y >= self->private_impl.f_height) && (v_code == 0u)) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
+ goto exit;
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, 18446744073709551615u);
+ self->private_impl.f_dst_x = 0u;
+ self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
+ if (v_code > 0u) {
+ goto label__outer__break;
+ }
+ v_rle_state = 0u;
+ goto label__outer__continue;
+ } else if (v_code == 2u) {
+ v_rle_state = 4u;
+ continue;
+ }
+ self->private_impl.f_rle_length = ((uint32_t)(v_code));
+ self->private_impl.f_rle_padded = ((self->private_impl.f_bits_per_pixel == 8u) && ((v_code & 1u) != 0u));
+ v_rle_state = 3u;
+ continue;
+ } else if (v_rle_state == 3u) {
+ if (self->private_impl.f_bits_per_pixel == 8u) {
+ v_n = wuffs_base__pixel_swizzler__limited_swizzle_u32_interleaved_from_reader(
+ &self->private_impl.f_swizzler,
+ self->private_impl.f_rle_length,
+ v_dst,
+ v_dst_palette,
+ &iop_a_src,
+ io2_a_src);
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
+ wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, ((uint32_t)(v_n)));
+ } else {
+ v_chunk_count = ((self->private_impl.f_rle_length + 3u) / 4u);
+ v_p0 = 0u;
+ while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 2u)) {
+ v_chunk_bits = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2u;
+ self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u))));
+ self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u))));
+ self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u))));
+ self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u))));
+ v_p0 = ((v_p0 & 255u) + 4u);
+ v_chunk_count -= 1u;
+ }
+ v_p0 = wuffs_base__u32__min(v_p0, self->private_impl.f_rle_length);
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, v_p0));
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, v_p0);
+ wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_rle_length, v_p0);
+ }
+ if (self->private_impl.f_rle_length > 0u) {
+ goto label__goto_suspend__break;
+ }
+ if (self->private_impl.f_rle_padded) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
+ goto label__goto_suspend__break;
+ }
+ iop_a_src += 1u;
+ self->private_impl.f_rle_padded = false;
+ }
+ v_rle_state = 0u;
+ goto label__middle__continue;
+ } else if (v_rle_state == 4u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
+ goto label__goto_suspend__break;
+ }
+ self->private_impl.f_rle_delta_x = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ v_rle_state = 5u;
+ continue;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 1u) {
+ goto label__goto_suspend__break;
+ }
+ v_code = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ if (self->private_impl.f_rle_delta_x > 0u) {
+ wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_dst, v_dst_palette, ((uint64_t)(self->private_impl.f_rle_delta_x)));
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(self->private_impl.f_rle_delta_x)));
+ self->private_impl.f_rle_delta_x = 0u;
+ if (self->private_impl.f_dst_x > self->private_impl.f_width) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
+ goto exit;
+ }
+ }
+ if (v_code > 0u) {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_code -= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ while (true) {
+ self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
+ if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_rle_compression);
+ goto exit;
+ }
+ v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
+ v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
+ }
+ if (v_code <= 0u) {
+ wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, ((uint64_t)(self->private_impl.f_dst_x)));
+ break;
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_code -= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ }
+ }
+ v_rle_state = 0u;
+ goto label__middle__continue;
+ }
+ }
+ label__goto_suspend__break:;
+ self->private_impl.f_rle_state = v_rle_state;
+ status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
+ goto ok;
+ }
+ }
+ label__outer__break:;
+ while (self->private_impl.f_dst_y < self->private_impl.f_height) {
+ v_row = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (v_dst_bytes_per_row < ((uint64_t)(v_row.len))) {
+ v_row = wuffs_base__slice_u8__subslice_j(v_row, v_dst_bytes_per_row);
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_transparent_black(&self->private_impl.f_swizzler, v_row, v_dst_palette, 18446744073709551615u);
+ self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
+ }
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bmp.decoder.swizzle_bitfields
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__swizzle_bitfields(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint32_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_bytes_per_row = 0;
+ wuffs_base__slice_u8 v_dst_palette = {0};
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint64_t v_i = 0;
+ uint64_t v_n = 0;
+ uint32_t v_p0 = 0;
+ uint32_t v_p1 = 0;
+ uint32_t v_p1_temp = 0;
+ uint32_t v_num_bits = 0;
+ uint32_t v_c = 0;
+ uint32_t v_c32 = 0;
+ uint32_t v_channel = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ goto exit;
+ }
+ v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
+ v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
+ v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ label__outer__continue:;
+ while (true) {
+ while (self->private_impl.f_pending_pad > 0u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
+ goto ok;
+ }
+ self->private_impl.f_pending_pad -= 1u;
+ iop_a_src += 1u;
+ }
+ while (true) {
+ if (self->private_impl.f_dst_x == self->private_impl.f_width) {
+ self->private_impl.f_dst_x = 0u;
+ self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
+ if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
+ if (self->private_impl.f_height > 0u) {
+ self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
+ }
+ goto label__outer__break;
+ } else if (self->private_impl.f_pad_per_row != 0u) {
+ self->private_impl.f_pending_pad = self->private_impl.f_pad_per_row;
+ goto label__outer__continue;
+ }
+ }
+ v_p1_temp = ((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x));
+ v_p1 = wuffs_base__u32__min(v_p1_temp, 256u);
+ v_p0 = 0u;
+ while (v_p0 < v_p1) {
+ if (self->private_impl.f_bits_per_pixel == 16u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
+ break;
+ }
+ v_c32 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2u;
+ } else {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
+ break;
+ }
+ v_c32 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4u;
+ }
+ v_channel = 0u;
+ while (v_channel < 4u) {
+ if (self->private_impl.f_channel_num_bits[v_channel] == 0u) {
+ self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = 255u;
+ self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = 255u;
+ } else {
+ v_c = ((v_c32 & self->private_impl.f_channel_masks[v_channel]) >> self->private_impl.f_channel_shifts[v_channel]);
+ v_num_bits = ((uint32_t)(self->private_impl.f_channel_num_bits[v_channel]));
+ while (v_num_bits < 16u) {
+ v_c |= ((uint32_t)(v_c << v_num_bits));
+ v_num_bits *= 2u;
+ }
+ v_c >>= (v_num_bits - 16u);
+ self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 0u)] = ((uint8_t)((v_c >> 0u)));
+ self->private_data.f_scratch[((8u * v_p0) + (2u * v_channel) + 1u)] = ((uint8_t)((v_c >> 8u)));
+ }
+ v_channel += 1u;
+ }
+ v_p0 += 1u;
+ }
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
+ }
+ v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
+ if (v_i >= ((uint64_t)(v_dst.len))) {
+ v_n = ((uint64_t)(v_p0));
+ } else {
+ v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, (8u * v_p0)));
+ }
+ if (v_n == 0u) {
+ status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
+ goto ok;
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
+ }
+ }
+ label__outer__break:;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bmp.decoder.swizzle_low_bit_depth
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__swizzle_low_bit_depth(
+ wuffs_bmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint32_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_bytes_per_row = 0;
+ wuffs_base__slice_u8 v_dst_palette = {0};
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint64_t v_i = 0;
+ uint64_t v_n = 0;
+ uint32_t v_p0 = 0;
+ uint32_t v_chunk_bits = 0;
+ uint32_t v_chunk_count = 0;
+ uint32_t v_pixels_per_chunk = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ goto exit;
+ }
+ v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
+ v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
+ v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_scratch, 1024, 2048));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ while (true) {
+ if (self->private_impl.f_dst_x == self->private_impl.f_width) {
+ self->private_impl.f_dst_x = 0u;
+ self->private_impl.f_dst_y += self->private_impl.f_dst_y_inc;
+ if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
+ break;
+ }
+ }
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
+ }
+ v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
+ if (v_i >= ((uint64_t)(v_dst.len))) {
+ if (self->private_impl.f_bits_per_pixel == 1u) {
+ v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u);
+ v_pixels_per_chunk = 32u;
+ } else if (self->private_impl.f_bits_per_pixel == 2u) {
+ v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u);
+ v_pixels_per_chunk = 16u;
+ } else {
+ v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u);
+ v_pixels_per_chunk = 8u;
+ }
+ while ((v_chunk_count >= 64u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 256u)) {
+ iop_a_src += 256u;
+ self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 64u))));
+ v_chunk_count -= 64u;
+ }
+ while ((v_chunk_count >= 8u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 32u)) {
+ iop_a_src += 32u;
+ self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 8u))));
+ v_chunk_count -= 8u;
+ }
+ while (v_chunk_count > 0u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
+ status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
+ goto ok;
+ }
+ iop_a_src += 4u;
+ self->private_impl.f_dst_x = wuffs_base__u32__min(self->private_impl.f_width, ((uint32_t)(self->private_impl.f_dst_x + (v_pixels_per_chunk * 1u))));
+ v_chunk_count -= 1u;
+ }
+ continue;
+ }
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
+ v_p0 = 0u;
+ if (self->private_impl.f_bits_per_pixel == 1u) {
+ v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 31u) / 32u);
+ v_chunk_count = wuffs_base__u32__min(v_chunk_count, 16u);
+ while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
+ v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4u;
+ self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((1u & (v_chunk_bits >> 31u))));
+ self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((1u & (v_chunk_bits >> 30u))));
+ self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((1u & (v_chunk_bits >> 29u))));
+ self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((1u & (v_chunk_bits >> 28u))));
+ self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((1u & (v_chunk_bits >> 27u))));
+ self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((1u & (v_chunk_bits >> 26u))));
+ self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((1u & (v_chunk_bits >> 25u))));
+ self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((1u & (v_chunk_bits >> 24u))));
+ self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((1u & (v_chunk_bits >> 23u))));
+ self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((1u & (v_chunk_bits >> 22u))));
+ self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((1u & (v_chunk_bits >> 21u))));
+ self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((1u & (v_chunk_bits >> 20u))));
+ self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((1u & (v_chunk_bits >> 19u))));
+ self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((1u & (v_chunk_bits >> 18u))));
+ self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((1u & (v_chunk_bits >> 17u))));
+ self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((1u & (v_chunk_bits >> 16u))));
+ self->private_data.f_scratch[(v_p0 + 16u)] = ((uint8_t)((1u & (v_chunk_bits >> 15u))));
+ self->private_data.f_scratch[(v_p0 + 17u)] = ((uint8_t)((1u & (v_chunk_bits >> 14u))));
+ self->private_data.f_scratch[(v_p0 + 18u)] = ((uint8_t)((1u & (v_chunk_bits >> 13u))));
+ self->private_data.f_scratch[(v_p0 + 19u)] = ((uint8_t)((1u & (v_chunk_bits >> 12u))));
+ self->private_data.f_scratch[(v_p0 + 20u)] = ((uint8_t)((1u & (v_chunk_bits >> 11u))));
+ self->private_data.f_scratch[(v_p0 + 21u)] = ((uint8_t)((1u & (v_chunk_bits >> 10u))));
+ self->private_data.f_scratch[(v_p0 + 22u)] = ((uint8_t)((1u & (v_chunk_bits >> 9u))));
+ self->private_data.f_scratch[(v_p0 + 23u)] = ((uint8_t)((1u & (v_chunk_bits >> 8u))));
+ self->private_data.f_scratch[(v_p0 + 24u)] = ((uint8_t)((1u & (v_chunk_bits >> 7u))));
+ self->private_data.f_scratch[(v_p0 + 25u)] = ((uint8_t)((1u & (v_chunk_bits >> 6u))));
+ self->private_data.f_scratch[(v_p0 + 26u)] = ((uint8_t)((1u & (v_chunk_bits >> 5u))));
+ self->private_data.f_scratch[(v_p0 + 27u)] = ((uint8_t)((1u & (v_chunk_bits >> 4u))));
+ self->private_data.f_scratch[(v_p0 + 28u)] = ((uint8_t)((1u & (v_chunk_bits >> 3u))));
+ self->private_data.f_scratch[(v_p0 + 29u)] = ((uint8_t)((1u & (v_chunk_bits >> 2u))));
+ self->private_data.f_scratch[(v_p0 + 30u)] = ((uint8_t)((1u & (v_chunk_bits >> 1u))));
+ self->private_data.f_scratch[(v_p0 + 31u)] = ((uint8_t)((1u & (v_chunk_bits >> 0u))));
+ v_p0 = ((v_p0 & 511u) + 32u);
+ v_chunk_count -= 1u;
+ }
+ } else if (self->private_impl.f_bits_per_pixel == 2u) {
+ v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 15u) / 16u);
+ v_chunk_count = wuffs_base__u32__min(v_chunk_count, 32u);
+ while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
+ v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4u;
+ self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((3u & (v_chunk_bits >> 30u))));
+ self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((3u & (v_chunk_bits >> 28u))));
+ self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((3u & (v_chunk_bits >> 26u))));
+ self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((3u & (v_chunk_bits >> 24u))));
+ self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((3u & (v_chunk_bits >> 22u))));
+ self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((3u & (v_chunk_bits >> 20u))));
+ self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((3u & (v_chunk_bits >> 18u))));
+ self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((3u & (v_chunk_bits >> 16u))));
+ self->private_data.f_scratch[(v_p0 + 8u)] = ((uint8_t)((3u & (v_chunk_bits >> 14u))));
+ self->private_data.f_scratch[(v_p0 + 9u)] = ((uint8_t)((3u & (v_chunk_bits >> 12u))));
+ self->private_data.f_scratch[(v_p0 + 10u)] = ((uint8_t)((3u & (v_chunk_bits >> 10u))));
+ self->private_data.f_scratch[(v_p0 + 11u)] = ((uint8_t)((3u & (v_chunk_bits >> 8u))));
+ self->private_data.f_scratch[(v_p0 + 12u)] = ((uint8_t)((3u & (v_chunk_bits >> 6u))));
+ self->private_data.f_scratch[(v_p0 + 13u)] = ((uint8_t)((3u & (v_chunk_bits >> 4u))));
+ self->private_data.f_scratch[(v_p0 + 14u)] = ((uint8_t)((3u & (v_chunk_bits >> 2u))));
+ self->private_data.f_scratch[(v_p0 + 15u)] = ((uint8_t)((3u & (v_chunk_bits >> 0u))));
+ v_p0 = ((v_p0 & 511u) + 16u);
+ v_chunk_count -= 1u;
+ }
+ } else {
+ v_chunk_count = ((wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x) + 7u) / 8u);
+ v_chunk_count = wuffs_base__u32__min(v_chunk_count, 64u);
+ while ((v_chunk_count > 0u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
+ v_chunk_bits = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4u;
+ self->private_data.f_scratch[(v_p0 + 0u)] = ((uint8_t)((15u & (v_chunk_bits >> 28u))));
+ self->private_data.f_scratch[(v_p0 + 1u)] = ((uint8_t)((15u & (v_chunk_bits >> 24u))));
+ self->private_data.f_scratch[(v_p0 + 2u)] = ((uint8_t)((15u & (v_chunk_bits >> 20u))));
+ self->private_data.f_scratch[(v_p0 + 3u)] = ((uint8_t)((15u & (v_chunk_bits >> 16u))));
+ self->private_data.f_scratch[(v_p0 + 4u)] = ((uint8_t)((15u & (v_chunk_bits >> 12u))));
+ self->private_data.f_scratch[(v_p0 + 5u)] = ((uint8_t)((15u & (v_chunk_bits >> 8u))));
+ self->private_data.f_scratch[(v_p0 + 6u)] = ((uint8_t)((15u & (v_chunk_bits >> 4u))));
+ self->private_data.f_scratch[(v_p0 + 7u)] = ((uint8_t)((15u & (v_chunk_bits >> 0u))));
+ v_p0 = ((v_p0 & 511u) + 8u);
+ v_chunk_count -= 1u;
+ }
+ }
+ v_p0 = wuffs_base__u32__min(v_p0, wuffs_base__u32__sat_sub(self->private_impl.f_width, self->private_impl.f_dst_x));
+ v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, v_p0));
+ if (v_n == 0u) {
+ status = wuffs_base__make_status(wuffs_bmp__note__internal_note_short_read);
+ goto ok;
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
+ }
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bmp.decoder.frame_dirty_rect
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_bmp__decoder__frame_dirty_rect(
+ const wuffs_bmp__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ return wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height);
+}
+
+// -------- func bmp.decoder.num_animation_loops
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_bmp__decoder__num_animation_loops(
+ const wuffs_bmp__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func bmp.decoder.num_decoded_frame_configs
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bmp__decoder__num_decoded_frame_configs(
+ const wuffs_bmp__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 32u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func bmp.decoder.num_decoded_frames
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bmp__decoder__num_decoded_frames(
+ const wuffs_bmp__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 64u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func bmp.decoder.restart_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__restart_frame(
+ wuffs_bmp__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (self->private_impl.f_call_sequence < 32u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ }
+ if (a_index != 0u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_call_sequence = 40u;
+ self->private_impl.f_frame_config_io_position = a_io_position;
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func bmp.decoder.set_report_metadata
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_bmp__decoder__set_report_metadata(
+ wuffs_bmp__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func bmp.decoder.tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bmp__decoder__tell_me_more(
+ wuffs_bmp__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 4)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_bmp__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_bmp__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_tell_me_more[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func bmp.decoder.do_tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__do_tell_me_more(
+ wuffs_bmp__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ if (self->private_impl.f_io_redirect_fourcc <= 1u) {
+ status = wuffs_base__make_status(wuffs_base__error__no_more_information);
+ goto exit;
+ }
+ if (a_minfo != NULL) {
+ wuffs_base__more_information__set(a_minfo,
+ 1u,
+ self->private_impl.f_io_redirect_fourcc,
+ 0u,
+ self->private_impl.f_io_redirect_pos,
+ 18446744073709551615u);
+ }
+ self->private_impl.f_io_redirect_fourcc = 1u;
+
+ goto ok;
+ ok:
+ goto exit;
+ exit:
+ return status;
+}
+
+// -------- func bmp.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bmp__decoder__history_retain_length(
+ const wuffs_bmp__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func bmp.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_bmp__decoder__workbuf_len(
+ const wuffs_bmp__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(0u, 0u);
+}
+
+// -------- func bmp.decoder.read_palette
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__read_palette(
+ wuffs_bmp__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_i = 0;
+ uint32_t v_argb = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_read_palette[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_read_palette[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_bitmap_info_len == 12u) {
+ while ((v_i < 256u) && (self->private_impl.f_padding >= 3u)) {
+ self->private_impl.f_padding -= 3u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
+ t_0 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
+ iop_a_src += 3;
+ } else {
+ self->private_data.s_read_palette[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
+ if (num_bits_0 == 16) {
+ t_0 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0)) << 56;
+ }
+ }
+ v_argb = t_0;
+ }
+ v_argb |= 4278190080u;
+ self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
+ self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
+ self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
+ self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
+ v_i += 1u;
+ }
+ } else {
+ while ((v_i < 256u) && (self->private_impl.f_padding >= 4u)) {
+ self->private_impl.f_padding -= 4u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_read_palette[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_read_palette[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1)) << 56;
+ }
+ }
+ v_argb = t_1;
+ }
+ v_argb |= 4278190080u;
+ self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
+ self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
+ self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
+ self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
+ v_i += 1u;
+ }
+ }
+ while (v_i < 256u) {
+ self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u;
+ self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u;
+ self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u;
+ self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u;
+ v_i += 1u;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_read_palette[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_read_palette[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_read_palette[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bmp.decoder.process_masks
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bmp__decoder__process_masks(
+ wuffs_bmp__decoder* self) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_i = 0;
+ uint32_t v_mask = 0;
+ uint32_t v_n = 0;
+
+ while (v_i < 4u) {
+ v_mask = self->private_impl.f_channel_masks[v_i];
+ if (v_mask != 0u) {
+ v_n = 0u;
+ while ((v_mask & 1u) == 0u) {
+ v_n += 1u;
+ v_mask >>= 1u;
+ }
+ self->private_impl.f_channel_shifts[v_i] = ((uint8_t)((v_n & 31u)));
+ v_n = 0u;
+ while ((v_mask & 1u) == 1u) {
+ v_n += 1u;
+ v_mask >>= 1u;
+ }
+ if ((v_mask != 0u) || (v_n > 32u)) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_channel_num_bits[v_i] = ((uint8_t)(v_n));
+ } else if (v_i != 3u) {
+ status = wuffs_base__make_status(wuffs_bmp__error__bad_header);
+ goto exit;
+ }
+ v_i += 1u;
+ }
+
+ goto ok;
+ ok:
+ goto exit;
+ exit:
+ return status;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_bzip2__error__bad_huffman_code_over_subscribed[] = "#bzip2: bad Huffman code (over-subscribed)";
+const char wuffs_bzip2__error__bad_huffman_code_under_subscribed[] = "#bzip2: bad Huffman code (under-subscribed)";
+const char wuffs_bzip2__error__bad_block_header[] = "#bzip2: bad block header";
+const char wuffs_bzip2__error__bad_block_length[] = "#bzip2: bad block length";
+const char wuffs_bzip2__error__bad_checksum[] = "#bzip2: bad checksum";
+const char wuffs_bzip2__error__bad_header[] = "#bzip2: bad header";
+const char wuffs_bzip2__error__bad_number_of_sections[] = "#bzip2: bad number of sections";
+const char wuffs_bzip2__error__truncated_input[] = "#bzip2: truncated input";
+const char wuffs_bzip2__error__unsupported_block_randomization[] = "#bzip2: unsupported block randomization";
+const char wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state[] = "#bzip2: internal error: inconsistent Huffman decoder state";
+
+// ---------------- Private Consts
+
+static const uint8_t
+WUFFS_BZIP2__CLAMP_TO_5[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 1, 2, 3, 4, 5, 5, 5,
+};
+
+static const uint32_t
+WUFFS_BZIP2__REV_CRC32_TABLE[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 79764919, 159529838, 222504665, 319059676, 398814059, 445009330, 507990021,
+ 638119352, 583659535, 797628118, 726387553, 890018660, 835552979, 1015980042, 944750013,
+ 1276238704, 1221641927, 1167319070, 1095957929, 1595256236, 1540665371, 1452775106, 1381403509,
+ 1780037320, 1859660671, 1671105958, 1733955601, 2031960084, 2111593891, 1889500026, 1952343757,
+ 2552477408, 2632100695, 2443283854, 2506133561, 2334638140, 2414271883, 2191915858, 2254759653,
+ 3190512472, 3135915759, 3081330742, 3009969537, 2905550212, 2850959411, 2762807018, 2691435357,
+ 3560074640, 3505614887, 3719321342, 3648080713, 3342211916, 3287746299, 3467911202, 3396681109,
+ 4063920168, 4143685023, 4223187782, 4286162673, 3779000052, 3858754371, 3904687514, 3967668269,
+ 881225847, 809987520, 1023691545, 969234094, 662832811, 591600412, 771767749, 717299826,
+ 311336399, 374308984, 453813921, 533576470, 25881363, 88864420, 134795389, 214552010,
+ 2023205639, 2086057648, 1897238633, 1976864222, 1804852699, 1867694188, 1645340341, 1724971778,
+ 1587496639, 1516133128, 1461550545, 1406951526, 1302016099, 1230646740, 1142491917, 1087903418,
+ 2896545431, 2825181984, 2770861561, 2716262478, 3215044683, 3143675388, 3055782693, 3001194130,
+ 2326604591, 2389456536, 2200899649, 2280525302, 2578013683, 2640855108, 2418763421, 2498394922,
+ 3769900519, 3832873040, 3912640137, 3992402750, 4088425275, 4151408268, 4197601365, 4277358050,
+ 3334271071, 3263032808, 3476998961, 3422541446, 3585640067, 3514407732, 3694837229, 3640369242,
+ 1762451694, 1842216281, 1619975040, 1682949687, 2047383090, 2127137669, 1938468188, 2001449195,
+ 1325665622, 1271206113, 1183200824, 1111960463, 1543535498, 1489069629, 1434599652, 1363369299,
+ 622672798, 568075817, 748617968, 677256519, 907627842, 853037301, 1067152940, 995781531,
+ 51762726, 131386257, 177728840, 240578815, 269590778, 349224269, 429104020, 491947555,
+ 4046411278, 4126034873, 4172115296, 4234965207, 3794477266, 3874110821, 3953728444, 4016571915,
+ 3609705398, 3555108353, 3735388376, 3664026991, 3290680682, 3236090077, 3449943556, 3378572211,
+ 3174993278, 3120533705, 3032266256, 2961025959, 2923101090, 2868635157, 2813903052, 2742672763,
+ 2604032198, 2683796849, 2461293480, 2524268063, 2284983834, 2364738477, 2175806836, 2238787779,
+ 1569362073, 1498123566, 1409854455, 1355396672, 1317987909, 1246755826, 1192025387, 1137557660,
+ 2072149281, 2135122070, 1912620623, 1992383480, 1753615357, 1816598090, 1627664531, 1707420964,
+ 295390185, 358241886, 404320391, 483945776, 43990325, 106832002, 186451547, 266083308,
+ 932423249, 861060070, 1041341759, 986742920, 613929101, 542559546, 756411363, 701822548,
+ 3316196985, 3244833742, 3425377559, 3370778784, 3601682597, 3530312978, 3744426955, 3689838204,
+ 3819031489, 3881883254, 3928223919, 4007849240, 4037393693, 4100235434, 4180117107, 4259748804,
+ 2310601993, 2373574846, 2151335527, 2231098320, 2596047829, 2659030626, 2470359227, 2550115596,
+ 2947551409, 2876312838, 2788305887, 2733848168, 3165939309, 3094707162, 3040238851, 2985771188,
+};
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__do_transform_io(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__prepare_block(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__read_code_lengths(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__build_huffman_tree(
+ wuffs_bzip2__decoder* self,
+ uint32_t a_which);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_bzip2__decoder__build_huffman_table(
+ wuffs_bzip2__decoder* self,
+ uint32_t a_which);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_bzip2__decoder__invert_bwt(
+ wuffs_bzip2__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_bzip2__decoder__flush_fast(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_dst);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__flush_slow(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_dst);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__decode_huffman_fast(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__decode_huffman_slow(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+// ---------------- VTables
+
+const wuffs_base__io_transformer__func_ptrs
+wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer = {
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_bzip2__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_bzip2__decoder__history_retain_length),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_bzip2__decoder__set_quirk),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__slice_u8))(&wuffs_bzip2__decoder__transform_io),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_bzip2__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_bzip2__decoder__initialize(
+ wuffs_bzip2__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
+ wuffs_base__io_transformer__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
+ (const void*)(&wuffs_bzip2__decoder__func_ptrs_for__wuffs_base__io_transformer);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_bzip2__decoder*
+wuffs_bzip2__decoder__alloc(void) {
+ wuffs_bzip2__decoder* x =
+ (wuffs_bzip2__decoder*)(calloc(sizeof(wuffs_bzip2__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_bzip2__decoder__initialize(
+ x, sizeof(wuffs_bzip2__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_bzip2__decoder(void) {
+ return sizeof(wuffs_bzip2__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func bzip2.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bzip2__decoder__get_quirk(
+ const wuffs_bzip2__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func bzip2.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bzip2__decoder__set_quirk(
+ wuffs_bzip2__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (a_key == 1u) {
+ self->private_impl.f_ignore_checksum = (a_value > 0u);
+ return wuffs_base__make_status(NULL);
+ }
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func bzip2.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_bzip2__decoder__history_retain_length(
+ const wuffs_bzip2__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func bzip2.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_bzip2__decoder__workbuf_len(
+ const wuffs_bzip2__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(0u, 0u);
+}
+
+// -------- func bzip2.decoder.transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_bzip2__decoder__transform_io(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_bzip2__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func bzip2.decoder.do_transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__do_transform_io(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_i = 0;
+ uint64_t v_tag = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ uint32_t v_final_checksum_want = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_do_transform_io[0].v_i;
+ v_tag = self->private_data.s_do_transform_io[0].v_tag;
+ v_final_checksum_want = self->private_data.s_do_transform_io[0].v_final_checksum_want;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c != 66u) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ if (v_c != 90u) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_c = t_2;
+ }
+ if (v_c != 104u) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_c = t_3;
+ }
+ if ((v_c < 49u) || (57u < v_c)) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_max_incl_block_size = (((uint32_t)((v_c - 48u))) * 100000u);
+ while (true) {
+ v_tag = 0u;
+ v_i = 0u;
+ while (v_i < 48u) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_4 = *iop_a_src++;
+ v_c = t_4;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ v_tag <<= 1u;
+ v_tag |= ((uint64_t)((self->private_impl.f_bits >> 31u)));
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 1u;
+ }
+ if (v_tag == 25779555029136u) {
+ break;
+ } else if (v_tag != 54156738319193u) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ status = wuffs_bzip2__decoder__prepare_block(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_block_size = 0u;
+ self->private_impl.f_decode_huffman_finished = false;
+ self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[0u] & 7u)];
+ self->private_impl.f_decode_huffman_ticks = 50u;
+ self->private_impl.f_decode_huffman_section = 0u;
+ self->private_impl.f_decode_huffman_run_shift = 0u;
+ while ( ! self->private_impl.f_decode_huffman_finished) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_status = wuffs_bzip2__decoder__decode_huffman_fast(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (wuffs_base__status__is_error(&v_status)) {
+ status = v_status;
+ goto exit;
+ } else if (self->private_impl.f_decode_huffman_finished) {
+ break;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ status = wuffs_bzip2__decoder__decode_huffman_slow(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ wuffs_bzip2__decoder__invert_bwt(self);
+ self->private_impl.f_block_checksum_have = 4294967295u;
+ if (self->private_impl.f_original_pointer >= self->private_impl.f_block_size) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
+ goto exit;
+ }
+ self->private_impl.f_flush_pointer = (self->private_data.f_bwt[self->private_impl.f_original_pointer] >> 12u);
+ self->private_impl.f_flush_repeat_count = 0u;
+ self->private_impl.f_flush_prev = 0u;
+ while (self->private_impl.f_block_size > 0u) {
+ wuffs_bzip2__decoder__flush_fast(self, a_dst);
+ if (self->private_impl.f_block_size <= 0u) {
+ break;
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ status = wuffs_bzip2__decoder__flush_slow(self, a_dst);
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ self->private_impl.f_block_checksum_have ^= 4294967295u;
+ if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_block_checksum_have != self->private_impl.f_block_checksum_want)) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum);
+ goto exit;
+ }
+ self->private_impl.f_final_checksum_have = (self->private_impl.f_block_checksum_have ^ ((self->private_impl.f_final_checksum_have >> 31u) | ((uint32_t)(self->private_impl.f_final_checksum_have << 1u))));
+ }
+ v_final_checksum_want = 0u;
+ v_i = 0u;
+ while (v_i < 32u) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ v_c = t_5;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ v_final_checksum_want <<= 1u;
+ v_final_checksum_want |= (self->private_impl.f_bits >> 31u);
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 1u;
+ }
+ if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_final_checksum_have != v_final_checksum_want)) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_checksum);
+ goto exit;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_do_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_transform_io[0].v_i = v_i;
+ self->private_data.s_do_transform_io[0].v_tag = v_tag;
+ self->private_data.s_do_transform_io[0].v_final_checksum_want = v_final_checksum_want;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bzip2.decoder.prepare_block
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__prepare_block(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_i = 0;
+ uint32_t v_j = 0;
+ uint32_t v_selector = 0;
+ uint32_t v_sel_ff = 0;
+ uint8_t v_movee = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_prepare_block[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_prepare_block[0].v_i;
+ v_selector = self->private_data.s_prepare_block[0].v_selector;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.f_block_checksum_want = 0u;
+ v_i = 0u;
+ while (v_i < 32u) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ self->private_impl.f_block_checksum_want <<= 1u;
+ self->private_impl.f_block_checksum_want |= (self->private_impl.f_bits >> 31u);
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 1u;
+ }
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ if ((self->private_impl.f_bits >> 31u) != 0u) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__unsupported_block_randomization);
+ goto exit;
+ }
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ self->private_impl.f_original_pointer = 0u;
+ v_i = 0u;
+ while (v_i < 24u) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_c = t_2;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ self->private_impl.f_original_pointer <<= 1u;
+ self->private_impl.f_original_pointer |= (self->private_impl.f_bits >> 31u);
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < 256u) {
+ self->private_data.f_presence[v_i] = 0u;
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < 256u) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_c = t_3;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ if ((self->private_impl.f_bits >> 31u) != 0u) {
+ self->private_data.f_presence[v_i] = 1u;
+ }
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 16u;
+ }
+ self->private_data.f_scratch = 0u;
+ v_i = 0u;
+ while (v_i < 256u) {
+ if (self->private_data.f_presence[v_i] == 0u) {
+ v_i += 16u;
+ continue;
+ }
+ while (true) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_4 = *iop_a_src++;
+ v_c = t_4;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ self->private_data.f_scratch += (self->private_impl.f_bits >> 31u);
+ self->private_data.f_presence[(v_i & 255u)] = ((uint8_t)((self->private_impl.f_bits >> 31u)));
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 1u;
+ if ((v_i & 15u) == 0u) {
+ break;
+ }
+ }
+ }
+ if ((self->private_data.f_scratch < 1u) || (256u < self->private_data.f_scratch)) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
+ goto exit;
+ }
+ self->private_impl.f_num_symbols = (self->private_data.f_scratch + 2u);
+ self->private_data.f_scratch = 0u;
+ v_i = 0u;
+ while (v_i < 3u) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ v_c = t_5;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ self->private_data.f_scratch <<= 1u;
+ self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u);
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 1u;
+ }
+ if ((self->private_data.f_scratch < 2u) || (6u < self->private_data.f_scratch)) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
+ goto exit;
+ }
+ self->private_impl.f_num_huffman_codes = self->private_data.f_scratch;
+ self->private_data.f_scratch = 0u;
+ v_i = 0u;
+ while (v_i < 15u) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_6 = *iop_a_src++;
+ v_c = t_6;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ self->private_data.f_scratch <<= 1u;
+ self->private_data.f_scratch |= (self->private_impl.f_bits >> 31u);
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 1u;
+ }
+ if ((self->private_data.f_scratch < 1u) || (18001u < self->private_data.f_scratch)) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
+ goto exit;
+ }
+ self->private_impl.f_num_sections = self->private_data.f_scratch;
+ v_i = 0u;
+ while (v_i < self->private_impl.f_num_huffman_codes) {
+ self->private_data.f_mtft[v_i] = ((uint8_t)(v_i));
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < self->private_impl.f_num_sections) {
+ v_selector = 0u;
+ while (true) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_7 = *iop_a_src++;
+ v_c = t_7;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ if ((self->private_impl.f_bits >> 31u) == 0u) {
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ break;
+ }
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_selector += 1u;
+ if (v_selector >= self->private_impl.f_num_huffman_codes) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
+ goto exit;
+ }
+ }
+ if (v_selector == 0u) {
+ self->private_data.f_huffman_selectors[v_i] = self->private_data.f_mtft[0u];
+ } else {
+ v_sel_ff = (v_selector & 255u);
+ v_movee = self->private_data.f_mtft[v_sel_ff];
+ wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_sel_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_sel_ff));
+ self->private_data.f_mtft[0u] = v_movee;
+ self->private_data.f_huffman_selectors[v_i] = v_movee;
+ }
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < self->private_impl.f_num_huffman_codes) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ status = wuffs_bzip2__decoder__read_code_lengths(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ v_status = wuffs_bzip2__decoder__build_huffman_tree(self, v_i);
+ if (wuffs_base__status__is_error(&v_status)) {
+ status = v_status;
+ goto exit;
+ }
+ wuffs_bzip2__decoder__build_huffman_table(self, v_i);
+ v_i += 1u;
+ }
+ v_i = 0u;
+ v_j = 0u;
+ while (v_i < 256u) {
+ if (self->private_data.f_presence[v_i] != 0u) {
+ self->private_data.f_mtft[(v_j & 255u)] = ((uint8_t)(v_i));
+ v_j += 1u;
+ }
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < 256u) {
+ self->private_data.f_letter_counts[v_i] = 0u;
+ v_i += 1u;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_prepare_block[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_prepare_block[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_prepare_block[0].v_i = v_i;
+ self->private_data.s_prepare_block[0].v_selector = v_selector;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bzip2.decoder.read_code_lengths
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__read_code_lengths(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_i = 0;
+ uint32_t v_code_length = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_read_code_lengths[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_read_code_lengths[0].v_i;
+ v_code_length = self->private_data.s_read_code_lengths[0].v_code_length;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.f_code_lengths_bitmask = 0u;
+ v_i = 0u;
+ while (v_i < 5u) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ v_code_length <<= 1u;
+ v_code_length |= (self->private_impl.f_bits >> 31u);
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < self->private_impl.f_num_symbols) {
+ while (true) {
+ if ((v_code_length < 1u) || (20u < v_code_length)) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_header);
+ goto exit;
+ }
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ if ((self->private_impl.f_bits >> 31u) == 0u) {
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ break;
+ }
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_c = t_2;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ if ((self->private_impl.f_bits >> 31u) == 0u) {
+ v_code_length += 1u;
+ } else {
+ v_code_length -= 1u;
+ }
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ }
+ self->private_impl.f_code_lengths_bitmask |= (((uint32_t)(1u)) << (v_code_length & 31u));
+ self->private_data.f_bwt[v_i] = v_code_length;
+ v_i += 1u;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_read_code_lengths[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_read_code_lengths[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_read_code_lengths[0].v_i = v_i;
+ self->private_data.s_read_code_lengths[0].v_code_length = v_code_length;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bzip2.decoder.build_huffman_tree
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__build_huffman_tree(
+ wuffs_bzip2__decoder* self,
+ uint32_t a_which) {
+ uint32_t v_code_length = 0;
+ uint32_t v_symbol_index = 0;
+ uint32_t v_num_branch_nodes = 0;
+ uint32_t v_stack_height = 0;
+ uint32_t v_stack_values[21] = {0};
+ uint32_t v_node_index = 0;
+ uint16_t v_leaf_value = 0;
+
+ self->private_data.f_huffman_trees[a_which][0u][0u] = 0u;
+ self->private_data.f_huffman_trees[a_which][0u][1u] = 0u;
+ v_num_branch_nodes = 1u;
+ v_stack_height = 1u;
+ v_stack_values[0u] = 0u;
+ v_code_length = 1u;
+ while (v_code_length <= 20u) {
+ if ((self->private_impl.f_code_lengths_bitmask & (((uint32_t)(1u)) << v_code_length)) == 0u) {
+ v_code_length += 1u;
+ continue;
+ }
+ v_symbol_index = 0u;
+ while (v_symbol_index < self->private_impl.f_num_symbols) {
+ if (self->private_data.f_bwt[v_symbol_index] != v_code_length) {
+ v_symbol_index += 1u;
+ continue;
+ }
+ while (true) {
+ if (v_stack_height <= 0u) {
+ return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_over_subscribed);
+ } else if (v_stack_height >= v_code_length) {
+ break;
+ }
+ v_node_index = v_stack_values[(v_stack_height - 1u)];
+ if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) {
+ self->private_data.f_huffman_trees[a_which][v_node_index][0u] = ((uint16_t)(v_num_branch_nodes));
+ } else {
+ self->private_data.f_huffman_trees[a_which][v_node_index][1u] = ((uint16_t)(v_num_branch_nodes));
+ }
+ if (v_num_branch_nodes >= 257u) {
+ return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed);
+ }
+ v_stack_values[v_stack_height] = v_num_branch_nodes;
+ self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][0u] = 0u;
+ self->private_data.f_huffman_trees[a_which][v_num_branch_nodes][1u] = 0u;
+ v_num_branch_nodes += 1u;
+ v_stack_height += 1u;
+ }
+ v_node_index = v_stack_values[(v_stack_height - 1u)];
+ if (v_symbol_index < 2u) {
+ v_leaf_value = ((uint16_t)((769u + v_symbol_index)));
+ } else if ((v_symbol_index + 1u) < self->private_impl.f_num_symbols) {
+ v_leaf_value = ((uint16_t)((511u + v_symbol_index)));
+ } else {
+ v_leaf_value = 768u;
+ }
+ if (self->private_data.f_huffman_trees[a_which][v_node_index][0u] == 0u) {
+ self->private_data.f_huffman_trees[a_which][v_node_index][0u] = v_leaf_value;
+ } else {
+ self->private_data.f_huffman_trees[a_which][v_node_index][1u] = v_leaf_value;
+ v_stack_height -= 1u;
+ while (v_stack_height > 0u) {
+ v_node_index = v_stack_values[(v_stack_height - 1u)];
+ if (self->private_data.f_huffman_trees[a_which][v_node_index][1u] == 0u) {
+ break;
+ }
+ v_stack_height -= 1u;
+ }
+ }
+ v_symbol_index += 1u;
+ }
+ v_code_length += 1u;
+ }
+ if (v_stack_height != 0u) {
+ return wuffs_base__make_status(wuffs_bzip2__error__bad_huffman_code_under_subscribed);
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func bzip2.decoder.build_huffman_table
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_bzip2__decoder__build_huffman_table(
+ wuffs_bzip2__decoder* self,
+ uint32_t a_which) {
+ uint32_t v_i = 0;
+ uint32_t v_bits = 0;
+ uint16_t v_n_bits = 0;
+ uint16_t v_child = 0;
+
+ while (v_i < 256u) {
+ v_bits = (v_i << 24u);
+ v_n_bits = 0u;
+ v_child = 0u;
+ while ((v_child < 257u) && (v_n_bits < 8u)) {
+ v_child = self->private_data.f_huffman_trees[a_which][v_child][(v_bits >> 31u)];
+ v_bits <<= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_n_bits += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ }
+ self->private_data.f_huffman_tables[a_which][v_i] = ((uint16_t)((v_child | (v_n_bits << 12u))));
+ v_i += 1u;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func bzip2.decoder.invert_bwt
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_bzip2__decoder__invert_bwt(
+ wuffs_bzip2__decoder* self) {
+ uint32_t v_i = 0;
+ uint32_t v_letter = 0;
+ uint32_t v_sum = 0;
+ uint32_t v_old_sum = 0;
+
+ v_sum = 0u;
+ v_i = 0u;
+ while (v_i < 256u) {
+ v_old_sum = v_sum;
+ v_sum += self->private_data.f_letter_counts[v_i];
+ self->private_data.f_letter_counts[v_i] = v_old_sum;
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < self->private_impl.f_block_size) {
+ v_letter = (self->private_data.f_bwt[v_i] & 255u);
+ self->private_data.f_bwt[(self->private_data.f_letter_counts[v_letter] & 1048575u)] |= (v_i << 12u);
+ self->private_data.f_letter_counts[v_letter] += 1u;
+ v_i += 1u;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func bzip2.decoder.flush_fast
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_bzip2__decoder__flush_fast(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_dst) {
+ uint32_t v_flush_pointer = 0;
+ uint32_t v_flush_repeat_count = 0;
+ uint8_t v_flush_prev = 0;
+ uint32_t v_block_checksum_have = 0;
+ uint32_t v_block_size = 0;
+ uint32_t v_entry = 0;
+ uint8_t v_curr = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+
+ v_flush_pointer = self->private_impl.f_flush_pointer;
+ v_flush_repeat_count = self->private_impl.f_flush_repeat_count;
+ v_flush_prev = self->private_impl.f_flush_prev;
+ v_block_checksum_have = self->private_impl.f_block_checksum_have;
+ v_block_size = self->private_impl.f_block_size;
+ while ((v_block_size > 0u) && (((uint64_t)(io2_a_dst - iop_a_dst)) >= 255u)) {
+ if (v_flush_repeat_count < 4u) {
+ v_entry = self->private_data.f_bwt[v_flush_pointer];
+ v_curr = ((uint8_t)(v_entry));
+ v_flush_pointer = (v_entry >> 12u);
+ if (v_curr == v_flush_prev) {
+ v_flush_repeat_count += 1u;
+ } else {
+ v_flush_repeat_count = 1u;
+ }
+ v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr)] ^ ((uint32_t)(v_block_checksum_have << 8u)));
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_curr), iop_a_dst += 1);
+ v_flush_prev = v_curr;
+ v_block_size -= 1u;
+ } else {
+ v_entry = self->private_data.f_bwt[v_flush_pointer];
+ v_curr = ((uint8_t)(v_entry));
+ v_flush_pointer = (v_entry >> 12u);
+ v_flush_repeat_count = ((uint32_t)(v_curr));
+ while (v_flush_repeat_count > 0u) {
+ v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev)] ^ ((uint32_t)(v_block_checksum_have << 8u)));
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) > 0u) {
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_flush_prev), iop_a_dst += 1);
+ }
+ v_flush_repeat_count -= 1u;
+ }
+ v_flush_repeat_count = 0u;
+ v_flush_prev = v_curr;
+ v_block_size -= 1u;
+ }
+ }
+ self->private_impl.f_flush_pointer = v_flush_pointer;
+ self->private_impl.f_flush_repeat_count = v_flush_repeat_count;
+ self->private_impl.f_flush_prev = v_flush_prev;
+ self->private_impl.f_block_checksum_have = v_block_checksum_have;
+ if (v_block_size <= 900000u) {
+ self->private_impl.f_block_size = v_block_size;
+ }
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func bzip2.decoder.flush_slow
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__flush_slow(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_dst) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_flush_pointer = 0;
+ uint32_t v_flush_repeat_count = 0;
+ uint8_t v_flush_prev = 0;
+ uint32_t v_block_checksum_have = 0;
+ uint32_t v_block_size = 0;
+ uint32_t v_entry = 0;
+ uint8_t v_curr = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_flush_slow[0];
+ if (coro_susp_point) {
+ v_flush_pointer = self->private_data.s_flush_slow[0].v_flush_pointer;
+ v_flush_repeat_count = self->private_data.s_flush_slow[0].v_flush_repeat_count;
+ v_flush_prev = self->private_data.s_flush_slow[0].v_flush_prev;
+ v_block_checksum_have = self->private_data.s_flush_slow[0].v_block_checksum_have;
+ v_block_size = self->private_data.s_flush_slow[0].v_block_size;
+ v_curr = self->private_data.s_flush_slow[0].v_curr;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ v_flush_pointer = self->private_impl.f_flush_pointer;
+ v_flush_repeat_count = self->private_impl.f_flush_repeat_count;
+ v_flush_prev = self->private_impl.f_flush_prev;
+ v_block_checksum_have = self->private_impl.f_block_checksum_have;
+ v_block_size = self->private_impl.f_block_size;
+ while ((v_block_size > 0u) && ! (self->private_impl.p_flush_slow[0] != 0)) {
+ if (v_flush_repeat_count < 4u) {
+ v_entry = self->private_data.f_bwt[v_flush_pointer];
+ v_curr = ((uint8_t)(v_entry));
+ v_flush_pointer = (v_entry >> 12u);
+ if (v_curr == v_flush_prev) {
+ v_flush_repeat_count += 1u;
+ } else {
+ v_flush_repeat_count = 1u;
+ }
+ v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_curr)] ^ ((uint32_t)(v_block_checksum_have << 8u)));
+ self->private_data.s_flush_slow[0].scratch = v_curr;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (iop_a_dst == io2_a_dst) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ goto suspend;
+ }
+ *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow[0].scratch));
+ v_flush_prev = v_curr;
+ v_block_size -= 1u;
+ } else {
+ v_entry = self->private_data.f_bwt[v_flush_pointer];
+ v_curr = ((uint8_t)(v_entry));
+ v_flush_pointer = (v_entry >> 12u);
+ v_flush_repeat_count = ((uint32_t)(v_curr));
+ while (v_flush_repeat_count > 0u) {
+ v_block_checksum_have = (WUFFS_BZIP2__REV_CRC32_TABLE[(((uint8_t)((v_block_checksum_have >> 24u))) ^ v_flush_prev)] ^ ((uint32_t)(v_block_checksum_have << 8u)));
+ self->private_data.s_flush_slow[0].scratch = v_flush_prev;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (iop_a_dst == io2_a_dst) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ goto suspend;
+ }
+ *iop_a_dst++ = ((uint8_t)(self->private_data.s_flush_slow[0].scratch));
+ v_flush_repeat_count -= 1u;
+ }
+ v_flush_repeat_count = 0u;
+ v_flush_prev = v_curr;
+ v_block_size -= 1u;
+ }
+ }
+ self->private_impl.f_flush_pointer = v_flush_pointer;
+ self->private_impl.f_flush_repeat_count = v_flush_repeat_count;
+ self->private_impl.f_flush_prev = v_flush_prev;
+ self->private_impl.f_block_checksum_have = v_block_checksum_have;
+ if (v_block_size <= 900000u) {
+ self->private_impl.f_block_size = v_block_size;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_flush_slow[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_flush_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_flush_slow[0].v_flush_pointer = v_flush_pointer;
+ self->private_data.s_flush_slow[0].v_flush_repeat_count = v_flush_repeat_count;
+ self->private_data.s_flush_slow[0].v_flush_prev = v_flush_prev;
+ self->private_data.s_flush_slow[0].v_block_checksum_have = v_block_checksum_have;
+ self->private_data.s_flush_slow[0].v_block_size = v_block_size;
+ self->private_data.s_flush_slow[0].v_curr = v_curr;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bzip2.decoder.decode_huffman_fast
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__decode_huffman_fast(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint32_t v_block_size = 0;
+ uint8_t v_which = 0;
+ uint32_t v_ticks = 0;
+ uint32_t v_section = 0;
+ uint32_t v_run_shift = 0;
+ uint16_t v_table_entry = 0;
+ uint16_t v_child = 0;
+ uint32_t v_child_ff = 0;
+ uint32_t v_i = 0;
+ uint32_t v_j = 0;
+ uint32_t v_output = 0;
+ uint32_t v_run = 0;
+ uint32_t v_mtft0 = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_bits = self->private_impl.f_bits;
+ v_n_bits = self->private_impl.f_n_bits;
+ v_block_size = self->private_impl.f_block_size;
+ v_which = self->private_impl.f_decode_huffman_which;
+ v_ticks = self->private_impl.f_decode_huffman_ticks;
+ v_section = self->private_impl.f_decode_huffman_section;
+ v_run_shift = self->private_impl.f_decode_huffman_run_shift;
+ while (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
+ if (v_ticks > 0u) {
+ v_ticks -= 1u;
+ } else {
+ v_ticks = 49u;
+ v_section += 1u;
+ if (v_section >= self->private_impl.f_num_sections) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections);
+ goto exit;
+ }
+ v_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[(v_section & 32767u)] & 7u)];
+ }
+ v_bits |= (wuffs_base__peek_u32be__no_bounds_check(iop_a_src) >> v_n_bits);
+ iop_a_src += ((31u - v_n_bits) >> 3u);
+ v_n_bits |= 24u;
+ v_table_entry = self->private_data.f_huffman_tables[v_which][(v_bits >> 24u)];
+ v_bits <<= (v_table_entry >> 12u);
+ v_n_bits -= ((uint32_t)((v_table_entry >> 12u)));
+ v_child = (v_table_entry & 1023u);
+ while (v_child < 257u) {
+ v_child = self->private_data.f_huffman_trees[v_which][v_child][(v_bits >> 31u)];
+ v_bits <<= 1u;
+ if (v_n_bits <= 0u) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_n_bits -= 1u;
+ }
+ if (v_child < 768u) {
+ v_child_ff = ((uint32_t)((v_child & 255u)));
+ v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff]));
+ wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_child_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_child_ff));
+ self->private_data.f_mtft[0u] = ((uint8_t)(v_output));
+ self->private_data.f_letter_counts[v_output] += 1u;
+ self->private_data.f_bwt[v_block_size] = v_output;
+ if (v_block_size >= self->private_impl.f_max_incl_block_size) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
+ goto exit;
+ }
+ v_block_size += 1u;
+ v_run_shift = 0u;
+ continue;
+ } else if (v_child == 768u) {
+ self->private_impl.f_decode_huffman_finished = true;
+ break;
+ }
+ if (v_run_shift >= 23u) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
+ goto exit;
+ }
+ v_run = ((((uint32_t)(v_child)) & 3u) << v_run_shift);
+ v_run_shift += 1u;
+ v_i = v_block_size;
+ v_j = (v_run + v_block_size);
+ if (v_j > self->private_impl.f_max_incl_block_size) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
+ goto exit;
+ }
+ v_block_size = v_j;
+ v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u]));
+ self->private_data.f_letter_counts[v_mtft0] += v_run;
+ while (v_i < v_j) {
+ self->private_data.f_bwt[v_i] = v_mtft0;
+ v_i += 1u;
+ }
+ }
+ self->private_impl.f_bits = v_bits;
+ self->private_impl.f_n_bits = v_n_bits;
+ self->private_impl.f_block_size = v_block_size;
+ self->private_impl.f_decode_huffman_which = v_which;
+ self->private_impl.f_decode_huffman_ticks = v_ticks;
+ self->private_impl.f_decode_huffman_section = v_section;
+ self->private_impl.f_decode_huffman_run_shift = v_run_shift;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func bzip2.decoder.decode_huffman_slow
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_bzip2__decoder__decode_huffman_slow(
+ wuffs_bzip2__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_node_index = 0;
+ uint16_t v_child = 0;
+ uint32_t v_child_ff = 0;
+ uint32_t v_i = 0;
+ uint32_t v_j = 0;
+ uint32_t v_output = 0;
+ uint32_t v_run = 0;
+ uint32_t v_mtft0 = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
+ if (coro_susp_point) {
+ v_node_index = self->private_data.s_decode_huffman_slow[0].v_node_index;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) {
+ if (self->private_impl.f_decode_huffman_ticks > 0u) {
+ self->private_impl.f_decode_huffman_ticks -= 1u;
+ } else {
+ self->private_impl.f_decode_huffman_ticks = 49u;
+ self->private_impl.f_decode_huffman_section += 1u;
+ if (self->private_impl.f_decode_huffman_section >= self->private_impl.f_num_sections) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_number_of_sections);
+ goto exit;
+ }
+ self->private_impl.f_decode_huffman_which = WUFFS_BZIP2__CLAMP_TO_5[(self->private_data.f_huffman_selectors[(self->private_impl.f_decode_huffman_section & 32767u)] & 7u)];
+ }
+ v_node_index = 0u;
+ while (true) {
+ if (self->private_impl.f_n_bits <= 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ self->private_impl.f_bits = (((uint32_t)(v_c)) << 24u);
+ self->private_impl.f_n_bits = 8u;
+ }
+ v_child = self->private_data.f_huffman_trees[self->private_impl.f_decode_huffman_which][v_node_index][(self->private_impl.f_bits >> 31u)];
+ self->private_impl.f_bits <<= 1u;
+ self->private_impl.f_n_bits -= 1u;
+ if (v_child < 257u) {
+ v_node_index = ((uint32_t)(v_child));
+ continue;
+ } else if (v_child < 768u) {
+ v_child_ff = ((uint32_t)((v_child & 255u)));
+ v_output = ((uint32_t)(self->private_data.f_mtft[v_child_ff]));
+ wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_mtft, 1, (1u + v_child_ff)), wuffs_base__make_slice_u8(self->private_data.f_mtft, v_child_ff));
+ self->private_data.f_mtft[0u] = ((uint8_t)(v_output));
+ self->private_data.f_letter_counts[v_output] += 1u;
+ self->private_data.f_bwt[self->private_impl.f_block_size] = v_output;
+ if (self->private_impl.f_block_size >= self->private_impl.f_max_incl_block_size) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
+ goto exit;
+ }
+ self->private_impl.f_block_size += 1u;
+ self->private_impl.f_decode_huffman_run_shift = 0u;
+ break;
+ } else if (v_child == 768u) {
+ self->private_impl.f_decode_huffman_finished = true;
+ goto label__outer__break;
+ }
+ if (self->private_impl.f_decode_huffman_run_shift >= 23u) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
+ goto exit;
+ }
+ v_run = ((((uint32_t)(v_child)) & 3u) << self->private_impl.f_decode_huffman_run_shift);
+ self->private_impl.f_decode_huffman_run_shift += 1u;
+ v_i = self->private_impl.f_block_size;
+ v_j = (v_run + self->private_impl.f_block_size);
+ if (v_j > self->private_impl.f_max_incl_block_size) {
+ status = wuffs_base__make_status(wuffs_bzip2__error__bad_block_length);
+ goto exit;
+ }
+ self->private_impl.f_block_size = v_j;
+ v_mtft0 = ((uint32_t)(self->private_data.f_mtft[0u]));
+ self->private_data.f_letter_counts[v_mtft0] += v_run;
+ while (v_i < v_j) {
+ self->private_data.f_bwt[v_i] = v_mtft0;
+ v_i += 1u;
+ }
+ break;
+ }
+ }
+ label__outer__break:;
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_huffman_slow[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_huffman_slow[0].v_node_index = v_node_index;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BZIP2)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_cbor__error__bad_input[] = "#cbor: bad input";
+const char wuffs_cbor__error__unsupported_recursion_depth[] = "#cbor: unsupported recursion depth";
+const char wuffs_cbor__error__internal_error_inconsistent_i_o[] = "#cbor: internal error: inconsistent I/O";
+const char wuffs_cbor__error__internal_error_inconsistent_token_length[] = "#cbor: internal error: inconsistent token length";
+
+// ---------------- Private Consts
+
+static const uint32_t
+WUFFS_CBOR__LITERALS[4] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 8388612, 8388616, 8388610, 8388609,
+};
+
+static const uint8_t
+WUFFS_CBOR__TOKEN_LENGTHS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1,
+ 2, 3, 5, 9, 0, 0, 0, 1,
+};
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+// ---------------- VTables
+
+const wuffs_base__token_decoder__func_ptrs
+wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__token_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__slice_u8))(&wuffs_cbor__decoder__decode_tokens),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_cbor__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_cbor__decoder__history_retain_length),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_cbor__decoder__set_quirk),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_cbor__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_cbor__decoder__initialize(
+ wuffs_cbor__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
+ wuffs_base__token_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
+ (const void*)(&wuffs_cbor__decoder__func_ptrs_for__wuffs_base__token_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_cbor__decoder*
+wuffs_cbor__decoder__alloc(void) {
+ wuffs_cbor__decoder* x =
+ (wuffs_cbor__decoder*)(calloc(sizeof(wuffs_cbor__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_cbor__decoder__initialize(
+ x, sizeof(wuffs_cbor__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_cbor__decoder(void) {
+ return sizeof(wuffs_cbor__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func cbor.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_cbor__decoder__get_quirk(
+ const wuffs_cbor__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func cbor.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_cbor__decoder__set_quirk(
+ wuffs_cbor__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func cbor.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_cbor__decoder__history_retain_length(
+ const wuffs_cbor__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func cbor.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_cbor__decoder__workbuf_len(
+ const wuffs_cbor__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__empty_range_ii_u64();
+}
+
+// -------- func cbor.decoder.decode_tokens
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_cbor__decoder__decode_tokens(
+ wuffs_cbor__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint64_t v_string_length = 0;
+ uint64_t v_n64 = 0;
+ uint32_t v_depth = 0;
+ uint32_t v_stack_byte = 0;
+ uint32_t v_stack_bit = 0;
+ uint32_t v_stack_val = 0;
+ uint32_t v_token_length = 0;
+ uint32_t v_vminor = 0;
+ uint32_t v_vminor_alt = 0;
+ uint32_t v_continued = 0;
+ uint8_t v_c = 0;
+ uint8_t v_c_major = 0;
+ uint8_t v_c_minor = 0;
+ bool v_tagged = false;
+ uint8_t v_indefinite_string_major_type = 0;
+
+ wuffs_base__token* iop_a_dst = NULL;
+ wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
+ if (coro_susp_point) {
+ v_string_length = self->private_data.s_decode_tokens[0].v_string_length;
+ v_depth = self->private_data.s_decode_tokens[0].v_depth;
+ v_tagged = self->private_data.s_decode_tokens[0].v_tagged;
+ v_indefinite_string_major_type = self->private_data.s_decode_tokens[0].v_indefinite_string_major_type;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_end_of_data) {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ label__outer__continue:;
+ while (true) {
+ while (true) {
+ do {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ goto label__outer__continue;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ goto label__outer__continue;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if ((v_indefinite_string_major_type != 0u) && (v_indefinite_string_major_type != (v_c >> 5u))) {
+ if (v_c != 255u) {
+ status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
+ goto exit;
+ }
+ v_vminor = 4194560u;
+ if (v_indefinite_string_major_type == 3u) {
+ v_vminor |= 19u;
+ }
+ v_indefinite_string_major_type = 0u;
+ iop_a_src += 1u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ iop_a_src += 1u;
+ v_c_major = ((uint8_t)((v_c >> 5u)));
+ v_c_minor = (v_c & 31u);
+ if (v_c_minor < 24u) {
+ v_string_length = ((uint64_t)(v_c_minor));
+ } else {
+ while (true) {
+ if (v_c_minor == 24u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= 1u) {
+ v_string_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
+ iop_a_src += 1u;
+ break;
+ }
+ } else if (v_c_minor == 25u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= 2u) {
+ v_string_length = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2u;
+ break;
+ }
+ } else if (v_c_minor == 26u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
+ v_string_length = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4u;
+ break;
+ }
+ } else if (v_c_minor == 27u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= 8u) {
+ v_string_length = wuffs_base__peek_u64be__no_bounds_check(iop_a_src);
+ iop_a_src += 8u;
+ break;
+ }
+ } else {
+ v_string_length = 0u;
+ break;
+ }
+ if (iop_a_src > io1_a_src) {
+ iop_a_src--;
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ goto label__outer__continue;
+ }
+ status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ }
+ if (v_c_major == 0u) {
+ if (v_c_minor < 26u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((14680064u | ((uint32_t)((v_string_length & 65535u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor < 28u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((14680064u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ *iop_a_dst++ = wuffs_base__make_token(
+ (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ } else if (v_c_major == 1u) {
+ if (v_c_minor < 26u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length & 65535u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor < 28u) {
+ if (v_string_length < 9223372036854775808u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((12582912u | (2097151u - ((uint32_t)((v_string_length >> 46u))))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ *iop_a_dst++ = wuffs_base__make_token(
+ (~((18446744073709551615u - v_string_length) & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ } else {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
+ (((uint64_t)(16777216u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ }
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ } else if (v_c_major == 2u) {
+ if (v_c_minor < 28u) {
+ if (v_string_length == 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ } else if (v_c_minor == 31u) {
+ if (v_indefinite_string_major_type != 0u) {
+ break;
+ }
+ v_indefinite_string_major_type = 2u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194560u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__outer__continue;
+ } else {
+ break;
+ }
+ while (true) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
+ continue;
+ }
+ v_n64 = wuffs_base__u64__min(v_string_length, ((uint64_t)(io2_a_src - iop_a_src)));
+ v_token_length = ((uint32_t)((v_n64 & 65535u)));
+ if (v_n64 > 65535u) {
+ v_token_length = 65535u;
+ } else if (v_token_length <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
+ continue;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
+ status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
+ goto exit;
+ }
+ v_string_length -= ((uint64_t)(v_token_length));
+ v_continued = 0u;
+ if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) {
+ v_continued = 1u;
+ }
+ iop_a_src += v_token_length;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194816u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (v_string_length > 0u) {
+ continue;
+ } else if (v_indefinite_string_major_type > 0u) {
+ goto label__outer__continue;
+ }
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ } else if (v_c_major == 3u) {
+ if (v_c_minor < 28u) {
+ if (v_string_length == 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ } else if (v_c_minor == 31u) {
+ if (v_indefinite_string_major_type != 0u) {
+ break;
+ }
+ v_indefinite_string_major_type = 3u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__outer__continue;
+ } else {
+ break;
+ }
+ while (true) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
+ continue;
+ }
+ v_n64 = wuffs_base__u64__min(v_string_length, 65535u);
+ v_n64 = ((uint64_t)(wuffs_base__utf_8__longest_valid_prefix(iop_a_src,
+ ((size_t)(wuffs_base__u64__min(((uint64_t)(io2_a_src - iop_a_src)), v_n64))))));
+ v_token_length = ((uint32_t)((v_n64 & 65535u)));
+ if (v_token_length <= 0u) {
+ if ((a_src && a_src->meta.closed) || (((uint64_t)(io2_a_src - iop_a_src)) >= 4u)) {
+ status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
+ continue;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) < ((uint64_t)(v_token_length))) {
+ status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_token_length);
+ goto exit;
+ }
+ v_string_length -= ((uint64_t)(v_token_length));
+ v_continued = 0u;
+ if ((v_string_length > 0u) || (v_indefinite_string_major_type > 0u)) {
+ v_continued = 1u;
+ }
+ iop_a_src += v_token_length;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_continued)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_token_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (v_string_length > 0u) {
+ continue;
+ } else if (v_indefinite_string_major_type > 0u) {
+ goto label__outer__continue;
+ }
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ } else if (v_c_major == 4u) {
+ if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) {
+ break;
+ } else if (v_depth >= 1024u) {
+ v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
+ while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) {
+ iop_a_src--;
+ v_token_length -= 1u;
+ }
+ status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
+ goto exit;
+ }
+ v_vminor = 2105361u;
+ v_vminor_alt = 2101282u;
+ if (v_depth > 0u) {
+ v_stack_byte = ((v_depth - 1u) / 16u);
+ v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
+ if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
+ v_vminor = 2105377u;
+ v_vminor_alt = 2105378u;
+ } else {
+ v_vminor = 2105409u;
+ v_vminor_alt = 2113570u;
+ }
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (v_c_minor == 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ v_stack_byte = (v_depth / 16u);
+ v_stack_bit = ((v_depth & 15u) * 2u);
+ self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(3u)) << v_stack_bit));
+ self->private_data.f_container_num_remaining[v_depth] = v_string_length;
+ v_depth += 1u;
+ v_tagged = false;
+ goto label__outer__continue;
+ } else if (v_c_major == 5u) {
+ if (WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor] == 0u) {
+ break;
+ } else if (v_depth >= 1024u) {
+ v_token_length = ((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor]));
+ while ((v_token_length > 0u) && (iop_a_src > io1_a_src)) {
+ iop_a_src--;
+ v_token_length -= 1u;
+ }
+ status = wuffs_base__make_status(wuffs_cbor__error__unsupported_recursion_depth);
+ goto exit;
+ }
+ v_vminor = 2113553u;
+ v_vminor_alt = 2101314u;
+ if (v_depth > 0u) {
+ v_stack_byte = ((v_depth - 1u) / 16u);
+ v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
+ if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
+ v_vminor = 2113569u;
+ v_vminor_alt = 2105410u;
+ } else {
+ v_vminor = 2113601u;
+ v_vminor_alt = 2113602u;
+ }
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (v_c_minor == 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ v_stack_byte = (v_depth / 16u);
+ v_stack_bit = ((v_depth & 15u) * 2u);
+ self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(3u)) << v_stack_bit);
+ self->private_data.f_container_num_remaining[v_depth] = v_string_length;
+ v_depth += 1u;
+ v_tagged = false;
+ goto label__outer__continue;
+ } else if (v_c_major == 6u) {
+ if (v_c_minor >= 28u) {
+ break;
+ }
+ if (v_string_length < 262144u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
+ (((uint64_t)((4194304u | ((uint32_t)(v_string_length))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ } else {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
+ (((uint64_t)((4194304u | ((uint32_t)((v_string_length >> 46u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ *iop_a_dst++ = wuffs_base__make_token(
+ (~(v_string_length & 70368744177663u) << WUFFS_BASE__TOKEN__VALUE_EXTENSION__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ }
+ v_tagged = true;
+ goto label__outer__continue;
+ } else if (v_c_major == 7u) {
+ if (v_c_minor < 20u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
+ (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor < 24u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(WUFFS_CBOR__LITERALS[(v_c_minor & 3u)])) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor == 24u) {
+ if (v_string_length < 24u) {
+ if ( ! (iop_a_src > io1_a_src)) {
+ status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ iop_a_src--;
+ break;
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(787997u)) << WUFFS_BASE__TOKEN__VALUE_MAJOR__SHIFT) |
+ (((uint64_t)((8388608u | ((uint32_t)((v_string_length & 255u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor < 28u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(10490113u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(((uint32_t)(WUFFS_CBOR__TOKEN_LENGTHS[v_c_minor])))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ } else if (v_c_minor == 31u) {
+ if (v_tagged || (v_depth <= 0u)) {
+ break;
+ }
+ v_depth -= 1u;
+ if (self->private_data.f_container_num_remaining[v_depth] != 0u) {
+ break;
+ }
+ v_stack_byte = (v_depth / 16u);
+ v_stack_bit = ((v_depth & 15u) * 2u);
+ v_stack_val = (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit));
+ if (v_stack_val == 1u) {
+ break;
+ }
+ if (v_stack_val != 3u) {
+ v_vminor_alt = 2097186u;
+ } else {
+ v_vminor_alt = 2097218u;
+ }
+ if (v_depth <= 0u) {
+ v_vminor_alt |= 4096u;
+ } else {
+ v_stack_byte = ((v_depth - 1u) / 16u);
+ v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
+ if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
+ v_vminor_alt |= 8192u;
+ } else {
+ v_vminor_alt |= 16384u;
+ }
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__goto_parsed_a_leaf_value__break;
+ }
+ }
+ } while (0);
+ if (iop_a_src > io1_a_src) {
+ iop_a_src--;
+ status = wuffs_base__make_status(wuffs_cbor__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_cbor__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ label__goto_parsed_a_leaf_value__break:;
+ v_tagged = false;
+ while (v_depth > 0u) {
+ v_stack_byte = ((v_depth - 1u) / 16u);
+ v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
+ self->private_data.f_stack[v_stack_byte] ^= (((uint32_t)(1u)) << (v_stack_bit + 1u));
+ if (1u == (3u & (self->private_data.f_stack[v_stack_byte] >> v_stack_bit))) {
+ goto label__outer__continue;
+ }
+ if (self->private_data.f_container_num_remaining[(v_depth - 1u)] <= 0u) {
+ goto label__outer__continue;
+ }
+ self->private_data.f_container_num_remaining[(v_depth - 1u)] -= 1u;
+ if (self->private_data.f_container_num_remaining[(v_depth - 1u)] > 0u) {
+ goto label__outer__continue;
+ }
+ while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
+ continue;
+ }
+ v_depth -= 1u;
+ v_stack_byte = (v_depth / 16u);
+ v_stack_bit = ((v_depth & 15u) * 2u);
+ if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
+ v_vminor_alt = 2097186u;
+ } else {
+ v_vminor_alt = 2097218u;
+ }
+ if (v_depth <= 0u) {
+ v_vminor_alt |= 4096u;
+ } else {
+ v_stack_byte = ((v_depth - 1u) / 16u);
+ v_stack_bit = (((v_depth - 1u) & 15u) * 2u);
+ if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
+ v_vminor_alt |= 8192u;
+ } else {
+ v_vminor_alt |= 16384u;
+ }
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor_alt)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ }
+ break;
+ }
+ self->private_impl.f_end_of_data = true;
+
+ ok:
+ self->private_impl.p_decode_tokens[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+ self->private_data.s_decode_tokens[0].v_string_length = v_string_length;
+ self->private_data.s_decode_tokens[0].v_depth = v_depth;
+ self->private_data.s_decode_tokens[0].v_tagged = v_tagged;
+ self->private_data.s_decode_tokens[0].v_indefinite_string_major_type = v_indefinite_string_major_type;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CBOR)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
+
+// ---------------- Status Codes Implementations
+
+// ---------------- Private Consts
+
+static const uint32_t
+WUFFS_CRC32__IEEE_TABLE[16][256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ {
+ 0, 1996959894, 3993919788, 2567524794, 124634137, 1886057615, 3915621685, 2657392035,
+ 249268274, 2044508324, 3772115230, 2547177864, 162941995, 2125561021, 3887607047, 2428444049,
+ 498536548, 1789927666, 4089016648, 2227061214, 450548861, 1843258603, 4107580753, 2211677639,
+ 325883990, 1684777152, 4251122042, 2321926636, 335633487, 1661365465, 4195302755, 2366115317,
+ 997073096, 1281953886, 3579855332, 2724688242, 1006888145, 1258607687, 3524101629, 2768942443,
+ 901097722, 1119000684, 3686517206, 2898065728, 853044451, 1172266101, 3705015759, 2882616665,
+ 651767980, 1373503546, 3369554304, 3218104598, 565507253, 1454621731, 3485111705, 3099436303,
+ 671266974, 1594198024, 3322730930, 2970347812, 795835527, 1483230225, 3244367275, 3060149565,
+ 1994146192, 31158534, 2563907772, 4023717930, 1907459465, 112637215, 2680153253, 3904427059,
+ 2013776290, 251722036, 2517215374, 3775830040, 2137656763, 141376813, 2439277719, 3865271297,
+ 1802195444, 476864866, 2238001368, 4066508878, 1812370925, 453092731, 2181625025, 4111451223,
+ 1706088902, 314042704, 2344532202, 4240017532, 1658658271, 366619977, 2362670323, 4224994405,
+ 1303535960, 984961486, 2747007092, 3569037538, 1256170817, 1037604311, 2765210733, 3554079995,
+ 1131014506, 879679996, 2909243462, 3663771856, 1141124467, 855842277, 2852801631, 3708648649,
+ 1342533948, 654459306, 3188396048, 3373015174, 1466479909, 544179635, 3110523913, 3462522015,
+ 1591671054, 702138776, 2966460450, 3352799412, 1504918807, 783551873, 3082640443, 3233442989,
+ 3988292384, 2596254646, 62317068, 1957810842, 3939845945, 2647816111, 81470997, 1943803523,
+ 3814918930, 2489596804, 225274430, 2053790376, 3826175755, 2466906013, 167816743, 2097651377,
+ 4027552580, 2265490386, 503444072, 1762050814, 4150417245, 2154129355, 426522225, 1852507879,
+ 4275313526, 2312317920, 282753626, 1742555852, 4189708143, 2394877945, 397917763, 1622183637,
+ 3604390888, 2714866558, 953729732, 1340076626, 3518719985, 2797360999, 1068828381, 1219638859,
+ 3624741850, 2936675148, 906185462, 1090812512, 3747672003, 2825379669, 829329135, 1181335161,
+ 3412177804, 3160834842, 628085408, 1382605366, 3423369109, 3138078467, 570562233, 1426400815,
+ 3317316542, 2998733608, 733239954, 1555261956, 3268935591, 3050360625, 752459403, 1541320221,
+ 2607071920, 3965973030, 1969922972, 40735498, 2617837225, 3943577151, 1913087877, 83908371,
+ 2512341634, 3803740692, 2075208622, 213261112, 2463272603, 3855990285, 2094854071, 198958881,
+ 2262029012, 4057260610, 1759359992, 534414190, 2176718541, 4139329115, 1873836001, 414664567,
+ 2282248934, 4279200368, 1711684554, 285281116, 2405801727, 4167216745, 1634467795, 376229701,
+ 2685067896, 3608007406, 1308918612, 956543938, 2808555105, 3495958263, 1231636301, 1047427035,
+ 2932959818, 3654703836, 1088359270, 936918000, 2847714899, 3736837829, 1202900863, 817233897,
+ 3183342108, 3401237130, 1404277552, 615818150, 3134207493, 3453421203, 1423857449, 601450431,
+ 3009837614, 3294710456, 1567103746, 711928724, 3020668471, 3272380065, 1510334235, 755167117,
+ }, {
+ 0, 421212481, 842424962, 724390851, 1684849924, 2105013317, 1448781702, 1329698503,
+ 3369699848, 3519200073, 4210026634, 3824474571, 2897563404, 3048111693, 2659397006, 2274893007,
+ 1254232657, 1406739216, 2029285587, 1643069842, 783210325, 934667796, 479770071, 92505238,
+ 2182846553, 2600511768, 2955803355, 2838940570, 3866582365, 4285295644, 3561045983, 3445231262,
+ 2508465314, 2359236067, 2813478432, 3198777185, 4058571174, 3908292839, 3286139684, 3670389349,
+ 1566420650, 1145479147, 1869335592, 1987116393, 959540142, 539646703, 185010476, 303839341,
+ 3745920755, 3327985586, 3983561841, 4100678960, 3140154359, 2721170102, 2300350837, 2416418868,
+ 396344571, 243568058, 631889529, 1018359608, 1945336319, 1793607870, 1103436669, 1490954812,
+ 4034481925, 3915546180, 3259968903, 3679722694, 2484439553, 2366552896, 2787371139, 3208174018,
+ 950060301, 565965900, 177645455, 328046286, 1556873225, 1171730760, 1861902987, 2011255754,
+ 3132841300, 2745199637, 2290958294, 2442530455, 3738671184, 3352078609, 3974232786, 4126854035,
+ 1919080284, 1803150877, 1079293406, 1498383519, 370020952, 253043481, 607678682, 1025720731,
+ 1711106983, 2095471334, 1472923941, 1322268772, 26324643, 411738082, 866634785, 717028704,
+ 2904875439, 3024081134, 2668790573, 2248782444, 3376948395, 3495106026, 4219356713, 3798300520,
+ 792689142, 908347575, 487136116, 68299317, 1263779058, 1380486579, 2036719216, 1618931505,
+ 3890672638, 4278043327, 3587215740, 3435896893, 2206873338, 2593195963, 2981909624, 2829542713,
+ 998479947, 580430090, 162921161, 279890824, 1609522511, 1190423566, 1842954189, 1958874764,
+ 4082766403, 3930137346, 3245109441, 3631694208, 2536953671, 2385372678, 2768287173, 3155920004,
+ 1900120602, 1750776667, 1131931800, 1517083097, 355290910, 204897887, 656092572, 1040194781,
+ 3113746450, 2692952403, 2343461520, 2461357009, 3723805974, 3304059991, 4022511508, 4141455061,
+ 2919742697, 3072101800, 2620513899, 2234183466, 3396041197, 3547351212, 4166851439, 3779471918,
+ 1725839073, 2143618976, 1424512099, 1307796770, 45282277, 464110244, 813994343, 698327078,
+ 3838160568, 4259225593, 3606301754, 3488152955, 2158586812, 2578602749, 2996767038, 2877569151,
+ 740041904, 889656817, 506086962, 120682355, 1215357364, 1366020341, 2051441462, 1667084919,
+ 3422213966, 3538019855, 4190942668, 3772220557, 2945847882, 3062702859, 2644537544, 2226864521,
+ 52649286, 439905287, 823476164, 672009861, 1733269570, 2119477507, 1434057408, 1281543041,
+ 2167981343, 2552493150, 3004082077, 2853541596, 3847487515, 4233048410, 3613549209, 3464057816,
+ 1239502615, 1358593622, 2077699477, 1657543892, 764250643, 882293586, 532408465, 111204816,
+ 1585378284, 1197851309, 1816695150, 1968414767, 974272232, 587794345, 136598634, 289367339,
+ 2527558116, 2411481253, 2760973158, 3179948583, 4073438432, 3956313505, 3237863010, 3655790371,
+ 347922877, 229101820, 646611775, 1066513022, 1892689081, 1774917112, 1122387515, 1543337850,
+ 3697634229, 3313392372, 3998419255, 4148705398, 3087642289, 2702352368, 2319436851, 2468674930,
+ }, {
+ 0, 29518391, 59036782, 38190681, 118073564, 114017003, 76381362, 89069189,
+ 236147128, 265370511, 228034006, 206958561, 152762724, 148411219, 178138378, 190596925,
+ 472294256, 501532999, 530741022, 509615401, 456068012, 451764635, 413917122, 426358261,
+ 305525448, 334993663, 296822438, 275991697, 356276756, 352202787, 381193850, 393929805,
+ 944588512, 965684439, 1003065998, 973863097, 1061482044, 1049003019, 1019230802, 1023561829,
+ 912136024, 933002607, 903529270, 874031361, 827834244, 815125939, 852716522, 856752605,
+ 611050896, 631869351, 669987326, 640506825, 593644876, 580921211, 551983394, 556069653,
+ 712553512, 733666847, 704405574, 675154545, 762387700, 749958851, 787859610, 792175277,
+ 1889177024, 1901651959, 1931368878, 1927033753, 2006131996, 1985040171, 1947726194, 1976933189,
+ 2122964088, 2135668303, 2098006038, 2093965857, 2038461604, 2017599123, 2047123658, 2076625661,
+ 1824272048, 1836991623, 1866005214, 1861914857, 1807058540, 1786244187, 1748062722, 1777547317,
+ 1655668488, 1668093247, 1630251878, 1625932113, 1705433044, 1684323811, 1713505210, 1742760333,
+ 1222101792, 1226154263, 1263738702, 1251046777, 1339974652, 1310460363, 1281013650, 1301863845,
+ 1187289752, 1191637167, 1161842422, 1149379777, 1103966788, 1074747507, 1112139306, 1133218845,
+ 1425107024, 1429406311, 1467333694, 1454888457, 1408811148, 1379576507, 1350309090, 1371438805,
+ 1524775400, 1528845279, 1499917702, 1487177649, 1575719220, 1546255107, 1584350554, 1605185389,
+ 3778354048, 3774312887, 3803303918, 3816007129, 3862737756, 3892238699, 3854067506, 3833203973,
+ 4012263992, 4007927823, 3970080342, 3982554209, 3895452388, 3924658387, 3953866378, 3932773565,
+ 4245928176, 4241609415, 4271336606, 4283762345, 4196012076, 4225268251, 4187931714, 4166823541,
+ 4076923208, 4072833919, 4035198246, 4047918865, 4094247316, 4123732899, 4153251322, 4132437965,
+ 3648544096, 3636082519, 3673983246, 3678331705, 3732010428, 3753090955, 3723829714, 3694611429,
+ 3614117080, 3601426159, 3572488374, 3576541825, 3496125444, 3516976691, 3555094634, 3525581405,
+ 3311336976, 3298595879, 3336186494, 3340255305, 3260503756, 3281337595, 3251864226, 3222399125,
+ 3410866088, 3398419871, 3368647622, 3372945905, 3427010420, 3448139075, 3485520666, 3456284973,
+ 2444203584, 2423127159, 2452308526, 2481530905, 2527477404, 2539934891, 2502093554, 2497740997,
+ 2679949304, 2659102159, 2620920726, 2650438049, 2562027300, 2574714131, 2603727690, 2599670141,
+ 2374579504, 2353749767, 2383274334, 2412743529, 2323684844, 2336421851, 2298759554, 2294686645,
+ 2207933576, 2186809023, 2149495014, 2178734801, 2224278612, 2236720739, 2266437690, 2262135309,
+ 2850214048, 2820717207, 2858812622, 2879680249, 2934667388, 2938704459, 2909776914, 2897069605,
+ 2817622296, 2788420399, 2759153014, 2780249921, 2700618180, 2704950259, 2742877610, 2730399645,
+ 3049550800, 3020298727, 3057690558, 3078802825, 2999835404, 3004150075, 2974355298, 2961925461,
+ 3151438440, 3121956959, 3092510214, 3113327665, 3168701108, 3172786307, 3210370778, 3197646061,
+ }, {
+ 0, 3099354981, 2852767883, 313896942, 2405603159, 937357362, 627793884, 2648127673,
+ 3316918511, 2097696650, 1874714724, 3607201537, 1255587768, 4067088605, 3772741427, 1482887254,
+ 1343838111, 3903140090, 4195393300, 1118632049, 3749429448, 1741137837, 1970407491, 3452858150,
+ 2511175536, 756094997, 1067759611, 2266550430, 449832999, 2725482306, 2965774508, 142231497,
+ 2687676222, 412010587, 171665333, 2995192016, 793786473, 2548850444, 2237264098, 1038456711,
+ 1703315409, 3711623348, 3482275674, 1999841343, 3940814982, 1381529571, 1089329165, 4166106984,
+ 4029413537, 1217896388, 1512189994, 3802027855, 2135519222, 3354724499, 3577784189, 1845280792,
+ 899665998, 2367928107, 2677414085, 657096608, 3137160985, 37822588, 284462994, 2823350519,
+ 2601801789, 598228824, 824021174, 2309093331, 343330666, 2898962447, 3195996129, 113467524,
+ 1587572946, 3860600759, 4104763481, 1276501820, 3519211397, 1769898208, 2076913422, 3279374443,
+ 3406630818, 1941006535, 1627703081, 3652755532, 1148164341, 4241751952, 3999682686, 1457141531,
+ 247015245, 3053797416, 2763059142, 470583459, 2178658330, 963106687, 735213713, 2473467892,
+ 992409347, 2207944806, 2435792776, 697522413, 3024379988, 217581361, 508405983, 2800865210,
+ 4271038444, 1177467017, 1419450215, 3962007554, 1911572667, 3377213406, 3690561584, 1665525589,
+ 1799331996, 3548628985, 3241568279, 2039091058, 3831314379, 1558270126, 1314193216, 4142438437,
+ 2928380019, 372764438, 75645176, 3158189981, 568925988, 2572515393, 2346768303, 861712586,
+ 3982079547, 1441124702, 1196457648, 4293663189, 1648042348, 3666298377, 3358779879, 1888390786,
+ 686661332, 2421291441, 2196002399, 978858298, 2811169155, 523464422, 226935048, 3040519789,
+ 3175145892, 100435649, 390670639, 2952089162, 841119475, 2325614998, 2553003640, 546822429,
+ 2029308235, 3225988654, 3539796416, 1782671013, 4153826844, 1328167289, 1570739863, 3844338162,
+ 1298864389, 4124540512, 3882013070, 1608431339, 3255406162, 2058742071, 1744848601, 3501990332,
+ 2296328682, 811816591, 584513889, 2590678532, 129869501, 3204563416, 2914283062, 352848211,
+ 494030490, 2781751807, 3078325777, 264757620, 2450577869, 715964072, 941166918, 2158327331,
+ 3636881013, 1618608400, 1926213374, 3396585883, 1470427426, 4011365959, 4255988137, 1158766284,
+ 1984818694, 3471935843, 3695453837, 1693991400, 4180638033, 1100160564, 1395044826, 3952793279,
+ 3019491049, 189112716, 435162722, 2706139399, 1016811966, 2217162459, 2526189877, 774831696,
+ 643086745, 2666061564, 2354934034, 887166583, 2838900430, 294275499, 54519365, 3145957664,
+ 3823145334, 1532818963, 1240029693, 4048895640, 1820460577, 3560857924, 3331051178, 2117577167,
+ 3598663992, 1858283101, 2088143283, 3301633750, 1495127663, 3785470218, 4078182116, 1269332353,
+ 332098007, 2876706482, 3116540252, 25085497, 2628386432, 605395429, 916469259, 2384220526,
+ 2254837415, 1054503362, 745528876, 2496903497, 151290352, 2981684885, 2735556987, 464596510,
+ 1137851976, 4218313005, 3923506883, 1365741990, 3434129695, 1946996346, 1723425172, 3724871409,
+ }, {
+ 0, 1029712304, 2059424608, 1201699536, 4118849216, 3370159984, 2403399072, 2988497936,
+ 812665793, 219177585, 1253054625, 2010132753, 3320900865, 4170237105, 3207642721, 2186319825,
+ 1625331586, 1568718386, 438355170, 658566482, 2506109250, 2818578674, 4020265506, 3535817618,
+ 1351670851, 1844508147, 709922595, 389064339, 2769320579, 2557498163, 3754961379, 3803185235,
+ 3250663172, 4238411444, 3137436772, 2254525908, 876710340, 153198708, 1317132964, 1944187668,
+ 4054934725, 3436268917, 2339452837, 3054575125, 70369797, 961670069, 2129760613, 1133623509,
+ 2703341702, 2621542710, 3689016294, 3867263574, 1419845190, 1774270454, 778128678, 318858390,
+ 2438067015, 2888948471, 3952189479, 3606153623, 1691440519, 1504803895, 504432359, 594620247,
+ 1492342857, 1704161785, 573770537, 525542041, 2910060169, 2417219385, 3618876905, 3939730521,
+ 1753420680, 1440954936, 306397416, 790849880, 2634265928, 2690882808, 3888375336, 3668168600,
+ 940822475, 91481723, 1121164459, 2142483739, 3448989963, 4042473659, 3075684971, 2318603227,
+ 140739594, 889433530, 1923340138, 1338244826, 4259521226, 3229813626, 2267247018, 3124975642,
+ 2570221389, 2756861693, 3824297005, 3734113693, 1823658381, 1372780605, 376603373, 722643805,
+ 2839690380, 2485261628, 3548540908, 4007806556, 1556257356, 1638052860, 637716780, 459464860,
+ 4191346895, 3300051327, 2199040943, 3195181599, 206718479, 825388991, 1989285231, 1274166495,
+ 3382881038, 4106388158, 3009607790, 2382549470, 1008864718, 21111934, 1189240494, 2072147742,
+ 2984685714, 2357631266, 3408323570, 4131834434, 1147541074, 2030452706, 1051084082, 63335554,
+ 2174155603, 3170292451, 4216760371, 3325460867, 1947622803, 1232499747, 248909555, 867575619,
+ 3506841360, 3966111392, 2881909872, 2527485376, 612794832, 434546784, 1581699760, 1663499008,
+ 3782634705, 3692447073, 2612412337, 2799048193, 351717905, 697754529, 1849071985, 1398190273,
+ 1881644950, 1296545318, 182963446, 931652934, 2242328918, 3100053734, 4284967478, 3255255942,
+ 1079497815, 2100821479, 983009079, 133672583, 3050795671, 2293717799, 3474399735, 4067887175,
+ 281479188, 765927844, 1778867060, 1466397380, 3846680276, 3626469220, 2676489652, 2733102084,
+ 548881365, 500656741, 1517752501, 1729575173, 3577210133, 3898068133, 2952246901, 2459410373,
+ 3910527195, 3564487019, 2480257979, 2931134987, 479546907, 569730987, 1716854139, 1530213579,
+ 3647316762, 3825568426, 2745561210, 2663766474, 753206746, 293940330, 1445287610, 1799716618,
+ 2314567513, 3029685993, 4080348217, 3461678473, 2088098201, 1091956777, 112560889, 1003856713,
+ 3112514712, 2229607720, 3276105720, 4263857736, 1275433560, 1902492648, 918929720, 195422344,
+ 685033439, 364179055, 1377080511, 1869921551, 3713294623, 3761522863, 2811507327, 2599689167,
+ 413436958, 633644462, 1650777982, 1594160846, 3978570462, 3494118254, 2548332990, 2860797966,
+ 1211387997, 1968470509, 854852413, 261368461, 3182753437, 2161434413, 3346310653, 4195650637,
+ 2017729436, 1160000044, 42223868, 1071931724, 2378480988, 2963576044, 4144295484, 3395602316,
+ }, {
+ 0, 3411858341, 1304994059, 2257875630, 2609988118, 1355649459, 3596215069, 486879416,
+ 3964895853, 655315400, 2711298918, 1791488195, 2009251963, 3164476382, 973758832, 4048990933,
+ 64357019, 3364540734, 1310630800, 2235723829, 2554806413, 1394316072, 3582976390, 517157411,
+ 4018503926, 618222419, 2722963965, 1762783832, 1947517664, 3209171269, 970744811, 4068520014,
+ 128714038, 3438335635, 1248109629, 2167961496, 2621261600, 1466012805, 3522553387, 447296910,
+ 3959392091, 547575038, 2788632144, 1835791861, 1886307661, 3140622056, 1034314822, 4143626211,
+ 75106221, 3475428360, 1236444838, 2196665603, 2682996155, 1421317662, 3525567664, 427767573,
+ 3895035328, 594892389, 2782995659, 1857943406, 1941489622, 3101955187, 1047553757, 4113347960,
+ 257428076, 3288652233, 1116777319, 2311878850, 2496219258, 1603640287, 3640781169, 308099796,
+ 3809183745, 676813732, 2932025610, 1704983215, 2023410199, 3016104370, 894593820, 4262377657,
+ 210634999, 3352484690, 1095150076, 2316991065, 2535410401, 1547934020, 3671583722, 294336591,
+ 3772615322, 729897279, 2903845777, 1716123700, 2068629644, 2953845545, 914647431, 4258839074,
+ 150212442, 3282623743, 1161604689, 2388688372, 2472889676, 1480171241, 3735940167, 368132066,
+ 3836185911, 805002898, 2842635324, 1647574937, 2134298401, 3026852996, 855535146, 4188192143,
+ 186781121, 3229539940, 1189784778, 2377547631, 2427670487, 1542429810, 3715886812, 371670393,
+ 3882979244, 741170185, 2864262823, 1642462466, 2095107514, 3082559007, 824732849, 4201955092,
+ 514856152, 3589064573, 1400419795, 2552522358, 2233554638, 1316849003, 3370776517, 62202976,
+ 4075001525, 968836368, 3207280574, 1954014235, 1769133219, 2720925446, 616199592, 4024870413,
+ 493229635, 3594175974, 1353627464, 2616354029, 2264355925, 1303087088, 3409966430, 6498043,
+ 4046820398, 979978123, 3170710821, 2007099008, 1789187640, 2717386141, 661419827, 3962610838,
+ 421269998, 3527459403, 1423225061, 2676515648, 2190300152, 1238466653, 3477467891, 68755798,
+ 4115633027, 1041448998, 3095868040, 1943789869, 1860096405, 2776760880, 588673182, 3897205563,
+ 449450869, 3516317904, 1459794558, 2623431131, 2170245475, 1242006214, 3432247400, 131015629,
+ 4137259288, 1036337853, 3142660115, 1879958454, 1829294862, 2790523051, 549483013, 3952910752,
+ 300424884, 3669282065, 1545650111, 2541513754, 2323209378, 1092980487, 3350330793, 216870412,
+ 4256931033, 921128828, 2960342482, 2066738807, 1714085583, 2910195050, 736264132, 3770592353,
+ 306060335, 3647131530, 1610005796, 2494197377, 2309971513, 1123257756, 3295149874, 255536279,
+ 4268596802, 892423655, 3013951305, 2029645036, 1711070292, 2929725425, 674528607, 3815288570,
+ 373562242, 3709388839, 1535949449, 2429577516, 2379569556, 1183418929, 3223189663, 188820282,
+ 4195850735, 827017802, 3084859620, 2089020225, 1636228089, 2866415708, 743340786, 3876759895,
+ 361896217, 3738094268, 1482340370, 2466671543, 2382584591, 1163888810, 3284924932, 144124321,
+ 4190215028, 849168593, 3020503679, 2136336858, 1649465698, 2836138695, 798521449, 3838094284,
+ }, {
+ 0, 2792819636, 2543784233, 837294749, 4098827283, 1379413927, 1674589498, 3316072078,
+ 871321191, 2509784531, 2758827854, 34034938, 3349178996, 1641505216, 1346337629, 4131942633,
+ 1742642382, 3249117050, 4030828007, 1446413907, 2475800797, 904311657, 68069876, 2725880384,
+ 1412551337, 4064729373, 3283010432, 1708771380, 2692675258, 101317902, 937551763, 2442587175,
+ 3485284764, 1774858792, 1478633653, 4266992385, 1005723023, 2642744891, 2892827814, 169477906,
+ 4233263099, 1512406095, 1808623314, 3451546982, 136139752, 2926205020, 2676114113, 972376437,
+ 2825102674, 236236518, 1073525883, 2576072655, 1546420545, 4200303349, 3417542760, 1841601500,
+ 2609703733, 1039917185, 202635804, 2858742184, 1875103526, 3384067218, 4166835727, 1579931067,
+ 1141601657, 3799809741, 3549717584, 1977839588, 2957267306, 372464350, 668680259, 2175552503,
+ 2011446046, 3516084394, 3766168119, 1175200131, 2209029901, 635180217, 338955812, 2990736784,
+ 601221559, 2242044419, 3024812190, 306049834, 3617246628, 1911408144, 1074125965, 3866285881,
+ 272279504, 3058543716, 2275784441, 567459149, 3832906691, 1107462263, 1944752874, 3583875422,
+ 2343980261, 767641425, 472473036, 3126744696, 2147051766, 3649987394, 3899029983, 1309766251,
+ 3092841090, 506333494, 801510315, 2310084639, 1276520081, 3932237093, 3683203000, 2113813516,
+ 3966292011, 1243601823, 2079834370, 3716205238, 405271608, 3192979340, 2411259153, 701492901,
+ 3750207052, 2045810168, 1209569125, 4000285905, 734575199, 2378150379, 3159862134, 438345922,
+ 2283203314, 778166598, 529136603, 3120492655, 2086260449, 3660498261, 3955679176, 1303499900,
+ 3153699989, 495890209, 744928700, 2316418568, 1337360518, 3921775410, 3626602927, 2120129051,
+ 4022892092, 1237286280, 2018993941, 3726666913, 461853231, 3186645403, 2350400262, 711936178,
+ 3693557851, 2052076527, 1270360434, 3989775046, 677911624, 2384402428, 3220639073, 427820757,
+ 1202443118, 3789347034, 3493118535, 1984154099, 3018127229, 362020041, 612099668, 2181885408,
+ 1950653705, 3526596285, 3822816288, 1168934804, 2148251930, 645706414, 395618355, 2984485767,
+ 544559008, 2248295444, 3085590153, 295523645, 3560598451, 1917673479, 1134918298, 3855773998,
+ 328860103, 3052210803, 2214924526, 577903450, 3889505748, 1101147744, 1883911421, 3594338121,
+ 3424493451, 1785369663, 1535282850, 4260726038, 944946072, 2653270060, 2949491377, 163225861,
+ 4294103532, 1501944408, 1752023237, 3457862513, 196998655, 2915761739, 2619532502, 978710370,
+ 2881684293, 229902577, 1012666988, 2586515928, 1603020630, 4193987810, 3356702335, 1852063179,
+ 2553040162, 1046169238, 263412747, 2848217023, 1818454321, 3390333573, 4227627032, 1569420204,
+ 60859927, 2782375331, 2487203646, 843627658, 4159668740, 1368951216, 1617990445, 3322386585,
+ 810543216, 2520310724, 2815490393, 27783917, 3288386659, 1652017111, 1402985802, 4125677310,
+ 1685994201, 3255382381, 4091620336, 1435902020, 2419138250, 910562686, 128847843, 2715354199,
+ 1469150398, 4058414858, 3222168983, 1719234083, 2749255853, 94984985, 876691844, 2453031472,
+ }, {
+ 0, 3433693342, 1109723005, 2391738339, 2219446010, 1222643300, 3329165703, 180685081,
+ 3555007413, 525277995, 2445286600, 1567235158, 1471092047, 2600801745, 361370162, 3642757804,
+ 2092642603, 2953916853, 1050555990, 4063508168, 4176560081, 878395215, 3134470316, 1987983410,
+ 2942184094, 1676945920, 3984272867, 567356797, 722740324, 3887998202, 1764827929, 2778407815,
+ 4185285206, 903635656, 3142804779, 2012833205, 2101111980, 2979425330, 1058630609, 4088621903,
+ 714308067, 3862526333, 1756790430, 2753330688, 2933487385, 1651734407, 3975966820, 542535930,
+ 2244825981, 1231508451, 3353891840, 188896414, 25648519, 3442302233, 1134713594, 2399689316,
+ 1445480648, 2592229462, 336416693, 3634843435, 3529655858, 516441772, 2420588879, 1559052753,
+ 698204909, 3845636723, 1807271312, 2803025166, 2916600855, 1635634313, 4025666410, 593021940,
+ 4202223960, 919787974, 3093159461, 1962401467, 2117261218, 2996361020, 1008193759, 4038971457,
+ 1428616134, 2576151384, 386135227, 3685348389, 3513580860, 499580322, 2471098945, 1608776415,
+ 2260985971, 1248454893, 3303468814, 139259792, 42591881, 3458459159, 1085071860, 2349261162,
+ 3505103035, 474062885, 2463016902, 1583654744, 1419882049, 2550902495, 377792828, 3660491170,
+ 51297038, 3483679632, 1093385331, 2374089965, 2269427188, 1273935210, 3311514249, 164344343,
+ 2890961296, 1627033870, 4000683757, 585078387, 672833386, 3836780532, 1782552599, 2794821769,
+ 2142603813, 3005188795, 1032883544, 4047146438, 4227826911, 928351297, 3118105506, 1970307900,
+ 1396409818, 2677114180, 287212199, 3719594553, 3614542624, 467372990, 2505346141, 1509854403,
+ 2162073199, 1282711281, 3271268626, 240228748, 76845205, 3359543307, 1186043880, 2317064054,
+ 796964081, 3811226735, 1839575948, 2702160658, 2882189835, 1734392469, 3924802934, 625327592,
+ 4234522436, 818917338, 3191908409, 1927981223, 2016387518, 3028656416, 973776579, 4137723485,
+ 2857232268, 1726474002, 3899187441, 616751215, 772270454, 3803048424, 1814228491, 2693328533,
+ 2041117753, 3036871847, 999160644, 4146592730, 4259508931, 826864221, 3217552830, 1936586016,
+ 3606501031, 442291769, 2496909786, 1484378436, 1388107869, 2652297411, 278519584, 3694387134,
+ 85183762, 3384397196, 1194773103, 2342308593, 2170143720, 1307820918, 3279733909, 265733131,
+ 2057717559, 3054258089, 948125770, 4096344276, 4276898253, 843467091, 3167309488, 1885556270,
+ 2839764098, 1709792284, 3949353983, 667704161, 755585656, 3785577190, 1865176325, 2743489947,
+ 102594076, 3401021058, 1144549729, 2291298815, 2186770662, 1325234296, 3228729243, 215514885,
+ 3589828009, 424832311, 2547870420, 1534552650, 1370645331, 2635621325, 328688686, 3745342640,
+ 2211456353, 1333405183, 3254067740, 224338562, 127544219, 3408931589, 1170156774, 2299866232,
+ 1345666772, 2627681866, 303053225, 3736746295, 3565105198, 416624816, 2522494803, 1525692365,
+ 4285207626, 868291796, 3176010551, 1910772649, 2065767088, 3079346734, 956571085, 4121828691,
+ 747507711, 3760459617, 1856702594, 2717976604, 2831417605, 1684930971, 3940615800, 642451174,
+ },
+ {
+ 0, 393942083, 787884166, 965557445, 1575768332, 1251427663, 1931114890, 1684106697,
+ 3151536664, 2896410203, 2502855326, 2186649309, 3862229780, 4048545623, 3368213394, 3753496529,
+ 2898281073, 3149616690, 2184604407, 2504883892, 4046197629, 3864463166, 3755621371, 3366006712,
+ 387506281, 6550570, 971950319, 781573292, 1257550181, 1569695014, 1677892067, 1937345952,
+ 2196865699, 2508887776, 2886183461, 3145514598, 3743273903, 3362179052, 4058774313, 3868258154,
+ 958996667, 777139448, 400492605, 10755198, 1690661303, 1941857780, 1244879153, 1565019506,
+ 775012562, 961205393, 13101140, 398261271, 1943900638, 1688634781, 1563146584, 1246801179,
+ 2515100362, 2190636681, 3139390028, 2892258831, 3355784134, 3749586821, 3874691904, 4052225795,
+ 3734110983, 3387496260, 4033096577, 3877584834, 2206093835, 2483373640, 2911402637, 3136515790,
+ 1699389727, 1915860316, 1270647193, 1556585946, 950464531, 803071056, 374397077, 19647702,
+ 1917993334, 1697207605, 1554278896, 1272937907, 800985210, 952435769, 21510396, 372452543,
+ 3381322606, 3740399405, 3883715560, 4027047851, 2489758306, 2199758369, 3130039012, 2917895847,
+ 1550025124, 1259902439, 1922410786, 1710144865, 26202280, 385139947, 796522542, 939715693,
+ 3887801276, 4039129087, 3377269562, 3728088953, 3126293168, 2905368307, 2493602358, 2212122229,
+ 4037264341, 3889747862, 3730172755, 3375300368, 2907673305, 3124004506, 2209987167, 2495786524,
+ 1266377165, 1543533966, 1703758155, 1928748296, 379007169, 32253058, 945887303, 790236164,
+ 1716846671, 1898845196, 1218652361, 1608006794, 1002000707, 750929152, 357530053, 36990342,
+ 3717046871, 3405166100, 4084959953, 3825245842, 2153902939, 2535122712, 2929187805, 3119304606,
+ 3398779454, 3723384445, 3831720632, 4078468859, 2541294386, 2147616625, 3113171892, 2935238647,
+ 1900929062, 1714877541, 1606142112, 1220599011, 748794154, 1004184937, 39295404, 355241455,
+ 3835986668, 4091516591, 3394415210, 3710500393, 3108557792, 2922629027, 2545875814, 2160455461,
+ 1601970420, 1208431799, 1904871538, 1727077425, 43020792, 367748539, 744905086, 991776061,
+ 1214562461, 1595921630, 1720903707, 1911159896, 361271697, 49513938, 998160663, 738569556,
+ 4089209477, 3838277318, 3712633347, 3392233024, 2924491657, 3106613194, 2158369551, 2547846988,
+ 3100050248, 2948339467, 2519804878, 2169126797, 3844821572, 4065347079, 3420289730, 3701894785,
+ 52404560, 342144275, 770279894, 982687125, 1593045084, 1233708063, 1879431386, 1736363161,
+ 336019769, 58479994, 988899775, 764050940, 1240141877, 1586496630, 1729968307, 1885744368,
+ 2950685473, 3097818978, 2166999975, 2522013668, 4063474221, 3846743662, 3703937707, 3418263272,
+ 976650731, 760059304, 348170605, 62635310, 1742393575, 1889649828, 1227683937, 1582820386,
+ 2179867635, 2526361520, 2937588597, 3093503798, 3691148031, 3413731004, 4076100217, 3851374138,
+ 2532754330, 2173556697, 3087067932, 2944139103, 3407516310, 3697379029, 3857496592, 4070026835,
+ 758014338, 978679233, 64506116, 346250567, 1891774606, 1740186829, 1580472328, 1229917259,
+ }, {
+ 0, 4022496062, 83218493, 3946298115, 166436986, 3861498692, 220098631, 3806075769,
+ 332873972, 4229245898, 388141257, 4175494135, 440197262, 4127099824, 516501683, 4044053389,
+ 665747944, 3362581206, 593187285, 3432594155, 776282514, 3246869164, 716239279, 3312622225,
+ 880394524, 3686509090, 814485793, 3746462239, 1033003366, 3528460888, 963096923, 3601193573,
+ 1331495888, 2694801646, 1269355501, 2758457555, 1186374570, 2843003028, 1111716759, 2910918825,
+ 1552565028, 3007850522, 1484755737, 3082680359, 1432478558, 3131279456, 1368666979, 3193329757,
+ 1760789048, 2268195078, 1812353541, 2210675003, 1628971586, 2396670332, 1710092927, 2318375233,
+ 2066006732, 2498144754, 2144408305, 2417195471, 1926193846, 2634877320, 1983558283, 2583222709,
+ 2662991776, 1903717534, 2588923805, 1972223139, 2538711002, 2022952164, 2477029351, 2087066841,
+ 2372749140, 1655647338, 2308478825, 1717238871, 2223433518, 1799654416, 2155034387, 1873894445,
+ 3105130056, 1456926070, 3185661557, 1378041163, 2969511474, 1597852940, 3020617231, 1539874097,
+ 2864957116, 1157737858, 2922780289, 1106542015, 2737333958, 1290407416, 2816325371, 1210047941,
+ 3521578096, 1042640718, 3574781005, 986759027, 3624707082, 936300340, 3707335735, 859512585,
+ 3257943172, 770846650, 3334837433, 688390023, 3420185854, 605654976, 3475911875, 552361981,
+ 4132013464, 428600998, 4072428965, 494812827, 4288816610, 274747100, 4216845791, 345349857,
+ 3852387692, 173846098, 3781891409, 245988975, 3967116566, 62328360, 3900749099, 121822741,
+ 3859089665, 164061759, 3807435068, 221426178, 4025395579, 2933317, 3944446278, 81334904,
+ 4124199413, 437265099, 4045904328, 518386422, 4231653775, 335250097, 4174133682, 386814604,
+ 3249244393, 778691543, 3311294676, 714879978, 3359647891, 662848429, 3434477742, 595039120,
+ 3531393053, 1035903779, 3599308832, 961245982, 3684132967, 877986649, 3747788890, 815846244,
+ 2841119441, 1184522735, 2913852140, 1114616274, 2696129195, 1332855189, 2756082326, 1266946472,
+ 3129952805, 1431118107, 3195705880, 1371074854, 3009735263, 1554415969, 3079748194, 1481855324,
+ 2398522169, 1630855175, 2315475716, 1707159610, 2266835779, 1759461501, 2213084030, 1814728768,
+ 2636237773, 1927520499, 2580814832, 1981182158, 2496293815, 2064121993, 2420095882, 2147340468,
+ 2025787041, 2541577631, 2085281436, 2475210146, 1901375195, 2660681189, 1973518054, 2590184920,
+ 1801997909, 2225743211, 1872600680, 2153772374, 1652813359, 2369881361, 1719025170, 2310296876,
+ 1594986313, 2966676599, 1541693300, 3022402634, 1459236659, 3107472397, 1376780046, 3184366640,
+ 1288097725, 2734990467, 1211309952, 2817619134, 1160605639, 2867791097, 1104723962, 2920993988,
+ 937561457, 3626001999, 857201996, 3704993394, 1040821515, 3519792693, 989625654, 3577615880,
+ 607473029, 3421972155, 549494200, 3473077894, 769584639, 3256649409, 690699714, 3337180924,
+ 273452185, 4287555495, 347692196, 4219156378, 430386403, 4133832669, 491977950, 4069562336,
+ 60542061, 3965298515, 124656720, 3903616878, 175139863, 3853649705, 243645482, 3779581716,
+ }, {
+ 0, 3247366080, 1483520449, 2581751297, 2967040898, 1901571138, 3904227907, 691737987,
+ 3133399365, 2068659845, 3803142276, 589399876, 169513671, 3415493895, 1383475974, 2482566342,
+ 2935407819, 1870142219, 4137319690, 924099274, 506443593, 3751897225, 1178799752, 2278412616,
+ 339027342, 3585866318, 1280941135, 2379694991, 2766951948, 1700956620, 4236308429, 1024339981,
+ 2258407383, 1192382487, 3740284438, 528411094, 910556245, 4157285269, 1848198548, 2946996820,
+ 1012887186, 4258378066, 1681119059, 2780629139, 2357599504, 1292419792, 3572147409, 358906641,
+ 678054684, 3924071644, 1879503581, 2978491677, 2561882270, 1497229150, 3235873119, 22109855,
+ 2460592729, 1395094937, 3401913240, 189516888, 577821147, 3825075739, 2048679962, 3146956762,
+ 3595049455, 398902831, 2384764974, 1336573934, 1720805997, 2803873197, 1056822188, 4285729900,
+ 1821112490, 2902796138, 887570795, 4117339819, 3696397096, 500978920, 2218668777, 1169222953,
+ 2025774372, 3106931428, 550659301, 3780950821, 3362238118, 166293862, 2416645991, 1367722151,
+ 3262987361, 66315169, 2584839584, 1537170016, 1923370979, 3005911075, 717813282, 3947244002,
+ 1356109368, 2438613496, 146288633, 3375820857, 3759007162, 562248314, 3093388411, 2045739963,
+ 3927406461, 731490493, 2994458300, 1945440636, 1523451135, 2604718911, 44219710, 3274466046,
+ 4263662323, 1068272947, 2790189874, 1740649714, 1325080945, 2406874801, 379033776, 3608758128,
+ 1155642294, 2238671990, 479005303, 3708016055, 4097359924, 901128180, 2891217397, 1843045941,
+ 2011248031, 3060787807, 797805662, 3993195422, 3342353949, 112630237, 2673147868, 1591353372,
+ 3441611994, 212601626, 2504944923, 1421914843, 2113644376, 3161815192, 630660761, 3826893145,
+ 3642224980, 412692116, 2172340373, 1089836885, 1775141590, 2822790422, 832715543, 4029474007,
+ 1674842129, 2723860433, 1001957840, 4197873168, 3540870035, 310623315, 2338445906, 1257178514,
+ 4051548744, 821257608, 2836464521, 1755307081, 1101318602, 2150241802, 432566283, 3628511179,
+ 1270766349, 2318435533, 332587724, 3529260300, 4217841807, 988411727, 2735444302, 1652903566,
+ 1602977411, 2651169091, 132630338, 3328776322, 4015131905, 786223809, 3074340032, 1991273216,
+ 3846741958, 616972294, 3173262855, 2091579847, 1435626564, 2485072772, 234706309, 3430124101,
+ 2712218736, 1613231024, 4190475697, 944458353, 292577266, 3506339890, 1226630707, 2291284467,
+ 459984181, 3672380149, 1124496628, 2189994804, 2880683703, 1782407543, 4091479926, 844224694,
+ 257943739, 3469817723, 1462980986, 2529005242, 3213269817, 2114471161, 3890881272, 644152632,
+ 3046902270, 1947391550, 3991973951, 746483711, 88439420, 3301680572, 1563018173, 2628197501,
+ 657826727, 3871046759, 2136545894, 3201811878, 2548879397, 1449267173, 3481299428, 235845156,
+ 2650161890, 1551408418, 3315268387, 68429027, 758067552, 3970035360, 1967360161, 3033356129,
+ 2311284588, 1213053100, 3517963949, 270598509, 958010606, 4170500910, 1635167535, 2700636911,
+ 855672361, 4069415401, 1802256360, 2866995240, 2212099499, 1113008747, 3686091882, 440112042,
+ }, {
+ 0, 2611301487, 3963330207, 2006897392, 50740095, 2560849680, 4013794784, 1956178319,
+ 101480190, 2645113489, 3929532513, 1905435662, 84561281, 2662269422, 3912356638, 1922342769,
+ 202960380, 2545787283, 3760419683, 2072395532, 253679235, 2495322860, 3810871324, 2021655667,
+ 169122562, 2444351341, 3861841309, 2106214898, 152215677, 2461527058, 3844685538, 2123133581,
+ 405920760, 2207553431, 4094313831, 1873742088, 456646791, 2157096168, 4144791064, 1823027831,
+ 507358470, 2241388905, 4060492697, 1772322806, 490444409, 2258557462, 4043311334, 1789215881,
+ 338245124, 2408348267, 4161972379, 1672996084, 388959611, 2357870868, 4212429796, 1622269835,
+ 304431354, 2306870421, 4263435877, 1706791434, 287538053, 2324051946, 4246267162, 1723705717,
+ 811841520, 2881944479, 3696765295, 1207788800, 862293135, 2831204576, 3747484176, 1157324415,
+ 913293582, 2915732833, 3662962577, 1106318334, 896137841, 2932651550, 3646055662, 1123494017,
+ 1014716940, 2816349795, 3493905555, 1273334012, 1065181555, 2765630748, 3544645612, 1222882179,
+ 980888818, 2714919069, 3595350637, 1307180546, 963712909, 2731826146, 3578431762, 1324336509,
+ 676490248, 3019317351, 3295277719, 1607253752, 726947703, 2968591128, 3345992168, 1556776327,
+ 777919222, 3053147801, 3261432937, 1505806342, 760750473, 3070062054, 3244539670, 1522987897,
+ 608862708, 3220163995, 3362856811, 1406423812, 659339915, 3169449700, 3413582868, 1355966587,
+ 575076106, 3118709605, 3464325525, 1440228858, 557894773, 3135602714, 3447411434, 1457397381,
+ 1623683040, 4217512847, 2365387135, 391757072, 1673614495, 4167309552, 2415577600, 341804655,
+ 1724586270, 4251866481, 2331019137, 290835438, 1707942497, 4268256782, 2314648830, 307490961,
+ 1826587164, 4152020595, 2162433155, 457265388, 1876539747, 4101829900, 2212636668, 407333779,
+ 1792275682, 4051089549, 2263378557, 491595282, 1775619997, 4067460082, 2246988034, 508239213,
+ 2029433880, 3813931127, 2496473735, 258500328, 2079362919, 3763716872, 2546668024, 208559511,
+ 2130363110, 3848244873, 2462145657, 157552662, 2113730969, 3864638966, 2445764358, 174205801,
+ 1961777636, 4014675339, 2564147067, 57707284, 2011718299, 3964481268, 2614361092, 7778411,
+ 1927425818, 3913769845, 2665066885, 92077546, 1910772837, 3930150922, 2648673018, 108709525,
+ 1352980496, 3405878399, 3164554895, 658115296, 1403183983, 3355946752, 3214507504, 607924639,
+ 1453895406, 3440239233, 3130208369, 557218846, 1437504913, 3456883198, 3113552654, 573589345,
+ 1555838444, 3340335491, 2961681267, 723707676, 1606028947, 3290383100, 3011612684, 673504355,
+ 1521500946, 3239382909, 3062619533, 758026722, 1505130605, 3256038402, 3045975794, 774417053,
+ 1217725416, 3543158663, 2762906999, 1057739032, 1267939479, 3493229816, 2812847624, 1007544935,
+ 1318679830, 3577493881, 2728586121, 956803046, 1302285929, 3594125830, 2711933174, 973184153,
+ 1150152212, 3743982203, 2830528651, 856898788, 1200346475, 3694041348, 2880457716, 806684571,
+ 1115789546, 3643069573, 2931426933, 891243034, 1099408277, 3659722746, 2914794762, 907637093,
+ }, {
+ 0, 3717650821, 1616688459, 3184159950, 3233376918, 489665299, 2699419613, 2104690264,
+ 1510200173, 2274691816, 979330598, 3888758691, 2595928571, 1194090622, 4209380528, 661706037,
+ 3020400346, 1771143007, 3562738577, 164481556, 1958661196, 2837976521, 350386439, 3379863682,
+ 3993269687, 865250354, 2388181244, 1406015865, 784146209, 4079732388, 1323412074, 2474079215,
+ 3011398645, 1860735600, 3542286014, 246687547, 1942430051, 2924607718, 328963112, 3456978349,
+ 3917322392, 887832861, 2300653011, 1421341782, 700772878, 4099025803, 1234716485, 2483986112,
+ 125431087, 3673109674, 1730500708, 3132326369, 3351283641, 441867836, 2812031730, 2047535991,
+ 1568292418, 2163009479, 1025936137, 3769651852, 2646824148, 1079348561, 4255113631, 537475098,
+ 3180171691, 1612400686, 3721471200, 4717925, 2100624189, 2694980280, 493375094, 3237910515,
+ 3884860102, 974691139, 2278750093, 1514417672, 657926224, 4204917205, 1198234907, 2600289438,
+ 160053105, 3558665972, 1775665722, 3024116671, 3375586791, 346391650, 2842683564, 1962488105,
+ 1401545756, 2384412057, 869618007, 3997403346, 2469432970, 1319524111, 4083956673, 788193860,
+ 250862174, 3546612699, 1856990997, 3006903952, 3461001416, 333211981, 2920678787, 1937824774,
+ 1425017139, 2305216694, 883735672, 3912918525, 2487837605, 1239398944, 4095071982, 696455019,
+ 3136584836, 1734518017, 3668494799, 121507914, 2051872274, 2816200599, 437363545, 3347544796,
+ 3774328809, 1029797484, 2158697122, 1564328743, 542033279, 4258798842, 1074950196, 2642717105,
+ 2691310871, 2113731730, 3224801372, 497043929, 1624461185, 3175454212, 9435850, 3709412175,
+ 4201248378, 671035391, 2587181873, 1201904308, 986750188, 3880142185, 1519135143, 2266689570,
+ 342721485, 3388693064, 1949382278, 2846355203, 3570723163, 155332830, 3028835344, 1763607957,
+ 1315852448, 2482538789, 775087595, 4087626862, 2396469814, 1396827059, 4002123645, 857560824,
+ 320106210, 3464673127, 1934154665, 2933785132, 3551331444, 238804465, 3018961215, 1852270778,
+ 1226292623, 2491507722, 692783300, 4108177729, 2309936921, 1412959900, 3924976210, 879016919,
+ 2803091512, 2055541181, 3343875443, 450471158, 1739236014, 3124525867, 133568485, 3663777376,
+ 4245691221, 545702608, 2639048222, 1088059291, 1034514883, 3762268230, 1576387720, 2153979149,
+ 501724348, 3228659001, 2109407735, 2687359090, 3713981994, 13109167, 3171052385, 1620357860,
+ 1206151121, 2591211092, 666423962, 4197321503, 2271022407, 1523307714, 3875649548, 982999433,
+ 2850034278, 1953942499, 3384583981, 338329256, 1767471344, 3033506165, 151375291, 3566408766,
+ 4091789579, 779425934, 2478797888, 1311354309, 861580189, 4006375960, 1392910038, 2391852883,
+ 2929327945, 1930372812, 3469036034, 324244359, 1847629279, 3015068762, 243015828, 3555391761,
+ 4103744548, 688715169, 2496043375, 1229996266, 874727090, 3920994103, 1417671673, 2313759356,
+ 446585235, 3339223062, 2059594968, 2807313757, 3660002053, 129100416, 3128657486, 1743609803,
+ 1084066558, 2634765179, 549535669, 4250396208, 2149900392, 1571961325, 3765982499, 1039043750,
+ }, {
+ 0, 2635063670, 3782132909, 2086741467, 430739227, 2225303149, 4173482934, 1707977408,
+ 861478454, 2924937024, 3526875803, 1329085421, 720736557, 3086643291, 3415954816, 1452586230,
+ 1722956908, 4223524122, 2279405761, 450042295, 2132718455, 3792785921, 2658170842, 58693292,
+ 1441473114, 3370435372, 3028674295, 696911745, 1279765825, 3511176247, 2905172460, 807831706,
+ 3445913816, 1349228974, 738901109, 2969918723, 3569940419, 1237784245, 900084590, 2829701656,
+ 4265436910, 1664255896, 525574723, 2187084597, 3885099509, 2057177219, 117386584, 2616249390,
+ 2882946228, 920233410, 1253605401, 3619119471, 2994391983, 796207833, 1393823490, 3457937012,
+ 2559531650, 92322804, 2044829231, 3840835417, 2166609305, 472659183, 1615663412, 4249022530,
+ 1102706673, 3702920839, 2698457948, 1037619754, 1477802218, 3306854812, 3111894087, 611605809,
+ 1927342535, 4025419953, 2475568490, 243387420, 1800169180, 4131620778, 2317525617, 388842247,
+ 655084445, 3120835307, 3328511792, 1533734470, 1051149446, 2745738736, 3754524715, 1120297309,
+ 340972971, 2304586973, 4114354438, 1748234352, 234773168, 2431761350, 3968900637, 1906278251,
+ 2363330345, 299003487, 1840466820, 4038896370, 2507210802, 142532932, 1948239007, 3910149609,
+ 3213136159, 579563625, 1592415666, 3286611140, 2787646980, 992477042, 1195825833, 3662232543,
+ 3933188933, 2002801203, 184645608, 2517538462, 4089658462, 1858919720, 313391347, 2409765253,
+ 3644239219, 1144605701, 945318366, 2773977256, 3231326824, 1570095902, 569697989, 3170568115,
+ 2205413346, 511446676, 1646078799, 4279421497, 2598330617, 131105167, 2075239508, 3871229218,
+ 2955604436, 757403810, 1363424633, 3427521551, 2844163791, 881434553, 1223211618, 3588709140,
+ 3854685070, 2026779384, 78583587, 2577462869, 4235025557, 1633861091, 486774840, 2148301134,
+ 3600338360, 1268198606, 938871061, 2868504675, 3476308643, 1379640277, 777684494, 3008718712,
+ 1310168890, 3541595724, 2943964055, 846639841, 1471879201, 3400857943, 3067468940, 735723002,
+ 2102298892, 3762382970, 2619362721, 19901655, 1692534295, 4193118049, 2240594618, 411247564,
+ 681945942, 3047836192, 3385552891, 1422167693, 822682701, 2886124859, 3496468704, 1298661782,
+ 469546336, 2264093718, 4203901389, 1738379451, 38812283, 2673859341, 3812556502, 2117148576,
+ 3268024339, 1606809957, 598006974, 3198893512, 3680933640, 1181316734, 973624229, 2802299603,
+ 4052944421, 1822222163, 285065864, 2381456382, 3896478014, 1966106696, 156323219, 2489232613,
+ 2759337087, 964150537, 1159127250, 3625517476, 3184831332, 551242258, 1555722185, 3249901247,
+ 2535537225, 170842943, 1984954084, 3946848146, 2391651666, 327308324, 1877176831, 4075589769,
+ 263086283, 2460058045, 4005602406, 1942963472, 369291216, 2332888742, 4151061373, 1784924683,
+ 1022852861, 2717425547, 3717839440, 1083595558, 626782694, 3092517008, 3291821387, 1497027645,
+ 1763466407, 4094934481, 2289211402, 360544636, 1890636732, 3988730570, 2447251217, 215086695,
+ 1514488465, 3343557607, 3140191804, 639919946, 1139395978, 3739626748, 2726758695, 1065936977,
+ }, {
+ 0, 3120290792, 2827399569, 293431929, 2323408227, 864534155, 586863858, 2600537882,
+ 3481914503, 1987188591, 1729068310, 3740575486, 1173727716, 4228805132, 3983743093, 1418249117,
+ 1147313999, 4254680231, 3974377182, 1428157750, 3458136620, 2011505092, 1721256893, 3747844181,
+ 2347455432, 839944224, 594403929, 2593536433, 26687147, 3094146371, 2836498234, 283794642,
+ 2294627998, 826205558, 541298447, 2578994407, 45702141, 3141697557, 2856315500, 331624836,
+ 1196225049, 4273416689, 4023010184, 1446090848, 3442513786, 1959480466, 1706436331, 3696098563,
+ 3433538001, 1968994873, 1679888448, 3722103720, 1188807858, 4280295258, 3999102243, 1470541515,
+ 53374294, 3134568126, 2879970503, 307431215, 2303854645, 816436189, 567589284, 2553242188,
+ 3405478781, 1929420949, 1652411116, 3682996484, 1082596894, 4185703926, 3892424591, 1375368295,
+ 91404282, 3163122706, 2918450795, 336584067, 2400113305, 922028401, 663249672, 2658384096,
+ 2392450098, 929185754, 639587747, 2682555979, 82149713, 3172883129, 2892181696, 362343208,
+ 1091578037, 4176212829, 3918960932, 1349337804, 3412872662, 1922537022, 1676344391, 3658557359,
+ 1111377379, 4224032267, 3937989746, 1396912026, 3359776896, 1908013928, 1623494929, 3644803833,
+ 2377615716, 877417100, 623982837, 2630542109, 130804743, 3190831087, 2941083030, 381060734,
+ 106748588, 3215393092, 2933549885, 388083925, 2350956495, 903570471, 614862430, 2640172470,
+ 3386185259, 1882115523, 1632872378, 3634920530, 1135178568, 4199721120, 3945775833, 1389631793,
+ 1317531835, 4152109907, 3858841898, 1610259138, 3304822232, 2097172016, 1820140617, 3582394273,
+ 2165193788, 955639764, 696815021, 2423477829, 192043359, 2995356343, 2750736590, 437203750,
+ 182808564, 3005133852, 2724453989, 462947725, 2157513367, 962777471, 673168134, 2447663342,
+ 3312231283, 2090301595, 1844056802, 3557935370, 1326499344, 4142603768, 3885397889, 1584245865,
+ 3326266917, 2142836173, 1858371508, 3611272284, 1279175494, 4123357358, 3837270743, 1564721471,
+ 164299426, 2955991370, 2706223923, 414607579, 2209834945, 978107433, 724686416, 2462715320,
+ 2183156074, 1004243586, 715579643, 2472360723, 140260361, 2980573153, 2698675608, 421617264,
+ 1302961645, 4099032581, 3845074044, 1557460884, 3352688782, 2116952934, 1867729183, 3601371895,
+ 2222754758, 1032278062, 754596439, 2499928511, 234942117, 3086693709, 2793824052, 528319708,
+ 1274365761, 4061043881, 3816027856, 1518873912, 3246989858, 2020800970, 1762628531, 3505670235,
+ 3223196809, 2045103969, 1754834200, 3512958704, 1247965674, 4086934018, 3806642299, 1528765331,
+ 261609486, 3060532198, 2802936223, 518697591, 2246819181, 1007707781, 762121468, 2492913428,
+ 213497176, 3041029808, 2755593417, 499441441, 2261110843, 1061030867, 776167850, 2545465922,
+ 3274734047, 2060165687, 1807140942, 3528266662, 1229724860, 4038575956, 3788156205, 1479636677,
+ 1222322711, 4045468159, 3764231046, 1504067694, 3265744756, 2069664924, 1780612837, 3554288909,
+ 2270357136, 1051278712, 802445057, 2519698665, 221152243, 3033880603, 2779263586, 475261322,
+ }, {
+ 0, 2926088593, 2275419491, 701019378, 3560000647, 2052709654, 1402038756, 4261017717,
+ 1930665807, 3715829470, 4105419308, 1524313021, 2804077512, 155861593, 545453739, 2397726522,
+ 3861331614, 1213181711, 1636244477, 3488582252, 840331801, 2625561480, 3048626042, 467584747,
+ 2503254481, 995897408, 311723186, 3170637091, 1090907478, 4016929991, 3332753461, 1758288292,
+ 390036349, 3109546732, 2426363422, 1056427919, 3272488954, 1835443819, 1152258713, 3938878216,
+ 1680663602, 3393484195, 3817652561, 1306808512, 2954733749, 510998820, 935169494, 2580880455,
+ 4044899811, 1601229938, 1991794816, 3637571857, 623446372, 2336332021, 2726898695, 216120726,
+ 2181814956, 744704829, 95158223, 2881711710, 1446680107, 4166125498, 3516576584, 2146575065,
+ 780072698, 2148951915, 2849952665, 129384968, 4199529085, 1411853292, 2112855838, 3548843663,
+ 1567451573, 4077254692, 3670887638, 1957027143, 2304517426, 657765539, 251396177, 2694091200,
+ 3361327204, 1714510325, 1341779207, 3784408214, 476611811, 2986349938, 2613617024, 899690513,
+ 3142211371, 354600634, 1021997640, 2458051545, 1870338988, 3239283261, 3906682575, 1186180958,
+ 960597383, 2536053782, 3202459876, 277428597, 3983589632, 1125666961, 1792074851, 3300423154,
+ 1246892744, 3829039961, 3455203243, 1671079482, 2657312335, 806080478, 432241452, 3081497277,
+ 3748049689, 1896751752, 1489409658, 4138600427, 190316446, 2772397583, 2365053693, 580864876,
+ 2893360214, 35503559, 735381813, 2243795108, 2017747153, 3593269568, 4293150130, 1368183843,
+ 1560145396, 4069882981, 3680356503, 1966430470, 2295112051, 648294626, 258769936, 2701399425,
+ 804156091, 2173100842, 2823706584, 103204425, 4225711676, 1438101421, 2088704863, 3524758222,
+ 3134903146, 347226875, 1031468553, 2467456920, 1860935661, 3229814396, 3914054286, 1193487135,
+ 3385412645, 1738661300, 1315531078, 3758225623, 502792354, 3012596019, 2589468097, 875607120,
+ 1271043721, 3853125400, 3429020650, 1644831355, 2683558414, 832261023, 408158061, 3057348348,
+ 953223622, 2528745559, 3211865253, 286899508, 3974120769, 1116263632, 1799381026, 3307794867,
+ 2917509143, 59586950, 709201268, 2217549029, 2043995280, 3619452161, 4269064691, 1344032866,
+ 3740677976, 1889445577, 1498812987, 4148069290, 180845535, 2762992206, 2372361916, 588238637,
+ 1921194766, 3706423967, 4112727661, 1531686908, 2796705673, 148555288, 554857194, 2407195515,
+ 26248257, 2952271312, 2251333922, 676868275, 3584149702, 2076793175, 1375858085, 4234771508,
+ 2493785488, 986493953, 319029491, 3178008930, 1083533591, 4009621638, 3342158964, 1767759333,
+ 3887577823, 1239362382, 1612160956, 3464433197, 864482904, 2649647049, 3022443323, 441336490,
+ 1706844275, 3419730402, 3793503504, 1282724993, 2978819316, 535149925, 908921239, 2554697734,
+ 380632892, 3100077741, 2433735263, 1063734222, 3265180603, 1828069930, 1161729752, 3948283721,
+ 2207997677, 770953084, 71007118, 2857626143, 1470763626, 4190274555, 3490330377, 2120394392,
+ 4035494306, 1591758899, 1999168705, 3644880208, 616140069, 2328960180, 2736367686, 225524183,
+ },
+};
+
+static const uint8_t
+WUFFS_CRC32__IEEE_X86_SSE42_K1K2[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 212, 43, 68, 84, 1, 0, 0, 0,
+ 150, 21, 228, 198, 1, 0, 0, 0,
+};
+
+static const uint8_t
+WUFFS_CRC32__IEEE_X86_SSE42_K3K4[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 208, 151, 25, 117, 1, 0, 0, 0,
+ 158, 0, 170, 204, 0, 0, 0, 0,
+};
+
+static const uint8_t
+WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 36, 97, 205, 99, 1, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const uint8_t
+WUFFS_CRC32__IEEE_X86_SSE42_PXMU[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 65, 6, 113, 219, 1, 0, 0, 0,
+ 65, 22, 1, 247, 1, 0, 0, 0,
+};
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up__choosy_default(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up_arm_crc32(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x);
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up_x86_avx2(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64)
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up_x86_sse42(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+
+// ---------------- VTables
+
+const wuffs_base__hasher_u32__func_ptrs
+wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
+ (uint32_t(*)(const void*))(&wuffs_crc32__ieee_hasher__checksum_u32),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_crc32__ieee_hasher__get_quirk),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_crc32__ieee_hasher__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update),
+ (uint32_t(*)(void*,
+ wuffs_base__slice_u8))(&wuffs_crc32__ieee_hasher__update_u32),
+};
+
+// ---------------- Initializer Implementations
+
+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 options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.choosy_up = &wuffs_crc32__ieee_hasher__up__choosy_default;
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
+ wuffs_base__hasher_u32__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
+ (const void*)(&wuffs_crc32__ieee_hasher__func_ptrs_for__wuffs_base__hasher_u32);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_crc32__ieee_hasher*
+wuffs_crc32__ieee_hasher__alloc(void) {
+ wuffs_crc32__ieee_hasher* x =
+ (wuffs_crc32__ieee_hasher*)(calloc(sizeof(wuffs_crc32__ieee_hasher), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_crc32__ieee_hasher__initialize(
+ x, sizeof(wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_crc32__ieee_hasher(void) {
+ return sizeof(wuffs_crc32__ieee_hasher);
+}
+
+// ---------------- Function Implementations
+
+// -------- func crc32.ieee_hasher.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_crc32__ieee_hasher__get_quirk(
+ const wuffs_crc32__ieee_hasher* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func crc32.ieee_hasher.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_crc32__ieee_hasher__set_quirk(
+ wuffs_crc32__ieee_hasher* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func crc32.ieee_hasher.update
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__update(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ if (self->private_impl.f_state == 0u) {
+ self->private_impl.choosy_up = (
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
+ wuffs_base__cpu_arch__have_arm_crc32() ? &wuffs_crc32__ieee_hasher__up_arm_crc32 :
+#endif
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+ wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_crc32__ieee_hasher__up_x86_avx2 :
+#endif
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_crc32__ieee_hasher__up_x86_sse42 :
+#endif
+ self->private_impl.choosy_up);
+ }
+ wuffs_crc32__ieee_hasher__up(self, a_x);
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func crc32.ieee_hasher.update_u32
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_crc32__ieee_hasher__update_u32(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return 0;
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return 0;
+ }
+
+ wuffs_crc32__ieee_hasher__update(self, a_x);
+ return self->private_impl.f_state;
+}
+
+// -------- func crc32.ieee_hasher.up
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ return (*self->private_impl.choosy_up)(self, a_x);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up__choosy_default(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ uint32_t v_s = 0;
+ wuffs_base__slice_u8 v_p = {0};
+
+ v_s = (4294967295u ^ self->private_impl.f_state);
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 16;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
+ while (v_p.ptr < i_end0_p) {
+ v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
+ (((uint32_t)(v_p.ptr[1u])) << 8u) |
+ (((uint32_t)(v_p.ptr[2u])) << 16u) |
+ (((uint32_t)(v_p.ptr[3u])) << 24u));
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
+ WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
+ WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
+ WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
+ WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
+ WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
+ WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
+ WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
+ WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
+ WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
+ WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
+ WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
+ WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
+ WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
+ WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
+ WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
+ v_p.ptr += 16;
+ v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
+ (((uint32_t)(v_p.ptr[1u])) << 8u) |
+ (((uint32_t)(v_p.ptr[2u])) << 16u) |
+ (((uint32_t)(v_p.ptr[3u])) << 24u));
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
+ WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
+ WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
+ WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
+ WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
+ WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
+ WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
+ WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
+ WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
+ WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
+ WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
+ WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
+ WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
+ WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
+ WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
+ WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
+ v_p.ptr += 16;
+ }
+ v_p.len = 16;
+ uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16);
+ while (v_p.ptr < i_end1_p) {
+ v_s ^= ((((uint32_t)(v_p.ptr[0u])) << 0u) |
+ (((uint32_t)(v_p.ptr[1u])) << 8u) |
+ (((uint32_t)(v_p.ptr[2u])) << 16u) |
+ (((uint32_t)(v_p.ptr[3u])) << 24u));
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][v_p.ptr[15u]] ^
+ WUFFS_CRC32__IEEE_TABLE[1u][v_p.ptr[14u]] ^
+ WUFFS_CRC32__IEEE_TABLE[2u][v_p.ptr[13u]] ^
+ WUFFS_CRC32__IEEE_TABLE[3u][v_p.ptr[12u]] ^
+ WUFFS_CRC32__IEEE_TABLE[4u][v_p.ptr[11u]] ^
+ WUFFS_CRC32__IEEE_TABLE[5u][v_p.ptr[10u]] ^
+ WUFFS_CRC32__IEEE_TABLE[6u][v_p.ptr[9u]] ^
+ WUFFS_CRC32__IEEE_TABLE[7u][v_p.ptr[8u]] ^
+ WUFFS_CRC32__IEEE_TABLE[8u][v_p.ptr[7u]] ^
+ WUFFS_CRC32__IEEE_TABLE[9u][v_p.ptr[6u]] ^
+ WUFFS_CRC32__IEEE_TABLE[10u][v_p.ptr[5u]] ^
+ WUFFS_CRC32__IEEE_TABLE[11u][v_p.ptr[4u]] ^
+ WUFFS_CRC32__IEEE_TABLE[12u][(255u & (v_s >> 24u))] ^
+ WUFFS_CRC32__IEEE_TABLE[13u][(255u & (v_s >> 16u))] ^
+ WUFFS_CRC32__IEEE_TABLE[14u][(255u & (v_s >> 8u))] ^
+ WUFFS_CRC32__IEEE_TABLE[15u][(255u & (v_s >> 0u))]);
+ v_p.ptr += 16;
+ }
+ v_p.len = 1;
+ uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end2_p) {
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ self->private_impl.f_state = (4294967295u ^ v_s);
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func crc32.ieee_hasher.checksum_u32
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_crc32__ieee_hasher__checksum_u32(
+ const wuffs_crc32__ieee_hasher* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return self->private_impl.f_state;
+}
+
+// ‼ WUFFS MULTI-FILE SECTION +arm_crc32
+// -------- func crc32.ieee_hasher.up_arm_crc32
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up_arm_crc32(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ wuffs_base__slice_u8 v_p = {0};
+ uint32_t v_s = 0;
+
+ v_s = (4294967295u ^ self->private_impl.f_state);
+ while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
+ v_s = __crc32b(v_s, a_x.ptr[0u]);
+ a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
+ }
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 8;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 128) * 128);
+ while (v_p.ptr < i_end0_p) {
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ }
+ v_p.len = 8;
+ uint8_t* i_end1_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 8) * 8);
+ while (v_p.ptr < i_end1_p) {
+ v_s = __crc32d(v_s, wuffs_base__peek_u64le__no_bounds_check(v_p.ptr));
+ v_p.ptr += 8;
+ }
+ v_p.len = 1;
+ uint8_t* i_end2_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end2_p) {
+ v_s = __crc32b(v_s, v_p.ptr[0u]);
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ self->private_impl.f_state = (4294967295u ^ v_s);
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_CRC32)
+// ‼ WUFFS MULTI-FILE SECTION -arm_crc32
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_avx2
+// -------- func crc32.ieee_hasher.up_x86_avx2
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up_x86_avx2(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ uint32_t v_s = 0;
+ wuffs_base__slice_u8 v_p = {0};
+ __m128i v_k = {0};
+ __m128i v_x0 = {0};
+ __m128i v_x1 = {0};
+ __m128i v_x2 = {0};
+ __m128i v_x3 = {0};
+ __m128i v_y0 = {0};
+ __m128i v_y1 = {0};
+ __m128i v_y2 = {0};
+ __m128i v_y3 = {0};
+ uint64_t v_tail_index = 0;
+
+ v_s = (4294967295u ^ self->private_impl.f_state);
+ while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ a_x.ptr[0u])] ^ (v_s >> 8u));
+ a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
+ }
+ if (((uint64_t)(a_x.len)) < 64u) {
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 1;
+ uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end0_p) {
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ self->private_impl.f_state = (4294967295u ^ v_s);
+ return wuffs_base__make_empty_struct();
+ }
+ v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u));
+ v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u));
+ v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u));
+ v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u));
+ v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
+ v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
+ {
+ wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64u);
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 64;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
+ while (v_p.ptr < i_end0_p) {
+ v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u));
+ v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0u));
+ v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0u));
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
+ v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17u));
+ v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17u));
+ v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17u));
+ v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0u)));
+ v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u)));
+ v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32u)));
+ v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48u)));
+ v_p.ptr += 64;
+ }
+ v_p.len = 0;
+ }
+ v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
+ v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
+ v_x0 = _mm_xor_si128(v_x0, v_x1);
+ v_x0 = _mm_xor_si128(v_x0, v_y0);
+ v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
+ v_x0 = _mm_xor_si128(v_x0, v_x2);
+ v_x0 = _mm_xor_si128(v_x0, v_y0);
+ v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
+ v_x0 = _mm_xor_si128(v_x0, v_x3);
+ v_x0 = _mm_xor_si128(v_x0, v_y0);
+ v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16u));
+ v_x2 = _mm_set_epi32((int32_t)(0u), (int32_t)(4294967295u), (int32_t)(0u), (int32_t)(4294967295u));
+ v_x0 = _mm_srli_si128(v_x0, (int32_t)(8u));
+ v_x0 = _mm_xor_si128(v_x0, v_x1);
+ v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
+ v_x1 = _mm_srli_si128(v_x0, (int32_t)(4u));
+ v_x0 = _mm_and_si128(v_x0, v_x2);
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_x0 = _mm_xor_si128(v_x0, v_x1);
+ v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
+ v_x1 = _mm_and_si128(v_x0, v_x2);
+ v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16u));
+ v_x1 = _mm_and_si128(v_x1, v_x2);
+ v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u));
+ v_x0 = _mm_xor_si128(v_x0, v_x1);
+ v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1u))));
+ v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
+ if (v_tail_index < ((uint64_t)(a_x.len))) {
+ {
+ wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 1;
+ uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end0_p) {
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ }
+ self->private_impl.f_state = (4294967295u ^ v_s);
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64)
+// ‼ WUFFS MULTI-FILE SECTION -x86_avx2
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+// -------- func crc32.ieee_hasher.up_x86_sse42
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_crc32__ieee_hasher__up_x86_sse42(
+ wuffs_crc32__ieee_hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ uint32_t v_s = 0;
+ wuffs_base__slice_u8 v_p = {0};
+ __m128i v_k = {0};
+ __m128i v_x0 = {0};
+ __m128i v_x1 = {0};
+ __m128i v_x2 = {0};
+ __m128i v_x3 = {0};
+ __m128i v_y0 = {0};
+ __m128i v_y1 = {0};
+ __m128i v_y2 = {0};
+ __m128i v_y3 = {0};
+ uint64_t v_tail_index = 0;
+
+ v_s = (4294967295u ^ self->private_impl.f_state);
+ while ((((uint64_t)(a_x.len)) > 0u) && ((15u & ((uint32_t)(0xFFFu & (uintptr_t)(a_x.ptr)))) != 0u)) {
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ a_x.ptr[0u])] ^ (v_s >> 8u));
+ a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
+ }
+ if (((uint64_t)(a_x.len)) < 64u) {
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 1;
+ uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end0_p) {
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ self->private_impl.f_state = (4294967295u ^ v_s);
+ return wuffs_base__make_empty_struct();
+ }
+ v_x0 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 0u));
+ v_x1 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 16u));
+ v_x2 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 32u));
+ v_x3 = _mm_lddqu_si128((const __m128i*)(const void*)(a_x.ptr + 48u));
+ v_x0 = _mm_xor_si128(v_x0, _mm_cvtsi32_si128((int32_t)(v_s)));
+ v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K1K2));
+ {
+ wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, 64u);
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 64;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 64) * 64);
+ while (v_p.ptr < i_end0_p) {
+ v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_y1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u));
+ v_y2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(0u));
+ v_y3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(0u));
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
+ v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(17u));
+ v_x2 = _mm_clmulepi64_si128(v_x2, v_k, (int32_t)(17u));
+ v_x3 = _mm_clmulepi64_si128(v_x3, v_k, (int32_t)(17u));
+ v_x0 = _mm_xor_si128(_mm_xor_si128(v_x0, v_y0), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 0u)));
+ v_x1 = _mm_xor_si128(_mm_xor_si128(v_x1, v_y1), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 16u)));
+ v_x2 = _mm_xor_si128(_mm_xor_si128(v_x2, v_y2), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 32u)));
+ v_x3 = _mm_xor_si128(_mm_xor_si128(v_x3, v_y3), _mm_lddqu_si128((const __m128i*)(const void*)(v_p.ptr + 48u)));
+ v_p.ptr += 64;
+ }
+ v_p.len = 0;
+ }
+ v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K3K4));
+ v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
+ v_x0 = _mm_xor_si128(v_x0, v_x1);
+ v_x0 = _mm_xor_si128(v_x0, v_y0);
+ v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
+ v_x0 = _mm_xor_si128(v_x0, v_x2);
+ v_x0 = _mm_xor_si128(v_x0, v_y0);
+ v_y0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(17u));
+ v_x0 = _mm_xor_si128(v_x0, v_x3);
+ v_x0 = _mm_xor_si128(v_x0, v_y0);
+ v_x1 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(16u));
+ v_x2 = _mm_set_epi32((int32_t)(0u), (int32_t)(4294967295u), (int32_t)(0u), (int32_t)(4294967295u));
+ v_x0 = _mm_srli_si128(v_x0, (int32_t)(8u));
+ v_x0 = _mm_xor_si128(v_x0, v_x1);
+ v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_K5ZZ));
+ v_x1 = _mm_srli_si128(v_x0, (int32_t)(4u));
+ v_x0 = _mm_and_si128(v_x0, v_x2);
+ v_x0 = _mm_clmulepi64_si128(v_x0, v_k, (int32_t)(0u));
+ v_x0 = _mm_xor_si128(v_x0, v_x1);
+ v_k = _mm_lddqu_si128((const __m128i*)(const void*)(WUFFS_CRC32__IEEE_X86_SSE42_PXMU));
+ v_x1 = _mm_and_si128(v_x0, v_x2);
+ v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(16u));
+ v_x1 = _mm_and_si128(v_x1, v_x2);
+ v_x1 = _mm_clmulepi64_si128(v_x1, v_k, (int32_t)(0u));
+ v_x0 = _mm_xor_si128(v_x0, v_x1);
+ v_s = ((uint32_t)(_mm_extract_epi32(v_x0, (int32_t)(1u))));
+ v_tail_index = (((uint64_t)(a_x.len)) & 18446744073709551552u);
+ if (v_tail_index < ((uint64_t)(a_x.len))) {
+ {
+ wuffs_base__slice_u8 i_slice_p = wuffs_base__slice_u8__subslice_i(a_x, v_tail_index);
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 1;
+ uint8_t* i_end0_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end0_p) {
+ v_s = (WUFFS_CRC32__IEEE_TABLE[0u][(((uint8_t)(v_s)) ^ v_p.ptr[0u])] ^ (v_s >> 8u));
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ }
+ self->private_impl.f_state = (4294967295u ^ v_s);
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__CRC32)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_deflate__error__bad_huffman_code_over_subscribed[] = "#deflate: bad Huffman code (over-subscribed)";
+const char wuffs_deflate__error__bad_huffman_code_under_subscribed[] = "#deflate: bad Huffman code (under-subscribed)";
+const char wuffs_deflate__error__bad_huffman_code_length_count[] = "#deflate: bad Huffman code length count";
+const char wuffs_deflate__error__bad_huffman_code_length_repetition[] = "#deflate: bad Huffman code length repetition";
+const char wuffs_deflate__error__bad_huffman_code[] = "#deflate: bad Huffman code";
+const char wuffs_deflate__error__bad_huffman_minimum_code_length[] = "#deflate: bad Huffman minimum code length";
+const char wuffs_deflate__error__bad_block[] = "#deflate: bad block";
+const char wuffs_deflate__error__bad_distance[] = "#deflate: bad distance";
+const char wuffs_deflate__error__bad_distance_code_count[] = "#deflate: bad distance code count";
+const char wuffs_deflate__error__bad_literal_length_code_count[] = "#deflate: bad literal/length code count";
+const char wuffs_deflate__error__inconsistent_stored_block_length[] = "#deflate: inconsistent stored block length";
+const char wuffs_deflate__error__missing_end_of_block_code[] = "#deflate: missing end-of-block code";
+const char wuffs_deflate__error__no_huffman_codes[] = "#deflate: no Huffman codes";
+const char wuffs_deflate__error__truncated_input[] = "#deflate: truncated input";
+const char wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state[] = "#deflate: internal error: inconsistent Huffman decoder state";
+const char wuffs_deflate__error__internal_error_inconsistent_i_o[] = "#deflate: internal error: inconsistent I/O";
+const char wuffs_deflate__error__internal_error_inconsistent_distance[] = "#deflate: internal error: inconsistent distance";
+const char wuffs_deflate__error__internal_error_inconsistent_n_bits[] = "#deflate: internal error: inconsistent n_bits";
+
+// ---------------- Private Consts
+
+static const uint8_t
+WUFFS_DEFLATE__CODE_ORDER[19] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 16, 17, 18, 0, 8, 7, 9, 6,
+ 10, 5, 11, 4, 12, 3, 13, 2,
+ 14, 1, 15,
+};
+
+static const uint8_t
+WUFFS_DEFLATE__REVERSE8[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 128, 64, 192, 32, 160, 96, 224,
+ 16, 144, 80, 208, 48, 176, 112, 240,
+ 8, 136, 72, 200, 40, 168, 104, 232,
+ 24, 152, 88, 216, 56, 184, 120, 248,
+ 4, 132, 68, 196, 36, 164, 100, 228,
+ 20, 148, 84, 212, 52, 180, 116, 244,
+ 12, 140, 76, 204, 44, 172, 108, 236,
+ 28, 156, 92, 220, 60, 188, 124, 252,
+ 2, 130, 66, 194, 34, 162, 98, 226,
+ 18, 146, 82, 210, 50, 178, 114, 242,
+ 10, 138, 74, 202, 42, 170, 106, 234,
+ 26, 154, 90, 218, 58, 186, 122, 250,
+ 6, 134, 70, 198, 38, 166, 102, 230,
+ 22, 150, 86, 214, 54, 182, 118, 246,
+ 14, 142, 78, 206, 46, 174, 110, 238,
+ 30, 158, 94, 222, 62, 190, 126, 254,
+ 1, 129, 65, 193, 33, 161, 97, 225,
+ 17, 145, 81, 209, 49, 177, 113, 241,
+ 9, 137, 73, 201, 41, 169, 105, 233,
+ 25, 153, 89, 217, 57, 185, 121, 249,
+ 5, 133, 69, 197, 37, 165, 101, 229,
+ 21, 149, 85, 213, 53, 181, 117, 245,
+ 13, 141, 77, 205, 45, 173, 109, 237,
+ 29, 157, 93, 221, 61, 189, 125, 253,
+ 3, 131, 67, 195, 35, 163, 99, 227,
+ 19, 147, 83, 211, 51, 179, 115, 243,
+ 11, 139, 75, 203, 43, 171, 107, 235,
+ 27, 155, 91, 219, 59, 187, 123, 251,
+ 7, 135, 71, 199, 39, 167, 103, 231,
+ 23, 151, 87, 215, 55, 183, 119, 247,
+ 15, 143, 79, 207, 47, 175, 111, 239,
+ 31, 159, 95, 223, 63, 191, 127, 255,
+};
+
+static const uint32_t
+WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 1073741824, 1073742080, 1073742336, 1073742592, 1073742848, 1073743104, 1073743360, 1073743616,
+ 1073743888, 1073744400, 1073744912, 1073745424, 1073745952, 1073746976, 1073748000, 1073749024,
+ 1073750064, 1073752112, 1073754160, 1073756208, 1073758272, 1073762368, 1073766464, 1073770560,
+ 1073774672, 1073782864, 1073791056, 1073799248, 1073807104, 134217728, 134217728, 134217728,
+};
+
+static const uint32_t
+WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[32] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 1073741824, 1073742080, 1073742336, 1073742592, 1073742864, 1073743376, 1073743904, 1073744928,
+ 1073745968, 1073748016, 1073750080, 1073754176, 1073758288, 1073766480, 1073774688, 1073791072,
+ 1073807472, 1073840240, 1073873024, 1073938560, 1074004112, 1074135184, 1074266272, 1074528416,
+ 1074790576, 1075314864, 1075839168, 1076887744, 1077936336, 1080033488, 134217728, 134217728,
+};
+
+#define WUFFS_DEFLATE__HUFFS_TABLE_SIZE 1024
+
+#define WUFFS_DEFLATE__HUFFS_TABLE_MASK 1023
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__do_transform_io(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_blocks(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_uncompressed(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__init_fixed_huffman(
+ wuffs_deflate__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__init_dynamic_huffman(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__init_huff(
+ wuffs_deflate__decoder* self,
+ uint32_t a_which,
+ uint32_t a_n_codes0,
+ uint32_t a_n_codes1,
+ uint32_t a_base_symbol);
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_bmi2(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_fast32(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_fast64(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_slow(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+// ---------------- VTables
+
+const wuffs_base__io_transformer__func_ptrs
+wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer = {
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_deflate__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_deflate__decoder__history_retain_length),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_deflate__decoder__set_quirk),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__slice_u8))(&wuffs_deflate__decoder__transform_io),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_deflate__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+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 options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.choosy_decode_huffman_fast64 = &wuffs_deflate__decoder__decode_huffman_fast64__choosy_default;
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
+ wuffs_base__io_transformer__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
+ (const void*)(&wuffs_deflate__decoder__func_ptrs_for__wuffs_base__io_transformer);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_deflate__decoder*
+wuffs_deflate__decoder__alloc(void) {
+ wuffs_deflate__decoder* x =
+ (wuffs_deflate__decoder*)(calloc(sizeof(wuffs_deflate__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_deflate__decoder__initialize(
+ x, sizeof(wuffs_deflate__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_deflate__decoder(void) {
+ return sizeof(wuffs_deflate__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func deflate.decoder.add_history
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_deflate__decoder__add_history(
+ wuffs_deflate__decoder* self,
+ wuffs_base__slice_u8 a_hist) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ wuffs_base__slice_u8 v_s = {0};
+ uint64_t v_n_copied = 0;
+ uint32_t v_already_full = 0;
+
+ v_s = a_hist;
+ if (((uint64_t)(v_s.len)) >= 32768u) {
+ v_s = wuffs_base__slice_u8__suffix(v_s, 32768u);
+ wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
+ self->private_impl.f_history_index = 32768u;
+ } else {
+ v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_history, (self->private_impl.f_history_index & 32767u), 32768), v_s);
+ if (v_n_copied < ((uint64_t)(v_s.len))) {
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, v_n_copied);
+ v_n_copied = wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_history, 32768), v_s);
+ self->private_impl.f_history_index = (((uint32_t)((v_n_copied & 32767u))) + 32768u);
+ } else {
+ v_already_full = 0u;
+ if (self->private_impl.f_history_index >= 32768u) {
+ v_already_full = 32768u;
+ }
+ self->private_impl.f_history_index = ((self->private_impl.f_history_index & 32767u) + ((uint32_t)((v_n_copied & 32767u))) + v_already_full);
+ }
+ }
+ wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8_ij(self->private_data.f_history, 32768, 33025), wuffs_base__make_slice_u8(self->private_data.f_history, 33025));
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func deflate.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_deflate__decoder__get_quirk(
+ const wuffs_deflate__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func deflate.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_deflate__decoder__set_quirk(
+ wuffs_deflate__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func deflate.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_deflate__decoder__history_retain_length(
+ const wuffs_deflate__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func deflate.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_deflate__decoder__workbuf_len(
+ const wuffs_deflate__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(1u, 1u);
+}
+
+// -------- func deflate.decoder.transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_deflate__decoder__transform_io(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_deflate__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func deflate.decoder.do_transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__do_transform_io(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint64_t v_mark = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.choosy_decode_huffman_fast64 = (
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ wuffs_base__cpu_arch__have_x86_bmi2() ? &wuffs_deflate__decoder__decode_huffman_bmi2 :
+#endif
+ self->private_impl.choosy_decode_huffman_fast64);
+ while (true) {
+ v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
+ {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ wuffs_base__status t_0 = wuffs_deflate__decoder__decode_blocks(self, a_dst, a_src);
+ v_status = t_0;
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ }
+ if ( ! wuffs_base__status__is_suspension(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_transformed_history_count, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst))));
+ wuffs_deflate__decoder__add_history(self, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_do_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func deflate.decoder.decode_blocks
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_blocks(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_final = 0;
+ uint32_t v_b0 = 0;
+ uint32_t v_type = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_blocks[0];
+ if (coro_susp_point) {
+ v_final = self->private_data.s_decode_blocks[0].v_final;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ label__outer__continue:;
+ while (v_final == 0u) {
+ while (self->private_impl.f_n_bits < 3u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_0 = *iop_a_src++;
+ v_b0 = t_0;
+ }
+ self->private_impl.f_bits |= (v_b0 << (self->private_impl.f_n_bits & 3u));
+ self->private_impl.f_n_bits = ((self->private_impl.f_n_bits & 3u) + 8u);
+ }
+ v_final = (self->private_impl.f_bits & 1u);
+ v_type = ((self->private_impl.f_bits >> 1u) & 3u);
+ self->private_impl.f_bits >>= 3u;
+ self->private_impl.f_n_bits -= 3u;
+ if (v_type == 0u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ status = wuffs_deflate__decoder__decode_uncompressed(self, a_dst, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ continue;
+ } else if (v_type == 1u) {
+ v_status = wuffs_deflate__decoder__init_fixed_huffman(self);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ } else if (v_type == 2u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_deflate__decoder__init_dynamic_huffman(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_block);
+ goto exit;
+ }
+ self->private_impl.f_end_of_block = false;
+ while (true) {
+ if (sizeof(void*) == 4u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_status = wuffs_deflate__decoder__decode_huffman_fast32(self, a_dst, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ } else {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_status = wuffs_deflate__decoder__decode_huffman_fast64(self, a_dst, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ if (wuffs_base__status__is_error(&v_status)) {
+ status = v_status;
+ goto exit;
+ }
+ if (self->private_impl.f_end_of_block) {
+ goto label__outer__continue;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ status = wuffs_deflate__decoder__decode_huffman_slow(self, a_dst, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ if (self->private_impl.f_end_of_block) {
+ goto label__outer__continue;
+ }
+ }
+ }
+
+ ok:
+ self->private_impl.p_decode_blocks[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_blocks[0].v_final = v_final;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func deflate.decoder.decode_uncompressed
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_uncompressed(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_length = 0;
+ uint32_t v_n_copied = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_uncompressed[0];
+ if (coro_susp_point) {
+ v_length = self->private_data.s_decode_uncompressed[0].v_length;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ self->private_impl.f_n_bits = 0u;
+ self->private_impl.f_bits = 0u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_uncompressed[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_uncompressed[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0)) << 56;
+ }
+ }
+ v_length = t_0;
+ }
+ if ((((v_length) & 0xFFFFu) + ((v_length) >> (32u - 16u))) != 65535u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__inconsistent_stored_block_length);
+ goto exit;
+ }
+ v_length = ((v_length) & 0xFFFFu);
+ while (true) {
+ v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_reader(
+ &iop_a_dst, io2_a_dst,v_length, &iop_a_src, io2_a_src);
+ if (v_length <= v_n_copied) {
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ v_length -= v_n_copied;
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) == 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ } else {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
+ }
+ }
+
+ ok:
+ self->private_impl.p_decode_uncompressed[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_uncompressed[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_uncompressed[0].v_length = v_length;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func deflate.decoder.init_fixed_huffman
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__init_fixed_huffman(
+ wuffs_deflate__decoder* self) {
+ uint32_t v_i = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ while (v_i < 144u) {
+ self->private_data.f_code_lengths[v_i] = 8u;
+ v_i += 1u;
+ }
+ while (v_i < 256u) {
+ self->private_data.f_code_lengths[v_i] = 9u;
+ v_i += 1u;
+ }
+ while (v_i < 280u) {
+ self->private_data.f_code_lengths[v_i] = 7u;
+ v_i += 1u;
+ }
+ while (v_i < 288u) {
+ self->private_data.f_code_lengths[v_i] = 8u;
+ v_i += 1u;
+ }
+ while (v_i < 320u) {
+ self->private_data.f_code_lengths[v_i] = 5u;
+ v_i += 1u;
+ }
+ v_status = wuffs_deflate__decoder__init_huff(self,
+ 0u,
+ 0u,
+ 288u,
+ 257u);
+ if (wuffs_base__status__is_error(&v_status)) {
+ return v_status;
+ }
+ v_status = wuffs_deflate__decoder__init_huff(self,
+ 1u,
+ 288u,
+ 320u,
+ 0u);
+ if (wuffs_base__status__is_error(&v_status)) {
+ return v_status;
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func deflate.decoder.init_dynamic_huffman
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__init_dynamic_huffman(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint32_t v_b0 = 0;
+ uint32_t v_n_lit = 0;
+ uint32_t v_n_dist = 0;
+ uint32_t v_n_clen = 0;
+ uint32_t v_i = 0;
+ uint32_t v_b1 = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ uint32_t v_mask = 0;
+ uint32_t v_table_entry = 0;
+ uint32_t v_table_entry_n_bits = 0;
+ uint32_t v_b2 = 0;
+ uint32_t v_n_extra_bits = 0;
+ uint8_t v_rep_symbol = 0;
+ uint32_t v_rep_count = 0;
+ uint32_t v_b3 = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_init_dynamic_huffman[0];
+ if (coro_susp_point) {
+ v_bits = self->private_data.s_init_dynamic_huffman[0].v_bits;
+ v_n_bits = self->private_data.s_init_dynamic_huffman[0].v_n_bits;
+ v_n_lit = self->private_data.s_init_dynamic_huffman[0].v_n_lit;
+ v_n_dist = self->private_data.s_init_dynamic_huffman[0].v_n_dist;
+ v_n_clen = self->private_data.s_init_dynamic_huffman[0].v_n_clen;
+ v_i = self->private_data.s_init_dynamic_huffman[0].v_i;
+ v_mask = self->private_data.s_init_dynamic_huffman[0].v_mask;
+ v_n_extra_bits = self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits;
+ v_rep_symbol = self->private_data.s_init_dynamic_huffman[0].v_rep_symbol;
+ v_rep_count = self->private_data.s_init_dynamic_huffman[0].v_rep_count;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ v_bits = self->private_impl.f_bits;
+ v_n_bits = self->private_impl.f_n_bits;
+ while (v_n_bits < 14u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_0 = *iop_a_src++;
+ v_b0 = t_0;
+ }
+ v_bits |= (v_b0 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ v_n_lit = (((v_bits) & 0x1Fu) + 257u);
+ if (v_n_lit > 286u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_literal_length_code_count);
+ goto exit;
+ }
+ v_bits >>= 5u;
+ v_n_dist = (((v_bits) & 0x1Fu) + 1u);
+ if (v_n_dist > 30u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_distance_code_count);
+ goto exit;
+ }
+ v_bits >>= 5u;
+ v_n_clen = (((v_bits) & 0xFu) + 4u);
+ v_bits >>= 4u;
+ v_n_bits -= 14u;
+ v_i = 0u;
+ while (v_i < v_n_clen) {
+ while (v_n_bits < 3u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_1 = *iop_a_src++;
+ v_b1 = t_1;
+ }
+ v_bits |= (v_b1 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = ((uint8_t)((v_bits & 7u)));
+ v_bits >>= 3u;
+ v_n_bits -= 3u;
+ v_i += 1u;
+ }
+ while (v_i < 19u) {
+ self->private_data.f_code_lengths[WUFFS_DEFLATE__CODE_ORDER[v_i]] = 0u;
+ v_i += 1u;
+ }
+ v_status = wuffs_deflate__decoder__init_huff(self,
+ 0u,
+ 0u,
+ 19u,
+ 4095u);
+ if (wuffs_base__status__is_error(&v_status)) {
+ status = v_status;
+ goto exit;
+ }
+ v_mask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
+ v_i = 0u;
+ while (v_i < (v_n_lit + v_n_dist)) {
+ while (true) {
+ v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_mask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ if (v_n_bits >= v_table_entry_n_bits) {
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_2 = *iop_a_src++;
+ v_b2 = t_2;
+ }
+ v_bits |= (v_b2 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ if ((v_table_entry >> 24u) != 128u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_table_entry = ((v_table_entry >> 8u) & 255u);
+ if (v_table_entry < 16u) {
+ self->private_data.f_code_lengths[v_i] = ((uint8_t)(v_table_entry));
+ v_i += 1u;
+ continue;
+ }
+ v_n_extra_bits = 0u;
+ v_rep_symbol = 0u;
+ v_rep_count = 0u;
+ if (v_table_entry == 16u) {
+ v_n_extra_bits = 2u;
+ if (v_i <= 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_repetition);
+ goto exit;
+ }
+ v_rep_symbol = (self->private_data.f_code_lengths[(v_i - 1u)] & 15u);
+ v_rep_count = 3u;
+ } else if (v_table_entry == 17u) {
+ v_n_extra_bits = 3u;
+ v_rep_symbol = 0u;
+ v_rep_count = 3u;
+ } else if (v_table_entry == 18u) {
+ v_n_extra_bits = 7u;
+ v_rep_symbol = 0u;
+ v_rep_count = 11u;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ while (v_n_bits < v_n_extra_bits) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_3 = *iop_a_src++;
+ v_b3 = t_3;
+ }
+ v_bits |= (v_b3 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ v_rep_count += ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_n_extra_bits));
+ v_bits >>= v_n_extra_bits;
+ v_n_bits -= v_n_extra_bits;
+ while (v_rep_count > 0u) {
+ if (v_i >= (v_n_lit + v_n_dist)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
+ goto exit;
+ }
+ self->private_data.f_code_lengths[v_i] = v_rep_symbol;
+ v_i += 1u;
+ v_rep_count -= 1u;
+ }
+ }
+ if (v_i != (v_n_lit + v_n_dist)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_length_count);
+ goto exit;
+ }
+ if (self->private_data.f_code_lengths[256u] == 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__missing_end_of_block_code);
+ goto exit;
+ }
+ v_status = wuffs_deflate__decoder__init_huff(self,
+ 0u,
+ 0u,
+ v_n_lit,
+ 257u);
+ if (wuffs_base__status__is_error(&v_status)) {
+ status = v_status;
+ goto exit;
+ }
+ v_status = wuffs_deflate__decoder__init_huff(self,
+ 1u,
+ v_n_lit,
+ (v_n_lit + v_n_dist),
+ 0u);
+ if (wuffs_base__status__is_error(&v_status)) {
+ status = v_status;
+ goto exit;
+ }
+ self->private_impl.f_bits = v_bits;
+ self->private_impl.f_n_bits = v_n_bits;
+
+ goto ok;
+ ok:
+ self->private_impl.p_init_dynamic_huffman[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_init_dynamic_huffman[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_init_dynamic_huffman[0].v_bits = v_bits;
+ self->private_data.s_init_dynamic_huffman[0].v_n_bits = v_n_bits;
+ self->private_data.s_init_dynamic_huffman[0].v_n_lit = v_n_lit;
+ self->private_data.s_init_dynamic_huffman[0].v_n_dist = v_n_dist;
+ self->private_data.s_init_dynamic_huffman[0].v_n_clen = v_n_clen;
+ self->private_data.s_init_dynamic_huffman[0].v_i = v_i;
+ self->private_data.s_init_dynamic_huffman[0].v_mask = v_mask;
+ self->private_data.s_init_dynamic_huffman[0].v_n_extra_bits = v_n_extra_bits;
+ self->private_data.s_init_dynamic_huffman[0].v_rep_symbol = v_rep_symbol;
+ self->private_data.s_init_dynamic_huffman[0].v_rep_count = v_rep_count;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func deflate.decoder.init_huff
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__init_huff(
+ wuffs_deflate__decoder* self,
+ uint32_t a_which,
+ uint32_t a_n_codes0,
+ uint32_t a_n_codes1,
+ uint32_t a_base_symbol) {
+ uint16_t v_counts[16] = {0};
+ uint32_t v_i = 0;
+ uint32_t v_remaining = 0;
+ uint16_t v_offsets[16] = {0};
+ uint32_t v_n_symbols = 0;
+ uint32_t v_count = 0;
+ uint16_t v_symbols[320] = {0};
+ uint32_t v_min_cl = 0;
+ uint32_t v_max_cl = 0;
+ uint32_t v_initial_high_bits = 0;
+ uint32_t v_prev_cl = 0;
+ uint32_t v_prev_redirect_key = 0;
+ uint32_t v_top = 0;
+ uint32_t v_next_top = 0;
+ uint32_t v_code = 0;
+ uint32_t v_key = 0;
+ uint32_t v_value = 0;
+ uint32_t v_cl = 0;
+ uint32_t v_redirect_key = 0;
+ uint32_t v_j = 0;
+ uint32_t v_reversed_key = 0;
+ uint32_t v_symbol = 0;
+ uint32_t v_high_bits = 0;
+ uint32_t v_delta = 0;
+
+ v_i = a_n_codes0;
+ while (v_i < a_n_codes1) {
+ if (v_counts[(self->private_data.f_code_lengths[v_i] & 15u)] >= 320u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_counts[(self->private_data.f_code_lengths[v_i] & 15u)] += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ v_i += 1u;
+ }
+ if ((((uint32_t)(v_counts[0u])) + a_n_codes0) == a_n_codes1) {
+ return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
+ }
+ v_remaining = 1u;
+ v_i = 1u;
+ while (v_i <= 15u) {
+ if (v_remaining > 1073741824u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_remaining <<= 1u;
+ if (v_remaining < ((uint32_t)(v_counts[v_i]))) {
+ return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_over_subscribed);
+ }
+ v_remaining -= ((uint32_t)(v_counts[v_i]));
+ v_i += 1u;
+ }
+ if (v_remaining != 0u) {
+ if ((a_which == 1u) && (v_counts[1u] == 1u) && ((((uint32_t)(v_counts[0u])) + a_n_codes0 + 1u) == a_n_codes1)) {
+ v_i = 0u;
+ while (v_i <= 29u) {
+ if (self->private_data.f_code_lengths[(a_n_codes0 + v_i)] == 1u) {
+ self->private_impl.f_n_huffs_bits[1u] = 1u;
+ self->private_data.f_huffs[1u][0u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[v_i] | 1u);
+ self->private_data.f_huffs[1u][1u] = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[31u] | 1u);
+ return wuffs_base__make_status(NULL);
+ }
+ v_i += 1u;
+ }
+ }
+ return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code_under_subscribed);
+ }
+ v_i = 1u;
+ while (v_i <= 15u) {
+ v_offsets[v_i] = ((uint16_t)(v_n_symbols));
+ v_count = ((uint32_t)(v_counts[v_i]));
+ if (v_n_symbols > (320u - v_count)) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_n_symbols = (v_n_symbols + v_count);
+ v_i += 1u;
+ }
+ if (v_n_symbols > 288u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_i = a_n_codes0;
+ while (v_i < a_n_codes1) {
+ if (v_i < a_n_codes0) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ if (self->private_data.f_code_lengths[v_i] != 0u) {
+ if (v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)] >= 320u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_symbols[v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)]] = ((uint16_t)((v_i - a_n_codes0)));
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_offsets[(self->private_data.f_code_lengths[v_i] & 15u)] += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ }
+ v_i += 1u;
+ }
+ v_min_cl = 1u;
+ while (true) {
+ if (v_counts[v_min_cl] != 0u) {
+ break;
+ }
+ if (v_min_cl >= 9u) {
+ return wuffs_base__make_status(wuffs_deflate__error__bad_huffman_minimum_code_length);
+ }
+ v_min_cl += 1u;
+ }
+ v_max_cl = 15u;
+ while (true) {
+ if (v_counts[v_max_cl] != 0u) {
+ break;
+ }
+ if (v_max_cl <= 1u) {
+ return wuffs_base__make_status(wuffs_deflate__error__no_huffman_codes);
+ }
+ v_max_cl -= 1u;
+ }
+ if (v_max_cl <= 9u) {
+ self->private_impl.f_n_huffs_bits[a_which] = v_max_cl;
+ } else {
+ self->private_impl.f_n_huffs_bits[a_which] = 9u;
+ }
+ v_i = 0u;
+ if ((v_n_symbols != ((uint32_t)(v_offsets[v_max_cl]))) || (v_n_symbols != ((uint32_t)(v_offsets[15u])))) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ if ((a_n_codes0 + ((uint32_t)(v_symbols[0u]))) >= 320u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_initial_high_bits = 512u;
+ if (v_max_cl < 9u) {
+ v_initial_high_bits = (((uint32_t)(1u)) << v_max_cl);
+ }
+ v_prev_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[0u])))] & 15u)));
+ v_prev_redirect_key = 4294967295u;
+ v_top = 0u;
+ v_next_top = 512u;
+ v_code = 0u;
+ v_key = 0u;
+ v_value = 0u;
+ while (true) {
+ if ((a_n_codes0 + ((uint32_t)(v_symbols[v_i]))) >= 320u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_cl = ((uint32_t)((self->private_data.f_code_lengths[(a_n_codes0 + ((uint32_t)(v_symbols[v_i])))] & 15u)));
+ if (v_cl > v_prev_cl) {
+ v_code <<= (v_cl - v_prev_cl);
+ if (v_code >= 32768u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ }
+ v_prev_cl = v_cl;
+ v_key = v_code;
+ if (v_cl > 9u) {
+ v_cl -= 9u;
+ v_redirect_key = ((v_key >> v_cl) & 511u);
+ v_key = ((v_key) & WUFFS_BASE__LOW_BITS_MASK__U32(v_cl));
+ if (v_prev_redirect_key != v_redirect_key) {
+ v_prev_redirect_key = v_redirect_key;
+ v_remaining = (((uint32_t)(1u)) << v_cl);
+ v_j = v_prev_cl;
+ while (v_j <= 15u) {
+ if (v_remaining <= ((uint32_t)(v_counts[v_j]))) {
+ break;
+ }
+ v_remaining -= ((uint32_t)(v_counts[v_j]));
+ if (v_remaining > 1073741824u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_remaining <<= 1u;
+ v_j += 1u;
+ }
+ if ((v_j <= 9u) || (15u < v_j)) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_j -= 9u;
+ v_initial_high_bits = (((uint32_t)(1u)) << v_j);
+ v_top = v_next_top;
+ if ((v_top + (((uint32_t)(1u)) << v_j)) > 1024u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_next_top = (v_top + (((uint32_t)(1u)) << v_j));
+ v_redirect_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_redirect_key >> 1u)])) | ((v_redirect_key & 1u) << 8u));
+ self->private_data.f_huffs[a_which][v_redirect_key] = (268435465u | (v_top << 8u) | (v_j << 4u));
+ }
+ }
+ if ((v_key >= 512u) || (v_counts[v_prev_cl] <= 0u)) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_counts[v_prev_cl] -= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ v_reversed_key = (((uint32_t)(WUFFS_DEFLATE__REVERSE8[(v_key >> 1u)])) | ((v_key & 1u) << 8u));
+ v_reversed_key >>= (9u - v_cl);
+ v_symbol = ((uint32_t)(v_symbols[v_i]));
+ if (v_symbol == 256u) {
+ v_value = (536870912u | v_cl);
+ } else if ((v_symbol < 256u) && (a_which == 0u)) {
+ v_value = (2147483648u | (v_symbol << 8u) | v_cl);
+ } else if (v_symbol >= a_base_symbol) {
+ v_symbol -= a_base_symbol;
+ if (a_which == 0u) {
+ v_value = (WUFFS_DEFLATE__LCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl);
+ } else {
+ v_value = (WUFFS_DEFLATE__DCODE_MAGIC_NUMBERS[(v_symbol & 31u)] | v_cl);
+ }
+ } else {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ v_high_bits = v_initial_high_bits;
+ v_delta = (((uint32_t)(1u)) << v_cl);
+ while (v_high_bits >= v_delta) {
+ v_high_bits -= v_delta;
+ if ((v_top + ((v_high_bits | v_reversed_key) & 511u)) >= 1024u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ self->private_data.f_huffs[a_which][(v_top + ((v_high_bits | v_reversed_key) & 511u))] = v_value;
+ }
+ v_i += 1u;
+ if (v_i >= v_n_symbols) {
+ break;
+ }
+ v_code += 1u;
+ if (v_code >= 32768u) {
+ return wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ }
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_bmi2
+// -------- func deflate.decoder.decode_huffman_bmi2
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("bmi2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_bmi2(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint64_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint32_t v_table_entry = 0;
+ uint32_t v_table_entry_n_bits = 0;
+ uint64_t v_lmask = 0;
+ uint64_t v_dmask = 0;
+ uint32_t v_redir_top = 0;
+ uint32_t v_redir_mask = 0;
+ uint32_t v_length = 0;
+ uint32_t v_dist_minus_1 = 0;
+ uint32_t v_hlen = 0;
+ uint32_t v_hdist = 0;
+ uint32_t v_hdist_adjustment = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ v_bits = ((uint64_t)(self->private_impl.f_bits));
+ v_n_bits = self->private_impl.f_n_bits;
+ v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
+ v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
+ if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
+ goto exit;
+ }
+ v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
+ label__loop__continue:;
+ while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) {
+ v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u)));
+ iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 31u) != 0u) {
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
+ continue;
+ } else if ((v_table_entry >> 30u) != 0u) {
+ } else if ((v_table_entry >> 29u) != 0u) {
+ self->private_impl.f_end_of_block = true;
+ break;
+ } else if ((v_table_entry >> 28u) != 0u) {
+ v_redir_top = ((v_table_entry >> 8u) & 65535u);
+ v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
+ v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 31u) != 0u) {
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
+ continue;
+ } else if ((v_table_entry >> 30u) != 0u) {
+ } else if ((v_table_entry >> 29u) != 0u) {
+ self->private_impl.f_end_of_block = true;
+ break;
+ } else if ((v_table_entry >> 28u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ } else if ((v_table_entry >> 27u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ } else if ((v_table_entry >> 27u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_length = (((v_table_entry >> 8u) & 255u) + 3u);
+ v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
+ if (v_table_entry_n_bits > 0u) {
+ v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ }
+ v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 28u) == 1u) {
+ v_redir_top = ((v_table_entry >> 8u) & 65535u);
+ v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
+ v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ }
+ if ((v_table_entry >> 24u) != 64u) {
+ if ((v_table_entry >> 24u) == 8u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
+ v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
+ v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ do {
+ if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
+ v_hlen = 0u;
+ v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
+ if (v_length > v_hdist) {
+ v_length -= v_hdist;
+ v_hlen = v_hdist;
+ } else {
+ v_hlen = v_length;
+ v_length = 0u;
+ }
+ v_hdist += v_hdist_adjustment;
+ if (self->private_impl.f_history_index < v_hdist) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
+ goto exit;
+ }
+ wuffs_base__io_writer__limited_copy_u32_from_slice(
+ &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025));
+ if (v_length == 0u) {
+ goto label__loop__continue;
+ }
+ if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
+ goto exit;
+ }
+ }
+ if ((v_dist_minus_1 + 1u) >= 8u) {
+ wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ } else if ((v_dist_minus_1 + 1u) == 1u) {
+ wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ } else {
+ wuffs_base__io_writer__limited_copy_u32_from_history_fast(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ }
+ } while (0);
+ }
+ if (v_n_bits > 63u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ while (v_n_bits >= 8u) {
+ v_n_bits -= 8u;
+ if (iop_a_src > io1_a_src) {
+ iop_a_src--;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ }
+ self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u))));
+ self->private_impl.f_n_bits = v_n_bits;
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_bmi2
+
+// -------- func deflate.decoder.decode_huffman_fast32
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_fast32(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint32_t v_table_entry = 0;
+ uint32_t v_table_entry_n_bits = 0;
+ uint32_t v_lmask = 0;
+ uint32_t v_dmask = 0;
+ uint32_t v_redir_top = 0;
+ uint32_t v_redir_mask = 0;
+ uint32_t v_length = 0;
+ uint32_t v_dist_minus_1 = 0;
+ uint32_t v_hlen = 0;
+ uint32_t v_hdist = 0;
+ uint32_t v_hdist_adjustment = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ v_bits = self->private_impl.f_bits;
+ v_n_bits = self->private_impl.f_n_bits;
+ v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
+ v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
+ if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
+ goto exit;
+ }
+ v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
+ label__loop__continue:;
+ while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 12u)) {
+ if (v_n_bits < 15u) {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ } else {
+ }
+ v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 31u) != 0u) {
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
+ continue;
+ } else if ((v_table_entry >> 30u) != 0u) {
+ } else if ((v_table_entry >> 29u) != 0u) {
+ self->private_impl.f_end_of_block = true;
+ break;
+ } else if ((v_table_entry >> 28u) != 0u) {
+ if (v_n_bits < 15u) {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ } else {
+ }
+ v_redir_top = ((v_table_entry >> 8u) & 65535u);
+ v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
+ v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 31u) != 0u) {
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
+ continue;
+ } else if ((v_table_entry >> 30u) != 0u) {
+ } else if ((v_table_entry >> 29u) != 0u) {
+ self->private_impl.f_end_of_block = true;
+ break;
+ } else if ((v_table_entry >> 28u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ } else if ((v_table_entry >> 27u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ } else if ((v_table_entry >> 27u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_length = (((v_table_entry >> 8u) & 255u) + 3u);
+ v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
+ if (v_table_entry_n_bits > 0u) {
+ if (v_n_bits < 15u) {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ } else {
+ }
+ v_length = (((v_length + 253u + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ } else {
+ }
+ if (v_n_bits < 15u) {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ } else {
+ }
+ v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 28u) == 1u) {
+ if (v_n_bits < 15u) {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ } else {
+ }
+ v_redir_top = ((v_table_entry >> 8u) & 65535u);
+ v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
+ v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ } else {
+ }
+ if ((v_table_entry >> 24u) != 64u) {
+ if ((v_table_entry >> 24u) == 8u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
+ v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
+ if (v_n_bits < v_table_entry_n_bits) {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ }
+ v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ do {
+ if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
+ v_hlen = 0u;
+ v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
+ if (v_length > v_hdist) {
+ v_length -= v_hdist;
+ v_hlen = v_hdist;
+ } else {
+ v_hlen = v_length;
+ v_length = 0u;
+ }
+ v_hdist += v_hdist_adjustment;
+ if (self->private_impl.f_history_index < v_hdist) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
+ goto exit;
+ }
+ wuffs_base__io_writer__limited_copy_u32_from_slice(
+ &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025));
+ if (v_length == 0u) {
+ goto label__loop__continue;
+ }
+ if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
+ goto exit;
+ }
+ }
+ if ((v_dist_minus_1 + 1u) >= 8u) {
+ wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ } else {
+ wuffs_base__io_writer__limited_copy_u32_from_history_fast(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ }
+ } while (0);
+ }
+ while (v_n_bits >= 8u) {
+ v_n_bits -= 8u;
+ if (iop_a_src > io1_a_src) {
+ iop_a_src--;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ }
+ self->private_impl.f_bits = (v_bits & ((((uint32_t)(1u)) << v_n_bits) - 1u));
+ self->private_impl.f_n_bits = v_n_bits;
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func deflate.decoder.decode_huffman_fast64
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_fast64(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ return (*self->private_impl.choosy_decode_huffman_fast64)(self, a_dst, a_src);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_fast64__choosy_default(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint64_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint32_t v_table_entry = 0;
+ uint32_t v_table_entry_n_bits = 0;
+ uint64_t v_lmask = 0;
+ uint64_t v_dmask = 0;
+ uint32_t v_redir_top = 0;
+ uint32_t v_redir_mask = 0;
+ uint32_t v_length = 0;
+ uint32_t v_dist_minus_1 = 0;
+ uint32_t v_hlen = 0;
+ uint32_t v_hdist = 0;
+ uint32_t v_hdist_adjustment = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ v_bits = ((uint64_t)(self->private_impl.f_bits));
+ v_n_bits = self->private_impl.f_n_bits;
+ v_lmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
+ v_dmask = ((((uint64_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
+ if (self->private_impl.f_transformed_history_count < (a_dst ? a_dst->meta.pos : 0u)) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
+ goto exit;
+ }
+ v_hdist_adjustment = ((uint32_t)((self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u))));
+ label__loop__continue:;
+ while ((((uint64_t)(io2_a_dst - iop_a_dst)) >= 266u) && (((uint64_t)(io2_a_src - iop_a_src)) >= 8u)) {
+ v_bits |= ((uint64_t)(wuffs_base__peek_u64le__no_bounds_check(iop_a_src) << (v_n_bits & 63u)));
+ iop_a_src += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 31u) != 0u) {
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
+ continue;
+ } else if ((v_table_entry >> 30u) != 0u) {
+ } else if ((v_table_entry >> 29u) != 0u) {
+ self->private_impl.f_end_of_block = true;
+ break;
+ } else if ((v_table_entry >> 28u) != 0u) {
+ v_redir_top = ((v_table_entry >> 8u) & 65535u);
+ v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
+ v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 31u) != 0u) {
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)((v_table_entry >> 8u)))), iop_a_dst += 1);
+ continue;
+ } else if ((v_table_entry >> 30u) != 0u) {
+ } else if ((v_table_entry >> 29u) != 0u) {
+ self->private_impl.f_end_of_block = true;
+ break;
+ } else if ((v_table_entry >> 28u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ } else if ((v_table_entry >> 27u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ } else if ((v_table_entry >> 27u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_length = (((v_table_entry >> 8u) & 255u) + 3u);
+ v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
+ if (v_table_entry_n_bits > 0u) {
+ v_length = (((v_length + 253u + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 255u) + 3u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ }
+ v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ if ((v_table_entry >> 28u) == 1u) {
+ v_redir_top = ((v_table_entry >> 8u) & 65535u);
+ v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
+ v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (((uint32_t)(v_bits)) & v_redir_mask)) & 1023u)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ }
+ if ((v_table_entry >> 24u) != 64u) {
+ if ((v_table_entry >> 24u) == 8u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
+ v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
+ v_dist_minus_1 = ((v_dist_minus_1 + ((uint32_t)(((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U64(v_table_entry_n_bits))))) & 32767u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ do {
+ if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
+ v_hlen = 0u;
+ v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
+ if (v_length > v_hdist) {
+ v_length -= v_hdist;
+ v_hlen = v_hdist;
+ } else {
+ v_hlen = v_length;
+ v_length = 0u;
+ }
+ v_hdist += v_hdist_adjustment;
+ if (self->private_impl.f_history_index < v_hdist) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
+ goto exit;
+ }
+ wuffs_base__io_writer__limited_copy_u32_from_slice(
+ &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025));
+ if (v_length == 0u) {
+ goto label__loop__continue;
+ }
+ if ((((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) || (((uint64_t)(v_length)) > ((uint64_t)(io2_a_dst - iop_a_dst))) || (((uint64_t)((v_length + 8u))) > ((uint64_t)(io2_a_dst - iop_a_dst)))) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_distance);
+ goto exit;
+ }
+ }
+ if ((v_dist_minus_1 + 1u) >= 8u) {
+ wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_fast(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ } else if ((v_dist_minus_1 + 1u) == 1u) {
+ wuffs_base__io_writer__limited_copy_u32_from_history_8_byte_chunks_distance_1_fast(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ } else {
+ wuffs_base__io_writer__limited_copy_u32_from_history_fast(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ }
+ } while (0);
+ }
+ if (v_n_bits > 63u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ while (v_n_bits >= 8u) {
+ v_n_bits -= 8u;
+ if (iop_a_src > io1_a_src) {
+ iop_a_src--;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ }
+ self->private_impl.f_bits = ((uint32_t)((v_bits & ((((uint64_t)(1u)) << v_n_bits) - 1u))));
+ self->private_impl.f_n_bits = v_n_bits;
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> self->private_impl.f_n_bits) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func deflate.decoder.decode_huffman_slow
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_deflate__decoder__decode_huffman_slow(
+ wuffs_deflate__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint32_t v_table_entry = 0;
+ uint32_t v_table_entry_n_bits = 0;
+ uint32_t v_lmask = 0;
+ uint32_t v_dmask = 0;
+ uint32_t v_b0 = 0;
+ uint32_t v_redir_top = 0;
+ uint32_t v_redir_mask = 0;
+ uint32_t v_b1 = 0;
+ uint32_t v_length = 0;
+ uint32_t v_b2 = 0;
+ uint32_t v_b3 = 0;
+ uint32_t v_b4 = 0;
+ uint32_t v_dist_minus_1 = 0;
+ uint32_t v_b5 = 0;
+ uint32_t v_n_copied = 0;
+ uint32_t v_hlen = 0;
+ uint32_t v_hdist = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_huffman_slow[0];
+ if (coro_susp_point) {
+ v_bits = self->private_data.s_decode_huffman_slow[0].v_bits;
+ v_n_bits = self->private_data.s_decode_huffman_slow[0].v_n_bits;
+ v_table_entry_n_bits = self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits;
+ v_lmask = self->private_data.s_decode_huffman_slow[0].v_lmask;
+ v_dmask = self->private_data.s_decode_huffman_slow[0].v_dmask;
+ v_redir_top = self->private_data.s_decode_huffman_slow[0].v_redir_top;
+ v_redir_mask = self->private_data.s_decode_huffman_slow[0].v_redir_mask;
+ v_length = self->private_data.s_decode_huffman_slow[0].v_length;
+ v_dist_minus_1 = self->private_data.s_decode_huffman_slow[0].v_dist_minus_1;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+ v_bits = self->private_impl.f_bits;
+ v_n_bits = self->private_impl.f_n_bits;
+ v_lmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[0u]) - 1u);
+ v_dmask = ((((uint32_t)(1u)) << self->private_impl.f_n_huffs_bits[1u]) - 1u);
+ label__loop__continue:;
+ while ( ! (self->private_impl.p_decode_huffman_slow[0] != 0)) {
+ while (true) {
+ v_table_entry = self->private_data.f_huffs[0u][(v_bits & v_lmask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ if (v_n_bits >= v_table_entry_n_bits) {
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_0 = *iop_a_src++;
+ v_b0 = t_0;
+ }
+ v_bits |= (v_b0 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ if ((v_table_entry >> 31u) != 0u) {
+ self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)((v_table_entry >> 8u)));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (iop_a_dst == io2_a_dst) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ goto suspend;
+ }
+ *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
+ continue;
+ } else if ((v_table_entry >> 30u) != 0u) {
+ } else if ((v_table_entry >> 29u) != 0u) {
+ self->private_impl.f_end_of_block = true;
+ break;
+ } else if ((v_table_entry >> 28u) != 0u) {
+ v_redir_top = ((v_table_entry >> 8u) & 65535u);
+ v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
+ while (true) {
+ v_table_entry = self->private_data.f_huffs[0u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ if (v_n_bits >= v_table_entry_n_bits) {
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_1 = *iop_a_src++;
+ v_b1 = t_1;
+ }
+ v_bits |= (v_b1 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ if ((v_table_entry >> 31u) != 0u) {
+ self->private_data.s_decode_huffman_slow[0].scratch = ((uint8_t)((v_table_entry >> 8u)));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (iop_a_dst == io2_a_dst) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ goto suspend;
+ }
+ *iop_a_dst++ = ((uint8_t)(self->private_data.s_decode_huffman_slow[0].scratch));
+ continue;
+ } else if ((v_table_entry >> 30u) != 0u) {
+ } else if ((v_table_entry >> 29u) != 0u) {
+ self->private_impl.f_end_of_block = true;
+ break;
+ } else if ((v_table_entry >> 28u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ } else if ((v_table_entry >> 27u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ } else if ((v_table_entry >> 27u) != 0u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_length = (((v_table_entry >> 8u) & 255u) + 3u);
+ v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
+ if (v_table_entry_n_bits > 0u) {
+ while (v_n_bits < v_table_entry_n_bits) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_2 = *iop_a_src++;
+ v_b2 = t_2;
+ }
+ v_bits |= (v_b2 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ v_length = (((v_length + 253u + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 255u) + 3u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ }
+ while (true) {
+ v_table_entry = self->private_data.f_huffs[1u][(v_bits & v_dmask)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ if (v_n_bits >= v_table_entry_n_bits) {
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_3 = *iop_a_src++;
+ v_b3 = t_3;
+ }
+ v_bits |= (v_b3 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ if ((v_table_entry >> 28u) == 1u) {
+ v_redir_top = ((v_table_entry >> 8u) & 65535u);
+ v_redir_mask = ((((uint32_t)(1u)) << ((v_table_entry >> 4u) & 15u)) - 1u);
+ while (true) {
+ v_table_entry = self->private_data.f_huffs[1u][((v_redir_top + (v_bits & v_redir_mask)) & 1023u)];
+ v_table_entry_n_bits = (v_table_entry & 15u);
+ if (v_n_bits >= v_table_entry_n_bits) {
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_4 = *iop_a_src++;
+ v_b4 = t_4;
+ }
+ v_bits |= (v_b4 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ }
+ if ((v_table_entry >> 24u) != 64u) {
+ if ((v_table_entry >> 24u) == 8u) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_huffman_code);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_huffman_decoder_state);
+ goto exit;
+ }
+ v_dist_minus_1 = ((v_table_entry >> 8u) & 32767u);
+ v_table_entry_n_bits = ((v_table_entry >> 4u) & 15u);
+ if (v_table_entry_n_bits > 0u) {
+ while (v_n_bits < v_table_entry_n_bits) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_5 = *iop_a_src++;
+ v_b5 = t_5;
+ }
+ v_bits |= (v_b5 << v_n_bits);
+ v_n_bits += 8u;
+ }
+ v_dist_minus_1 = ((v_dist_minus_1 + ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_table_entry_n_bits))) & 32767u);
+ v_bits >>= v_table_entry_n_bits;
+ v_n_bits -= v_table_entry_n_bits;
+ }
+ while (true) {
+ if (((uint64_t)((v_dist_minus_1 + 1u))) > ((uint64_t)(iop_a_dst - io0_a_dst))) {
+ v_hdist = ((uint32_t)((((uint64_t)((v_dist_minus_1 + 1u))) - ((uint64_t)(iop_a_dst - io0_a_dst)))));
+ if (v_hdist < v_length) {
+ v_hlen = v_hdist;
+ } else {
+ v_hlen = v_length;
+ }
+ v_hdist += ((uint32_t)(((uint64_t)(self->private_impl.f_transformed_history_count - (a_dst ? a_dst->meta.pos : 0u)))));
+ if (self->private_impl.f_history_index < v_hdist) {
+ status = wuffs_base__make_status(wuffs_deflate__error__bad_distance);
+ goto exit;
+ }
+ v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_slice(
+ &iop_a_dst, io2_a_dst,v_hlen, wuffs_base__make_slice_u8_ij(self->private_data.f_history, ((self->private_impl.f_history_index - v_hdist) & 32767u), 33025));
+ if (v_n_copied < v_hlen) {
+ v_length -= v_n_copied;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
+ continue;
+ }
+ v_length -= v_hlen;
+ if (v_length == 0u) {
+ goto label__loop__continue;
+ }
+ }
+ v_n_copied = wuffs_base__io_writer__limited_copy_u32_from_history(
+ &iop_a_dst, io0_a_dst, io2_a_dst, v_length, (v_dist_minus_1 + 1u));
+ if (v_length <= v_n_copied) {
+ goto label__loop__continue;
+ }
+ v_length -= v_n_copied;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
+ }
+ }
+ self->private_impl.f_bits = v_bits;
+ self->private_impl.f_n_bits = v_n_bits;
+ if ((self->private_impl.f_n_bits >= 8u) || ((self->private_impl.f_bits >> (self->private_impl.f_n_bits & 7u)) != 0u)) {
+ status = wuffs_base__make_status(wuffs_deflate__error__internal_error_inconsistent_n_bits);
+ goto exit;
+ }
+
+ ok:
+ self->private_impl.p_decode_huffman_slow[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_huffman_slow[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_huffman_slow[0].v_bits = v_bits;
+ self->private_data.s_decode_huffman_slow[0].v_n_bits = v_n_bits;
+ self->private_data.s_decode_huffman_slow[0].v_table_entry_n_bits = v_table_entry_n_bits;
+ self->private_data.s_decode_huffman_slow[0].v_lmask = v_lmask;
+ self->private_data.s_decode_huffman_slow[0].v_dmask = v_dmask;
+ self->private_data.s_decode_huffman_slow[0].v_redir_top = v_redir_top;
+ self->private_data.s_decode_huffman_slow[0].v_redir_mask = v_redir_mask;
+ self->private_data.s_decode_huffman_slow[0].v_length = v_length;
+ self->private_data.s_decode_huffman_slow[0].v_dist_minus_1 = v_dist_minus_1;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__DEFLATE)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_gif__error__bad_lzw_code[] = "#gif: bad LZW code";
+const char wuffs_gif__error__bad_extension_label[] = "#gif: bad extension label";
+const char wuffs_gif__error__bad_frame_size[] = "#gif: bad frame size";
+const char wuffs_gif__error__bad_graphic_control[] = "#gif: bad graphic control";
+const char wuffs_gif__error__bad_header[] = "#gif: bad header";
+const char wuffs_gif__error__bad_literal_width[] = "#gif: bad literal width";
+const char wuffs_gif__error__bad_palette[] = "#gif: bad palette";
+const char wuffs_gif__error__truncated_input[] = "#gif: truncated input";
+const char wuffs_gif__error__internal_error_inconsistent_i_o[] = "#gif: internal error: inconsistent I/O";
+
+// ---------------- Private Consts
+
+static const uint32_t
+WUFFS_GIF__INTERLACE_START[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 4294967295, 1, 2, 4, 0,
+};
+
+static const uint8_t
+WUFFS_GIF__INTERLACE_DELTA[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 1, 2, 4, 8, 8,
+};
+
+static const uint8_t
+WUFFS_GIF__INTERLACE_COUNT[5] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 1, 2, 4, 8,
+};
+
+static const uint8_t
+WUFFS_GIF__ANIMEXTS1DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 65, 78, 73, 77, 69, 88, 84, 83,
+ 49, 46, 48,
+};
+
+static const uint8_t
+WUFFS_GIF__NETSCAPE2DOT0[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 78, 69, 84, 83, 67, 65, 80, 69,
+ 50, 46, 48,
+};
+
+static const uint8_t
+WUFFS_GIF__ICCRGBG1012[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 73, 67, 67, 82, 71, 66, 71, 49,
+ 48, 49, 50,
+};
+
+static const uint8_t
+WUFFS_GIF__XMPDATAXMP[11] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 88, 77, 80, 32, 68, 97, 116, 97,
+ 88, 77, 80,
+};
+
+#define WUFFS_GIF__QUIRKS_BASE 1041635328
+
+#define WUFFS_GIF__QUIRKS_COUNT 7
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__do_decode_image_config(
+ wuffs_gif__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__do_tell_me_more(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__do_decode_frame_config(
+ wuffs_gif__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__skip_frame(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__do_decode_frame(
+ wuffs_gif__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_gif__decoder__reset_gc(
+ wuffs_gif__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_up_to_id_part1(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_header(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_lsd(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_extension(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__skip_blocks(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_ae(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_gc(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_id_part0(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_id_part1(
+ wuffs_gif__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_id_part2(
+ wuffs_gif__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__copy_to_image_buffer(
+ wuffs_gif__decoder* self,
+ wuffs_base__pixel_buffer* a_pb,
+ wuffs_base__slice_u8 a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_gif__decoder__lzw_init(
+ wuffs_gif__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_gif__decoder__lzw_read_from(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+// ---------------- VTables
+
+const wuffs_base__image_decoder__func_ptrs
+wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__pixel_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
+ wuffs_base__slice_u8,
+ wuffs_base__decode_frame_options*))(&wuffs_gif__decoder__decode_frame),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__frame_config*,
+ wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_frame_config),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__image_config*,
+ wuffs_base__io_buffer*))(&wuffs_gif__decoder__decode_image_config),
+ (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_gif__decoder__frame_dirty_rect),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_gif__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_gif__decoder__history_retain_length),
+ (uint32_t(*)(const void*))(&wuffs_gif__decoder__num_animation_loops),
+ (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frame_configs),
+ (uint64_t(*)(const void*))(&wuffs_gif__decoder__num_decoded_frames),
+ (wuffs_base__status(*)(void*,
+ uint64_t,
+ uint64_t))(&wuffs_gif__decoder__restart_frame),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_gif__decoder__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ uint32_t,
+ bool))(&wuffs_gif__decoder__set_report_metadata),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*))(&wuffs_gif__decoder__tell_me_more),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gif__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+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 options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
+ wuffs_base__image_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
+ (const void*)(&wuffs_gif__decoder__func_ptrs_for__wuffs_base__image_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_gif__decoder*
+wuffs_gif__decoder__alloc(void) {
+ wuffs_gif__decoder* x =
+ (wuffs_gif__decoder*)(calloc(sizeof(wuffs_gif__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_gif__decoder__initialize(
+ x, sizeof(wuffs_gif__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_gif__decoder(void) {
+ return sizeof(wuffs_gif__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func gif.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gif__decoder__get_quirk(
+ const wuffs_gif__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ uint32_t v_key = 0;
+
+ if (a_key >= 1041635328u) {
+ v_key = (a_key - 1041635328u);
+ if (v_key < 7u) {
+ if (self->private_impl.f_quirks[v_key]) {
+ return 1u;
+ }
+ }
+ }
+ return 0u;
+}
+
+// -------- func gif.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_gif__decoder__set_quirk(
+ wuffs_gif__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if ((self->private_impl.f_call_sequence == 0u) && (a_key >= 1041635328u)) {
+ a_key -= 1041635328u;
+ if (a_key < 7u) {
+ self->private_impl.f_quirks[a_key] = (a_value > 0u);
+ return wuffs_base__make_status(NULL);
+ }
+ }
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func gif.decoder.decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+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) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_image_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func gif.decoder.do_decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__do_decode_image_config(
+ wuffs_gif__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ bool v_ffio = false;
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ } else if ( ! self->private_impl.f_seen_header) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_gif__decoder__decode_header(self, a_src);
+ if (status.repr) {
+ goto suspend;
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ status = wuffs_gif__decoder__decode_lsd(self, a_src);
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_header = true;
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
+ if (status.repr) {
+ goto suspend;
+ }
+ v_ffio = ! self->private_impl.f_gc_has_transparent_index;
+ if ( ! self->private_impl.f_quirks[2u]) {
+ v_ffio = (v_ffio &&
+ (self->private_impl.f_frame_rect_x0 == 0u) &&
+ (self->private_impl.f_frame_rect_y0 == 0u) &&
+ (self->private_impl.f_frame_rect_x1 == self->private_impl.f_width) &&
+ (self->private_impl.f_frame_rect_y1 == self->private_impl.f_height));
+ } else if (v_ffio) {
+ self->private_impl.f_black_color_u32_argb_premul = 4278190080u;
+ }
+ if (self->private_impl.f_background_color_u32_argb_premul == 77u) {
+ self->private_impl.f_background_color_u32_argb_premul = self->private_impl.f_black_color_u32_argb_premul;
+ }
+ if (a_dst != NULL) {
+ wuffs_base__image_config__set(
+ a_dst,
+ 2198077448u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ self->private_impl.f_frame_config_io_position,
+ v_ffio);
+ }
+ if (self->private_impl.f_call_sequence == 0u) {
+ self->private_impl.f_call_sequence = 32u;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_do_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ return status;
+}
+
+// -------- func gif.decoder.set_report_metadata
+
+WUFFS_BASE__GENERATED_C_CODE
+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) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ if (a_fourcc == 1229144912u) {
+ self->private_impl.f_report_metadata_iccp = a_report;
+ } else if (a_fourcc == 1481461792u) {
+ self->private_impl.f_report_metadata_xmp = a_report;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func gif.decoder.tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_gif__decoder__tell_me_more(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 2)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_gif__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_tell_me_more[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func gif.decoder.do_tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__do_tell_me_more(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint64_t v_chunk_length = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_call_sequence & 16u) == 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ }
+ if (self->private_impl.f_metadata_fourcc == 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__no_more_information);
+ goto exit;
+ }
+ while (true) {
+ while (true) {
+ if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_io_position) {
+ if (a_minfo != NULL) {
+ wuffs_base__more_information__set(a_minfo,
+ 2u,
+ 0u,
+ self->private_impl.f_metadata_io_position,
+ 0u,
+ 0u);
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__mispositioned_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ continue;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_minfo != NULL) {
+ wuffs_base__more_information__set(a_minfo,
+ 0u,
+ 0u,
+ 0u,
+ 0u,
+ 0u);
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ continue;
+ }
+ break;
+ }
+ v_chunk_length = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
+ if (v_chunk_length <= 0u) {
+ iop_a_src += 1u;
+ break;
+ }
+ if (self->private_impl.f_metadata_fourcc == 1481461792u) {
+ v_chunk_length += 1u;
+ } else {
+ iop_a_src += 1u;
+ }
+ self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add(wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))), v_chunk_length);
+ if (a_minfo != NULL) {
+ wuffs_base__more_information__set(a_minfo,
+ 3u,
+ self->private_impl.f_metadata_fourcc,
+ 0u,
+ wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))),
+ self->private_impl.f_metadata_io_position);
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ }
+ if (a_minfo != NULL) {
+ wuffs_base__more_information__set(a_minfo,
+ 3u,
+ self->private_impl.f_metadata_fourcc,
+ 0u,
+ self->private_impl.f_metadata_io_position,
+ self->private_impl.f_metadata_io_position);
+ }
+ self->private_impl.f_call_sequence &= 239u;
+ self->private_impl.f_metadata_fourcc = 0u;
+ self->private_impl.f_metadata_io_position = 0u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ self->private_impl.p_do_tell_me_more[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.num_animation_loops
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_gif__decoder__num_animation_loops(
+ const wuffs_gif__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_seen_num_animation_loops_value) {
+ return self->private_impl.f_num_animation_loops_value;
+ }
+ if (self->private_impl.f_num_decoded_frame_configs_value > 1u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func gif.decoder.num_decoded_frame_configs
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gif__decoder__num_decoded_frame_configs(
+ const wuffs_gif__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return self->private_impl.f_num_decoded_frame_configs_value;
+}
+
+// -------- func gif.decoder.num_decoded_frames
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gif__decoder__num_decoded_frames(
+ const wuffs_gif__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return self->private_impl.f_num_decoded_frames_value;
+}
+
+// -------- func gif.decoder.frame_dirty_rect
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_gif__decoder__frame_dirty_rect(
+ const wuffs_gif__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ return wuffs_base__utility__make_rect_ie_u32(
+ wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
+ wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
+ wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
+ wuffs_base__u32__min(self->private_impl.f_dirty_max_excl_y, self->private_impl.f_height));
+}
+
+// -------- func gif.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gif__decoder__history_retain_length(
+ const wuffs_gif__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func gif.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_gif__decoder__workbuf_len(
+ const wuffs_gif__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(0u, 0u);
+}
+
+// -------- func gif.decoder.restart_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+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) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (self->private_impl.f_call_sequence < 32u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ } else if (a_io_position == 0u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_delayed_num_decoded_frames = false;
+ self->private_impl.f_frame_config_io_position = a_io_position;
+ self->private_impl.f_num_decoded_frame_configs_value = a_index;
+ self->private_impl.f_num_decoded_frames_value = a_index;
+ wuffs_gif__decoder__reset_gc(self);
+ self->private_impl.f_call_sequence = 40u;
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func gif.decoder.decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+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) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 3)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func gif.decoder.do_decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__do_decode_frame_config(
+ wuffs_gif__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_background_color = 0;
+ uint8_t v_flags = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
+ if (coro_susp_point) {
+ v_background_color = self->private_data.s_do_decode_frame_config[0].v_background_color;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.f_dirty_max_excl_y = 0u;
+ if ((self->private_impl.f_call_sequence & 16u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ } else if (self->private_impl.f_call_sequence == 32u) {
+ } else if (self->private_impl.f_call_sequence < 32u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_gif__decoder__do_decode_image_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (self->private_impl.f_call_sequence == 40u) {
+ if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_restart);
+ goto exit;
+ }
+ } else if (self->private_impl.f_call_sequence == 64u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ status = wuffs_gif__decoder__skip_frame(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ if (self->private_impl.f_call_sequence >= 96u) {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if ((self->private_impl.f_num_decoded_frame_configs_value > 0u) || (self->private_impl.f_call_sequence == 40u)) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_gif__decoder__decode_up_to_id_part1(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ if (self->private_impl.f_call_sequence >= 96u) {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ }
+ v_background_color = self->private_impl.f_black_color_u32_argb_premul;
+ if ( ! self->private_impl.f_gc_has_transparent_index) {
+ v_background_color = self->private_impl.f_background_color_u32_argb_premul;
+ if (self->private_impl.f_quirks[1u] && (self->private_impl.f_num_decoded_frame_configs_value == 0u)) {
+ while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
+ }
+ v_flags = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if ((v_flags & 128u) != 0u) {
+ v_background_color = self->private_impl.f_black_color_u32_argb_premul;
+ }
+ }
+ }
+ if (a_dst != NULL) {
+ wuffs_base__frame_config__set(
+ a_dst,
+ wuffs_base__utility__make_rect_ie_u32(
+ wuffs_base__u32__min(self->private_impl.f_frame_rect_x0, self->private_impl.f_width),
+ wuffs_base__u32__min(self->private_impl.f_frame_rect_y0, self->private_impl.f_height),
+ wuffs_base__u32__min(self->private_impl.f_frame_rect_x1, self->private_impl.f_width),
+ wuffs_base__u32__min(self->private_impl.f_frame_rect_y1, self->private_impl.f_height)),
+ ((wuffs_base__flicks)(self->private_impl.f_gc_duration)),
+ self->private_impl.f_num_decoded_frame_configs_value,
+ self->private_impl.f_frame_config_io_position,
+ self->private_impl.f_gc_disposal,
+ ! self->private_impl.f_gc_has_transparent_index,
+ false,
+ v_background_color);
+ }
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u);
+ self->private_impl.f_call_sequence = 64u;
+
+ ok:
+ self->private_impl.p_do_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_decode_frame_config[0].v_background_color = v_background_color;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.skip_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__skip_frame(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_flags = 0;
+ uint8_t v_lw = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_flags = t_0;
+ }
+ if ((v_flags & 128u) != 0u) {
+ self->private_data.s_skip_frame[0].scratch = (((uint32_t)(3u)) << (1u + (v_flags & 7u)));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_skip_frame[0].scratch;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_lw = t_1;
+ }
+ if (v_lw > 8u) {
+ status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ status = wuffs_gif__decoder__skip_blocks(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ if (self->private_impl.f_quirks[0u]) {
+ self->private_impl.f_delayed_num_decoded_frames = true;
+ } else {
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
+ }
+ wuffs_gif__decoder__reset_gc(self);
+ self->private_impl.f_call_sequence = 32u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_skip_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+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__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 4)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_gif__decoder__do_decode_frame(self,
+ a_dst,
+ a_src,
+ a_blend,
+ a_workbuf,
+ a_opts);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func gif.decoder.do_decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__do_decode_frame(
+ wuffs_gif__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 64u) {
+ } else if (self->private_impl.f_call_sequence < 64u) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_gif__decoder__do_decode_frame_config(self, NULL, a_src);
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (self->private_impl.f_quirks[5u] && ((self->private_impl.f_frame_rect_x0 == self->private_impl.f_frame_rect_x1) || (self->private_impl.f_frame_rect_y0 == self->private_impl.f_frame_rect_y1))) {
+ status = wuffs_base__make_status(wuffs_gif__error__bad_frame_size);
+ goto exit;
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ status = wuffs_gif__decoder__decode_id_part1(self, a_dst, a_src, a_blend);
+ if (status.repr) {
+ goto suspend;
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_gif__decoder__decode_id_part2(self, a_dst, a_src, a_workbuf);
+ if (status.repr) {
+ goto suspend;
+ }
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
+ wuffs_gif__decoder__reset_gc(self);
+ self->private_impl.f_call_sequence = 32u;
+
+ ok:
+ self->private_impl.p_do_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ return status;
+}
+
+// -------- func gif.decoder.reset_gc
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_gif__decoder__reset_gc(
+ wuffs_gif__decoder* self) {
+ self->private_impl.f_gc_has_transparent_index = false;
+ self->private_impl.f_gc_transparent_index = 0u;
+ self->private_impl.f_gc_disposal = 0u;
+ self->private_impl.f_gc_duration = 0u;
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func gif.decoder.decode_up_to_id_part1
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_up_to_id_part1(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_block_type = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_up_to_id_part1[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_frame_config_io_position == 0u) || (self->private_impl.f_num_decoded_frame_configs_value > 0u)) {
+ self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_block_type = t_0;
+ }
+ if (v_block_type == 33u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ status = wuffs_gif__decoder__decode_extension(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (v_block_type == 44u) {
+ if (self->private_impl.f_delayed_num_decoded_frames) {
+ self->private_impl.f_delayed_num_decoded_frames = false;
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_gif__decoder__decode_id_part0(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ break;
+ } else {
+ if (self->private_impl.f_delayed_num_decoded_frames) {
+ self->private_impl.f_delayed_num_decoded_frames = false;
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
+ }
+ self->private_impl.f_call_sequence = 96u;
+ break;
+ }
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_up_to_id_part1[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_up_to_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_header
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_header(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c[6] = {0};
+ uint32_t v_i = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_header[0];
+ if (coro_susp_point) {
+ memcpy(v_c, self->private_data.s_decode_header[0].v_c, sizeof(v_c));
+ v_i = self->private_data.s_decode_header[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (v_i < 6u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c[v_i] = t_0;
+ }
+ v_i += 1u;
+ }
+ if ((v_c[0u] != 71u) ||
+ (v_c[1u] != 73u) ||
+ (v_c[2u] != 70u) ||
+ (v_c[3u] != 56u) ||
+ ((v_c[4u] != 55u) && (v_c[4u] != 57u)) ||
+ (v_c[5u] != 97u)) {
+ status = wuffs_base__make_status(wuffs_gif__error__bad_header);
+ goto exit;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_header[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_header[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ memcpy(self->private_data.s_decode_header[0].v_c, v_c, sizeof(v_c));
+ self->private_data.s_decode_header[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_lsd
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_lsd(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_flags = 0;
+ uint8_t v_background_color_index = 0;
+ uint32_t v_num_palette_entries = 0;
+ uint32_t v_i = 0;
+ uint32_t v_j = 0;
+ uint32_t v_argb = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_lsd[0];
+ if (coro_susp_point) {
+ v_flags = self->private_data.s_decode_lsd[0].v_flags;
+ v_background_color_index = self->private_data.s_decode_lsd[0].v_background_color_index;
+ v_num_palette_entries = self->private_data.s_decode_lsd[0].v_num_palette_entries;
+ v_i = self->private_data.s_decode_lsd[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_lsd[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
+ if (num_bits_0 == 8) {
+ t_0 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0)) << 56;
+ }
+ }
+ self->private_impl.f_width = t_0;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_lsd[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
+ if (num_bits_1 == 8) {
+ t_1 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1)) << 56;
+ }
+ }
+ self->private_impl.f_height = t_1;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_flags = t_2;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_background_color_index = t_3;
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src++;
+ v_i = 0u;
+ self->private_impl.f_has_global_palette = ((v_flags & 128u) != 0u);
+ if (self->private_impl.f_has_global_palette) {
+ v_num_palette_entries = (((uint32_t)(1u)) << (1u + (v_flags & 7u)));
+ while (v_i < v_num_palette_entries) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ uint32_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
+ t_4 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
+ iop_a_src += 3;
+ } else {
+ self->private_data.s_decode_lsd[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_lsd[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
+ if (num_bits_4 == 16) {
+ t_4 = ((uint32_t)(*scratch >> 40));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4));
+ }
+ }
+ v_argb = t_4;
+ }
+ v_argb |= 4278190080u;
+ self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
+ self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
+ self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
+ self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
+ v_i += 1u;
+ }
+ if (self->private_impl.f_quirks[2u]) {
+ if ((v_background_color_index != 0u) && (((uint32_t)(v_background_color_index)) < v_num_palette_entries)) {
+ v_j = (4u * ((uint32_t)(v_background_color_index)));
+ self->private_impl.f_background_color_u32_argb_premul = ((((uint32_t)(self->private_data.f_palettes[0u][(v_j + 0u)])) << 0u) |
+ (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 1u)])) << 8u) |
+ (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 2u)])) << 16u) |
+ (((uint32_t)(self->private_data.f_palettes[0u][(v_j + 3u)])) << 24u));
+ } else {
+ self->private_impl.f_background_color_u32_argb_premul = 77u;
+ }
+ }
+ }
+ while (v_i < 256u) {
+ self->private_data.f_palettes[0u][((4u * v_i) + 0u)] = 0u;
+ self->private_data.f_palettes[0u][((4u * v_i) + 1u)] = 0u;
+ self->private_data.f_palettes[0u][((4u * v_i) + 2u)] = 0u;
+ self->private_data.f_palettes[0u][((4u * v_i) + 3u)] = 255u;
+ v_i += 1u;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_lsd[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_lsd[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_lsd[0].v_flags = v_flags;
+ self->private_data.s_decode_lsd[0].v_background_color_index = v_background_color_index;
+ self->private_data.s_decode_lsd[0].v_num_palette_entries = v_num_palette_entries;
+ self->private_data.s_decode_lsd[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_extension
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_extension(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_label = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_extension[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_label = t_0;
+ }
+ if (v_label == 249u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ status = wuffs_gif__decoder__decode_gc(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ } else if (v_label == 255u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_gif__decoder__decode_ae(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ status = wuffs_gif__decoder__skip_blocks(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+
+ ok:
+ self->private_impl.p_decode_extension[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_extension[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.skip_blocks
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__skip_blocks(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_block_size = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_skip_blocks[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_block_size = t_0;
+ }
+ if (v_block_size == 0u) {
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ self->private_data.s_skip_blocks[0].scratch = ((uint32_t)(v_block_size));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (self->private_data.s_skip_blocks[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_skip_blocks[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_skip_blocks[0].scratch;
+ }
+
+ ok:
+ self->private_impl.p_skip_blocks[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_skip_blocks[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_ae
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_ae(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint8_t v_block_size = 0;
+ bool v_is_animexts = false;
+ bool v_is_netscape = false;
+ bool v_is_iccp = false;
+ bool v_is_xmp = false;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_ae[0];
+ if (coro_susp_point) {
+ v_block_size = self->private_data.s_decode_ae[0].v_block_size;
+ v_is_animexts = self->private_data.s_decode_ae[0].v_is_animexts;
+ v_is_netscape = self->private_data.s_decode_ae[0].v_is_netscape;
+ v_is_iccp = self->private_data.s_decode_ae[0].v_is_iccp;
+ v_is_xmp = self->private_data.s_decode_ae[0].v_is_xmp;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ do {
+ if (self->private_impl.f_metadata_fourcc != 0u) {
+ status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
+ goto ok;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_block_size = t_0;
+ }
+ if (v_block_size == 0u) {
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ if (v_block_size != 11u) {
+ self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_decode_ae[0].scratch;
+ break;
+ }
+ v_is_animexts = true;
+ v_is_netscape = true;
+ v_is_iccp = true;
+ v_is_xmp = true;
+ v_block_size = 0u;
+ while (v_block_size < 11u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ v_is_animexts = (v_is_animexts && (v_c == WUFFS_GIF__ANIMEXTS1DOT0[v_block_size]));
+ v_is_netscape = (v_is_netscape && (v_c == WUFFS_GIF__NETSCAPE2DOT0[v_block_size]));
+ v_is_iccp = (v_is_iccp && (v_c == WUFFS_GIF__ICCRGBG1012[v_block_size]));
+ v_is_xmp = (v_is_xmp && (v_c == WUFFS_GIF__XMPDATAXMP[v_block_size]));
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_block_size += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ }
+ if (v_is_animexts || v_is_netscape) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_block_size = t_2;
+ }
+ if (v_block_size != 3u) {
+ self->private_data.s_decode_ae[0].scratch = ((uint32_t)(v_block_size));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_decode_ae[0].scratch;
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_c = t_3;
+ }
+ if (v_c != 1u) {
+ self->private_data.s_decode_ae[0].scratch = 2u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ if (self->private_data.s_decode_ae[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_decode_ae[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_decode_ae[0].scratch;
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ uint32_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_4 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_ae[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_ae[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
+ if (num_bits_4 == 8) {
+ t_4 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4)) << 56;
+ }
+ }
+ self->private_impl.f_num_animation_loops_value = t_4;
+ }
+ self->private_impl.f_seen_num_animation_loops_value = true;
+ if ((0u < self->private_impl.f_num_animation_loops_value) && (self->private_impl.f_num_animation_loops_value <= 65535u)) {
+ self->private_impl.f_num_animation_loops_value += 1u;
+ }
+ } else if (self->private_impl.f_call_sequence >= 32u) {
+ } else if (v_is_iccp && self->private_impl.f_report_metadata_iccp) {
+ self->private_impl.f_metadata_fourcc = 1229144912u;
+ self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ self->private_impl.f_call_sequence = 16u;
+ status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
+ goto ok;
+ } else if (v_is_xmp && self->private_impl.f_report_metadata_xmp) {
+ self->private_impl.f_metadata_fourcc = 1481461792u;
+ self->private_impl.f_metadata_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ self->private_impl.f_call_sequence = 16u;
+ status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
+ goto ok;
+ }
+ } while (0);
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ status = wuffs_gif__decoder__skip_blocks(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+
+ ok:
+ self->private_impl.p_decode_ae[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_ae[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_ae[0].v_block_size = v_block_size;
+ self->private_data.s_decode_ae[0].v_is_animexts = v_is_animexts;
+ self->private_data.s_decode_ae[0].v_is_netscape = v_is_netscape;
+ self->private_data.s_decode_ae[0].v_is_iccp = v_is_iccp;
+ self->private_data.s_decode_ae[0].v_is_xmp = v_is_xmp;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_gc
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_gc(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint8_t v_flags = 0;
+ uint16_t v_gc_duration_centiseconds = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_gc[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c != 4u) {
+ status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_flags = t_1;
+ }
+ self->private_impl.f_gc_has_transparent_index = ((v_flags & 1u) != 0u);
+ v_flags = ((v_flags >> 2u) & 7u);
+ if (v_flags == 2u) {
+ self->private_impl.f_gc_disposal = 1u;
+ } else if ((v_flags == 3u) || (v_flags == 4u)) {
+ self->private_impl.f_gc_disposal = 2u;
+ } else {
+ self->private_impl.f_gc_disposal = 0u;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint16_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_gc[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_gc[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
+ if (num_bits_2 == 8) {
+ t_2 = ((uint16_t)(*scratch));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2)) << 56;
+ }
+ }
+ v_gc_duration_centiseconds = t_2;
+ }
+ self->private_impl.f_gc_duration = (((uint64_t)(v_gc_duration_centiseconds)) * 7056000u);
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ self->private_impl.f_gc_transparent_index = t_3;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_4 = *iop_a_src++;
+ v_c = t_4;
+ }
+ if (v_c != 0u) {
+ status = wuffs_base__make_status(wuffs_gif__error__bad_graphic_control);
+ goto exit;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_gc[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_gc[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_id_part0
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_id_part0(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_id_part0[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_0 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_id_part0[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
+ if (num_bits_0 == 8) {
+ t_0 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0)) << 56;
+ }
+ }
+ self->private_impl.f_frame_rect_x0 = t_0;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_1 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_id_part0[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
+ if (num_bits_1 == 8) {
+ t_1 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1)) << 56;
+ }
+ }
+ self->private_impl.f_frame_rect_y0 = t_1;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_2 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_id_part0[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
+ if (num_bits_2 == 8) {
+ t_2 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2)) << 56;
+ }
+ }
+ self->private_impl.f_frame_rect_x1 = t_2;
+ }
+ self->private_impl.f_frame_rect_x1 += self->private_impl.f_frame_rect_x0;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ uint32_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_3 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_id_part0[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_id_part0[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
+ if (num_bits_3 == 8) {
+ t_3 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3)) << 56;
+ }
+ }
+ self->private_impl.f_frame_rect_y1 = t_3;
+ }
+ self->private_impl.f_frame_rect_y1 += self->private_impl.f_frame_rect_y0;
+ self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
+ self->private_impl.f_dst_y = self->private_impl.f_frame_rect_y0;
+ if ((self->private_impl.f_num_decoded_frame_configs_value == 0u) && ! self->private_impl.f_quirks[4u]) {
+ self->private_impl.f_width = wuffs_base__u32__max(self->private_impl.f_width, self->private_impl.f_frame_rect_x1);
+ self->private_impl.f_height = wuffs_base__u32__max(self->private_impl.f_height, self->private_impl.f_frame_rect_y1);
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_id_part0[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_id_part0[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_id_part1
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_id_part1(
+ wuffs_gif__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_flags = 0;
+ uint8_t v_which_palette = 0;
+ uint32_t v_num_palette_entries = 0;
+ uint32_t v_i = 0;
+ uint32_t v_argb = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ uint8_t v_lw = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_id_part1[0];
+ if (coro_susp_point) {
+ v_which_palette = self->private_data.s_decode_id_part1[0].v_which_palette;
+ v_num_palette_entries = self->private_data.s_decode_id_part1[0].v_num_palette_entries;
+ v_i = self->private_data.s_decode_id_part1[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_flags = t_0;
+ }
+ if ((v_flags & 64u) != 0u) {
+ self->private_impl.f_interlace = 4u;
+ } else {
+ self->private_impl.f_interlace = 0u;
+ }
+ v_which_palette = 1u;
+ if ((v_flags & 128u) != 0u) {
+ v_num_palette_entries = (((uint32_t)(1u)) << (1u + (v_flags & 7u)));
+ v_i = 0u;
+ while (v_i < v_num_palette_entries) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
+ t_1 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
+ iop_a_src += 3;
+ } else {
+ self->private_data.s_decode_id_part1[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_id_part1[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 16) {
+ t_1 = ((uint32_t)(*scratch >> 40));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ v_argb = t_1;
+ }
+ v_argb |= 4278190080u;
+ self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
+ self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
+ self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
+ self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
+ v_i += 1u;
+ }
+ while (v_i < 256u) {
+ self->private_data.f_palettes[1u][((4u * v_i) + 0u)] = 0u;
+ self->private_data.f_palettes[1u][((4u * v_i) + 1u)] = 0u;
+ self->private_data.f_palettes[1u][((4u * v_i) + 2u)] = 0u;
+ self->private_data.f_palettes[1u][((4u * v_i) + 3u)] = 255u;
+ v_i += 1u;
+ }
+ } else if (self->private_impl.f_quirks[6u] && ! self->private_impl.f_has_global_palette) {
+ status = wuffs_base__make_status(wuffs_gif__error__bad_palette);
+ goto exit;
+ } else if (self->private_impl.f_gc_has_transparent_index) {
+ wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_palettes[1u], 1024), wuffs_base__make_slice_u8(self->private_data.f_palettes[0u], 1024));
+ } else {
+ v_which_palette = 0u;
+ }
+ if (self->private_impl.f_gc_has_transparent_index) {
+ self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 0u)] = 0u;
+ self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 1u)] = 0u;
+ self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 2u)] = 0u;
+ self->private_data.f_palettes[1u][((4u * ((uint32_t)(self->private_impl.f_gc_transparent_index))) + 3u)] = 0u;
+ }
+ v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
+ wuffs_base__pixel_buffer__pixel_format(a_dst),
+ wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
+ wuffs_base__utility__make_pixel_format(2198077448u),
+ wuffs_base__make_slice_u8(self->private_data.f_palettes[v_which_palette], 1024),
+ a_blend);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ if (self->private_impl.f_ignored_but_affects_benchmarks) {
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_lw = t_2;
+ }
+ if (v_lw > 8u) {
+ status = wuffs_base__make_status(wuffs_gif__error__bad_literal_width);
+ goto exit;
+ }
+ self->private_impl.f_lzw_pending_literal_width_plus_one = ((uint32_t)((1u + v_lw)));
+ self->private_impl.f_ignored_but_affects_benchmarks = true;
+
+ ok:
+ self->private_impl.p_decode_id_part1[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_id_part1[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_id_part1[0].v_which_palette = v_which_palette;
+ self->private_data.s_decode_id_part1[0].v_num_palette_entries = v_num_palette_entries;
+ self->private_data.s_decode_id_part1[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.decode_id_part2
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__decode_id_part2(
+ wuffs_gif__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint64_t v_block_size = 0;
+ bool v_need_block_size = false;
+ uint32_t v_n_copied = 0;
+ uint64_t v_n_compressed = 0;
+ wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_r = &u_r;
+ const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint64_t v_mark = 0;
+ wuffs_base__status v_copy_status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_id_part2[0];
+ if (coro_susp_point) {
+ v_block_size = self->private_data.s_decode_id_part2[0].v_block_size;
+ v_need_block_size = self->private_data.s_decode_id_part2[0].v_need_block_size;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ wuffs_gif__decoder__lzw_init(self);
+ v_need_block_size = true;
+ label__outer__continue:;
+ while (true) {
+ if (v_need_block_size) {
+ v_need_block_size = false;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t t_0 = *iop_a_src++;
+ v_block_size = t_0;
+ }
+ }
+ if (v_block_size == 0u) {
+ break;
+ }
+ while (((uint64_t)(io2_a_src - iop_a_src)) == 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ }
+ if (self->private_impl.f_compressed_ri == self->private_impl.f_compressed_wi) {
+ self->private_impl.f_compressed_ri = 0u;
+ self->private_impl.f_compressed_wi = 0u;
+ }
+ while (self->private_impl.f_compressed_wi <= 3841u) {
+ v_n_compressed = wuffs_base__u64__min(v_block_size, ((uint64_t)(io2_a_src - iop_a_src)));
+ if (v_n_compressed <= 0u) {
+ break;
+ }
+ v_n_copied = wuffs_base__io_reader__limited_copy_u32_to_slice(
+ &iop_a_src, io2_a_src,((uint32_t)(v_n_compressed)), wuffs_base__make_slice_u8_ij(self->private_data.f_compressed, self->private_impl.f_compressed_wi, 4096));
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_wi, ((uint64_t)(v_n_copied)));
+ wuffs_base__u64__sat_sub_indirect(&v_block_size, ((uint64_t)(v_n_copied)));
+ if (v_block_size > 0u) {
+ break;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ v_need_block_size = true;
+ break;
+ }
+ v_block_size = ((uint64_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src)));
+ iop_a_src += 1u;
+ }
+ while (true) {
+ if ((self->private_impl.f_compressed_ri > self->private_impl.f_compressed_wi) || (self->private_impl.f_compressed_wi > 4096u)) {
+ status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ {
+ wuffs_base__io_buffer* o_0_v_r = v_r;
+ const uint8_t *o_0_iop_v_r = iop_v_r;
+ const uint8_t *o_0_io0_v_r = io0_v_r;
+ const uint8_t *o_0_io1_v_r = io1_v_r;
+ const uint8_t *o_0_io2_v_r = io2_v_r;
+ v_r = wuffs_base__io_reader__set(
+ &u_r,
+ &iop_v_r,
+ &io0_v_r,
+ &io1_v_r,
+ &io2_v_r,
+ wuffs_base__make_slice_u8_ij(self->private_data.f_compressed,
+ self->private_impl.f_compressed_ri,
+ self->private_impl.f_compressed_wi),
+ 0u);
+ v_mark = ((uint64_t)(iop_v_r - io0_v_r));
+ u_r.meta.ri = ((size_t)(iop_v_r - u_r.data.ptr));
+ wuffs_gif__decoder__lzw_read_from(self, v_r);
+ iop_v_r = u_r.data.ptr + u_r.meta.ri;
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_compressed_ri, wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_v_r - io0_v_r))));
+ v_r = o_0_v_r;
+ iop_v_r = o_0_iop_v_r;
+ io0_v_r = o_0_io0_v_r;
+ io1_v_r = o_0_io1_v_r;
+ io2_v_r = o_0_io2_v_r;
+ }
+ if (self->private_impl.f_lzw_output_ri < self->private_impl.f_lzw_output_wi) {
+ v_copy_status = wuffs_gif__decoder__copy_to_image_buffer(self, a_dst, wuffs_base__make_slice_u8_ij(self->private_data.f_lzw_output,
+ self->private_impl.f_lzw_output_ri,
+ self->private_impl.f_lzw_output_wi));
+ if (wuffs_base__status__is_error(&v_copy_status)) {
+ status = v_copy_status;
+ goto exit;
+ }
+ self->private_impl.f_lzw_output_ri = 0u;
+ self->private_impl.f_lzw_output_wi = 0u;
+ }
+ if (self->private_impl.f_lzw_read_from_return_value == 0u) {
+ self->private_impl.f_ignored_but_affects_benchmarks = false;
+ if (v_need_block_size || (v_block_size > 0u)) {
+ self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ status = wuffs_gif__decoder__skip_blocks(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ goto label__outer__break;
+ } else if (self->private_impl.f_lzw_read_from_return_value == 1u) {
+ continue;
+ } else if (self->private_impl.f_lzw_read_from_return_value == 2u) {
+ goto label__outer__continue;
+ } else if (self->private_impl.f_quirks[3u] && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) && (self->private_impl.f_interlace == 0u)) {
+ if (v_need_block_size || (v_block_size > 0u)) {
+ self->private_data.s_decode_id_part2[0].scratch = ((uint32_t)(v_block_size));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (self->private_data.s_decode_id_part2[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_decode_id_part2[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_decode_id_part2[0].scratch;
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ status = wuffs_gif__decoder__skip_blocks(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ goto label__outer__break;
+ } else if (self->private_impl.f_lzw_read_from_return_value == 3u) {
+ status = wuffs_base__make_status(wuffs_gif__error__truncated_input);
+ goto exit;
+ } else if (self->private_impl.f_lzw_read_from_return_value == 4u) {
+ status = wuffs_base__make_status(wuffs_gif__error__bad_lzw_code);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ }
+ label__outer__break:;
+ self->private_impl.f_compressed_ri = 0u;
+ self->private_impl.f_compressed_wi = 0u;
+ if ((self->private_impl.f_dst_y < self->private_impl.f_frame_rect_y1) && (self->private_impl.f_frame_rect_x0 != self->private_impl.f_frame_rect_x1) && (self->private_impl.f_frame_rect_y0 != self->private_impl.f_frame_rect_y1)) {
+ status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
+ goto exit;
+ }
+
+ ok:
+ self->private_impl.p_decode_id_part2[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_id_part2[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_id_part2[0].v_block_size = v_block_size;
+ self->private_data.s_decode_id_part2[0].v_need_block_size = v_need_block_size;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func gif.decoder.copy_to_image_buffer
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gif__decoder__copy_to_image_buffer(
+ wuffs_gif__decoder* self,
+ wuffs_base__pixel_buffer* a_pb,
+ wuffs_base__slice_u8 a_src) {
+ wuffs_base__slice_u8 v_dst = {0};
+ wuffs_base__slice_u8 v_src = {0};
+ uint64_t v_width_in_bytes = 0;
+ uint64_t v_n = 0;
+ uint64_t v_src_ri = 0;
+ wuffs_base__pixel_format v_pixfmt = {0};
+ uint32_t v_bytes_per_pixel = 0;
+ uint32_t v_bits_per_pixel = 0;
+ wuffs_base__table_u8 v_tab = {0};
+ uint64_t v_i = 0;
+ uint64_t v_j = 0;
+ uint32_t v_replicate_y0 = 0;
+ uint32_t v_replicate_y1 = 0;
+ wuffs_base__slice_u8 v_replicate_dst = {0};
+ wuffs_base__slice_u8 v_replicate_src = {0};
+
+ v_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_pb);
+ v_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_pixfmt);
+ if ((v_bits_per_pixel & 7u) != 0u) {
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ }
+ v_bytes_per_pixel = (v_bits_per_pixel >> 3u);
+ v_width_in_bytes = ((uint64_t)((self->private_impl.f_width * v_bytes_per_pixel)));
+ v_tab = wuffs_base__pixel_buffer__plane(a_pb, 0u);
+ while (v_src_ri < ((uint64_t)(a_src.len))) {
+ v_src = wuffs_base__slice_u8__subslice_i(a_src, v_src_ri);
+ if (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1) {
+ if (self->private_impl.f_quirks[3u]) {
+ return wuffs_base__make_status(NULL);
+ }
+ return wuffs_base__make_status(wuffs_base__error__too_much_data);
+ }
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, 0u);
+ } else if (v_width_in_bytes < ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_width_in_bytes);
+ }
+ v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_bytes_per_pixel)));
+ if (v_i < ((uint64_t)(v_dst.len))) {
+ v_j = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * ((uint64_t)(v_bytes_per_pixel)));
+ if ((v_i <= v_j) && (v_j <= ((uint64_t)(v_dst.len)))) {
+ v_dst = wuffs_base__slice_u8__subslice_ij(v_dst, v_i, v_j);
+ } else {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_i);
+ }
+ v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024), v_src);
+ wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
+ self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1u));
+ }
+ if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
+ self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
+ if (self->private_impl.f_interlace == 0u) {
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, 1u);
+ continue;
+ }
+ if ((self->private_impl.f_num_decoded_frames_value == 0u) && ! self->private_impl.f_gc_has_transparent_index && (self->private_impl.f_interlace > 1u)) {
+ v_replicate_src = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ v_replicate_y0 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, 1u);
+ v_replicate_y1 = wuffs_base__u32__sat_add(self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_COUNT[self->private_impl.f_interlace])));
+ v_replicate_y1 = wuffs_base__u32__min(v_replicate_y1, self->private_impl.f_frame_rect_y1);
+ while (v_replicate_y0 < v_replicate_y1) {
+ v_replicate_dst = wuffs_base__table_u8__row_u32(v_tab, v_replicate_y0);
+ wuffs_base__slice_u8__copy_from_slice(v_replicate_dst, v_replicate_src);
+ v_replicate_y0 += 1u;
+ }
+ self->private_impl.f_dirty_max_excl_y = wuffs_base__u32__max(self->private_impl.f_dirty_max_excl_y, v_replicate_y1);
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
+ while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_impl.f_interlace -= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]);
+ }
+ continue;
+ }
+ if (((uint64_t)(a_src.len)) == v_src_ri) {
+ break;
+ } else if (((uint64_t)(a_src.len)) < v_src_ri) {
+ return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
+ }
+ v_n = ((uint64_t)((self->private_impl.f_frame_rect_x1 - self->private_impl.f_dst_x)));
+ v_n = wuffs_base__u64__min(v_n, (((uint64_t)(a_src.len)) - v_src_ri));
+ wuffs_base__u64__sat_add_indirect(&v_src_ri, v_n);
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
+ if (self->private_impl.f_frame_rect_x1 <= self->private_impl.f_dst_x) {
+ self->private_impl.f_dst_x = self->private_impl.f_frame_rect_x0;
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_y, ((uint32_t)(WUFFS_GIF__INTERLACE_DELTA[self->private_impl.f_interlace])));
+ while ((self->private_impl.f_interlace > 0u) && (self->private_impl.f_dst_y >= self->private_impl.f_frame_rect_y1)) {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_impl.f_interlace -= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ self->private_impl.f_dst_y = wuffs_base__u32__sat_add(self->private_impl.f_frame_rect_y0, WUFFS_GIF__INTERLACE_START[self->private_impl.f_interlace]);
+ }
+ continue;
+ }
+ if (v_src_ri != ((uint64_t)(a_src.len))) {
+ return wuffs_base__make_status(wuffs_gif__error__internal_error_inconsistent_i_o);
+ }
+ break;
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func gif.decoder.lzw_init
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_gif__decoder__lzw_init(
+ wuffs_gif__decoder* self) {
+ uint32_t v_i = 0;
+
+ self->private_impl.f_lzw_literal_width = 8u;
+ if (self->private_impl.f_lzw_pending_literal_width_plus_one > 0u) {
+ self->private_impl.f_lzw_literal_width = (self->private_impl.f_lzw_pending_literal_width_plus_one - 1u);
+ }
+ self->private_impl.f_lzw_clear_code = (((uint32_t)(1u)) << self->private_impl.f_lzw_literal_width);
+ self->private_impl.f_lzw_end_code = (self->private_impl.f_lzw_clear_code + 1u);
+ self->private_impl.f_lzw_save_code = self->private_impl.f_lzw_end_code;
+ self->private_impl.f_lzw_prev_code = self->private_impl.f_lzw_end_code;
+ self->private_impl.f_lzw_width = (self->private_impl.f_lzw_literal_width + 1u);
+ self->private_impl.f_lzw_bits = 0u;
+ self->private_impl.f_lzw_n_bits = 0u;
+ self->private_impl.f_lzw_output_ri = 0u;
+ self->private_impl.f_lzw_output_wi = 0u;
+ v_i = 0u;
+ while (v_i < self->private_impl.f_lzw_clear_code) {
+ self->private_data.f_lzw_lm1s[v_i] = 0u;
+ self->private_data.f_lzw_suffixes[v_i][0u] = ((uint8_t)(v_i));
+ v_i += 1u;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func gif.decoder.lzw_read_from
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_gif__decoder__lzw_read_from(
+ wuffs_gif__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ uint32_t v_clear_code = 0;
+ uint32_t v_end_code = 0;
+ uint32_t v_save_code = 0;
+ uint32_t v_prev_code = 0;
+ uint32_t v_width = 0;
+ uint32_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint32_t v_output_wi = 0;
+ uint32_t v_code = 0;
+ uint32_t v_c = 0;
+ uint32_t v_o = 0;
+ uint32_t v_steps = 0;
+ uint8_t v_first_byte = 0;
+ uint16_t v_lm1_b = 0;
+ uint16_t v_lm1_a = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_clear_code = self->private_impl.f_lzw_clear_code;
+ v_end_code = self->private_impl.f_lzw_end_code;
+ v_save_code = self->private_impl.f_lzw_save_code;
+ v_prev_code = self->private_impl.f_lzw_prev_code;
+ v_width = self->private_impl.f_lzw_width;
+ v_bits = self->private_impl.f_lzw_bits;
+ v_n_bits = self->private_impl.f_lzw_n_bits;
+ v_output_wi = self->private_impl.f_lzw_output_wi;
+ while (true) {
+ if (v_n_bits < v_width) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
+ v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
+ iop_a_src += ((31u - v_n_bits) >> 3u);
+ v_n_bits |= 24u;
+ } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ self->private_impl.f_lzw_read_from_return_value = 3u;
+ } else {
+ self->private_impl.f_lzw_read_from_return_value = 2u;
+ }
+ break;
+ } else {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ if (v_n_bits >= v_width) {
+ } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ self->private_impl.f_lzw_read_from_return_value = 3u;
+ } else {
+ self->private_impl.f_lzw_read_from_return_value = 2u;
+ }
+ break;
+ } else {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ if (v_n_bits < v_width) {
+ self->private_impl.f_lzw_read_from_return_value = 5u;
+ break;
+ }
+ }
+ }
+ }
+ v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
+ v_bits >>= v_width;
+ v_n_bits -= v_width;
+ if (v_code < v_clear_code) {
+ self->private_data.f_lzw_output[v_output_wi] = ((uint8_t)(v_code));
+ v_output_wi = ((v_output_wi + 1u) & 8191u);
+ if (v_save_code <= 4095u) {
+ v_lm1_a = (((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u);
+ self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_a;
+ if ((v_lm1_a % 8u) != 0u) {
+ self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code];
+ memcpy(self->private_data.f_lzw_suffixes[v_save_code],self->private_data.f_lzw_suffixes[v_prev_code], sizeof(self->private_data.f_lzw_suffixes[v_save_code]));
+ self->private_data.f_lzw_suffixes[v_save_code][(v_lm1_a % 8u)] = ((uint8_t)(v_code));
+ } else {
+ self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
+ self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_code));
+ }
+ v_save_code += 1u;
+ if (v_width < 12u) {
+ v_width += (1u & (v_save_code >> v_width));
+ }
+ v_prev_code = v_code;
+ }
+ } else if (v_code <= v_end_code) {
+ if (v_code == v_end_code) {
+ self->private_impl.f_lzw_read_from_return_value = 0u;
+ break;
+ }
+ v_save_code = v_end_code;
+ v_prev_code = v_end_code;
+ v_width = (self->private_impl.f_lzw_literal_width + 1u);
+ } else if (v_code <= v_save_code) {
+ v_c = v_code;
+ if (v_code == v_save_code) {
+ v_c = v_prev_code;
+ }
+ v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) & 4294967288u)) & 8191u);
+ v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lzw_lm1s[v_c]))) & 8191u);
+ v_steps = (((uint32_t)(self->private_data.f_lzw_lm1s[v_c])) >> 3u);
+ while (true) {
+ memcpy((self->private_data.f_lzw_output)+(v_o), (self->private_data.f_lzw_suffixes[v_c]), 8u);
+ if (v_steps <= 0u) {
+ break;
+ }
+ v_steps -= 1u;
+ v_o = (((uint32_t)(v_o - 8u)) & 8191u);
+ v_c = ((uint32_t)(self->private_impl.f_lzw_prefixes[v_c]));
+ }
+ v_first_byte = self->private_data.f_lzw_suffixes[v_c][0u];
+ if (v_code == v_save_code) {
+ self->private_data.f_lzw_output[v_output_wi] = v_first_byte;
+ v_output_wi = ((v_output_wi + 1u) & 8191u);
+ }
+ if (v_save_code <= 4095u) {
+ v_lm1_b = (((uint16_t)(self->private_data.f_lzw_lm1s[v_prev_code] + 1u)) & 4095u);
+ self->private_data.f_lzw_lm1s[v_save_code] = v_lm1_b;
+ if ((v_lm1_b % 8u) != 0u) {
+ self->private_impl.f_lzw_prefixes[v_save_code] = self->private_impl.f_lzw_prefixes[v_prev_code];
+ memcpy(self->private_data.f_lzw_suffixes[v_save_code],self->private_data.f_lzw_suffixes[v_prev_code], sizeof(self->private_data.f_lzw_suffixes[v_save_code]));
+ self->private_data.f_lzw_suffixes[v_save_code][(v_lm1_b % 8u)] = v_first_byte;
+ } else {
+ self->private_impl.f_lzw_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
+ self->private_data.f_lzw_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte));
+ }
+ v_save_code += 1u;
+ if (v_width < 12u) {
+ v_width += (1u & (v_save_code >> v_width));
+ }
+ v_prev_code = v_code;
+ }
+ } else {
+ self->private_impl.f_lzw_read_from_return_value = 4u;
+ break;
+ }
+ if (v_output_wi > 4095u) {
+ self->private_impl.f_lzw_read_from_return_value = 1u;
+ break;
+ }
+ }
+ if (self->private_impl.f_lzw_read_from_return_value != 2u) {
+ while (v_n_bits >= 8u) {
+ v_n_bits -= 8u;
+ if (iop_a_src > io1_a_src) {
+ iop_a_src--;
+ } else {
+ self->private_impl.f_lzw_read_from_return_value = 5u;
+ break;
+ }
+ }
+ }
+ self->private_impl.f_lzw_save_code = v_save_code;
+ self->private_impl.f_lzw_prev_code = v_prev_code;
+ self->private_impl.f_lzw_width = v_width;
+ self->private_impl.f_lzw_bits = v_bits;
+ self->private_impl.f_lzw_n_bits = v_n_bits;
+ self->private_impl.f_lzw_output_wi = v_output_wi;
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return wuffs_base__make_empty_struct();
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_gzip__error__bad_checksum[] = "#gzip: bad checksum";
+const char wuffs_gzip__error__bad_compression_method[] = "#gzip: bad compression method";
+const char wuffs_gzip__error__bad_encoding_flags[] = "#gzip: bad encoding flags";
+const char wuffs_gzip__error__bad_header[] = "#gzip: bad header";
+const char wuffs_gzip__error__truncated_input[] = "#gzip: truncated input";
+
+// ---------------- Private Consts
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gzip__decoder__do_transform_io(
+ wuffs_gzip__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+// ---------------- VTables
+
+const wuffs_base__io_transformer__func_ptrs
+wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer = {
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_gzip__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_gzip__decoder__history_retain_length),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_gzip__decoder__set_quirk),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__slice_u8))(&wuffs_gzip__decoder__transform_io),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_gzip__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_gzip__decoder__initialize(
+ wuffs_gzip__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ {
+ wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
+ &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
+ if (z.repr) {
+ return z;
+ }
+ }
+ {
+ wuffs_base__status z = wuffs_deflate__decoder__initialize(
+ &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
+ if (z.repr) {
+ return z;
+ }
+ }
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
+ wuffs_base__io_transformer__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
+ (const void*)(&wuffs_gzip__decoder__func_ptrs_for__wuffs_base__io_transformer);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_gzip__decoder*
+wuffs_gzip__decoder__alloc(void) {
+ wuffs_gzip__decoder* x =
+ (wuffs_gzip__decoder*)(calloc(sizeof(wuffs_gzip__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_gzip__decoder__initialize(
+ x, sizeof(wuffs_gzip__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_gzip__decoder(void) {
+ return sizeof(wuffs_gzip__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func gzip.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gzip__decoder__get_quirk(
+ const wuffs_gzip__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func gzip.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_gzip__decoder__set_quirk(
+ wuffs_gzip__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (a_key == 1u) {
+ self->private_impl.f_ignore_checksum = (a_value > 0u);
+ return wuffs_base__make_status(NULL);
+ }
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func gzip.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_gzip__decoder__history_retain_length(
+ const wuffs_gzip__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func gzip.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_gzip__decoder__workbuf_len(
+ const wuffs_gzip__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(1u, 1u);
+}
+
+// -------- func gzip.decoder.transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_gzip__decoder__transform_io(
+ wuffs_gzip__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_gzip__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_gzip__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func gzip.decoder.do_transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_gzip__decoder__do_transform_io(
+ wuffs_gzip__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint8_t v_flags = 0;
+ uint16_t v_xlen = 0;
+ uint64_t v_mark = 0;
+ uint32_t v_checksum_got = 0;
+ uint32_t v_decoded_length_got = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ uint32_t v_checksum_want = 0;
+ uint32_t v_decoded_length_want = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0];
+ if (coro_susp_point) {
+ v_flags = self->private_data.s_do_transform_io[0].v_flags;
+ v_checksum_got = self->private_data.s_do_transform_io[0].v_checksum_got;
+ v_decoded_length_got = self->private_data.s_do_transform_io[0].v_decoded_length_got;
+ v_checksum_want = self->private_data.s_do_transform_io[0].v_checksum_want;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c != 31u) {
+ status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ if (v_c != 139u) {
+ status = wuffs_base__make_status(wuffs_gzip__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_c = t_2;
+ }
+ if (v_c != 8u) {
+ status = wuffs_base__make_status(wuffs_gzip__error__bad_compression_method);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_flags = t_3;
+ }
+ self->private_data.s_do_transform_io[0].scratch = 6u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_transform_io[0].scratch;
+ if ((v_flags & 4u) != 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ uint16_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_transform_io[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
+ if (num_bits_4 == 8) {
+ t_4 = ((uint16_t)(*scratch));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4)) << 56;
+ }
+ }
+ v_xlen = t_4;
+ }
+ self->private_data.s_do_transform_io[0].scratch = ((uint32_t)(v_xlen));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_transform_io[0].scratch;
+ }
+ if ((v_flags & 8u) != 0u) {
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ v_c = t_5;
+ }
+ if (v_c == 0u) {
+ break;
+ }
+ }
+ }
+ if ((v_flags & 16u) != 0u) {
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_6 = *iop_a_src++;
+ v_c = t_6;
+ }
+ if (v_c == 0u) {
+ break;
+ }
+ }
+ }
+ if ((v_flags & 2u) != 0u) {
+ self->private_data.s_do_transform_io[0].scratch = 2u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ if (self->private_data.s_do_transform_io[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_transform_io[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_transform_io[0].scratch;
+ }
+ if ((v_flags & 224u) != 0u) {
+ status = wuffs_base__make_status(wuffs_gzip__error__bad_encoding_flags);
+ goto exit;
+ }
+ while (true) {
+ v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
+ {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_7 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
+ v_status = t_7;
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ if ( ! self->private_impl.f_ignore_checksum) {
+ v_checksum_got = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
+ v_decoded_length_got += ((uint32_t)(wuffs_base__io__count_since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)))));
+ }
+ if (wuffs_base__status__is_ok(&v_status)) {
+ break;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
+ uint32_t t_8;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_transform_io[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
+ uint32_t num_bits_8 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_8;
+ if (num_bits_8 == 24) {
+ t_8 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_8 += 8u;
+ *scratch |= ((uint64_t)(num_bits_8)) << 56;
+ }
+ }
+ v_checksum_want = t_8;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
+ uint32_t t_9;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_9 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_transform_io[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
+ uint32_t num_bits_9 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_9;
+ if (num_bits_9 == 24) {
+ t_9 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_9 += 8u;
+ *scratch |= ((uint64_t)(num_bits_9)) << 56;
+ }
+ }
+ v_decoded_length_want = t_9;
+ }
+ if ( ! self->private_impl.f_ignore_checksum && ((v_checksum_got != v_checksum_want) || (v_decoded_length_got != v_decoded_length_want))) {
+ status = wuffs_base__make_status(wuffs_gzip__error__bad_checksum);
+ goto exit;
+ }
+
+ ok:
+ self->private_impl.p_do_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_transform_io[0].v_flags = v_flags;
+ self->private_data.s_do_transform_io[0].v_checksum_got = v_checksum_got;
+ self->private_data.s_do_transform_io[0].v_decoded_length_got = v_decoded_length_got;
+ self->private_data.s_do_transform_io[0].v_checksum_want = v_checksum_want;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GZIP)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_jpeg__error__bad_dht_marker[] = "#jpeg: bad DHT marker";
+const char wuffs_jpeg__error__bad_dqt_marker[] = "#jpeg: bad DQT marker";
+const char wuffs_jpeg__error__bad_dri_marker[] = "#jpeg: bad DRI marker";
+const char wuffs_jpeg__error__bad_sof_marker[] = "#jpeg: bad SOF marker";
+const char wuffs_jpeg__error__bad_sos_marker[] = "#jpeg: bad SOS marker";
+const char wuffs_jpeg__error__bad_header[] = "#jpeg: bad header";
+const char wuffs_jpeg__error__bad_marker[] = "#jpeg: bad marker";
+const char wuffs_jpeg__error__missing_huffman_table[] = "#jpeg: missing Huffman table";
+const char wuffs_jpeg__error__missing_quantization_table[] = "#jpeg: missing Quantization table";
+const char wuffs_jpeg__error__truncated_input[] = "#jpeg: truncated input";
+const char wuffs_jpeg__error__unsupported_arithmetic_coding[] = "#jpeg: unsupported arithmetic coding";
+const char wuffs_jpeg__error__unsupported_color_model[] = "#jpeg: unsupported color model";
+const char wuffs_jpeg__error__unsupported_fractional_sampling[] = "#jpeg: unsupported fractional sampling";
+const char wuffs_jpeg__error__unsupported_hierarchical_coding[] = "#jpeg: unsupported hierarchical coding";
+const char wuffs_jpeg__error__unsupported_implicit_height[] = "#jpeg: unsupported implicit height";
+const char wuffs_jpeg__error__unsupported_lossless_coding[] = "#jpeg: unsupported lossless coding";
+const char wuffs_jpeg__error__unsupported_marker[] = "#jpeg: unsupported marker";
+const char wuffs_jpeg__error__unsupported_precision_12_bits[] = "#jpeg: unsupported precision (12 bits)";
+const char wuffs_jpeg__error__unsupported_precision_16_bits[] = "#jpeg: unsupported precision (16 bits)";
+const char wuffs_jpeg__error__unsupported_precision[] = "#jpeg: unsupported precision";
+const char wuffs_jpeg__error__unsupported_scan_count[] = "#jpeg: unsupported scan count";
+const char wuffs_jpeg__error__internal_error_inconsistent_decoder_state[] = "#jpeg: internal error: inconsistent decoder state";
+
+// ---------------- Private Consts
+
+static const uint8_t
+WUFFS_JPEG__UNZIG[80] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 0, 1, 8, 16, 9, 2, 3,
+ 10, 17, 24, 32, 25, 18, 11, 4,
+ 5, 12, 19, 26, 33, 40, 48, 41,
+ 34, 27, 20, 13, 6, 7, 14, 21,
+ 28, 35, 42, 49, 56, 57, 50, 43,
+ 36, 29, 22, 15, 23, 30, 37, 44,
+ 51, 58, 59, 52, 45, 38, 31, 39,
+ 46, 53, 60, 61, 54, 47, 55, 62,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+ 63, 63, 63, 63, 63, 63, 63, 63,
+};
+
+static const uint8_t
+WUFFS_JPEG__BIAS_AND_CLAMP[1024] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 160, 161, 162, 163, 164, 165, 166, 167,
+ 168, 169, 170, 171, 172, 173, 174, 175,
+ 176, 177, 178, 179, 180, 181, 182, 183,
+ 184, 185, 186, 187, 188, 189, 190, 191,
+ 192, 193, 194, 195, 196, 197, 198, 199,
+ 200, 201, 202, 203, 204, 205, 206, 207,
+ 208, 209, 210, 211, 212, 213, 214, 215,
+ 216, 217, 218, 219, 220, 221, 222, 223,
+ 224, 225, 226, 227, 228, 229, 230, 231,
+ 232, 233, 234, 235, 236, 237, 238, 239,
+ 240, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250, 251, 252, 253, 254, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 255, 255, 255, 255, 255, 255, 255, 255,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23,
+ 24, 25, 26, 27, 28, 29, 30, 31,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 127,
+};
+
+static const uint16_t
+WUFFS_JPEG__EXTEND[16] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 65535, 65533, 65529, 65521, 65505, 65473, 65409,
+ 65281, 65025, 64513, 63489, 61441, 57345, 49153, 32769,
+};
+
+static const uint8_t
+WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 0, 1, 5, 1, 1, 1, 1,
+ 1, 1, 0, 0, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11,
+};
+
+static const uint8_t
+WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA[29] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 1, 0, 3, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 0, 0, 0, 0,
+ 0, 0, 1, 2, 3, 4, 5, 6,
+ 7, 8, 9, 10, 11,
+};
+
+static const uint8_t
+WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 16, 0, 2, 1, 3, 3, 2, 4,
+ 3, 5, 5, 4, 4, 0, 0, 1,
+ 125, 1, 2, 3, 0, 4, 17, 5,
+ 18, 33, 49, 65, 6, 19, 81, 97,
+ 7, 34, 113, 20, 50, 129, 145, 161,
+ 8, 35, 66, 177, 193, 21, 82, 209,
+ 240, 36, 51, 98, 114, 130, 9, 10,
+ 22, 23, 24, 25, 26, 37, 38, 39,
+ 40, 41, 42, 52, 53, 54, 55, 56,
+ 57, 58, 67, 68, 69, 70, 71, 72,
+ 73, 74, 83, 84, 85, 86, 87, 88,
+ 89, 90, 99, 100, 101, 102, 103, 104,
+ 105, 106, 115, 116, 117, 118, 119, 120,
+ 121, 122, 131, 132, 133, 134, 135, 136,
+ 137, 138, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 162, 163, 164, 165, 166,
+ 167, 168, 169, 170, 178, 179, 180, 181,
+ 182, 183, 184, 185, 186, 194, 195, 196,
+ 197, 198, 199, 200, 201, 202, 210, 211,
+ 212, 213, 214, 215, 216, 217, 218, 225,
+ 226, 227, 228, 229, 230, 231, 232, 233,
+ 234, 241, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250,
+};
+
+static const uint8_t
+WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA[179] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 17, 0, 2, 1, 2, 4, 4, 3,
+ 4, 7, 5, 4, 4, 0, 1, 2,
+ 119, 0, 1, 2, 3, 17, 4, 5,
+ 33, 49, 6, 18, 65, 81, 7, 97,
+ 113, 19, 34, 50, 129, 8, 20, 66,
+ 145, 161, 177, 193, 9, 35, 51, 82,
+ 240, 21, 98, 114, 209, 10, 22, 36,
+ 52, 225, 37, 241, 23, 24, 25, 26,
+ 38, 39, 40, 41, 42, 53, 54, 55,
+ 56, 57, 58, 67, 68, 69, 70, 71,
+ 72, 73, 74, 83, 84, 85, 86, 87,
+ 88, 89, 90, 99, 100, 101, 102, 103,
+ 104, 105, 106, 115, 116, 117, 118, 119,
+ 120, 121, 122, 130, 131, 132, 133, 134,
+ 135, 136, 137, 138, 146, 147, 148, 149,
+ 150, 151, 152, 153, 154, 162, 163, 164,
+ 165, 166, 167, 168, 169, 170, 178, 179,
+ 180, 181, 182, 183, 184, 185, 186, 194,
+ 195, 196, 197, 198, 199, 200, 201, 202,
+ 210, 211, 212, 213, 214, 215, 216, 217,
+ 218, 226, 227, 228, 229, 230, 231, 232,
+ 233, 234, 242, 243, 244, 245, 246, 247,
+ 248, 249, 250,
+};
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__decode_idct(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_dst_buffer,
+ uint64_t a_dst_stride,
+ uint32_t a_q);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__decode_idct__choosy_default(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_dst_buffer,
+ uint64_t a_dst_stride,
+ uint32_t a_q);
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__decode_idct_x86_avx2(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_dst_buffer,
+ uint64_t a_dst_stride,
+ uint32_t a_q);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64)
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__do_decode_image_config(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_dqt(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_dri(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_appn(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ uint8_t a_marker);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_sof(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__quantize_dimension(
+ const wuffs_jpeg__decoder* self,
+ uint32_t a_width,
+ uint8_t a_h,
+ uint8_t a_max_incl_h);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__do_decode_frame_config(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__do_decode_frame(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_dht(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static bool
+wuffs_jpeg__decoder__calculate_huff_tables(
+ wuffs_jpeg__decoder* self,
+ uint8_t a_tc4_th,
+ uint32_t a_total_count);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_sos(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__prepare_scan(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__use_default_huffman_table(
+ wuffs_jpeg__decoder* self,
+ uint8_t a_tc4_th);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__calculate_single_component_scan_fields(
+ wuffs_jpeg__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+static bool
+wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(
+ wuffs_jpeg__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__fill_bitstream(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_csel);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_csel);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__load_mcu_blocks(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__save_mcu_blocks(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__skip_past_the_next_restart_marker(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__apply_progressive_idct(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__swizzle_gray(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__swizzle_colorful(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static bool
+wuffs_jpeg__decoder__top_left_quants_has_zero(
+ const wuffs_jpeg__decoder* self,
+ uint32_t a_q);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_csel);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu__choosy_default(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my);
+
+// ---------------- VTables
+
+const wuffs_base__image_decoder__func_ptrs
+wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__pixel_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
+ wuffs_base__slice_u8,
+ wuffs_base__decode_frame_options*))(&wuffs_jpeg__decoder__decode_frame),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__frame_config*,
+ wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_frame_config),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__image_config*,
+ wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__decode_image_config),
+ (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_jpeg__decoder__frame_dirty_rect),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_jpeg__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__history_retain_length),
+ (uint32_t(*)(const void*))(&wuffs_jpeg__decoder__num_animation_loops),
+ (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frame_configs),
+ (uint64_t(*)(const void*))(&wuffs_jpeg__decoder__num_decoded_frames),
+ (wuffs_base__status(*)(void*,
+ uint64_t,
+ uint64_t))(&wuffs_jpeg__decoder__restart_frame),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_jpeg__decoder__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ uint32_t,
+ bool))(&wuffs_jpeg__decoder__set_report_metadata),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*))(&wuffs_jpeg__decoder__tell_me_more),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_jpeg__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_jpeg__decoder__initialize(
+ wuffs_jpeg__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.choosy_decode_idct = &wuffs_jpeg__decoder__decode_idct__choosy_default;
+ self->private_impl.choosy_load_mcu_blocks_for_single_component = &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default;
+ self->private_impl.choosy_decode_mcu = &wuffs_jpeg__decoder__decode_mcu__choosy_default;
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
+ wuffs_base__image_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
+ (const void*)(&wuffs_jpeg__decoder__func_ptrs_for__wuffs_base__image_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_jpeg__decoder*
+wuffs_jpeg__decoder__alloc(void) {
+ wuffs_jpeg__decoder* x =
+ (wuffs_jpeg__decoder*)(calloc(sizeof(wuffs_jpeg__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_jpeg__decoder__initialize(
+ x, sizeof(wuffs_jpeg__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_jpeg__decoder(void) {
+ return sizeof(wuffs_jpeg__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func jpeg.decoder.decode_idct
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__decode_idct(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_dst_buffer,
+ uint64_t a_dst_stride,
+ uint32_t a_q) {
+ return (*self->private_impl.choosy_decode_idct)(self, a_dst_buffer, a_dst_stride, a_q);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__decode_idct__choosy_default(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_dst_buffer,
+ uint64_t a_dst_stride,
+ uint32_t a_q) {
+ uint32_t v_bq0 = 0;
+ uint32_t v_bq2 = 0;
+ uint32_t v_bq4 = 0;
+ uint32_t v_bq6 = 0;
+ uint32_t v_ca = 0;
+ uint32_t v_cb2 = 0;
+ uint32_t v_cb6 = 0;
+ uint32_t v_ccp = 0;
+ uint32_t v_ccm = 0;
+ uint32_t v_cd0 = 0;
+ uint32_t v_cd1 = 0;
+ uint32_t v_cd2 = 0;
+ uint32_t v_cd3 = 0;
+ uint32_t v_bq1 = 0;
+ uint32_t v_bq3 = 0;
+ uint32_t v_bq5 = 0;
+ uint32_t v_bq7 = 0;
+ uint32_t v_ci51 = 0;
+ uint32_t v_ci53 = 0;
+ uint32_t v_ci71 = 0;
+ uint32_t v_ci73 = 0;
+ uint32_t v_cj = 0;
+ uint32_t v_ck1 = 0;
+ uint32_t v_ck3 = 0;
+ uint32_t v_ck5 = 0;
+ uint32_t v_ck7 = 0;
+ uint32_t v_cl51 = 0;
+ uint32_t v_cl73 = 0;
+ uint32_t v_in0 = 0;
+ uint32_t v_in2 = 0;
+ uint32_t v_in4 = 0;
+ uint32_t v_in6 = 0;
+ uint32_t v_ra = 0;
+ uint32_t v_rb2 = 0;
+ uint32_t v_rb6 = 0;
+ uint32_t v_rcp = 0;
+ uint32_t v_rcm = 0;
+ uint32_t v_rd0 = 0;
+ uint32_t v_rd1 = 0;
+ uint32_t v_rd2 = 0;
+ uint32_t v_rd3 = 0;
+ uint32_t v_in1 = 0;
+ uint32_t v_in3 = 0;
+ uint32_t v_in5 = 0;
+ uint32_t v_in7 = 0;
+ uint32_t v_ri51 = 0;
+ uint32_t v_ri53 = 0;
+ uint32_t v_ri71 = 0;
+ uint32_t v_ri73 = 0;
+ uint32_t v_rj = 0;
+ uint32_t v_rk1 = 0;
+ uint32_t v_rk3 = 0;
+ uint32_t v_rk5 = 0;
+ uint32_t v_rk7 = 0;
+ uint32_t v_rl51 = 0;
+ uint32_t v_rl73 = 0;
+ uint32_t v_intermediate[64] = {0};
+
+ if (8u > a_dst_stride) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (0u == (self->private_data.f_mcu_blocks[0u][8u] |
+ self->private_data.f_mcu_blocks[0u][16u] |
+ self->private_data.f_mcu_blocks[0u][24u] |
+ self->private_data.f_mcu_blocks[0u][32u] |
+ self->private_data.f_mcu_blocks[0u][40u] |
+ self->private_data.f_mcu_blocks[0u][48u] |
+ self->private_data.f_mcu_blocks[0u][56u])) {
+ v_intermediate[0u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][0u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][0u])))) << 2u));
+ v_intermediate[8u] = v_intermediate[0u];
+ v_intermediate[16u] = v_intermediate[0u];
+ v_intermediate[24u] = v_intermediate[0u];
+ v_intermediate[32u] = v_intermediate[0u];
+ v_intermediate[40u] = v_intermediate[0u];
+ v_intermediate[48u] = v_intermediate[0u];
+ v_intermediate[56u] = v_intermediate[0u];
+ } else {
+ v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][16u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][16u]))));
+ v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][48u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][48u]))));
+ v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
+ v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
+ v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
+ v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][0u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][0u]))));
+ v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][32u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][32u]))));
+ v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
+ v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
+ v_cd0 = ((uint32_t)(v_ccp + v_cb2));
+ v_cd1 = ((uint32_t)(v_ccm + v_cb6));
+ v_cd2 = ((uint32_t)(v_ccm - v_cb6));
+ v_cd3 = ((uint32_t)(v_ccp - v_cb2));
+ v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][8u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][8u]))));
+ v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][24u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][24u]))));
+ v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][40u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][40u]))));
+ v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][56u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][56u]))));
+ v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
+ v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
+ v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
+ v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
+ v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
+ v_ck1 = ((uint32_t)(v_bq1 * 12299u));
+ v_ck3 = ((uint32_t)(v_bq3 * 25172u));
+ v_ck5 = ((uint32_t)(v_bq5 * 16819u));
+ v_ck7 = ((uint32_t)(v_bq7 * 2446u));
+ v_ci51 *= 4294964100u;
+ v_ci53 *= 4294946301u;
+ v_ci71 *= 4294959923u;
+ v_ci73 *= 4294951227u;
+ v_cl51 = ((uint32_t)(v_ci51 + v_cj));
+ v_cl73 = ((uint32_t)(v_ci73 + v_cj));
+ v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
+ v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
+ v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
+ v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
+ v_intermediate[0u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
+ v_intermediate[56u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
+ v_intermediate[8u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
+ v_intermediate[48u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
+ v_intermediate[16u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
+ v_intermediate[40u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
+ v_intermediate[24u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
+ v_intermediate[32u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
+ }
+ if (0u == (self->private_data.f_mcu_blocks[0u][9u] |
+ self->private_data.f_mcu_blocks[0u][17u] |
+ self->private_data.f_mcu_blocks[0u][25u] |
+ self->private_data.f_mcu_blocks[0u][33u] |
+ self->private_data.f_mcu_blocks[0u][41u] |
+ self->private_data.f_mcu_blocks[0u][49u] |
+ self->private_data.f_mcu_blocks[0u][57u])) {
+ v_intermediate[1u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][1u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][1u])))) << 2u));
+ v_intermediate[9u] = v_intermediate[1u];
+ v_intermediate[17u] = v_intermediate[1u];
+ v_intermediate[25u] = v_intermediate[1u];
+ v_intermediate[33u] = v_intermediate[1u];
+ v_intermediate[41u] = v_intermediate[1u];
+ v_intermediate[49u] = v_intermediate[1u];
+ v_intermediate[57u] = v_intermediate[1u];
+ } else {
+ v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][17u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][17u]))));
+ v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][49u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][49u]))));
+ v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
+ v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
+ v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
+ v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][1u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][1u]))));
+ v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][33u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][33u]))));
+ v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
+ v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
+ v_cd0 = ((uint32_t)(v_ccp + v_cb2));
+ v_cd1 = ((uint32_t)(v_ccm + v_cb6));
+ v_cd2 = ((uint32_t)(v_ccm - v_cb6));
+ v_cd3 = ((uint32_t)(v_ccp - v_cb2));
+ v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][9u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][9u]))));
+ v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][25u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][25u]))));
+ v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][41u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][41u]))));
+ v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][57u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][57u]))));
+ v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
+ v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
+ v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
+ v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
+ v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
+ v_ck1 = ((uint32_t)(v_bq1 * 12299u));
+ v_ck3 = ((uint32_t)(v_bq3 * 25172u));
+ v_ck5 = ((uint32_t)(v_bq5 * 16819u));
+ v_ck7 = ((uint32_t)(v_bq7 * 2446u));
+ v_ci51 *= 4294964100u;
+ v_ci53 *= 4294946301u;
+ v_ci71 *= 4294959923u;
+ v_ci73 *= 4294951227u;
+ v_cl51 = ((uint32_t)(v_ci51 + v_cj));
+ v_cl73 = ((uint32_t)(v_ci73 + v_cj));
+ v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
+ v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
+ v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
+ v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
+ v_intermediate[1u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
+ v_intermediate[57u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
+ v_intermediate[9u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
+ v_intermediate[49u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
+ v_intermediate[17u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
+ v_intermediate[41u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
+ v_intermediate[25u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
+ v_intermediate[33u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
+ }
+ if (0u == (self->private_data.f_mcu_blocks[0u][10u] |
+ self->private_data.f_mcu_blocks[0u][18u] |
+ self->private_data.f_mcu_blocks[0u][26u] |
+ self->private_data.f_mcu_blocks[0u][34u] |
+ self->private_data.f_mcu_blocks[0u][42u] |
+ self->private_data.f_mcu_blocks[0u][50u] |
+ self->private_data.f_mcu_blocks[0u][58u])) {
+ v_intermediate[2u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][2u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][2u])))) << 2u));
+ v_intermediate[10u] = v_intermediate[2u];
+ v_intermediate[18u] = v_intermediate[2u];
+ v_intermediate[26u] = v_intermediate[2u];
+ v_intermediate[34u] = v_intermediate[2u];
+ v_intermediate[42u] = v_intermediate[2u];
+ v_intermediate[50u] = v_intermediate[2u];
+ v_intermediate[58u] = v_intermediate[2u];
+ } else {
+ v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][18u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][18u]))));
+ v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][50u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][50u]))));
+ v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
+ v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
+ v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
+ v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][2u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][2u]))));
+ v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][34u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][34u]))));
+ v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
+ v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
+ v_cd0 = ((uint32_t)(v_ccp + v_cb2));
+ v_cd1 = ((uint32_t)(v_ccm + v_cb6));
+ v_cd2 = ((uint32_t)(v_ccm - v_cb6));
+ v_cd3 = ((uint32_t)(v_ccp - v_cb2));
+ v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][10u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][10u]))));
+ v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][26u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][26u]))));
+ v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][42u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][42u]))));
+ v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][58u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][58u]))));
+ v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
+ v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
+ v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
+ v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
+ v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
+ v_ck1 = ((uint32_t)(v_bq1 * 12299u));
+ v_ck3 = ((uint32_t)(v_bq3 * 25172u));
+ v_ck5 = ((uint32_t)(v_bq5 * 16819u));
+ v_ck7 = ((uint32_t)(v_bq7 * 2446u));
+ v_ci51 *= 4294964100u;
+ v_ci53 *= 4294946301u;
+ v_ci71 *= 4294959923u;
+ v_ci73 *= 4294951227u;
+ v_cl51 = ((uint32_t)(v_ci51 + v_cj));
+ v_cl73 = ((uint32_t)(v_ci73 + v_cj));
+ v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
+ v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
+ v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
+ v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
+ v_intermediate[2u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
+ v_intermediate[58u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
+ v_intermediate[10u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
+ v_intermediate[50u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
+ v_intermediate[18u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
+ v_intermediate[42u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
+ v_intermediate[26u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
+ v_intermediate[34u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
+ }
+ if (0u == (self->private_data.f_mcu_blocks[0u][11u] |
+ self->private_data.f_mcu_blocks[0u][19u] |
+ self->private_data.f_mcu_blocks[0u][27u] |
+ self->private_data.f_mcu_blocks[0u][35u] |
+ self->private_data.f_mcu_blocks[0u][43u] |
+ self->private_data.f_mcu_blocks[0u][51u] |
+ self->private_data.f_mcu_blocks[0u][59u])) {
+ v_intermediate[3u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][3u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][3u])))) << 2u));
+ v_intermediate[11u] = v_intermediate[3u];
+ v_intermediate[19u] = v_intermediate[3u];
+ v_intermediate[27u] = v_intermediate[3u];
+ v_intermediate[35u] = v_intermediate[3u];
+ v_intermediate[43u] = v_intermediate[3u];
+ v_intermediate[51u] = v_intermediate[3u];
+ v_intermediate[59u] = v_intermediate[3u];
+ } else {
+ v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][19u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][19u]))));
+ v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][51u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][51u]))));
+ v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
+ v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
+ v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
+ v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][3u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][3u]))));
+ v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][35u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][35u]))));
+ v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
+ v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
+ v_cd0 = ((uint32_t)(v_ccp + v_cb2));
+ v_cd1 = ((uint32_t)(v_ccm + v_cb6));
+ v_cd2 = ((uint32_t)(v_ccm - v_cb6));
+ v_cd3 = ((uint32_t)(v_ccp - v_cb2));
+ v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][11u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][11u]))));
+ v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][27u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][27u]))));
+ v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][43u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][43u]))));
+ v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][59u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][59u]))));
+ v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
+ v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
+ v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
+ v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
+ v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
+ v_ck1 = ((uint32_t)(v_bq1 * 12299u));
+ v_ck3 = ((uint32_t)(v_bq3 * 25172u));
+ v_ck5 = ((uint32_t)(v_bq5 * 16819u));
+ v_ck7 = ((uint32_t)(v_bq7 * 2446u));
+ v_ci51 *= 4294964100u;
+ v_ci53 *= 4294946301u;
+ v_ci71 *= 4294959923u;
+ v_ci73 *= 4294951227u;
+ v_cl51 = ((uint32_t)(v_ci51 + v_cj));
+ v_cl73 = ((uint32_t)(v_ci73 + v_cj));
+ v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
+ v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
+ v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
+ v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
+ v_intermediate[3u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
+ v_intermediate[59u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
+ v_intermediate[11u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
+ v_intermediate[51u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
+ v_intermediate[19u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
+ v_intermediate[43u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
+ v_intermediate[27u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
+ v_intermediate[35u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
+ }
+ if (0u == (self->private_data.f_mcu_blocks[0u][12u] |
+ self->private_data.f_mcu_blocks[0u][20u] |
+ self->private_data.f_mcu_blocks[0u][28u] |
+ self->private_data.f_mcu_blocks[0u][36u] |
+ self->private_data.f_mcu_blocks[0u][44u] |
+ self->private_data.f_mcu_blocks[0u][52u] |
+ self->private_data.f_mcu_blocks[0u][60u])) {
+ v_intermediate[4u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][4u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][4u])))) << 2u));
+ v_intermediate[12u] = v_intermediate[4u];
+ v_intermediate[20u] = v_intermediate[4u];
+ v_intermediate[28u] = v_intermediate[4u];
+ v_intermediate[36u] = v_intermediate[4u];
+ v_intermediate[44u] = v_intermediate[4u];
+ v_intermediate[52u] = v_intermediate[4u];
+ v_intermediate[60u] = v_intermediate[4u];
+ } else {
+ v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][20u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][20u]))));
+ v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][52u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][52u]))));
+ v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
+ v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
+ v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
+ v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][4u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][4u]))));
+ v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][36u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][36u]))));
+ v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
+ v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
+ v_cd0 = ((uint32_t)(v_ccp + v_cb2));
+ v_cd1 = ((uint32_t)(v_ccm + v_cb6));
+ v_cd2 = ((uint32_t)(v_ccm - v_cb6));
+ v_cd3 = ((uint32_t)(v_ccp - v_cb2));
+ v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][12u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][12u]))));
+ v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][28u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][28u]))));
+ v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][44u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][44u]))));
+ v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][60u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][60u]))));
+ v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
+ v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
+ v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
+ v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
+ v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
+ v_ck1 = ((uint32_t)(v_bq1 * 12299u));
+ v_ck3 = ((uint32_t)(v_bq3 * 25172u));
+ v_ck5 = ((uint32_t)(v_bq5 * 16819u));
+ v_ck7 = ((uint32_t)(v_bq7 * 2446u));
+ v_ci51 *= 4294964100u;
+ v_ci53 *= 4294946301u;
+ v_ci71 *= 4294959923u;
+ v_ci73 *= 4294951227u;
+ v_cl51 = ((uint32_t)(v_ci51 + v_cj));
+ v_cl73 = ((uint32_t)(v_ci73 + v_cj));
+ v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
+ v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
+ v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
+ v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
+ v_intermediate[4u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
+ v_intermediate[60u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
+ v_intermediate[12u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
+ v_intermediate[52u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
+ v_intermediate[20u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
+ v_intermediate[44u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
+ v_intermediate[28u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
+ v_intermediate[36u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
+ }
+ if (0u == (self->private_data.f_mcu_blocks[0u][13u] |
+ self->private_data.f_mcu_blocks[0u][21u] |
+ self->private_data.f_mcu_blocks[0u][29u] |
+ self->private_data.f_mcu_blocks[0u][37u] |
+ self->private_data.f_mcu_blocks[0u][45u] |
+ self->private_data.f_mcu_blocks[0u][53u] |
+ self->private_data.f_mcu_blocks[0u][61u])) {
+ v_intermediate[5u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][5u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][5u])))) << 2u));
+ v_intermediate[13u] = v_intermediate[5u];
+ v_intermediate[21u] = v_intermediate[5u];
+ v_intermediate[29u] = v_intermediate[5u];
+ v_intermediate[37u] = v_intermediate[5u];
+ v_intermediate[45u] = v_intermediate[5u];
+ v_intermediate[53u] = v_intermediate[5u];
+ v_intermediate[61u] = v_intermediate[5u];
+ } else {
+ v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][21u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][21u]))));
+ v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][53u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][53u]))));
+ v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
+ v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
+ v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
+ v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][5u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][5u]))));
+ v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][37u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][37u]))));
+ v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
+ v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
+ v_cd0 = ((uint32_t)(v_ccp + v_cb2));
+ v_cd1 = ((uint32_t)(v_ccm + v_cb6));
+ v_cd2 = ((uint32_t)(v_ccm - v_cb6));
+ v_cd3 = ((uint32_t)(v_ccp - v_cb2));
+ v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][13u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][13u]))));
+ v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][29u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][29u]))));
+ v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][45u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][45u]))));
+ v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][61u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][61u]))));
+ v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
+ v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
+ v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
+ v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
+ v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
+ v_ck1 = ((uint32_t)(v_bq1 * 12299u));
+ v_ck3 = ((uint32_t)(v_bq3 * 25172u));
+ v_ck5 = ((uint32_t)(v_bq5 * 16819u));
+ v_ck7 = ((uint32_t)(v_bq7 * 2446u));
+ v_ci51 *= 4294964100u;
+ v_ci53 *= 4294946301u;
+ v_ci71 *= 4294959923u;
+ v_ci73 *= 4294951227u;
+ v_cl51 = ((uint32_t)(v_ci51 + v_cj));
+ v_cl73 = ((uint32_t)(v_ci73 + v_cj));
+ v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
+ v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
+ v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
+ v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
+ v_intermediate[5u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
+ v_intermediate[61u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
+ v_intermediate[13u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
+ v_intermediate[53u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
+ v_intermediate[21u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
+ v_intermediate[45u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
+ v_intermediate[29u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
+ v_intermediate[37u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
+ }
+ if (0u == (self->private_data.f_mcu_blocks[0u][14u] |
+ self->private_data.f_mcu_blocks[0u][22u] |
+ self->private_data.f_mcu_blocks[0u][30u] |
+ self->private_data.f_mcu_blocks[0u][38u] |
+ self->private_data.f_mcu_blocks[0u][46u] |
+ self->private_data.f_mcu_blocks[0u][54u] |
+ self->private_data.f_mcu_blocks[0u][62u])) {
+ v_intermediate[6u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][6u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][6u])))) << 2u));
+ v_intermediate[14u] = v_intermediate[6u];
+ v_intermediate[22u] = v_intermediate[6u];
+ v_intermediate[30u] = v_intermediate[6u];
+ v_intermediate[38u] = v_intermediate[6u];
+ v_intermediate[46u] = v_intermediate[6u];
+ v_intermediate[54u] = v_intermediate[6u];
+ v_intermediate[62u] = v_intermediate[6u];
+ } else {
+ v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][22u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][22u]))));
+ v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][54u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][54u]))));
+ v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
+ v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
+ v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
+ v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][6u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][6u]))));
+ v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][38u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][38u]))));
+ v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
+ v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
+ v_cd0 = ((uint32_t)(v_ccp + v_cb2));
+ v_cd1 = ((uint32_t)(v_ccm + v_cb6));
+ v_cd2 = ((uint32_t)(v_ccm - v_cb6));
+ v_cd3 = ((uint32_t)(v_ccp - v_cb2));
+ v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][14u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][14u]))));
+ v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][30u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][30u]))));
+ v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][46u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][46u]))));
+ v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][62u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][62u]))));
+ v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
+ v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
+ v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
+ v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
+ v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
+ v_ck1 = ((uint32_t)(v_bq1 * 12299u));
+ v_ck3 = ((uint32_t)(v_bq3 * 25172u));
+ v_ck5 = ((uint32_t)(v_bq5 * 16819u));
+ v_ck7 = ((uint32_t)(v_bq7 * 2446u));
+ v_ci51 *= 4294964100u;
+ v_ci53 *= 4294946301u;
+ v_ci71 *= 4294959923u;
+ v_ci73 *= 4294951227u;
+ v_cl51 = ((uint32_t)(v_ci51 + v_cj));
+ v_cl73 = ((uint32_t)(v_ci73 + v_cj));
+ v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
+ v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
+ v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
+ v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
+ v_intermediate[6u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
+ v_intermediate[62u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
+ v_intermediate[14u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
+ v_intermediate[54u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
+ v_intermediate[22u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
+ v_intermediate[46u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
+ v_intermediate[30u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
+ v_intermediate[38u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
+ }
+ if (0u == (self->private_data.f_mcu_blocks[0u][15u] |
+ self->private_data.f_mcu_blocks[0u][23u] |
+ self->private_data.f_mcu_blocks[0u][31u] |
+ self->private_data.f_mcu_blocks[0u][39u] |
+ self->private_data.f_mcu_blocks[0u][47u] |
+ self->private_data.f_mcu_blocks[0u][55u] |
+ self->private_data.f_mcu_blocks[0u][63u])) {
+ v_intermediate[7u] = ((uint32_t)(((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][7u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][7u])))) << 2u));
+ v_intermediate[15u] = v_intermediate[7u];
+ v_intermediate[23u] = v_intermediate[7u];
+ v_intermediate[31u] = v_intermediate[7u];
+ v_intermediate[39u] = v_intermediate[7u];
+ v_intermediate[47u] = v_intermediate[7u];
+ v_intermediate[55u] = v_intermediate[7u];
+ v_intermediate[63u] = v_intermediate[7u];
+ } else {
+ v_bq2 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][23u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][23u]))));
+ v_bq6 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][55u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][55u]))));
+ v_ca = ((uint32_t)(((uint32_t)(v_bq2 + v_bq6)) * 4433u));
+ v_cb2 = ((uint32_t)(v_ca + ((uint32_t)(v_bq2 * 6270u))));
+ v_cb6 = ((uint32_t)(v_ca - ((uint32_t)(v_bq6 * 15137u))));
+ v_bq0 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][7u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][7u]))));
+ v_bq4 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][39u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][39u]))));
+ v_ccp = ((uint32_t)(((uint32_t)(v_bq0 + v_bq4)) << 13u));
+ v_ccm = ((uint32_t)(((uint32_t)(v_bq0 - v_bq4)) << 13u));
+ v_cd0 = ((uint32_t)(v_ccp + v_cb2));
+ v_cd1 = ((uint32_t)(v_ccm + v_cb6));
+ v_cd2 = ((uint32_t)(v_ccm - v_cb6));
+ v_cd3 = ((uint32_t)(v_ccp - v_cb2));
+ v_bq1 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][15u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][15u]))));
+ v_bq3 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][31u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][31u]))));
+ v_bq5 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][47u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][47u]))));
+ v_bq7 = ((uint32_t)(wuffs_base__utility__sign_extend_convert_u16_u32(self->private_data.f_mcu_blocks[0u][63u]) * ((uint32_t)(self->private_impl.f_quant_tables[a_q][63u]))));
+ v_ci51 = ((uint32_t)(v_bq5 + v_bq1));
+ v_ci53 = ((uint32_t)(v_bq5 + v_bq3));
+ v_ci71 = ((uint32_t)(v_bq7 + v_bq1));
+ v_ci73 = ((uint32_t)(v_bq7 + v_bq3));
+ v_cj = ((uint32_t)(((uint32_t)(v_ci73 + v_ci51)) * 9633u));
+ v_ck1 = ((uint32_t)(v_bq1 * 12299u));
+ v_ck3 = ((uint32_t)(v_bq3 * 25172u));
+ v_ck5 = ((uint32_t)(v_bq5 * 16819u));
+ v_ck7 = ((uint32_t)(v_bq7 * 2446u));
+ v_ci51 *= 4294964100u;
+ v_ci53 *= 4294946301u;
+ v_ci71 *= 4294959923u;
+ v_ci73 *= 4294951227u;
+ v_cl51 = ((uint32_t)(v_ci51 + v_cj));
+ v_cl73 = ((uint32_t)(v_ci73 + v_cj));
+ v_ck1 += ((uint32_t)(v_ci71 + v_cl51));
+ v_ck3 += ((uint32_t)(v_ci53 + v_cl73));
+ v_ck5 += ((uint32_t)(v_ci53 + v_cl51));
+ v_ck7 += ((uint32_t)(v_ci71 + v_cl73));
+ v_intermediate[7u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 + v_ck1)) + 1024u)), 11u);
+ v_intermediate[63u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd0 - v_ck1)) + 1024u)), 11u);
+ v_intermediate[15u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 + v_ck3)) + 1024u)), 11u);
+ v_intermediate[55u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd1 - v_ck3)) + 1024u)), 11u);
+ v_intermediate[23u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 + v_ck5)) + 1024u)), 11u);
+ v_intermediate[47u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd2 - v_ck5)) + 1024u)), 11u);
+ v_intermediate[31u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 + v_ck7)) + 1024u)), 11u);
+ v_intermediate[39u] = wuffs_base__utility__sign_extend_rshift_u32(((uint32_t)(((uint32_t)(v_cd3 - v_ck7)) + 1024u)), 11u);
+ }
+ if (0u == (v_intermediate[1u] |
+ v_intermediate[2u] |
+ v_intermediate[3u] |
+ v_intermediate[4u] |
+ v_intermediate[5u] |
+ v_intermediate[6u] |
+ v_intermediate[7u])) {
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[0u] + 16u)) >> 5u) & 1023u)];
+ a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ } else {
+ v_in2 = v_intermediate[2u];
+ v_in6 = v_intermediate[6u];
+ v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
+ v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
+ v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
+ v_in0 = v_intermediate[0u];
+ v_in4 = v_intermediate[4u];
+ v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
+ v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
+ v_rd0 = ((uint32_t)(v_rcp + v_rb2));
+ v_rd1 = ((uint32_t)(v_rcm + v_rb6));
+ v_rd2 = ((uint32_t)(v_rcm - v_rb6));
+ v_rd3 = ((uint32_t)(v_rcp - v_rb2));
+ v_in1 = v_intermediate[1u];
+ v_in3 = v_intermediate[3u];
+ v_in5 = v_intermediate[5u];
+ v_in7 = v_intermediate[7u];
+ v_ri51 = ((uint32_t)(v_in5 + v_in1));
+ v_ri53 = ((uint32_t)(v_in5 + v_in3));
+ v_ri71 = ((uint32_t)(v_in7 + v_in1));
+ v_ri73 = ((uint32_t)(v_in7 + v_in3));
+ v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
+ v_rk1 = ((uint32_t)(v_in1 * 12299u));
+ v_rk3 = ((uint32_t)(v_in3 * 25172u));
+ v_rk5 = ((uint32_t)(v_in5 * 16819u));
+ v_rk7 = ((uint32_t)(v_in7 * 2446u));
+ v_ri51 *= 4294964100u;
+ v_ri53 *= 4294946301u;
+ v_ri71 *= 4294959923u;
+ v_ri73 *= 4294951227u;
+ v_rl51 = ((uint32_t)(v_ri51 + v_rj));
+ v_rl73 = ((uint32_t)(v_ri73 + v_rj));
+ v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
+ v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
+ v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
+ v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ }
+ if (0u == (v_intermediate[9u] |
+ v_intermediate[10u] |
+ v_intermediate[11u] |
+ v_intermediate[12u] |
+ v_intermediate[13u] |
+ v_intermediate[14u] |
+ v_intermediate[15u])) {
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[8u] + 16u)) >> 5u) & 1023u)];
+ a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ } else {
+ v_in2 = v_intermediate[10u];
+ v_in6 = v_intermediate[14u];
+ v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
+ v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
+ v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
+ v_in0 = v_intermediate[8u];
+ v_in4 = v_intermediate[12u];
+ v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
+ v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
+ v_rd0 = ((uint32_t)(v_rcp + v_rb2));
+ v_rd1 = ((uint32_t)(v_rcm + v_rb6));
+ v_rd2 = ((uint32_t)(v_rcm - v_rb6));
+ v_rd3 = ((uint32_t)(v_rcp - v_rb2));
+ v_in1 = v_intermediate[9u];
+ v_in3 = v_intermediate[11u];
+ v_in5 = v_intermediate[13u];
+ v_in7 = v_intermediate[15u];
+ v_ri51 = ((uint32_t)(v_in5 + v_in1));
+ v_ri53 = ((uint32_t)(v_in5 + v_in3));
+ v_ri71 = ((uint32_t)(v_in7 + v_in1));
+ v_ri73 = ((uint32_t)(v_in7 + v_in3));
+ v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
+ v_rk1 = ((uint32_t)(v_in1 * 12299u));
+ v_rk3 = ((uint32_t)(v_in3 * 25172u));
+ v_rk5 = ((uint32_t)(v_in5 * 16819u));
+ v_rk7 = ((uint32_t)(v_in7 * 2446u));
+ v_ri51 *= 4294964100u;
+ v_ri53 *= 4294946301u;
+ v_ri71 *= 4294959923u;
+ v_ri73 *= 4294951227u;
+ v_rl51 = ((uint32_t)(v_ri51 + v_rj));
+ v_rl73 = ((uint32_t)(v_ri73 + v_rj));
+ v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
+ v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
+ v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
+ v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ }
+ if (0u == (v_intermediate[17u] |
+ v_intermediate[18u] |
+ v_intermediate[19u] |
+ v_intermediate[20u] |
+ v_intermediate[21u] |
+ v_intermediate[22u] |
+ v_intermediate[23u])) {
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[16u] + 16u)) >> 5u) & 1023u)];
+ a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ } else {
+ v_in2 = v_intermediate[18u];
+ v_in6 = v_intermediate[22u];
+ v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
+ v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
+ v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
+ v_in0 = v_intermediate[16u];
+ v_in4 = v_intermediate[20u];
+ v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
+ v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
+ v_rd0 = ((uint32_t)(v_rcp + v_rb2));
+ v_rd1 = ((uint32_t)(v_rcm + v_rb6));
+ v_rd2 = ((uint32_t)(v_rcm - v_rb6));
+ v_rd3 = ((uint32_t)(v_rcp - v_rb2));
+ v_in1 = v_intermediate[17u];
+ v_in3 = v_intermediate[19u];
+ v_in5 = v_intermediate[21u];
+ v_in7 = v_intermediate[23u];
+ v_ri51 = ((uint32_t)(v_in5 + v_in1));
+ v_ri53 = ((uint32_t)(v_in5 + v_in3));
+ v_ri71 = ((uint32_t)(v_in7 + v_in1));
+ v_ri73 = ((uint32_t)(v_in7 + v_in3));
+ v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
+ v_rk1 = ((uint32_t)(v_in1 * 12299u));
+ v_rk3 = ((uint32_t)(v_in3 * 25172u));
+ v_rk5 = ((uint32_t)(v_in5 * 16819u));
+ v_rk7 = ((uint32_t)(v_in7 * 2446u));
+ v_ri51 *= 4294964100u;
+ v_ri53 *= 4294946301u;
+ v_ri71 *= 4294959923u;
+ v_ri73 *= 4294951227u;
+ v_rl51 = ((uint32_t)(v_ri51 + v_rj));
+ v_rl73 = ((uint32_t)(v_ri73 + v_rj));
+ v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
+ v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
+ v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
+ v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ }
+ if (0u == (v_intermediate[25u] |
+ v_intermediate[26u] |
+ v_intermediate[27u] |
+ v_intermediate[28u] |
+ v_intermediate[29u] |
+ v_intermediate[30u] |
+ v_intermediate[31u])) {
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[24u] + 16u)) >> 5u) & 1023u)];
+ a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ } else {
+ v_in2 = v_intermediate[26u];
+ v_in6 = v_intermediate[30u];
+ v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
+ v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
+ v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
+ v_in0 = v_intermediate[24u];
+ v_in4 = v_intermediate[28u];
+ v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
+ v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
+ v_rd0 = ((uint32_t)(v_rcp + v_rb2));
+ v_rd1 = ((uint32_t)(v_rcm + v_rb6));
+ v_rd2 = ((uint32_t)(v_rcm - v_rb6));
+ v_rd3 = ((uint32_t)(v_rcp - v_rb2));
+ v_in1 = v_intermediate[25u];
+ v_in3 = v_intermediate[27u];
+ v_in5 = v_intermediate[29u];
+ v_in7 = v_intermediate[31u];
+ v_ri51 = ((uint32_t)(v_in5 + v_in1));
+ v_ri53 = ((uint32_t)(v_in5 + v_in3));
+ v_ri71 = ((uint32_t)(v_in7 + v_in1));
+ v_ri73 = ((uint32_t)(v_in7 + v_in3));
+ v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
+ v_rk1 = ((uint32_t)(v_in1 * 12299u));
+ v_rk3 = ((uint32_t)(v_in3 * 25172u));
+ v_rk5 = ((uint32_t)(v_in5 * 16819u));
+ v_rk7 = ((uint32_t)(v_in7 * 2446u));
+ v_ri51 *= 4294964100u;
+ v_ri53 *= 4294946301u;
+ v_ri71 *= 4294959923u;
+ v_ri73 *= 4294951227u;
+ v_rl51 = ((uint32_t)(v_ri51 + v_rj));
+ v_rl73 = ((uint32_t)(v_ri73 + v_rj));
+ v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
+ v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
+ v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
+ v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ }
+ if (0u == (v_intermediate[33u] |
+ v_intermediate[34u] |
+ v_intermediate[35u] |
+ v_intermediate[36u] |
+ v_intermediate[37u] |
+ v_intermediate[38u] |
+ v_intermediate[39u])) {
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[32u] + 16u)) >> 5u) & 1023u)];
+ a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ } else {
+ v_in2 = v_intermediate[34u];
+ v_in6 = v_intermediate[38u];
+ v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
+ v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
+ v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
+ v_in0 = v_intermediate[32u];
+ v_in4 = v_intermediate[36u];
+ v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
+ v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
+ v_rd0 = ((uint32_t)(v_rcp + v_rb2));
+ v_rd1 = ((uint32_t)(v_rcm + v_rb6));
+ v_rd2 = ((uint32_t)(v_rcm - v_rb6));
+ v_rd3 = ((uint32_t)(v_rcp - v_rb2));
+ v_in1 = v_intermediate[33u];
+ v_in3 = v_intermediate[35u];
+ v_in5 = v_intermediate[37u];
+ v_in7 = v_intermediate[39u];
+ v_ri51 = ((uint32_t)(v_in5 + v_in1));
+ v_ri53 = ((uint32_t)(v_in5 + v_in3));
+ v_ri71 = ((uint32_t)(v_in7 + v_in1));
+ v_ri73 = ((uint32_t)(v_in7 + v_in3));
+ v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
+ v_rk1 = ((uint32_t)(v_in1 * 12299u));
+ v_rk3 = ((uint32_t)(v_in3 * 25172u));
+ v_rk5 = ((uint32_t)(v_in5 * 16819u));
+ v_rk7 = ((uint32_t)(v_in7 * 2446u));
+ v_ri51 *= 4294964100u;
+ v_ri53 *= 4294946301u;
+ v_ri71 *= 4294959923u;
+ v_ri73 *= 4294951227u;
+ v_rl51 = ((uint32_t)(v_ri51 + v_rj));
+ v_rl73 = ((uint32_t)(v_ri73 + v_rj));
+ v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
+ v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
+ v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
+ v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ }
+ if (0u == (v_intermediate[41u] |
+ v_intermediate[42u] |
+ v_intermediate[43u] |
+ v_intermediate[44u] |
+ v_intermediate[45u] |
+ v_intermediate[46u] |
+ v_intermediate[47u])) {
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[40u] + 16u)) >> 5u) & 1023u)];
+ a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ } else {
+ v_in2 = v_intermediate[42u];
+ v_in6 = v_intermediate[46u];
+ v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
+ v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
+ v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
+ v_in0 = v_intermediate[40u];
+ v_in4 = v_intermediate[44u];
+ v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
+ v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
+ v_rd0 = ((uint32_t)(v_rcp + v_rb2));
+ v_rd1 = ((uint32_t)(v_rcm + v_rb6));
+ v_rd2 = ((uint32_t)(v_rcm - v_rb6));
+ v_rd3 = ((uint32_t)(v_rcp - v_rb2));
+ v_in1 = v_intermediate[41u];
+ v_in3 = v_intermediate[43u];
+ v_in5 = v_intermediate[45u];
+ v_in7 = v_intermediate[47u];
+ v_ri51 = ((uint32_t)(v_in5 + v_in1));
+ v_ri53 = ((uint32_t)(v_in5 + v_in3));
+ v_ri71 = ((uint32_t)(v_in7 + v_in1));
+ v_ri73 = ((uint32_t)(v_in7 + v_in3));
+ v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
+ v_rk1 = ((uint32_t)(v_in1 * 12299u));
+ v_rk3 = ((uint32_t)(v_in3 * 25172u));
+ v_rk5 = ((uint32_t)(v_in5 * 16819u));
+ v_rk7 = ((uint32_t)(v_in7 * 2446u));
+ v_ri51 *= 4294964100u;
+ v_ri53 *= 4294946301u;
+ v_ri71 *= 4294959923u;
+ v_ri73 *= 4294951227u;
+ v_rl51 = ((uint32_t)(v_ri51 + v_rj));
+ v_rl73 = ((uint32_t)(v_ri73 + v_rj));
+ v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
+ v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
+ v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
+ v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ }
+ if (0u == (v_intermediate[49u] |
+ v_intermediate[50u] |
+ v_intermediate[51u] |
+ v_intermediate[52u] |
+ v_intermediate[53u] |
+ v_intermediate[54u] |
+ v_intermediate[55u])) {
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[48u] + 16u)) >> 5u) & 1023u)];
+ a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ } else {
+ v_in2 = v_intermediate[50u];
+ v_in6 = v_intermediate[54u];
+ v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
+ v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
+ v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
+ v_in0 = v_intermediate[48u];
+ v_in4 = v_intermediate[52u];
+ v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
+ v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
+ v_rd0 = ((uint32_t)(v_rcp + v_rb2));
+ v_rd1 = ((uint32_t)(v_rcm + v_rb6));
+ v_rd2 = ((uint32_t)(v_rcm - v_rb6));
+ v_rd3 = ((uint32_t)(v_rcp - v_rb2));
+ v_in1 = v_intermediate[49u];
+ v_in3 = v_intermediate[51u];
+ v_in5 = v_intermediate[53u];
+ v_in7 = v_intermediate[55u];
+ v_ri51 = ((uint32_t)(v_in5 + v_in1));
+ v_ri53 = ((uint32_t)(v_in5 + v_in3));
+ v_ri71 = ((uint32_t)(v_in7 + v_in1));
+ v_ri73 = ((uint32_t)(v_in7 + v_in3));
+ v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
+ v_rk1 = ((uint32_t)(v_in1 * 12299u));
+ v_rk3 = ((uint32_t)(v_in3 * 25172u));
+ v_rk5 = ((uint32_t)(v_in5 * 16819u));
+ v_rk7 = ((uint32_t)(v_in7 * 2446u));
+ v_ri51 *= 4294964100u;
+ v_ri53 *= 4294946301u;
+ v_ri71 *= 4294959923u;
+ v_ri73 *= 4294951227u;
+ v_rl51 = ((uint32_t)(v_ri51 + v_rj));
+ v_rl73 = ((uint32_t)(v_ri73 + v_rj));
+ v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
+ v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
+ v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
+ v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ }
+ if (0u == (v_intermediate[57u] |
+ v_intermediate[58u] |
+ v_intermediate[59u] |
+ v_intermediate[60u] |
+ v_intermediate[61u] |
+ v_intermediate[62u] |
+ v_intermediate[63u])) {
+ if (8u > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(v_intermediate[56u] + 16u)) >> 5u) & 1023u)];
+ a_dst_buffer.ptr[1u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[2u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[3u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[4u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[5u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[6u] = a_dst_buffer.ptr[0u];
+ a_dst_buffer.ptr[7u] = a_dst_buffer.ptr[0u];
+ } else {
+ v_in2 = v_intermediate[58u];
+ v_in6 = v_intermediate[62u];
+ v_ra = ((uint32_t)(((uint32_t)(v_in2 + v_in6)) * 4433u));
+ v_rb2 = ((uint32_t)(v_ra + ((uint32_t)(v_in2 * 6270u))));
+ v_rb6 = ((uint32_t)(v_ra - ((uint32_t)(v_in6 * 15137u))));
+ v_in0 = v_intermediate[56u];
+ v_in4 = v_intermediate[60u];
+ v_rcp = ((uint32_t)(((uint32_t)(v_in0 + v_in4)) << 13u));
+ v_rcm = ((uint32_t)(((uint32_t)(v_in0 - v_in4)) << 13u));
+ v_rd0 = ((uint32_t)(v_rcp + v_rb2));
+ v_rd1 = ((uint32_t)(v_rcm + v_rb6));
+ v_rd2 = ((uint32_t)(v_rcm - v_rb6));
+ v_rd3 = ((uint32_t)(v_rcp - v_rb2));
+ v_in1 = v_intermediate[57u];
+ v_in3 = v_intermediate[59u];
+ v_in5 = v_intermediate[61u];
+ v_in7 = v_intermediate[63u];
+ v_ri51 = ((uint32_t)(v_in5 + v_in1));
+ v_ri53 = ((uint32_t)(v_in5 + v_in3));
+ v_ri71 = ((uint32_t)(v_in7 + v_in1));
+ v_ri73 = ((uint32_t)(v_in7 + v_in3));
+ v_rj = ((uint32_t)(((uint32_t)(v_ri73 + v_ri51)) * 9633u));
+ v_rk1 = ((uint32_t)(v_in1 * 12299u));
+ v_rk3 = ((uint32_t)(v_in3 * 25172u));
+ v_rk5 = ((uint32_t)(v_in5 * 16819u));
+ v_rk7 = ((uint32_t)(v_in7 * 2446u));
+ v_ri51 *= 4294964100u;
+ v_ri53 *= 4294946301u;
+ v_ri71 *= 4294959923u;
+ v_ri73 *= 4294951227u;
+ v_rl51 = ((uint32_t)(v_ri51 + v_rj));
+ v_rl73 = ((uint32_t)(v_ri73 + v_rj));
+ v_rk1 += ((uint32_t)(v_ri71 + v_rl51));
+ v_rk3 += ((uint32_t)(v_ri53 + v_rl73));
+ v_rk5 += ((uint32_t)(v_ri53 + v_rl51));
+ v_rk7 += ((uint32_t)(v_ri71 + v_rl73));
+ if (8u > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ a_dst_buffer.ptr[0u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 + v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[7u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd0 - v_rk1)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[1u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 + v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[6u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd1 - v_rk3)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[2u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 + v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[5u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd2 - v_rk5)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[3u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 + v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ a_dst_buffer.ptr[4u] = WUFFS_JPEG__BIAS_AND_CLAMP[((((uint32_t)(((uint32_t)(v_rd3 - v_rk7)) + 131072u)) >> 18u) & 1023u)];
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_avx2
+// -------- func jpeg.decoder.decode_idct_x86_avx2
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2,avx2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__decode_idct_x86_avx2(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_dst_buffer,
+ uint64_t a_dst_stride,
+ uint32_t a_q) {
+ __m256i v_k_0000 = {0};
+ __m256i v_k_8080 = {0};
+ __m256i v_k_0000_0002 = {0};
+ __m256i v_k_0001_FFFF = {0};
+ __m256i v_k_0400_0000 = {0};
+ __m256i v_k_29CF_1151_D630_1151 = {0};
+ __m256i v_k_E333_133E_ADFD_1051 = {0};
+ __m256i v_k_E6DC_25A1_1925_25A1 = {0};
+ __m256i v_k_ECC1_E333_EFB0_ADFD = {0};
+ __m128i v_az_coeffs = {0};
+ __m256i v_az_ah00 = {0};
+ __m256i v_az_ad00 = {0};
+ __m256i v_az_eh00 = {0};
+ __m256i v_az_adeh = {0};
+ __m256i v_rows01 = {0};
+ __m256i v_rows23 = {0};
+ __m256i v_rows45 = {0};
+ __m256i v_rows67 = {0};
+ __m256i v_quants01 = {0};
+ __m256i v_quants23 = {0};
+ __m256i v_quants45 = {0};
+ __m256i v_quants67 = {0};
+ __m256i v_rows04 = {0};
+ __m256i v_rows31 = {0};
+ __m256i v_rows26 = {0};
+ __m256i v_rows75 = {0};
+ __m256i v_fp_rows62 = {0};
+ __m256i v_fp_bq2662ad = {0};
+ __m256i v_fp_bq2662eh = {0};
+ __m256i v_fp_cb26ad = {0};
+ __m256i v_fp_cb26eh = {0};
+ __m256i v_fp_rows40pos = {0};
+ __m256i v_fp_rows04neg = {0};
+ __m256i v_fp_rows0pm4 = {0};
+ __m256i v_fp_ccpmad = {0};
+ __m256i v_fp_ccpmeh = {0};
+ __m256i v_fp_cd01ad = {0};
+ __m256i v_fp_cd01eh = {0};
+ __m256i v_fp_cd32ad = {0};
+ __m256i v_fp_cd32eh = {0};
+ __m256i v_fp_sums7351 = {0};
+ __m256i v_fp_sums5173 = {0};
+ __m256i v_fp_ci73515173ad = {0};
+ __m256i v_fp_ci73515173eh = {0};
+ __m256i v_fp_cl7351ad = {0};
+ __m256i v_fp_cl7351eh = {0};
+ __m256i v_fp_rows13 = {0};
+ __m256i v_fp_bq7153ad = {0};
+ __m256i v_fp_bq7153eh = {0};
+ __m256i v_fp_ck75ad = {0};
+ __m256i v_fp_ck75eh = {0};
+ __m256i v_fp_cl5173ad = {0};
+ __m256i v_fp_cl5173eh = {0};
+ __m256i v_fp_ck13ad = {0};
+ __m256i v_fp_ck13eh = {0};
+ __m256i v_intermediate01ad = {0};
+ __m256i v_intermediate01eh = {0};
+ __m256i v_intermediate01 = {0};
+ __m256i v_intermediate32ad = {0};
+ __m256i v_intermediate32eh = {0};
+ __m256i v_intermediate32 = {0};
+ __m256i v_intermediate45ad = {0};
+ __m256i v_intermediate45eh = {0};
+ __m256i v_intermediate45 = {0};
+ __m256i v_intermediate76ad = {0};
+ __m256i v_intermediate76eh = {0};
+ __m256i v_intermediate76 = {0};
+ __m256i v_ita0a1e0e1 = {0};
+ __m256i v_ita2a3e2e3 = {0};
+ __m256i v_ita4a5e4e5 = {0};
+ __m256i v_ita6a7e6e7 = {0};
+ __m256i v_ita0c0e0g0 = {0};
+ __m256i v_ita1c1e1g1 = {0};
+ __m256i v_ita4c4e4g4 = {0};
+ __m256i v_ita5c5e5g5 = {0};
+ __m256i v_ita0b0e0f0 = {0};
+ __m256i v_ita4b4e4f4 = {0};
+ __m256i v_itc0d0g0h0 = {0};
+ __m256i v_itc4d4g4h4 = {0};
+ __m256i v_intermediateae = {0};
+ __m256i v_intermediatebf = {0};
+ __m256i v_intermediatecg = {0};
+ __m256i v_intermediatedh = {0};
+ __m256i v_intermediatedb = {0};
+ __m256i v_intermediatehf = {0};
+ __m256i v_sp_cols62 = {0};
+ __m256i v_sp_bq2662ad = {0};
+ __m256i v_sp_bq2662eh = {0};
+ __m256i v_sp_rb26ad = {0};
+ __m256i v_sp_rb26eh = {0};
+ __m256i v_sp_cols40pos = {0};
+ __m256i v_sp_cols04neg = {0};
+ __m256i v_sp_cols0pm4 = {0};
+ __m256i v_sp_rcpmad = {0};
+ __m256i v_sp_rcpmeh = {0};
+ __m256i v_sp_rd01ad = {0};
+ __m256i v_sp_rd01eh = {0};
+ __m256i v_sp_rd32ad = {0};
+ __m256i v_sp_rd32eh = {0};
+ __m256i v_sp_sums7351 = {0};
+ __m256i v_sp_sums5173 = {0};
+ __m256i v_sp_ri73515173ad = {0};
+ __m256i v_sp_ri73515173eh = {0};
+ __m256i v_sp_rl7351ad = {0};
+ __m256i v_sp_rl7351eh = {0};
+ __m256i v_sp_cols13 = {0};
+ __m256i v_sp_bq7153ad = {0};
+ __m256i v_sp_bq7153eh = {0};
+ __m256i v_sp_rk75ad = {0};
+ __m256i v_sp_rk75eh = {0};
+ __m256i v_sp_rl5173ad = {0};
+ __m256i v_sp_rl5173eh = {0};
+ __m256i v_sp_rk13ad = {0};
+ __m256i v_sp_rk13eh = {0};
+ __m256i v_final01ad = {0};
+ __m256i v_final01eh = {0};
+ __m256i v_final01 = {0};
+ __m256i v_final32ad = {0};
+ __m256i v_final32eh = {0};
+ __m256i v_final32 = {0};
+ __m256i v_final45ad = {0};
+ __m256i v_final45eh = {0};
+ __m256i v_final45 = {0};
+ __m256i v_final76ad = {0};
+ __m256i v_final76eh = {0};
+ __m256i v_final76 = {0};
+ __m256i v_fta0a1e0e1 = {0};
+ __m256i v_fta2a3e2e3 = {0};
+ __m256i v_fta4a5e4e5 = {0};
+ __m256i v_fta6a7e6e7 = {0};
+ __m256i v_fta0c0e0g0 = {0};
+ __m256i v_fta1c1e1g1 = {0};
+ __m256i v_fta4c4e4g4 = {0};
+ __m256i v_fta5c5e5g5 = {0};
+ __m256i v_fta0b0e0f0 = {0};
+ __m256i v_ftc0d0g0h0 = {0};
+ __m256i v_fta4b4e4f4 = {0};
+ __m256i v_ftc4d4g4h4 = {0};
+ __m256i v_finalae = {0};
+ __m256i v_finalbf = {0};
+ __m256i v_finalcg = {0};
+ __m256i v_finaldh = {0};
+ __m256i v_final0145 = {0};
+ __m256i v_final2367 = {0};
+ uint64_t v_final0 = 0;
+ uint64_t v_final1 = 0;
+ uint64_t v_final2 = 0;
+ uint64_t v_final3 = 0;
+ uint64_t v_final4 = 0;
+ uint64_t v_final5 = 0;
+ uint64_t v_final6 = 0;
+ uint64_t v_final7 = 0;
+ wuffs_base__slice_u8 v_remaining = {0};
+
+ if (8u > a_dst_stride) {
+ return wuffs_base__make_empty_struct();
+ }
+ v_k_0000 = _mm256_set_epi16((int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u), (int16_t)(0u));
+ v_k_8080 = _mm256_set_epi16((int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u), (int16_t)(32896u));
+ v_k_0000_0002 = _mm256_set_epi16((int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u), (int16_t)(2u), (int16_t)(0u));
+ v_k_0001_FFFF = _mm256_set_epi16((int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(65535u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u), (int16_t)(1u));
+ v_k_0400_0000 = _mm256_set_epi16((int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u), (int16_t)(0u), (int16_t)(1024u));
+ v_k_29CF_1151_D630_1151 = _mm256_set_epi16((int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(54832u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u), (int16_t)(4433u), (int16_t)(10703u));
+ v_k_E333_133E_ADFD_1051 = _mm256_set_epi16((int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4177u), (int16_t)(44541u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u), (int16_t)(4926u), (int16_t)(58163u));
+ v_k_E6DC_25A1_1925_25A1 = _mm256_set_epi16((int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(6437u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u), (int16_t)(9633u), (int16_t)(59100u));
+ v_k_ECC1_E333_EFB0_ADFD = _mm256_set_epi16((int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(44541u), (int16_t)(61360u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u), (int16_t)(58163u), (int16_t)(60609u));
+ do {
+ if (0u == (wuffs_base__peek_u64le__no_bounds_check((const uint8_t*)(const void*)(self->private_data.f_mcu_blocks[0u] + 8u)) | wuffs_base__peek_u64le__no_bounds_check((const uint8_t*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u)))) {
+ v_az_coeffs = _mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_or_si128(_mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 8u)), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 24u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 32u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 40u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 48u))), _mm_lddqu_si128((const __m128i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 56u)));
+ if (0u == ((uint64_t)(_mm_cvtsi128_si64(_mm_packs_epi16(v_az_coeffs, v_az_coeffs))))) {
+ v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u));
+ v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u));
+ v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01);
+ v_az_ah00 = _mm256_slli_epi16(v_rows01, (int32_t)(2u));
+ v_az_ad00 = _mm256_unpacklo_epi16(v_az_ah00, v_az_ah00);
+ v_az_eh00 = _mm256_unpackhi_epi16(v_az_ah00, v_az_ah00);
+ v_az_adeh = _mm256_inserti128_si256(v_az_ad00, _mm256_castsi256_si128(v_az_eh00), (int32_t)(1u));
+ v_intermediateae = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(0u));
+ v_intermediatebf = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(85u));
+ v_intermediatecg = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(170u));
+ v_intermediatedh = _mm256_shuffle_epi32(v_az_adeh, (int32_t)(255u));
+ break;
+ }
+ }
+ v_rows01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 0u));
+ v_rows23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 16u));
+ v_rows45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 32u));
+ v_rows67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_data.f_mcu_blocks[0u] + 48u));
+ v_quants01 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 0u));
+ v_quants23 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 16u));
+ v_quants45 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 32u));
+ v_quants67 = _mm256_lddqu_si256((const __m256i*)(const void*)(self->private_impl.f_quant_tables[a_q] + 48u));
+ v_rows01 = _mm256_mullo_epi16(v_rows01, v_quants01);
+ v_rows23 = _mm256_mullo_epi16(v_rows23, v_quants23);
+ v_rows45 = _mm256_mullo_epi16(v_rows45, v_quants45);
+ v_rows67 = _mm256_mullo_epi16(v_rows67, v_quants67);
+ v_rows04 = _mm256_permute2x128_si256(v_rows01, v_rows45, (int32_t)(32u));
+ v_rows31 = _mm256_permute2x128_si256(v_rows23, v_rows01, (int32_t)(49u));
+ v_rows26 = _mm256_permute2x128_si256(v_rows23, v_rows67, (int32_t)(32u));
+ v_rows75 = _mm256_permute2x128_si256(v_rows67, v_rows45, (int32_t)(49u));
+ v_fp_rows62 = _mm256_permute2x128_si256(v_rows26, v_rows26, (int32_t)(1u));
+ v_fp_bq2662ad = _mm256_unpacklo_epi16(v_rows26, v_fp_rows62);
+ v_fp_bq2662eh = _mm256_unpackhi_epi16(v_rows26, v_fp_rows62);
+ v_fp_cb26ad = _mm256_madd_epi16(v_fp_bq2662ad, v_k_29CF_1151_D630_1151);
+ v_fp_cb26eh = _mm256_madd_epi16(v_fp_bq2662eh, v_k_29CF_1151_D630_1151);
+ v_fp_rows40pos = _mm256_permute2x128_si256(v_rows04, v_rows04, (int32_t)(1u));
+ v_fp_rows04neg = _mm256_sign_epi16(v_rows04, v_k_0001_FFFF);
+ v_fp_rows0pm4 = _mm256_add_epi16(v_fp_rows40pos, v_fp_rows04neg);
+ v_fp_ccpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u));
+ v_fp_ccpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_fp_rows0pm4), (int32_t)(3u));
+ v_fp_cd01ad = _mm256_add_epi32(v_fp_ccpmad, v_fp_cb26ad);
+ v_fp_cd01eh = _mm256_add_epi32(v_fp_ccpmeh, v_fp_cb26eh);
+ v_fp_cd32ad = _mm256_sub_epi32(v_fp_ccpmad, v_fp_cb26ad);
+ v_fp_cd32eh = _mm256_sub_epi32(v_fp_ccpmeh, v_fp_cb26eh);
+ v_fp_sums7351 = _mm256_add_epi16(v_rows75, v_rows31);
+ v_fp_sums5173 = _mm256_permute2x128_si256(v_fp_sums7351, v_fp_sums7351, (int32_t)(1u));
+ v_fp_ci73515173ad = _mm256_unpacklo_epi16(v_fp_sums7351, v_fp_sums5173);
+ v_fp_ci73515173eh = _mm256_unpackhi_epi16(v_fp_sums7351, v_fp_sums5173);
+ v_fp_cl7351ad = _mm256_madd_epi16(v_fp_ci73515173ad, v_k_E6DC_25A1_1925_25A1);
+ v_fp_cl7351eh = _mm256_madd_epi16(v_fp_ci73515173eh, v_k_E6DC_25A1_1925_25A1);
+ v_fp_rows13 = _mm256_permute2x128_si256(v_rows31, v_rows31, (int32_t)(1u));
+ v_fp_bq7153ad = _mm256_unpacklo_epi16(v_rows75, v_fp_rows13);
+ v_fp_bq7153eh = _mm256_unpackhi_epi16(v_rows75, v_fp_rows13);
+ v_fp_ck75ad = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351ad);
+ v_fp_ck75eh = _mm256_add_epi32(_mm256_madd_epi16(v_fp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_fp_cl7351eh);
+ v_fp_cl5173ad = _mm256_permute2x128_si256(v_fp_cl7351ad, v_fp_cl7351ad, (int32_t)(1u));
+ v_fp_cl5173eh = _mm256_permute2x128_si256(v_fp_cl7351eh, v_fp_cl7351eh, (int32_t)(1u));
+ v_fp_ck13ad = _mm256_add_epi32(v_fp_cl5173ad, _mm256_madd_epi16(v_fp_bq7153ad, v_k_E333_133E_ADFD_1051));
+ v_fp_ck13eh = _mm256_add_epi32(v_fp_cl5173eh, _mm256_madd_epi16(v_fp_bq7153eh, v_k_E333_133E_ADFD_1051));
+ v_intermediate01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u));
+ v_intermediate01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u));
+ v_intermediate01 = _mm256_packs_epi32(v_intermediate01ad, v_intermediate01eh);
+ v_intermediate32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u));
+ v_intermediate32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u));
+ v_intermediate32 = _mm256_packs_epi32(v_intermediate32ad, v_intermediate32eh);
+ v_intermediate45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32ad, v_fp_ck75ad), v_k_0400_0000), (int32_t)(11u));
+ v_intermediate45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd32eh, v_fp_ck75eh), v_k_0400_0000), (int32_t)(11u));
+ v_intermediate45 = _mm256_packs_epi32(v_intermediate45ad, v_intermediate45eh);
+ v_intermediate76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01ad, v_fp_ck13ad), v_k_0400_0000), (int32_t)(11u));
+ v_intermediate76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_fp_cd01eh, v_fp_ck13eh), v_k_0400_0000), (int32_t)(11u));
+ v_intermediate76 = _mm256_packs_epi32(v_intermediate76ad, v_intermediate76eh);
+ v_ita0a1e0e1 = _mm256_permute4x64_epi64(v_intermediate01, (int32_t)(216u));
+ v_ita2a3e2e3 = _mm256_permute4x64_epi64(v_intermediate32, (int32_t)(114u));
+ v_ita4a5e4e5 = _mm256_permute4x64_epi64(v_intermediate45, (int32_t)(216u));
+ v_ita6a7e6e7 = _mm256_permute4x64_epi64(v_intermediate76, (int32_t)(114u));
+ v_ita0c0e0g0 = _mm256_unpacklo_epi16(v_ita0a1e0e1, v_ita2a3e2e3);
+ v_ita1c1e1g1 = _mm256_unpackhi_epi16(v_ita0a1e0e1, v_ita2a3e2e3);
+ v_ita4c4e4g4 = _mm256_unpacklo_epi16(v_ita4a5e4e5, v_ita6a7e6e7);
+ v_ita5c5e5g5 = _mm256_unpackhi_epi16(v_ita4a5e4e5, v_ita6a7e6e7);
+ v_ita0b0e0f0 = _mm256_unpacklo_epi16(v_ita0c0e0g0, v_ita1c1e1g1);
+ v_itc0d0g0h0 = _mm256_unpackhi_epi16(v_ita0c0e0g0, v_ita1c1e1g1);
+ v_ita4b4e4f4 = _mm256_unpacklo_epi16(v_ita4c4e4g4, v_ita5c5e5g5);
+ v_itc4d4g4h4 = _mm256_unpackhi_epi16(v_ita4c4e4g4, v_ita5c5e5g5);
+ v_intermediateae = _mm256_unpacklo_epi64(v_ita0b0e0f0, v_ita4b4e4f4);
+ v_intermediatebf = _mm256_unpackhi_epi64(v_ita0b0e0f0, v_ita4b4e4f4);
+ v_intermediatecg = _mm256_unpacklo_epi64(v_itc0d0g0h0, v_itc4d4g4h4);
+ v_intermediatedh = _mm256_unpackhi_epi64(v_itc0d0g0h0, v_itc4d4g4h4);
+ } while (0);
+ v_intermediatedb = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(32u));
+ v_intermediatehf = _mm256_permute2x128_si256(v_intermediatedh, v_intermediatebf, (int32_t)(49u));
+ v_sp_cols62 = _mm256_permute2x128_si256(v_intermediatecg, v_intermediatecg, (int32_t)(1u));
+ v_sp_bq2662ad = _mm256_unpacklo_epi16(v_intermediatecg, v_sp_cols62);
+ v_sp_bq2662eh = _mm256_unpackhi_epi16(v_intermediatecg, v_sp_cols62);
+ v_sp_rb26ad = _mm256_madd_epi16(v_sp_bq2662ad, v_k_29CF_1151_D630_1151);
+ v_sp_rb26eh = _mm256_madd_epi16(v_sp_bq2662eh, v_k_29CF_1151_D630_1151);
+ v_sp_cols40pos = _mm256_permute2x128_si256(v_intermediateae, v_intermediateae, (int32_t)(1u));
+ v_sp_cols04neg = _mm256_sign_epi16(v_intermediateae, v_k_0001_FFFF);
+ v_sp_cols0pm4 = _mm256_add_epi16(v_sp_cols40pos, v_sp_cols04neg);
+ v_sp_rcpmad = _mm256_srai_epi32(_mm256_unpacklo_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u));
+ v_sp_rcpmeh = _mm256_srai_epi32(_mm256_unpackhi_epi16(v_k_0000, v_sp_cols0pm4), (int32_t)(3u));
+ v_sp_rd01ad = _mm256_add_epi32(v_sp_rcpmad, v_sp_rb26ad);
+ v_sp_rd01eh = _mm256_add_epi32(v_sp_rcpmeh, v_sp_rb26eh);
+ v_sp_rd32ad = _mm256_sub_epi32(v_sp_rcpmad, v_sp_rb26ad);
+ v_sp_rd32eh = _mm256_sub_epi32(v_sp_rcpmeh, v_sp_rb26eh);
+ v_sp_sums7351 = _mm256_add_epi16(v_intermediatehf, v_intermediatedb);
+ v_sp_sums5173 = _mm256_permute2x128_si256(v_sp_sums7351, v_sp_sums7351, (int32_t)(1u));
+ v_sp_ri73515173ad = _mm256_unpacklo_epi16(v_sp_sums7351, v_sp_sums5173);
+ v_sp_ri73515173eh = _mm256_unpackhi_epi16(v_sp_sums7351, v_sp_sums5173);
+ v_sp_rl7351ad = _mm256_madd_epi16(v_sp_ri73515173ad, v_k_E6DC_25A1_1925_25A1);
+ v_sp_rl7351eh = _mm256_madd_epi16(v_sp_ri73515173eh, v_k_E6DC_25A1_1925_25A1);
+ v_sp_cols13 = _mm256_permute2x128_si256(v_intermediatedb, v_intermediatedb, (int32_t)(1u));
+ v_sp_bq7153ad = _mm256_unpacklo_epi16(v_intermediatehf, v_sp_cols13);
+ v_sp_bq7153eh = _mm256_unpackhi_epi16(v_intermediatehf, v_sp_cols13);
+ v_sp_rk75ad = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153ad, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351ad);
+ v_sp_rk75eh = _mm256_add_epi32(_mm256_madd_epi16(v_sp_bq7153eh, v_k_ECC1_E333_EFB0_ADFD), v_sp_rl7351eh);
+ v_sp_rl5173ad = _mm256_permute2x128_si256(v_sp_rl7351ad, v_sp_rl7351ad, (int32_t)(1u));
+ v_sp_rl5173eh = _mm256_permute2x128_si256(v_sp_rl7351eh, v_sp_rl7351eh, (int32_t)(1u));
+ v_sp_rk13ad = _mm256_add_epi32(v_sp_rl5173ad, _mm256_madd_epi16(v_sp_bq7153ad, v_k_E333_133E_ADFD_1051));
+ v_sp_rk13eh = _mm256_add_epi32(v_sp_rl5173eh, _mm256_madd_epi16(v_sp_bq7153eh, v_k_E333_133E_ADFD_1051));
+ v_final01ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u));
+ v_final01eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u));
+ v_final01 = _mm256_packs_epi32(v_final01ad, v_final01eh);
+ v_final32ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u));
+ v_final32eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_add_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u));
+ v_final32 = _mm256_packs_epi32(v_final32ad, v_final32eh);
+ v_final45ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32ad, v_sp_rk75ad), v_k_0000_0002), (int32_t)(18u));
+ v_final45eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd32eh, v_sp_rk75eh), v_k_0000_0002), (int32_t)(18u));
+ v_final45 = _mm256_packs_epi32(v_final45ad, v_final45eh);
+ v_final76ad = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01ad, v_sp_rk13ad), v_k_0000_0002), (int32_t)(18u));
+ v_final76eh = _mm256_srai_epi32(_mm256_add_epi32(_mm256_sub_epi32(v_sp_rd01eh, v_sp_rk13eh), v_k_0000_0002), (int32_t)(18u));
+ v_final76 = _mm256_packs_epi32(v_final76ad, v_final76eh);
+ v_fta0a1e0e1 = _mm256_permute4x64_epi64(v_final01, (int32_t)(216u));
+ v_fta2a3e2e3 = _mm256_permute4x64_epi64(v_final32, (int32_t)(114u));
+ v_fta4a5e4e5 = _mm256_permute4x64_epi64(v_final45, (int32_t)(216u));
+ v_fta6a7e6e7 = _mm256_permute4x64_epi64(v_final76, (int32_t)(114u));
+ v_fta0c0e0g0 = _mm256_unpacklo_epi16(v_fta0a1e0e1, v_fta2a3e2e3);
+ v_fta1c1e1g1 = _mm256_unpackhi_epi16(v_fta0a1e0e1, v_fta2a3e2e3);
+ v_fta4c4e4g4 = _mm256_unpacklo_epi16(v_fta4a5e4e5, v_fta6a7e6e7);
+ v_fta5c5e5g5 = _mm256_unpackhi_epi16(v_fta4a5e4e5, v_fta6a7e6e7);
+ v_fta0b0e0f0 = _mm256_unpacklo_epi16(v_fta0c0e0g0, v_fta1c1e1g1);
+ v_ftc0d0g0h0 = _mm256_unpackhi_epi16(v_fta0c0e0g0, v_fta1c1e1g1);
+ v_fta4b4e4f4 = _mm256_unpacklo_epi16(v_fta4c4e4g4, v_fta5c5e5g5);
+ v_ftc4d4g4h4 = _mm256_unpackhi_epi16(v_fta4c4e4g4, v_fta5c5e5g5);
+ v_finalae = _mm256_unpacklo_epi64(v_fta0b0e0f0, v_fta4b4e4f4);
+ v_finalbf = _mm256_unpackhi_epi64(v_fta0b0e0f0, v_fta4b4e4f4);
+ v_finalcg = _mm256_unpacklo_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4);
+ v_finaldh = _mm256_unpackhi_epi64(v_ftc0d0g0h0, v_ftc4d4g4h4);
+ v_final0145 = _mm256_add_epi8(_mm256_packs_epi16(v_finalae, v_finalbf), v_k_8080);
+ v_final2367 = _mm256_add_epi8(_mm256_packs_epi16(v_finalcg, v_finaldh), v_k_8080);
+ v_final0 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(0u))));
+ v_final1 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(1u))));
+ v_final2 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(0u))));
+ v_final3 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(1u))));
+ v_final4 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(2u))));
+ v_final5 = ((uint64_t)(_mm256_extract_epi64(v_final0145, (int32_t)(3u))));
+ v_final6 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(2u))));
+ v_final7 = ((uint64_t)(_mm256_extract_epi64(v_final2367, (int32_t)(3u))));
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final0);
+ a_dst_buffer = v_remaining;
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final1);
+ a_dst_buffer = v_remaining;
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final2);
+ a_dst_buffer = v_remaining;
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final3);
+ a_dst_buffer = v_remaining;
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final4);
+ a_dst_buffer = v_remaining;
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final5);
+ a_dst_buffer = v_remaining;
+ if (a_dst_stride > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_dst_buffer, a_dst_stride);
+ wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final6);
+ a_dst_buffer = v_remaining;
+ if (8u > ((uint64_t)(a_dst_buffer.len))) {
+ return wuffs_base__make_empty_struct();
+ }
+ wuffs_base__poke_u64le__no_bounds_check(a_dst_buffer.ptr, v_final7);
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_64)
+// ‼ WUFFS MULTI-FILE SECTION -x86_avx2
+
+// -------- func jpeg.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_jpeg__decoder__get_quirk(
+ const wuffs_jpeg__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func jpeg.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__set_quirk(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func jpeg.decoder.decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__decode_image_config(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_image_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func jpeg.decoder.do_decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__do_decode_image_config(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint8_t v_marker = 0;
+ uint32_t v_pixfmt = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
+ if (coro_susp_point) {
+ v_marker = self->private_data.s_do_decode_image_config[0].v_marker;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c != 255u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ if (v_c != 216u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_header);
+ goto exit;
+ }
+ while (true) {
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_c = t_2;
+ }
+ if (v_c == 255u) {
+ break;
+ }
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_c = t_3;
+ }
+ if (v_c != 255u) {
+ v_marker = v_c;
+ break;
+ }
+ }
+ if (v_marker == 0u) {
+ continue;
+ } else if ((208u <= v_marker) && (v_marker <= 217u)) {
+ if (v_marker <= 215u) {
+ continue;
+ }
+ } else {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ uint32_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_4 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
+ if (num_bits_4 == 8) {
+ t_4 = ((uint32_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4));
+ }
+ }
+ self->private_impl.f_payload_length = t_4;
+ }
+ if (self->private_impl.f_payload_length < 2u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length -= 2u;
+ }
+ if (v_marker < 192u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
+ goto exit;
+ } else if (v_marker < 208u) {
+ if (v_marker <= 194u) {
+ if (self->private_impl.f_sof_marker != 0u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
+ goto exit;
+ }
+ self->private_impl.f_sof_marker = v_marker;
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ status = wuffs_jpeg__decoder__decode_sof(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ break;
+ } else if (v_marker == 195u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_lossless_coding);
+ goto exit;
+ } else if (v_marker == 196u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ } else if ((197u <= v_marker) && (v_marker <= 199u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_hierarchical_coding);
+ goto exit;
+ } else if (v_marker == 200u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_arithmetic_coding);
+ goto exit;
+ }
+ } else if (v_marker < 224u) {
+ if (v_marker < 218u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
+ goto exit;
+ } else if (v_marker == 218u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ } else if (v_marker == 219u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ status = wuffs_jpeg__decoder__decode_dqt(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ continue;
+ } else if (v_marker == 221u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ status = wuffs_jpeg__decoder__decode_dri(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ continue;
+ } else {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
+ goto exit;
+ }
+ } else if (v_marker < 240u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ status = wuffs_jpeg__decoder__decode_appn(self, a_src, v_marker);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ continue;
+ } else {
+ if (v_marker == 254u) {
+ } else {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
+ goto exit;
+ }
+ }
+ self->private_data.s_do_decode_image_config[0].scratch = self->private_impl.f_payload_length;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
+ self->private_impl.f_payload_length = 0u;
+ }
+ self->private_impl.choosy_decode_idct = (
+#if defined(WUFFS_BASE__CPU_ARCH__X86_64)
+ wuffs_base__cpu_arch__have_x86_avx2() ? &wuffs_jpeg__decoder__decode_idct_x86_avx2 :
+#endif
+ self->private_impl.choosy_decode_idct);
+ self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ if (a_dst != NULL) {
+ v_pixfmt = 536870920u;
+ if (self->private_impl.f_num_components > 1u) {
+ v_pixfmt = 2415954056u;
+ }
+ wuffs_base__image_config__set(
+ a_dst,
+ v_pixfmt,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ self->private_impl.f_frame_config_io_position,
+ true);
+ }
+ self->private_impl.f_call_sequence = 32u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_do_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_decode_image_config[0].v_marker = v_marker;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.decode_dqt
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_dqt(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint8_t v_q = 0;
+ uint32_t v_i = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_dqt[0];
+ if (coro_susp_point) {
+ v_q = self->private_data.s_decode_dqt[0].v_q;
+ v_i = self->private_data.s_decode_dqt[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (self->private_impl.f_payload_length > 0u) {
+ self->private_impl.f_payload_length -= 1u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if ((v_c & 15u) > 3u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker);
+ goto exit;
+ }
+ v_q = (v_c & 15u);
+ if ((v_c >> 4u) == 1u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision);
+ goto exit;
+ } else if (((v_c >> 4u) > 1u) || (self->private_impl.f_payload_length < 64u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dqt_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length -= 64u;
+ v_i = 0u;
+ while (v_i < 64u) {
+ v_i += 1u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint16_t t_1 = *iop_a_src++;
+ self->private_impl.f_quant_tables[v_q][WUFFS_JPEG__UNZIG[v_i]] = t_1;
+ }
+ }
+ self->private_impl.f_seen_dqt[v_q] = true;
+ if (self->private_impl.f_sof_marker == 0u) {
+ v_i = 0u;
+ while (v_i < 64u) {
+ self->private_impl.f_saved_quant_tables[v_q][v_i] = self->private_impl.f_quant_tables[v_q][v_i];
+ v_i += 1u;
+ }
+ self->private_impl.f_saved_seen_dqt[v_q] = true;
+ }
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_dqt[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_dqt[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_dqt[0].v_q = v_q;
+ self->private_data.s_decode_dqt[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.decode_dri
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_dri(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_dri[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_payload_length != 2u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dri_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length = 0u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint16_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_dri[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_dri[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 8) {
+ t_0 = ((uint16_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ self->private_impl.f_restart_interval = t_0;
+ }
+ if (self->private_impl.f_sof_marker == 0u) {
+ self->private_impl.f_saved_restart_interval = self->private_impl.f_restart_interval;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_dri[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_dri[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.decode_appn
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_appn(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ uint8_t a_marker) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c8 = 0;
+ uint32_t v_c32 = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_appn[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ do {
+ if (a_marker == 224u) {
+ if (self->private_impl.f_payload_length >= 5u) {
+ self->private_impl.f_payload_length -= 5u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_appn[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0)) << 56;
+ }
+ }
+ v_c32 = t_0;
+ }
+ if (v_c32 != 1179207242u) {
+ self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 1u));
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c8 = t_1;
+ }
+ self->private_impl.f_is_jfif = (v_c8 == 0u);
+ }
+ } else if (a_marker == 238u) {
+ if (self->private_impl.f_payload_length >= 12u) {
+ self->private_impl.f_payload_length -= 12u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_appn[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
+ if (num_bits_2 == 24) {
+ t_2 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2)) << 56;
+ }
+ }
+ v_c32 = t_2;
+ }
+ if (v_c32 != 1651467329u) {
+ self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 8u));
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ uint32_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_appn[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
+ if (num_bits_3 == 24) {
+ t_3 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3)) << 56;
+ }
+ }
+ v_c32 = t_3;
+ }
+ if ((255u & v_c32) != 101u) {
+ self->private_impl.f_payload_length = (65535u & (self->private_impl.f_payload_length + 4u));
+ break;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ uint32_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_appn[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_appn[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
+ if (num_bits_4 == 24) {
+ t_4 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4)) << 56;
+ }
+ }
+ v_c32 = t_4;
+ }
+ if ((v_c32 >> 24u) == 0u) {
+ self->private_impl.f_is_adobe = 1u;
+ } else {
+ self->private_impl.f_is_adobe = 2u;
+ }
+ }
+ }
+ } while (0);
+ self->private_data.s_decode_appn[0].scratch = self->private_impl.f_payload_length;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ if (self->private_data.s_decode_appn[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_decode_appn[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_decode_appn[0].scratch;
+ self->private_impl.f_payload_length = 0u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_appn[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_appn[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.decode_sof
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_sof(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint8_t v_comp_h = 0;
+ uint8_t v_comp_v = 0;
+ uint32_t v_i = 0;
+ uint32_t v_j = 0;
+ bool v_has_h24 = false;
+ bool v_has_h3 = false;
+ bool v_has_v24 = false;
+ bool v_has_v3 = false;
+ uint32_t v_upper_bound = 0;
+ uint64_t v_wh0 = 0;
+ uint64_t v_wh1 = 0;
+ uint64_t v_wh2 = 0;
+ uint64_t v_wh3 = 0;
+ uint64_t v_progressive = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_sof[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_decode_sof[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_payload_length < 6u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length -= 6u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c == 8u) {
+ } else if (v_c == 12u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_12_bits);
+ goto exit;
+ } else if (v_c == 16u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision_16_bits);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_precision);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_1 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_sof[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_sof[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 8) {
+ t_1 = ((uint32_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ self->private_impl.f_height = t_1;
+ }
+ if (self->private_impl.f_height == 0u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_implicit_height);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_sof[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_sof[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
+ if (num_bits_2 == 8) {
+ t_2 = ((uint32_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2));
+ }
+ }
+ self->private_impl.f_width = t_2;
+ }
+ if (self->private_impl.f_width == 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_c = t_3;
+ }
+ if ((v_c == 0u) || (v_c > 4u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
+ goto exit;
+ } else if (v_c == 2u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_color_model);
+ goto exit;
+ }
+ self->private_impl.f_num_components = ((uint32_t)(v_c));
+ if (self->private_impl.f_payload_length != (3u * self->private_impl.f_num_components)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length = 0u;
+ v_i = 0u;
+ while (v_i < self->private_impl.f_num_components) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_4 = *iop_a_src++;
+ self->private_impl.f_components_c[v_i] = t_4;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ v_c = t_5;
+ }
+ v_comp_h = (v_c >> 4u);
+ v_comp_v = (v_c & 15u);
+ if ((v_comp_h == 0u) ||
+ (v_comp_h > 4u) ||
+ (v_comp_v == 0u) ||
+ (v_comp_v > 4u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
+ goto exit;
+ }
+ self->private_impl.f_components_h[v_i] = v_comp_h;
+ if (self->private_impl.f_max_incl_components_h < self->private_impl.f_components_h[v_i]) {
+ self->private_impl.f_max_incl_components_h = self->private_impl.f_components_h[v_i];
+ }
+ self->private_impl.f_components_v[v_i] = v_comp_v;
+ if (self->private_impl.f_max_incl_components_v < self->private_impl.f_components_v[v_i]) {
+ self->private_impl.f_max_incl_components_v = self->private_impl.f_components_v[v_i];
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_6 = *iop_a_src++;
+ v_c = t_6;
+ }
+ if (v_c >= 4u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
+ goto exit;
+ }
+ self->private_impl.f_components_tq[v_i] = v_c;
+ v_j = 0u;
+ while (v_j < v_i) {
+ if (self->private_impl.f_components_c[v_j] == self->private_impl.f_components_c[v_i]) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
+ goto exit;
+ }
+ v_j += 1u;
+ }
+ v_i += 1u;
+ }
+ if (self->private_impl.f_num_components == 1u) {
+ self->private_impl.f_max_incl_components_h = 1u;
+ self->private_impl.f_max_incl_components_v = 1u;
+ self->private_impl.f_components_h[0u] = 1u;
+ self->private_impl.f_components_v[0u] = 1u;
+ } else {
+ v_has_h24 = false;
+ v_has_h3 = false;
+ v_has_v24 = false;
+ v_has_v3 = false;
+ v_i = 0u;
+ while (v_i < self->private_impl.f_num_components) {
+ v_has_h24 = (v_has_h24 || (self->private_impl.f_components_h[v_i] == 2u) || (self->private_impl.f_components_h[v_i] == 4u));
+ v_has_h3 = (v_has_h3 || (self->private_impl.f_components_h[v_i] == 3u));
+ v_has_v24 = (v_has_v24 || (self->private_impl.f_components_v[v_i] == 2u) || (self->private_impl.f_components_v[v_i] == 4u));
+ v_has_v3 = (v_has_v3 || (self->private_impl.f_components_v[v_i] == 3u));
+ v_i += 1u;
+ }
+ if ((v_has_h24 && v_has_h3) || (v_has_v24 && v_has_v3)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_fractional_sampling);
+ goto exit;
+ }
+ if (self->private_impl.f_num_components == 4u) {
+ self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe < 2u);
+ } else {
+ if (self->private_impl.f_is_jfif) {
+ self->private_impl.f_is_rgb_or_cmyk = false;
+ } else if (self->private_impl.f_is_adobe > 0u) {
+ self->private_impl.f_is_rgb_or_cmyk = (self->private_impl.f_is_adobe == 1u);
+ } else {
+ self->private_impl.f_is_rgb_or_cmyk = ((self->private_impl.f_components_c[0u] == 82u) && (self->private_impl.f_components_c[1u] == 71u) && (self->private_impl.f_components_c[2u] == 66u));
+ }
+ }
+ }
+ self->private_impl.f_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, 1u, self->private_impl.f_max_incl_components_h);
+ self->private_impl.f_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, 1u, self->private_impl.f_max_incl_components_v);
+ v_upper_bound = 65544u;
+ self->private_impl.f_components_workbuf_widths[0u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[0u]))));
+ self->private_impl.f_components_workbuf_widths[1u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[1u]))));
+ self->private_impl.f_components_workbuf_widths[2u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[2u]))));
+ self->private_impl.f_components_workbuf_widths[3u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_width_in_mcus * ((uint32_t)(self->private_impl.f_components_h[3u]))));
+ self->private_impl.f_components_workbuf_heights[0u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[0u]))));
+ self->private_impl.f_components_workbuf_heights[1u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[1u]))));
+ self->private_impl.f_components_workbuf_heights[2u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[2u]))));
+ self->private_impl.f_components_workbuf_heights[3u] = wuffs_base__u32__min(v_upper_bound, (8u * self->private_impl.f_height_in_mcus * ((uint32_t)(self->private_impl.f_components_v[3u]))));
+ v_wh0 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[0u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[0u])));
+ v_wh1 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[1u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[1u])));
+ v_wh2 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[2u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[2u])));
+ v_wh3 = (((uint64_t)(self->private_impl.f_components_workbuf_widths[3u])) * ((uint64_t)(self->private_impl.f_components_workbuf_heights[3u])));
+ v_progressive = 0u;
+ if (self->private_impl.f_sof_marker >= 194u) {
+ v_progressive = 2u;
+ v_i = 0u;
+ while (v_i < 4u) {
+ v_j = 0u;
+ while (v_j < 10u) {
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u;
+ v_j += 1u;
+ }
+ v_i += 1u;
+ }
+ }
+ self->private_impl.f_components_workbuf_offsets[0u] = 0u;
+ self->private_impl.f_components_workbuf_offsets[1u] = (self->private_impl.f_components_workbuf_offsets[0u] + v_wh0);
+ self->private_impl.f_components_workbuf_offsets[2u] = (self->private_impl.f_components_workbuf_offsets[1u] + v_wh1);
+ self->private_impl.f_components_workbuf_offsets[3u] = (self->private_impl.f_components_workbuf_offsets[2u] + v_wh2);
+ self->private_impl.f_components_workbuf_offsets[4u] = (self->private_impl.f_components_workbuf_offsets[3u] + v_wh3);
+ self->private_impl.f_components_workbuf_offsets[5u] = (self->private_impl.f_components_workbuf_offsets[4u] + (v_wh0 * v_progressive));
+ self->private_impl.f_components_workbuf_offsets[6u] = (self->private_impl.f_components_workbuf_offsets[5u] + (v_wh1 * v_progressive));
+ self->private_impl.f_components_workbuf_offsets[7u] = (self->private_impl.f_components_workbuf_offsets[6u] + (v_wh2 * v_progressive));
+ self->private_impl.f_components_workbuf_offsets[8u] = (self->private_impl.f_components_workbuf_offsets[7u] + (v_wh3 * v_progressive));
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_sof[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_sof[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_sof[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.quantize_dimension
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__quantize_dimension(
+ const wuffs_jpeg__decoder* self,
+ uint32_t a_width,
+ uint8_t a_h,
+ uint8_t a_max_incl_h) {
+ uint32_t v_ratio = 0;
+
+ v_ratio = 0u;
+ if (a_h > 0u) {
+ v_ratio = ((uint32_t)((a_max_incl_h / a_h)));
+ }
+ if (v_ratio == 1u) {
+ return ((a_width + 7u) / 8u);
+ } else if (v_ratio == 2u) {
+ return ((a_width + 15u) / 16u);
+ } else if (v_ratio == 3u) {
+ return ((a_width + 23u) / 24u);
+ }
+ return ((a_width + 31u) / 32u);
+}
+
+// -------- func jpeg.decoder.decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__decode_frame_config(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 2)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func jpeg.decoder.do_decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__do_decode_frame_config(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 32u) {
+ } else if (self->private_impl.f_call_sequence < 32u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_jpeg__decoder__do_decode_image_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (self->private_impl.f_call_sequence == 40u) {
+ if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_restart);
+ goto exit;
+ }
+ } else if (self->private_impl.f_call_sequence == 64u) {
+ self->private_impl.f_call_sequence = 96u;
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (a_dst != NULL) {
+ wuffs_base__frame_config__set(
+ a_dst,
+ wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height),
+ ((wuffs_base__flicks)(0u)),
+ 0u,
+ self->private_impl.f_frame_config_io_position,
+ 0u,
+ true,
+ false,
+ 4278190080u);
+ }
+ self->private_impl.f_call_sequence = 64u;
+
+ ok:
+ self->private_impl.p_do_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__decode_frame(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 3)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_ddf_status = wuffs_base__make_status(NULL);
+ wuffs_base__status v_swizzle_status = wuffs_base__make_status(NULL);
+ uint32_t v_scan_count = 0;
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ v_scan_count = self->private_impl.f_scan_count;
+ {
+ wuffs_base__status t_0 = wuffs_jpeg__decoder__do_decode_frame(self,
+ a_dst,
+ a_src,
+ a_blend,
+ a_workbuf,
+ a_opts);
+ v_ddf_status = t_0;
+ }
+ if ((v_ddf_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ v_ddf_status = wuffs_base__make_status(wuffs_jpeg__error__truncated_input);
+ }
+ if (wuffs_base__status__is_error(&v_ddf_status) || (v_scan_count < self->private_impl.f_scan_count)) {
+ if (self->private_impl.f_sof_marker >= 194u) {
+ wuffs_jpeg__decoder__apply_progressive_idct(self, a_workbuf);
+ }
+ if (self->private_impl.f_num_components == 1u) {
+ v_swizzle_status = wuffs_jpeg__decoder__swizzle_gray(self, a_dst, a_workbuf);
+ } else {
+ v_swizzle_status = wuffs_jpeg__decoder__swizzle_colorful(self, a_dst, a_workbuf);
+ }
+ if (wuffs_base__status__is_error(&v_ddf_status)) {
+ status = v_ddf_status;
+ goto exit;
+ } else if (wuffs_base__status__is_error(&v_swizzle_status)) {
+ status = v_swizzle_status;
+ goto exit;
+ }
+ }
+ status = v_ddf_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func jpeg.decoder.do_decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__do_decode_frame(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_pixfmt = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ uint8_t v_c = 0;
+ uint8_t v_marker = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
+ if (coro_susp_point) {
+ v_marker = self->private_data.s_do_decode_frame[0].v_marker;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 64u) {
+ } else if (self->private_impl.f_call_sequence < 64u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_jpeg__decoder__do_decode_frame_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ v_pixfmt = 536870920u;
+ if (self->private_impl.f_num_components > 1u) {
+ v_pixfmt = 2415954056u;
+ }
+ v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
+ wuffs_base__pixel_buffer__pixel_format(a_dst),
+ wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
+ wuffs_base__utility__make_pixel_format(v_pixfmt),
+ wuffs_base__utility__empty_slice_u8(),
+ a_blend);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ if (self->private_impl.f_components_workbuf_offsets[8u] > ((uint64_t)(a_workbuf.len))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
+ goto exit;
+ } else if (self->private_impl.f_components_workbuf_offsets[4u] < self->private_impl.f_components_workbuf_offsets[8u]) {
+ wuffs_base__bulk_memset(a_workbuf.ptr + self->private_impl.f_components_workbuf_offsets[4u], (self->private_impl.f_components_workbuf_offsets[8u] - self->private_impl.f_components_workbuf_offsets[4u]), 0u);
+ }
+ if (self->private_impl.f_components_workbuf_offsets[4u] <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_base__bulk_memset(a_workbuf.ptr, self->private_impl.f_components_workbuf_offsets[4u], 128u);
+ }
+ while (true) {
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c == 255u) {
+ break;
+ }
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ if (v_c != 255u) {
+ v_marker = v_c;
+ break;
+ }
+ }
+ if (v_marker == 0u) {
+ continue;
+ } else if ((208u <= v_marker) && (v_marker <= 217u)) {
+ if (v_marker <= 215u) {
+ continue;
+ }
+ } else {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_2 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_frame[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_frame[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
+ if (num_bits_2 == 8) {
+ t_2 = ((uint32_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2));
+ }
+ }
+ self->private_impl.f_payload_length = t_2;
+ }
+ if (self->private_impl.f_payload_length < 2u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length -= 2u;
+ }
+ if (v_marker < 192u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
+ goto exit;
+ } else if (v_marker < 208u) {
+ if (v_marker == 196u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ status = wuffs_jpeg__decoder__decode_dht(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ continue;
+ } else if (v_marker == 200u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sof_marker);
+ goto exit;
+ } else if (v_marker < 224u) {
+ if (v_marker < 217u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_marker);
+ goto exit;
+ } else if (v_marker == 217u) {
+ break;
+ } else if (v_marker == 218u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ status = wuffs_jpeg__decoder__decode_sos(self, a_src, a_workbuf);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ continue;
+ } else if (v_marker == 219u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ status = wuffs_jpeg__decoder__decode_dqt(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ continue;
+ } else if (v_marker == 221u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ status = wuffs_jpeg__decoder__decode_dri(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ continue;
+ } else {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
+ goto exit;
+ }
+ } else if (v_marker < 240u) {
+ } else {
+ if (v_marker == 254u) {
+ } else {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_marker);
+ goto exit;
+ }
+ }
+ self->private_data.s_do_decode_frame[0].scratch = self->private_impl.f_payload_length;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
+ self->private_impl.f_payload_length = 0u;
+ }
+ self->private_impl.f_call_sequence = 96u;
+
+ ok:
+ self->private_impl.p_do_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_decode_frame[0].v_marker = v_marker;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.decode_dht
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_dht(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint8_t v_tc = 0;
+ uint8_t v_th = 0;
+ uint8_t v_tc4_th = 0;
+ uint32_t v_working_total_count = 0;
+ uint32_t v_total_count = 0;
+ uint32_t v_i = 0;
+ bool v_failed = false;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_dht[0];
+ if (coro_susp_point) {
+ v_tc4_th = self->private_data.s_decode_dht[0].v_tc4_th;
+ v_total_count = self->private_data.s_decode_dht[0].v_total_count;
+ v_i = self->private_data.s_decode_dht[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_sof_marker == 0u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ }
+ while (self->private_impl.f_payload_length > 0u) {
+ if (self->private_impl.f_payload_length < 17u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length -= 17u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (((v_c >> 4u) > 1u) || ((v_c & 15u) > 3u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ }
+ v_tc = (v_c >> 4u);
+ v_th = (v_c & 15u);
+ v_tc4_th = ((uint8_t)(((v_tc * 4u) | v_th)));
+ if ((self->private_impl.f_sof_marker == 192u) && ((v_tc4_th & 3u) > 1u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ }
+ v_i = 0u;
+ while (v_i < 16u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ self->private_data.f_dht_temp_counts[v_i] = t_1;
+ }
+ v_i += 1u;
+ }
+ v_working_total_count = 0u;
+ v_i = 0u;
+ while (v_i < 16u) {
+ v_working_total_count = ((v_working_total_count + ((uint32_t)(self->private_data.f_dht_temp_counts[v_i]))) & 65535u);
+ v_i += 1u;
+ }
+ if ((v_working_total_count <= 0u) || (256u < v_working_total_count)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ }
+ v_total_count = v_working_total_count;
+ if (self->private_impl.f_payload_length < v_total_count) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length -= v_total_count;
+ v_i = 0u;
+ while (v_i < v_total_count) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = t_2;
+ }
+ v_i += 1u;
+ }
+ while (v_i < 256u) {
+ self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] = 0u;
+ v_i += 1u;
+ }
+ if ((v_tc4_th & 4u) == 0u) {
+ v_i = 0u;
+ while (v_i < v_total_count) {
+ if (self->private_impl.f_huff_tables_symbols[v_tc4_th][v_i] > 15u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ }
+ v_i += 1u;
+ }
+ }
+ v_failed = wuffs_jpeg__decoder__calculate_huff_tables(self, v_tc4_th, v_total_count);
+ if (v_failed) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_dht_marker);
+ goto exit;
+ }
+ self->private_impl.f_seen_dht[v_tc4_th] = true;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_dht[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_dht[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_dht[0].v_tc4_th = v_tc4_th;
+ self->private_data.s_decode_dht[0].v_total_count = v_total_count;
+ self->private_data.s_decode_dht[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.calculate_huff_tables
+
+WUFFS_BASE__GENERATED_C_CODE
+static bool
+wuffs_jpeg__decoder__calculate_huff_tables(
+ wuffs_jpeg__decoder* self,
+ uint8_t a_tc4_th,
+ uint32_t a_total_count) {
+ uint32_t v_i = 0;
+ uint8_t v_j = 0;
+ uint8_t v_k = 0;
+ uint32_t v_bit_length_minus_one = 0;
+ uint8_t v_bit_length = 0;
+ uint32_t v_bit_string = 0;
+ uint32_t v_slow = 0;
+ uint8_t v_prefix = 0;
+ uint16_t v_fast = 0;
+ uint32_t v_reps = 0;
+
+ v_i = 0u;
+ v_k = 0u;
+ v_bit_length_minus_one = 0u;
+ while (v_i < a_total_count) {
+ while (v_k >= self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) {
+ v_k = 0u;
+ v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u);
+ }
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_k += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ self->private_data.f_dht_temp_bit_lengths[v_i] = ((uint8_t)((v_bit_length_minus_one + 1u)));
+ v_i += 1u;
+ }
+ v_bit_length = 0u;
+ v_bit_string = 0u;
+ v_i = 0u;
+ while (v_i < a_total_count) {
+ while (v_bit_length < self->private_data.f_dht_temp_bit_lengths[v_i]) {
+ if (v_bit_length >= 16u) {
+ return true;
+ }
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_bit_length += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ v_bit_string <<= 1u;
+ }
+ self->private_data.f_dht_temp_bit_strings[v_i] = ((uint16_t)(v_bit_string));
+ v_bit_string += 1u;
+ if ((v_bit_string >> v_bit_length) > 0u) {
+ return true;
+ }
+ v_i += 1u;
+ }
+ v_k = 0u;
+ v_bit_length_minus_one = 0u;
+ while (true) {
+ if (self->private_data.f_dht_temp_counts[v_bit_length_minus_one] == 0u) {
+ self->private_impl.f_huff_tables_slow[a_tc4_th][v_bit_length_minus_one] = 0u;
+ } else {
+ v_slow = (255u & ((uint32_t)(((uint32_t)(v_k)) - ((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_k])))));
+ v_k += self->private_data.f_dht_temp_counts[v_bit_length_minus_one];
+ self->private_impl.f_huff_tables_slow[a_tc4_th][v_bit_length_minus_one] = (v_slow | ((((uint32_t)(self->private_data.f_dht_temp_bit_strings[((uint8_t)(v_k - 1u))])) + 1u) << 8u));
+ }
+ v_bit_length_minus_one = ((v_bit_length_minus_one + 1u) & 15u);
+ if (v_bit_length_minus_one == 0u) {
+ break;
+ }
+ }
+ v_i = 0u;
+ while (v_i < 256u) {
+ self->private_impl.f_huff_tables_fast[a_tc4_th][v_i] = 65535u;
+ v_i += 1u;
+ }
+ v_j = 0u;
+ v_bit_length_minus_one = 0u;
+ while (v_bit_length_minus_one < 8u) {
+ v_k = 0u;
+ while (v_k < self->private_data.f_dht_temp_counts[v_bit_length_minus_one]) {
+ v_prefix = ((uint8_t)((((uint32_t)(self->private_data.f_dht_temp_bit_strings[v_j])) << (7u - v_bit_length_minus_one))));
+ v_fast = ((uint16_t)(((((uint32_t)((v_bit_length_minus_one + 1u))) << 8u) | ((uint32_t)(self->private_impl.f_huff_tables_symbols[a_tc4_th][v_j])))));
+ v_reps = (((uint32_t)(1u)) << (7u - v_bit_length_minus_one));
+ while (v_reps > 0u) {
+ self->private_impl.f_huff_tables_fast[a_tc4_th][v_prefix] = v_fast;
+ v_prefix += 1u;
+ v_reps -= 1u;
+ }
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ v_k += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ v_j += 1u;
+ }
+ v_bit_length_minus_one += 1u;
+ }
+ return false;
+}
+
+// -------- func jpeg.decoder.decode_sos
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__decode_sos(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_my = 0;
+ uint32_t v_mx = 0;
+ uint32_t v_decode_mcu_result = 0;
+ uint32_t v_bitstream_length = 0;
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_sos[0];
+ if (coro_susp_point) {
+ v_my = self->private_data.s_decode_sos[0].v_my;
+ v_mx = self->private_data.s_decode_sos[0].v_mx;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_scan_count >= 64u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__unsupported_scan_count);
+ goto exit;
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_jpeg__decoder__prepare_scan(self, a_src);
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_next_restart_marker = 0u;
+ self->private_impl.f_mcu_previous_dc_values[0u] = 0u;
+ self->private_impl.f_mcu_previous_dc_values[1u] = 0u;
+ self->private_impl.f_mcu_previous_dc_values[2u] = 0u;
+ self->private_impl.f_mcu_previous_dc_values[3u] = 0u;
+ self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval;
+ self->private_impl.f_eob_run = 0u;
+ self->private_impl.f_bitstream_bits = 0u;
+ self->private_impl.f_bitstream_n_bits = 0u;
+ self->private_impl.f_bitstream_ri = 0u;
+ self->private_impl.f_bitstream_wi = 0u;
+ self->private_impl.f_bitstream_padding = 12345u;
+ wuffs_jpeg__decoder__fill_bitstream(self, a_src);
+ v_my = 0u;
+ while (v_my < self->private_impl.f_scan_height_in_mcus) {
+ v_mx = 0u;
+ while (v_mx < self->private_impl.f_scan_width_in_mcus) {
+ self->private_impl.f_mcu_current_block = 0u;
+ self->private_impl.f_mcu_zig_index = ((uint32_t)(self->private_impl.f_scan_ss));
+ if (self->private_impl.f_sof_marker >= 194u) {
+ wuffs_jpeg__decoder__load_mcu_blocks(self, v_mx, v_my, a_workbuf);
+ }
+ while (true) {
+ v_decode_mcu_result = wuffs_jpeg__decoder__decode_mcu(self, a_workbuf, v_mx, v_my);
+ if (v_decode_mcu_result == 0u) {
+ break;
+ } else if (v_decode_mcu_result != 1u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__internal_error_inconsistent_decoder_state);
+ goto exit;
+ }
+ while (true) {
+ v_bitstream_length = ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri));
+ wuffs_jpeg__decoder__fill_bitstream(self, a_src);
+ if (v_bitstream_length < ((uint32_t)(self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri))) {
+ break;
+ } else if (self->private_impl.f_bitstream_padding == 0u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ } else if ((a_src && a_src->meta.closed) && ! self->private_impl.f_bitstream_is_closed) {
+ if (self->private_impl.f_bitstream_wi < 1024u) {
+ wuffs_base__bulk_memset(&self->private_data.f_bitstream_buffer[self->private_impl.f_bitstream_wi], 264u, 0u);
+ self->private_impl.f_bitstream_wi += 264u;
+ self->private_impl.f_bitstream_is_closed = true;
+ }
+ break;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ }
+ }
+ if (self->private_impl.f_sof_marker >= 194u) {
+ wuffs_jpeg__decoder__save_mcu_blocks(self, v_mx, v_my, a_workbuf);
+ }
+ if (self->private_impl.f_restarts_remaining > 0u) {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_impl.f_restarts_remaining -= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ if (self->private_impl.f_restarts_remaining == 0u) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_jpeg__decoder__skip_past_the_next_restart_marker(self, a_src);
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_mcu_previous_dc_values[0u] = 0u;
+ self->private_impl.f_mcu_previous_dc_values[1u] = 0u;
+ self->private_impl.f_mcu_previous_dc_values[2u] = 0u;
+ self->private_impl.f_mcu_previous_dc_values[3u] = 0u;
+ self->private_impl.f_restarts_remaining = self->private_impl.f_restart_interval;
+ self->private_impl.f_eob_run = 0u;
+ self->private_impl.f_bitstream_bits = 0u;
+ self->private_impl.f_bitstream_n_bits = 0u;
+ self->private_impl.f_bitstream_ri = 0u;
+ self->private_impl.f_bitstream_wi = 0u;
+ self->private_impl.f_bitstream_padding = 12345u;
+ }
+ }
+ v_mx += 1u;
+ }
+ v_my += 1u;
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_scan_count, 1u);
+
+ ok:
+ self->private_impl.p_decode_sos[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_sos[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_sos[0].v_my = v_my;
+ self->private_data.s_decode_sos[0].v_mx = v_mx;
+
+ goto exit;
+ exit:
+ return status;
+}
+
+// -------- func jpeg.decoder.prepare_scan
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__prepare_scan(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_i = 0;
+ uint32_t v_j = 0;
+ uint32_t v_j_max_incl = 0;
+ bool v_failed = false;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_prepare_scan[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_prepare_scan[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_payload_length < 6u) || (self->private_impl.f_payload_length > 12u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if ((v_c < 1u) || (v_c > 4u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ self->private_impl.f_scan_num_components = ((uint32_t)(v_c));
+ if ((self->private_impl.f_scan_num_components > self->private_impl.f_num_components) || (self->private_impl.f_payload_length != (4u + (2u * self->private_impl.f_scan_num_components)))) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ self->private_impl.f_payload_length = 0u;
+ v_i = 0u;
+ while (v_i < self->private_impl.f_scan_num_components) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ v_j = 0u;
+ while (true) {
+ if (v_j >= self->private_impl.f_num_components) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ if (v_c == self->private_impl.f_components_c[v_j]) {
+ if ( ! self->private_impl.f_seen_dqt[self->private_impl.f_components_tq[v_j]]) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__missing_quantization_table);
+ goto exit;
+ }
+ self->private_impl.f_scan_comps_cselector[v_i] = ((uint8_t)(v_j));
+ break;
+ }
+ v_j += 1u;
+ }
+ v_j = 0u;
+ while (v_j < v_i) {
+ if (self->private_impl.f_scan_comps_cselector[v_i] == self->private_impl.f_scan_comps_cselector[v_j]) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ v_j += 1u;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_c = t_2;
+ }
+ if (((v_c >> 4u) > 3u) || ((v_c & 15u) > 3u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ self->private_impl.f_scan_comps_td[v_i] = (v_c >> 4u);
+ self->private_impl.f_scan_comps_ta[v_i] = (v_c & 15u);
+ if (self->private_impl.f_sof_marker == 192u) {
+ if ((self->private_impl.f_scan_comps_td[v_i] > 1u) || (self->private_impl.f_scan_comps_ta[v_i] > 1u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ }
+ v_i += 1u;
+ }
+ if (self->private_impl.f_sof_marker < 194u) {
+ self->private_data.s_prepare_scan[0].scratch = 3u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (self->private_data.s_prepare_scan[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_prepare_scan[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_prepare_scan[0].scratch;
+ self->private_impl.f_scan_ss = 0u;
+ self->private_impl.f_scan_se = 63u;
+ self->private_impl.f_scan_ah = 0u;
+ self->private_impl.f_scan_al = 0u;
+ } else {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_c = t_3;
+ }
+ if (v_c > 63u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ self->private_impl.f_scan_ss = v_c;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_4 = *iop_a_src++;
+ v_c = t_4;
+ }
+ if ((v_c > 63u) || (v_c < self->private_impl.f_scan_ss)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ self->private_impl.f_scan_se = v_c;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ v_c = t_5;
+ }
+ if (((v_c >> 4u) > 14u) || ((v_c & 15u) > 13u)) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ self->private_impl.f_scan_ah = (v_c >> 4u);
+ self->private_impl.f_scan_al = (v_c & 15u);
+ if (self->private_impl.f_scan_ah > 0u) {
+ if ((self->private_impl.f_scan_ah - 1u) != self->private_impl.f_scan_al) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ }
+ if (self->private_impl.f_scan_ss == 0u) {
+ if (self->private_impl.f_scan_se != 0u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ } else if (self->private_impl.f_scan_ah == 0u) {
+ self->private_impl.choosy_decode_mcu = (
+ &wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits);
+ } else {
+ self->private_impl.choosy_decode_mcu = (
+ &wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit);
+ }
+ } else {
+ if (self->private_impl.f_scan_num_components != 1u) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ } else if (self->private_impl.f_scan_ah == 0u) {
+ self->private_impl.choosy_decode_mcu = (
+ &wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits);
+ } else {
+ self->private_impl.choosy_decode_mcu = (
+ &wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit);
+ }
+ }
+ }
+ v_i = 0u;
+ while (v_i < self->private_impl.f_scan_num_components) {
+ if ((self->private_impl.f_scan_ss == 0u) && ! self->private_impl.f_seen_dht[(0u | self->private_impl.f_scan_comps_td[v_i])]) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ status = wuffs_jpeg__decoder__use_default_huffman_table(self, (0u | self->private_impl.f_scan_comps_td[v_i]));
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ if ((self->private_impl.f_scan_se != 0u) && ! self->private_impl.f_seen_dht[(4u | self->private_impl.f_scan_comps_ta[v_i])]) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ status = wuffs_jpeg__decoder__use_default_huffman_table(self, (4u | self->private_impl.f_scan_comps_ta[v_i]));
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ v_j = ((uint32_t)(self->private_impl.f_scan_ss));
+ v_j_max_incl = ((uint32_t)(wuffs_base__u8__min(self->private_impl.f_scan_se, 9u)));
+ while (v_j <= v_j_max_incl) {
+ self->private_impl.f_block_smoothing_lowest_scan_al[self->private_impl.f_scan_comps_cselector[v_i]][v_j] = self->private_impl.f_scan_al;
+ v_j += 1u;
+ }
+ v_i += 1u;
+ }
+ if (self->private_impl.f_scan_num_components == 1u) {
+ wuffs_jpeg__decoder__calculate_single_component_scan_fields(self);
+ } else {
+ v_failed = wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(self);
+ if (v_failed) {
+ status = wuffs_base__make_status(wuffs_jpeg__error__bad_sos_marker);
+ goto exit;
+ }
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_prepare_scan[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_prepare_scan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_prepare_scan[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.use_default_huffman_table
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__use_default_huffman_table(
+ wuffs_jpeg__decoder* self,
+ uint8_t a_tc4_th) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__slice_u8 v_data = {0};
+ wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_r = &u_r;
+ const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ if (a_tc4_th == 0u) {
+ v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_LUMA), 29);
+ } else if (a_tc4_th == 1u) {
+ v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_DC_CHROMA), 29);
+ } else if (a_tc4_th == 4u) {
+ v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_LUMA), 179);
+ } else if (a_tc4_th == 5u) {
+ v_data = wuffs_base__make_slice_u8(wuffs_base__strip_const_from_u8_ptr(WUFFS_JPEG__DEFAULT_HUFF_TABLE_AC_CHROMA), 179);
+ } else {
+ status = wuffs_base__make_status(wuffs_jpeg__error__missing_huffman_table);
+ goto exit;
+ }
+ {
+ wuffs_base__io_buffer* o_0_v_r = v_r;
+ const uint8_t *o_0_iop_v_r = iop_v_r;
+ const uint8_t *o_0_io0_v_r = io0_v_r;
+ const uint8_t *o_0_io1_v_r = io1_v_r;
+ const uint8_t *o_0_io2_v_r = io2_v_r;
+ v_r = wuffs_base__io_reader__set(
+ &u_r,
+ &iop_v_r,
+ &io0_v_r,
+ &io1_v_r,
+ &io2_v_r,
+ v_data,
+ 0u);
+ self->private_impl.f_payload_length = ((uint32_t)((((uint64_t)(v_data.len)) & 65535u)));
+ {
+ wuffs_base__status t_0 = wuffs_jpeg__decoder__decode_dht(self, v_r);
+ v_status = t_0;
+ }
+ v_r = o_0_v_r;
+ iop_v_r = o_0_iop_v_r;
+ io0_v_r = o_0_io0_v_r;
+ io1_v_r = o_0_io1_v_r;
+ io2_v_r = o_0_io2_v_r;
+ }
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+
+ ok:
+ goto exit;
+ exit:
+ return status;
+}
+
+// -------- func jpeg.decoder.calculate_single_component_scan_fields
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__calculate_single_component_scan_fields(
+ wuffs_jpeg__decoder* self) {
+ uint8_t v_csel = 0;
+
+ self->private_impl.f_scan_comps_bx_offset[0u] = 0u;
+ self->private_impl.f_scan_comps_by_offset[0u] = 0u;
+ self->private_impl.f_mcu_num_blocks = 1u;
+ self->private_impl.f_mcu_blocks_sselector[0u] = 0u;
+ v_csel = self->private_impl.f_scan_comps_cselector[0u];
+ self->private_impl.f_mcu_blocks_offset[0u] = self->private_impl.f_components_workbuf_offsets[v_csel];
+ self->private_impl.f_mcu_blocks_mx_mul[0u] = 8u;
+ self->private_impl.f_mcu_blocks_my_mul[0u] = (8u * self->private_impl.f_components_workbuf_widths[v_csel]);
+ self->private_impl.f_mcu_blocks_dc_hselector[0u] = (0u | self->private_impl.f_scan_comps_td[0u]);
+ self->private_impl.f_mcu_blocks_ac_hselector[0u] = (4u | self->private_impl.f_scan_comps_ta[0u]);
+ self->private_impl.f_scan_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, self->private_impl.f_components_h[v_csel], self->private_impl.f_max_incl_components_h);
+ self->private_impl.f_scan_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, self->private_impl.f_components_v[v_csel], self->private_impl.f_max_incl_components_v);
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func jpeg.decoder.calculate_multiple_component_scan_fields
+
+WUFFS_BASE__GENERATED_C_CODE
+static bool
+wuffs_jpeg__decoder__calculate_multiple_component_scan_fields(
+ wuffs_jpeg__decoder* self) {
+ uint32_t v_i = 0;
+ uint32_t v_h = 0;
+ uint32_t v_v = 0;
+ uint32_t v_hv = 0;
+ uint32_t v_total_hv = 0;
+ uint32_t v_b = 0;
+ uint32_t v_bx_offset = 0;
+ uint32_t v_by_offset = 0;
+ uint8_t v_ssel = 0;
+ uint8_t v_csel = 0;
+
+ v_total_hv = 0u;
+ v_i = 0u;
+ v_b = 0u;
+ v_bx_offset = 0u;
+ v_by_offset = 0u;
+ while (v_i < self->private_impl.f_scan_num_components) {
+ v_h = ((uint32_t)(self->private_impl.f_components_h[self->private_impl.f_scan_comps_cselector[v_i]]));
+ v_v = ((uint32_t)(self->private_impl.f_components_v[self->private_impl.f_scan_comps_cselector[v_i]]));
+ v_hv = (((uint32_t)(self->private_impl.f_components_h[self->private_impl.f_scan_comps_cselector[v_i]])) * ((uint32_t)(self->private_impl.f_components_v[self->private_impl.f_scan_comps_cselector[v_i]])));
+ v_total_hv += v_hv;
+ while (v_hv > 0u) {
+ self->private_impl.f_scan_comps_bx_offset[(v_b & 15u)] = ((uint8_t)((v_bx_offset & 3u)));
+ self->private_impl.f_scan_comps_by_offset[(v_b & 15u)] = ((uint8_t)((v_by_offset & 3u)));
+ self->private_impl.f_mcu_blocks_sselector[(v_b & 15u)] = ((uint8_t)(v_i));
+ v_b += 1u;
+ v_bx_offset += 1u;
+ if (v_bx_offset == v_h) {
+ v_bx_offset = 0u;
+ v_by_offset += 1u;
+ if (v_by_offset == v_v) {
+ v_by_offset = 0u;
+ }
+ }
+ v_hv -= 1u;
+ }
+ v_i += 1u;
+ }
+ if (v_total_hv > 10u) {
+ return true;
+ }
+ self->private_impl.f_mcu_num_blocks = v_total_hv;
+ v_b = 0u;
+ while (v_b < self->private_impl.f_mcu_num_blocks) {
+ v_ssel = self->private_impl.f_mcu_blocks_sselector[v_b];
+ v_csel = self->private_impl.f_scan_comps_cselector[v_ssel];
+ self->private_impl.f_mcu_blocks_offset[v_b] = (self->private_impl.f_components_workbuf_offsets[v_csel] + (8u * ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) + (8u * ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b])) * ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel]))));
+ self->private_impl.f_mcu_blocks_mx_mul[v_b] = (8u * ((uint32_t)(self->private_impl.f_components_h[v_csel])));
+ self->private_impl.f_mcu_blocks_my_mul[v_b] = (8u * ((uint32_t)(self->private_impl.f_components_v[v_csel])) * self->private_impl.f_components_workbuf_widths[v_csel]);
+ self->private_impl.f_mcu_blocks_dc_hselector[v_b] = (0u | self->private_impl.f_scan_comps_td[v_ssel]);
+ self->private_impl.f_mcu_blocks_ac_hselector[v_b] = (4u | self->private_impl.f_scan_comps_ta[v_ssel]);
+ v_b += 1u;
+ }
+ self->private_impl.f_scan_width_in_mcus = self->private_impl.f_width_in_mcus;
+ self->private_impl.f_scan_height_in_mcus = self->private_impl.f_height_in_mcus;
+ return false;
+}
+
+// -------- func jpeg.decoder.fill_bitstream
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__fill_bitstream(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ uint32_t v_wi = 0;
+ uint8_t v_c = 0;
+ uint32_t v_new_wi = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ if (self->private_impl.f_bitstream_ri <= 0u) {
+ } else if (self->private_impl.f_bitstream_ri >= self->private_impl.f_bitstream_wi) {
+ self->private_impl.f_bitstream_ri = 0u;
+ self->private_impl.f_bitstream_wi = 0u;
+ } else {
+ v_wi = (self->private_impl.f_bitstream_wi - self->private_impl.f_bitstream_ri);
+ wuffs_base__slice_u8__copy_from_slice(wuffs_base__make_slice_u8(self->private_data.f_bitstream_buffer, 2048), wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
+ self->private_impl.f_bitstream_ri,
+ self->private_impl.f_bitstream_wi));
+ self->private_impl.f_bitstream_ri = 0u;
+ self->private_impl.f_bitstream_wi = v_wi;
+ }
+ v_wi = self->private_impl.f_bitstream_wi;
+ while ((v_wi < 2048u) && (((uint64_t)(io2_a_src - iop_a_src)) > 0u)) {
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if (v_c < 255u) {
+ self->private_data.f_bitstream_buffer[v_wi] = v_c;
+ v_wi += 1u;
+ iop_a_src += 1u;
+ continue;
+ } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) {
+ break;
+ } else if ((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u) > 0u) {
+ break;
+ } else {
+ self->private_data.f_bitstream_buffer[v_wi] = 255u;
+ v_wi += 1u;
+ iop_a_src += 2u;
+ }
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) > 1u) {
+ if ((wuffs_base__peek_u8be__no_bounds_check(iop_a_src) >= 255u) && ((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u) > 0u)) {
+ v_new_wi = (wuffs_base__u32__min(v_wi, 1784u) + 264u);
+ v_new_wi = wuffs_base__u32__min(v_new_wi, (v_wi + self->private_impl.f_bitstream_padding));
+ if (v_wi < v_new_wi) {
+ wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_bitstream_padding, (v_new_wi - v_wi));
+ wuffs_base__bulk_memset(&self->private_data.f_bitstream_buffer[v_wi], (v_new_wi - v_wi), 0u);
+ v_wi = v_new_wi;
+ }
+ }
+ }
+ self->private_impl.f_bitstream_wi = v_wi;
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func jpeg.decoder.load_mcu_blocks_for_single_component
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_csel) {
+ return (*self->private_impl.choosy_load_mcu_blocks_for_single_component)(self, a_mx, a_my, a_workbuf, a_csel);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_csel) {
+ uint64_t v_stride16 = 0;
+ uint64_t v_offset = 0;
+
+ v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u)));
+ v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16));
+ if (v_offset <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func jpeg.decoder.load_mcu_blocks
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__load_mcu_blocks(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf) {
+ uint32_t v_b = 0;
+ uint8_t v_csel = 0;
+ uint64_t v_h = 0;
+ uint64_t v_v = 0;
+ uint64_t v_stride16 = 0;
+ uint64_t v_offset = 0;
+
+ v_h = 1u;
+ v_v = 1u;
+ v_b = 0u;
+ while (v_b < self->private_impl.f_mcu_num_blocks) {
+ v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]];
+ if (self->private_impl.f_scan_num_components > 1u) {
+ v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel]));
+ v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel]));
+ }
+ v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u)));
+ v_offset = (self->private_impl.f_components_workbuf_offsets[(v_csel | 4u)] + (((v_h * ((uint64_t)(a_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) * 128u) + (((v_v * ((uint64_t)(a_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride16));
+ if (v_offset <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[v_b], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
+ }
+ v_b += 1u;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func jpeg.decoder.save_mcu_blocks
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__save_mcu_blocks(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf) {
+ uint32_t v_b = 0;
+ uint8_t v_csel = 0;
+ uint64_t v_h = 0;
+ uint64_t v_v = 0;
+ uint64_t v_stride16 = 0;
+ uint64_t v_offset = 0;
+
+ v_h = 1u;
+ v_v = 1u;
+ v_b = 0u;
+ while (v_b < self->private_impl.f_mcu_num_blocks) {
+ v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_b]];
+ if (self->private_impl.f_scan_num_components > 1u) {
+ v_h = ((uint64_t)(self->private_impl.f_components_h[v_csel]));
+ v_v = ((uint64_t)(self->private_impl.f_components_v[v_csel]));
+ }
+ v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[v_csel] * 16u)));
+ v_offset = (self->private_impl.f_components_workbuf_offsets[(v_csel | 4u)] + (((v_h * ((uint64_t)(a_mx))) + ((uint64_t)(self->private_impl.f_scan_comps_bx_offset[v_b]))) * 128u) + (((v_v * ((uint64_t)(a_my))) + ((uint64_t)(self->private_impl.f_scan_comps_by_offset[v_b]))) * v_stride16));
+ if (v_offset <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_base__bulk_save_host_endian(&self->private_data.f_mcu_blocks[v_b], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
+ }
+ v_b += 1u;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func jpeg.decoder.skip_past_the_next_restart_marker
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__skip_past_the_next_restart_marker(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_skip_past_the_next_restart_marker[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ continue;
+ } else if (wuffs_base__peek_u8be__no_bounds_check(iop_a_src) < 255u) {
+ iop_a_src += 1u;
+ continue;
+ }
+ v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)));
+ if (v_c < 192u) {
+ iop_a_src += 2u;
+ continue;
+ } else if ((v_c < 208u) || (215u < v_c)) {
+ break;
+ }
+ v_c &= 7u;
+ if ((self->private_impl.f_next_restart_marker == ((v_c + 1u) & 7u)) || (self->private_impl.f_next_restart_marker == ((v_c + 2u) & 7u))) {
+ break;
+ } else if ((self->private_impl.f_next_restart_marker == ((v_c + 7u) & 7u)) || (self->private_impl.f_next_restart_marker == ((v_c + 6u) & 7u))) {
+ iop_a_src += 2u;
+ continue;
+ } else {
+ iop_a_src += 2u;
+ break;
+ }
+ }
+ self->private_impl.f_next_restart_marker = (((uint8_t)(self->private_impl.f_next_restart_marker + 1u)) & 7u);
+
+ ok:
+ self->private_impl.p_skip_past_the_next_restart_marker[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_skip_past_the_next_restart_marker[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func jpeg.decoder.apply_progressive_idct
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__apply_progressive_idct(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf) {
+ uint32_t v_csel = 0;
+ bool v_block_smoothing_applicable = false;
+ uint32_t v_scan_width_in_mcus = 0;
+ uint32_t v_scan_height_in_mcus = 0;
+ uint32_t v_mcu_blocks_mx_mul_0 = 0;
+ uint32_t v_mcu_blocks_my_mul_0 = 0;
+ uint32_t v_my = 0;
+ uint32_t v_mx = 0;
+ uint64_t v_stride = 0;
+ uint64_t v_offset = 0;
+ uint8_t v_stashed_mcu_blocks_0[128] = {0};
+
+ wuffs_base__bulk_save_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__make_slice_u8(v_stashed_mcu_blocks_0, 128));
+ v_block_smoothing_applicable = true;
+ v_csel = 0u;
+ while (v_csel < self->private_impl.f_num_components) {
+ if ((self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][0u] >= 16u) || wuffs_jpeg__decoder__top_left_quants_has_zero(self, ((uint32_t)(self->private_impl.f_components_tq[v_csel])))) {
+ v_block_smoothing_applicable = false;
+ }
+ v_csel += 1u;
+ }
+ v_csel = 0u;
+ while (v_csel < self->private_impl.f_num_components) {
+ v_scan_width_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_width, self->private_impl.f_components_h[v_csel], self->private_impl.f_max_incl_components_h);
+ v_scan_height_in_mcus = wuffs_jpeg__decoder__quantize_dimension(self, self->private_impl.f_height, self->private_impl.f_components_v[v_csel], self->private_impl.f_max_incl_components_v);
+ v_mcu_blocks_mx_mul_0 = 8u;
+ v_mcu_blocks_my_mul_0 = (8u * self->private_impl.f_components_workbuf_widths[v_csel]);
+ if (v_block_smoothing_applicable && (0u != (self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][1u] |
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][2u] |
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][3u] |
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][4u] |
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][5u] |
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][6u] |
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] |
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][8u] |
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_csel][9u]))) {
+ self->private_impl.choosy_load_mcu_blocks_for_single_component = (
+ &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth);
+ self->private_impl.f_block_smoothing_mx_max_incl = wuffs_base__u32__sat_sub(v_scan_width_in_mcus, 1u);
+ self->private_impl.f_block_smoothing_my_max_incl = wuffs_base__u32__sat_sub(v_scan_height_in_mcus, 1u);
+ } else {
+ self->private_impl.choosy_load_mcu_blocks_for_single_component = (
+ &wuffs_jpeg__decoder__load_mcu_blocks_for_single_component__choosy_default);
+ }
+ v_my = 0u;
+ while (v_my < v_scan_height_in_mcus) {
+ v_mx = 0u;
+ while (v_mx < v_scan_width_in_mcus) {
+ wuffs_jpeg__decoder__load_mcu_blocks_for_single_component(self,
+ v_mx,
+ v_my,
+ a_workbuf,
+ v_csel);
+ v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel]));
+ v_offset = (self->private_impl.f_components_workbuf_offsets[v_csel] + (((uint64_t)(v_mcu_blocks_mx_mul_0)) * ((uint64_t)(v_mx))) + (((uint64_t)(v_mcu_blocks_my_mul_0)) * ((uint64_t)(v_my))));
+ if (v_offset <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_jpeg__decoder__decode_idct(self, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset), v_stride, ((uint32_t)(self->private_impl.f_components_tq[v_csel])));
+ }
+ v_mx += 1u;
+ }
+ v_my += 1u;
+ }
+ v_csel += 1u;
+ }
+ wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__make_slice_u8(v_stashed_mcu_blocks_0, 128));
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func jpeg.decoder.swizzle_gray
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__swizzle_gray(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint32_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_length = 0;
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint32_t v_y = 0;
+ uint64_t v_stride = 0;
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ }
+ v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
+ v_dst_length = ((uint64_t)((v_dst_bytes_per_pixel * self->private_impl.f_width)));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ v_y = 0u;
+ while (v_y < self->private_impl.f_height) {
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
+ if (v_dst_length < ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_length);
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)), a_workbuf);
+ v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[0u]));
+ if (v_stride <= ((uint64_t)(a_workbuf.len))) {
+ a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, v_stride);
+ } else {
+ a_workbuf = wuffs_base__utility__empty_slice_u8();
+ }
+ v_y += 1u;
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func jpeg.decoder.swizzle_colorful
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_jpeg__decoder__swizzle_colorful(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__slice_u8 v_src0 = {0};
+ wuffs_base__slice_u8 v_src1 = {0};
+ wuffs_base__slice_u8 v_src2 = {0};
+ wuffs_base__slice_u8 v_src3 = {0};
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ if ((self->private_impl.f_components_workbuf_offsets[0u] <= self->private_impl.f_components_workbuf_offsets[1u]) && (self->private_impl.f_components_workbuf_offsets[1u] <= ((uint64_t)(a_workbuf.len)))) {
+ v_src0 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
+ self->private_impl.f_components_workbuf_offsets[0u],
+ self->private_impl.f_components_workbuf_offsets[1u]);
+ }
+ if ((self->private_impl.f_components_workbuf_offsets[1u] <= self->private_impl.f_components_workbuf_offsets[2u]) && (self->private_impl.f_components_workbuf_offsets[2u] <= ((uint64_t)(a_workbuf.len)))) {
+ v_src1 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
+ self->private_impl.f_components_workbuf_offsets[1u],
+ self->private_impl.f_components_workbuf_offsets[2u]);
+ }
+ if ((self->private_impl.f_components_workbuf_offsets[2u] <= self->private_impl.f_components_workbuf_offsets[3u]) && (self->private_impl.f_components_workbuf_offsets[3u] <= ((uint64_t)(a_workbuf.len)))) {
+ v_src2 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
+ self->private_impl.f_components_workbuf_offsets[2u],
+ self->private_impl.f_components_workbuf_offsets[3u]);
+ }
+ if ((self->private_impl.f_components_workbuf_offsets[3u] <= self->private_impl.f_components_workbuf_offsets[4u]) && (self->private_impl.f_components_workbuf_offsets[4u] <= ((uint64_t)(a_workbuf.len)))) {
+ v_src3 = wuffs_base__slice_u8__subslice_ij(a_workbuf,
+ self->private_impl.f_components_workbuf_offsets[3u],
+ self->private_impl.f_components_workbuf_offsets[4u]);
+ }
+ v_status = wuffs_base__pixel_swizzler__swizzle_ycck(&self->private_impl.f_swizzler,
+ a_dst,
+ wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ v_src0,
+ v_src1,
+ v_src2,
+ v_src3,
+ self->private_impl.f_components_workbuf_widths[0u],
+ self->private_impl.f_components_workbuf_widths[1u],
+ self->private_impl.f_components_workbuf_widths[2u],
+ self->private_impl.f_components_workbuf_widths[3u],
+ self->private_impl.f_components_workbuf_heights[0u],
+ self->private_impl.f_components_workbuf_heights[1u],
+ self->private_impl.f_components_workbuf_heights[2u],
+ self->private_impl.f_components_workbuf_heights[3u],
+ self->private_impl.f_components_workbuf_widths[0u],
+ self->private_impl.f_components_workbuf_widths[1u],
+ self->private_impl.f_components_workbuf_widths[2u],
+ self->private_impl.f_components_workbuf_widths[3u],
+ self->private_impl.f_components_h[0u],
+ self->private_impl.f_components_h[1u],
+ self->private_impl.f_components_h[2u],
+ self->private_impl.f_components_h[3u],
+ self->private_impl.f_components_v[0u],
+ self->private_impl.f_components_v[1u],
+ self->private_impl.f_components_v[2u],
+ self->private_impl.f_components_v[3u],
+ self->private_impl.f_is_rgb_or_cmyk,
+ true,
+ wuffs_base__make_slice_u8(self->private_data.f_swizzle_ycck_scratch_buffer_2k, 2048));
+ return wuffs_base__status__ensure_not_a_suspension(v_status);
+}
+
+// -------- func jpeg.decoder.frame_dirty_rect
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_jpeg__decoder__frame_dirty_rect(
+ const wuffs_jpeg__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ return wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height);
+}
+
+// -------- func jpeg.decoder.num_animation_loops
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_jpeg__decoder__num_animation_loops(
+ const wuffs_jpeg__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func jpeg.decoder.num_decoded_frame_configs
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_jpeg__decoder__num_decoded_frame_configs(
+ const wuffs_jpeg__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 32u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func jpeg.decoder.num_decoded_frames
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_jpeg__decoder__num_decoded_frames(
+ const wuffs_jpeg__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 64u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func jpeg.decoder.restart_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__restart_frame(
+ wuffs_jpeg__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ uint32_t v_i = 0;
+ uint32_t v_j = 0;
+
+ if (self->private_impl.f_call_sequence < 32u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ }
+ if (a_index != 0u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_call_sequence = 40u;
+ self->private_impl.f_bitstream_is_closed = false;
+ self->private_impl.f_frame_config_io_position = a_io_position;
+ self->private_impl.f_scan_count = 0u;
+ self->private_impl.f_restart_interval = self->private_impl.f_saved_restart_interval;
+ v_i = 0u;
+ while (v_i < 4u) {
+ self->private_impl.f_seen_dqt[v_i] = self->private_impl.f_saved_seen_dqt[v_i];
+ v_j = 0u;
+ while (v_j < 64u) {
+ self->private_impl.f_quant_tables[v_i][v_j] = self->private_impl.f_saved_quant_tables[v_i][v_j];
+ v_j += 1u;
+ }
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < 4u) {
+ v_j = 0u;
+ while (v_j < 10u) {
+ self->private_impl.f_block_smoothing_lowest_scan_al[v_i][v_j] = 16u;
+ v_j += 1u;
+ }
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < 8u) {
+ self->private_impl.f_seen_dht[v_i] = false;
+ v_i += 1u;
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func jpeg.decoder.set_report_metadata
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_jpeg__decoder__set_report_metadata(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func jpeg.decoder.tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_jpeg__decoder__tell_me_more(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 4)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ status = wuffs_base__make_status(wuffs_base__error__no_more_information);
+ goto exit;
+
+ goto ok;
+ ok:
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func jpeg.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_jpeg__decoder__history_retain_length(
+ const wuffs_jpeg__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func jpeg.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_jpeg__decoder__workbuf_len(
+ const wuffs_jpeg__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_components_workbuf_offsets[8u], self->private_impl.f_components_workbuf_offsets[8u]);
+}
+
+// -------- func jpeg.decoder.top_left_quants_has_zero
+
+WUFFS_BASE__GENERATED_C_CODE
+static bool
+wuffs_jpeg__decoder__top_left_quants_has_zero(
+ const wuffs_jpeg__decoder* self,
+ uint32_t a_q) {
+ return ((self->private_impl.f_quant_tables[a_q][0u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][1u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][2u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][3u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][8u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][9u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][10u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][16u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][17u] == 0u) ||
+ (self->private_impl.f_quant_tables[a_q][24u] == 0u));
+}
+
+// -------- func jpeg.decoder.load_mcu_blocks_for_single_component_smooth
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_jpeg__decoder__load_mcu_blocks_for_single_component_smooth(
+ wuffs_jpeg__decoder* self,
+ uint32_t a_mx,
+ uint32_t a_my,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_csel) {
+ uint64_t v_stride16 = 0;
+ uint64_t v_offset = 0;
+ uint32_t v_dx = 0;
+ uint32_t v_dy = 0;
+ uint32_t v_mx = 0;
+ uint32_t v_my = 0;
+ uint8_t v_q = 0;
+ uint32_t v_q_00 = 0;
+ uint32_t v_q_xy = 0;
+ uint8_t v_al = 0;
+ uint32_t v_scratch = 0;
+ uint32_t v_limit = 0;
+
+ v_stride16 = ((uint64_t)((self->private_impl.f_components_workbuf_widths[a_csel] * 16u)));
+ v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(a_mx)) * 128u) + (((uint64_t)(a_my)) * v_stride16));
+ if (v_offset <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_base__bulk_load_host_endian(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
+ }
+ v_dy = 0u;
+ while (v_dy < 5u) {
+ v_my = wuffs_base__u32__min(self->private_impl.f_block_smoothing_my_max_incl, wuffs_base__u32__sat_sub((a_my + v_dy), 2u));
+ v_dx = 0u;
+ while (v_dx < 5u) {
+ v_mx = wuffs_base__u32__min(self->private_impl.f_block_smoothing_mx_max_incl, wuffs_base__u32__sat_sub((a_mx + v_dx), 2u));
+ v_offset = (self->private_impl.f_components_workbuf_offsets[(a_csel | 4u)] + (((uint64_t)(v_mx)) * 128u) + (((uint64_t)(v_my)) * v_stride16));
+ if (v_offset <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_base__bulk_load_host_endian(&self->private_impl.f_block_smoothing_dc_values[v_dy][v_dx], 1u * (size_t)2u, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset));
+ }
+ v_dx += 1u;
+ }
+ v_dy += 1u;
+ }
+ v_q = self->private_impl.f_components_tq[a_csel];
+ v_q_00 = ((uint32_t)(self->private_impl.f_quant_tables[v_q][0u]));
+ if (v_q_00 <= 0u) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (0u != (16u &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u] &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u] &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u] &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u] &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u] &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][6u] &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][7u] &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][8u] &
+ self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][9u])) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(152u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(42u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(6u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(4294967288u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(4294967290u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + 128u)) / 256u)));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + 128u)) / 256u)));
+ }
+ self->private_data.f_mcu_blocks[0u][0u] = ((uint16_t)(v_scratch));
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch));
+ }
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch));
+ }
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][3u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][3u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][3u] = ((uint16_t)(v_scratch));
+ }
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(38u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(4294967258u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(4294967283u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch));
+ }
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(4294967287u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(9u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch));
+ }
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][10u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][10u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][10u] = ((uint16_t)(v_scratch));
+ }
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(4294967282u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(4294967291u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch));
+ }
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][17u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][17u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(4294967293u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(3u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][17u] = ((uint16_t)(v_scratch));
+ }
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][24u]));
+ if ((v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][24u] == 0u)) {
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(2u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(4294967294u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ } else {
+ v_scratch = ((uint32_t)(0u - (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u))));
+ }
+ self->private_data.f_mcu_blocks[0u][24u] = ((uint16_t)(v_scratch));
+ }
+ } else {
+ v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][1u];
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][1u]));
+ if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][1u] == 0u)) {
+ v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ } else {
+ v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ }
+ self->private_data.f_mcu_blocks[0u][1u] = ((uint16_t)(v_scratch));
+ }
+ v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][5u];
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][2u]));
+ if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][2u] == 0u)) {
+ v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ } else {
+ v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ }
+ self->private_data.f_mcu_blocks[0u][2u] = ((uint16_t)(v_scratch));
+ }
+ v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][2u];
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][8u]));
+ if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][8u] == 0u)) {
+ v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(4294967289u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(50u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(4294967246u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(7u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ } else {
+ v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ }
+ self->private_data.f_mcu_blocks[0u][8u] = ((uint16_t)(v_scratch));
+ }
+ v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][4u];
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][9u]));
+ if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][9u] == 0u)) {
+ v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(4294967286u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(10u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(1u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ } else {
+ v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ }
+ self->private_data.f_mcu_blocks[0u][9u] = ((uint16_t)(v_scratch));
+ }
+ v_al = self->private_impl.f_block_smoothing_lowest_scan_al[a_csel][3u];
+ v_q_xy = ((uint32_t)(self->private_impl.f_quant_tables[v_q][16u]));
+ if ((v_al > 0u) && (v_q_xy > 0u) && (self->private_data.f_mcu_blocks[0u][16u] == 0u)) {
+ v_limit = ((((uint32_t)(1u)) << v_al) - 1u);
+ v_scratch = 0u;
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][1u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[0u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][1u])));
+ v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[1u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][1u])));
+ v_scratch += ((uint32_t)(4294967272u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[2u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][1u])));
+ v_scratch += ((uint32_t)(13u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[3u][4u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][0u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][1u])));
+ v_scratch += ((uint32_t)(4294967295u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][2u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][3u])));
+ v_scratch += ((uint32_t)(0u * wuffs_base__utility__sign_extend_convert_u16_u32(self->private_impl.f_block_smoothing_dc_values[4u][4u])));
+ v_scratch *= v_q_00;
+ if (v_scratch < 2147483648u) {
+ v_scratch = ((uint32_t)(0u + wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u + v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ } else {
+ v_scratch = ((uint32_t)(0u - wuffs_base__u32__min(v_limit, (((uint32_t)(((uint32_t)(0u - v_scratch)) + (v_q_xy << 7u))) / (v_q_xy << 8u)))));
+ }
+ self->private_data.f_mcu_blocks[0u][16u] = ((uint16_t)(v_scratch));
+ }
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func jpeg.decoder.decode_mcu
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my) {
+ return (*self->private_impl.choosy_decode_mcu)(self, a_workbuf, a_mx, a_my);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu__choosy_default(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my) {
+ uint32_t v_ret = 0;
+ uint64_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint8_t v_csel = 0;
+ wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_r = &u_r;
+ const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint32_t v_pos = 0;
+ uint8_t v_dc_h = 0;
+ uint32_t v_dc_symbol = 0;
+ uint32_t v_dc_ht_fast = 0;
+ uint32_t v_dc_bl = 0;
+ uint32_t v_dc_code = 0;
+ uint32_t v_dc_blm1 = 0;
+ uint32_t v_dc_ht_slow = 0;
+ uint16_t v_dc_value = 0;
+ uint16_t v_dc_extend = 0;
+ const uint16_t* v_ac_huff_table_fast = NULL;
+ uint8_t v_ac_h = 0;
+ uint32_t v_ac_symbol = 0;
+ uint32_t v_ac_ht_fast = 0;
+ uint32_t v_ac_bl = 0;
+ uint32_t v_ac_code = 0;
+ uint32_t v_ac_blm1 = 0;
+ uint32_t v_ac_ht_slow = 0;
+ uint16_t v_ac_value = 0;
+ uint16_t v_ac_extend = 0;
+ uint32_t v_ac_rrrr = 0;
+ uint32_t v_ac_ssss = 0;
+ uint32_t v_z = 0;
+ uint32_t v_mcb = 0;
+ uint64_t v_stride = 0;
+ uint64_t v_offset = 0;
+
+ v_bits = self->private_impl.f_bitstream_bits;
+ v_n_bits = self->private_impl.f_bitstream_n_bits;
+ if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
+ return 2u;
+ }
+ {
+ wuffs_base__io_buffer* o_0_v_r = v_r;
+ const uint8_t *o_0_iop_v_r = iop_v_r;
+ const uint8_t *o_0_io0_v_r = io0_v_r;
+ const uint8_t *o_0_io1_v_r = io1_v_r;
+ const uint8_t *o_0_io2_v_r = io2_v_r;
+ v_r = wuffs_base__io_reader__set(
+ &u_r,
+ &iop_v_r,
+ &io0_v_r,
+ &io1_v_r,
+ &io2_v_r,
+ wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
+ self->private_impl.f_bitstream_ri,
+ self->private_impl.f_bitstream_wi),
+ ((uint64_t)(self->private_impl.f_bitstream_ri)));
+ do {
+ while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
+ while (self->private_impl.f_mcu_zig_index <= 0u) {
+ wuffs_base__bulk_memset(&self->private_data.f_mcu_blocks[0], 1u * (size_t)128u, 0u);
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
+ v_ret = 1u;
+ goto label__goto_done__break;
+ }
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block];
+ v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)]));
+ v_dc_bl = (v_dc_ht_fast >> 8u);
+ if (v_n_bits >= v_dc_bl) {
+ v_dc_symbol = (15u & v_dc_ht_fast);
+ v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
+ v_bits <<= (v_dc_bl & 63u);
+ v_n_bits -= v_dc_bl;
+ } else {
+ v_dc_code = ((uint32_t)((v_bits >> 55u)));
+ v_dc_blm1 = 8u;
+ v_bits <<= 9u;
+ v_n_bits -= 9u;
+ while (true) {
+ v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1];
+ if (v_dc_code < (v_dc_ht_slow >> 8u)) {
+ v_dc_symbol = (15u & ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_dc_h][(255u & ((uint32_t)(v_dc_code + v_dc_ht_slow)))])));
+ v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
+ break;
+ }
+ v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u);
+ if (v_dc_blm1 == 0u) {
+ v_dc_symbol = 0u;
+ v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
+ break;
+ }
+ }
+ }
+ v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol))));
+ v_dc_value += (v_dc_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u));
+ v_bits <<= v_dc_symbol;
+ v_n_bits -= v_dc_symbol;
+ v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]];
+ self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value;
+ self->private_data.f_mcu_blocks[0u][0u] = self->private_impl.f_mcu_previous_dc_values[v_csel];
+ self->private_impl.f_mcu_zig_index = 1u;
+ break;
+ }
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
+ v_ret = 1u;
+ goto label__goto_done__break;
+ }
+ if (v_n_bits < 16u) {
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ }
+ v_z = 1u;
+ self->private_impl.f_mcu_zig_index = 0u;
+ v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[self->private_impl.f_mcu_current_block];
+ v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
+ while (v_z < 64u) {
+ v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
+ v_ret = 2u;
+ goto label__goto_done__break;
+ }
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ v_ac_bl = (v_ac_ht_fast >> 8u);
+ if (v_n_bits >= v_ac_bl) {
+ v_ac_symbol = (255u & v_ac_ht_fast);
+ v_bits <<= (v_ac_bl & 63u);
+ v_n_bits -= v_ac_bl;
+ } else {
+ v_ac_code = ((uint32_t)((v_bits >> 55u)));
+ v_ac_blm1 = 8u;
+ v_bits <<= 9u;
+ v_n_bits -= 9u;
+ while (true) {
+ v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
+ if (v_ac_code < (v_ac_ht_slow >> 8u)) {
+ v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))]));
+ break;
+ }
+ v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
+ if (v_ac_blm1 == 0u) {
+ v_ac_symbol = 0u;
+ break;
+ }
+ }
+ }
+ v_ac_rrrr = (v_ac_symbol >> 4u);
+ v_z += (v_ac_rrrr + 1u);
+ v_ac_ssss = (v_ac_symbol & 15u);
+ v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss];
+ if (v_ac_ssss > 0u) {
+ v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss))));
+ v_ac_value += (v_ac_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u));
+ v_bits <<= v_ac_ssss;
+ v_n_bits -= v_ac_ssss;
+ self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[v_z]] = v_ac_value;
+ } else if (v_ac_rrrr < 15u) {
+ break;
+ }
+ }
+ v_mcb = self->private_impl.f_mcu_current_block;
+ self->private_impl.f_mcu_current_block += 1u;
+ if (self->private_impl.f_test_only_interrupt_decode_mcu) {
+ goto label__goto_done__break;
+ }
+ v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[v_mcb]];
+ v_stride = ((uint64_t)(self->private_impl.f_components_workbuf_widths[v_csel]));
+ v_offset = (self->private_impl.f_mcu_blocks_offset[v_mcb] + (((uint64_t)(self->private_impl.f_mcu_blocks_mx_mul[v_mcb])) * ((uint64_t)(a_mx))) + (((uint64_t)(self->private_impl.f_mcu_blocks_my_mul[v_mcb])) * ((uint64_t)(a_my))));
+ if (v_offset <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_jpeg__decoder__decode_idct(self, wuffs_base__slice_u8__subslice_i(a_workbuf, v_offset), v_stride, ((uint32_t)(self->private_impl.f_components_tq[v_csel])));
+ }
+ }
+ self->private_impl.f_mcu_current_block = 0u;
+ } while (0);
+ label__goto_done__break:;
+ v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
+ if (v_pos > self->private_impl.f_bitstream_wi) {
+ v_ret = 2u;
+ } else {
+ self->private_impl.f_bitstream_ri = v_pos;
+ }
+ v_r = o_0_v_r;
+ iop_v_r = o_0_iop_v_r;
+ io0_v_r = o_0_io0_v_r;
+ io1_v_r = o_0_io1_v_r;
+ io2_v_r = o_0_io2_v_r;
+ }
+ self->private_impl.f_bitstream_bits = v_bits;
+ self->private_impl.f_bitstream_n_bits = v_n_bits;
+ return v_ret;
+}
+
+// -------- func jpeg.decoder.decode_mcu_progressive_ac_high_bits
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu_progressive_ac_high_bits(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my) {
+ uint32_t v_ret = 0;
+ uint64_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_r = &u_r;
+ const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint32_t v_pos = 0;
+ const uint16_t* v_ac_huff_table_fast = NULL;
+ uint8_t v_ac_h = 0;
+ uint32_t v_ac_symbol = 0;
+ uint32_t v_ac_ht_fast = 0;
+ uint32_t v_ac_bl = 0;
+ uint32_t v_ac_code = 0;
+ uint32_t v_ac_blm1 = 0;
+ uint32_t v_ac_ht_slow = 0;
+ uint16_t v_ac_value = 0;
+ uint16_t v_ac_extend = 0;
+ uint32_t v_ac_rrrr = 0;
+ uint32_t v_ac_ssss = 0;
+ uint32_t v_z = 0;
+
+ if (self->private_impl.f_eob_run > 0u) {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_impl.f_eob_run -= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ return 0u;
+ }
+ v_bits = self->private_impl.f_bitstream_bits;
+ v_n_bits = self->private_impl.f_bitstream_n_bits;
+ if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
+ return 2u;
+ }
+ {
+ wuffs_base__io_buffer* o_0_v_r = v_r;
+ const uint8_t *o_0_iop_v_r = iop_v_r;
+ const uint8_t *o_0_io0_v_r = io0_v_r;
+ const uint8_t *o_0_io1_v_r = io1_v_r;
+ const uint8_t *o_0_io2_v_r = io2_v_r;
+ v_r = wuffs_base__io_reader__set(
+ &u_r,
+ &iop_v_r,
+ &io0_v_r,
+ &io1_v_r,
+ &io2_v_r,
+ wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
+ self->private_impl.f_bitstream_ri,
+ self->private_impl.f_bitstream_wi),
+ ((uint64_t)(self->private_impl.f_bitstream_ri)));
+ do {
+ do {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
+ v_ret = 1u;
+ goto label__goto_done__break;
+ }
+ if (v_n_bits < 16u) {
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ }
+ v_z = self->private_impl.f_mcu_zig_index;
+ self->private_impl.f_mcu_zig_index = 0u;
+ v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u];
+ v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
+ while (v_z <= ((uint32_t)(self->private_impl.f_scan_se))) {
+ v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
+ v_ret = 2u;
+ goto label__goto_done__break;
+ }
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ v_ac_bl = (v_ac_ht_fast >> 8u);
+ if (v_n_bits >= v_ac_bl) {
+ v_ac_symbol = (255u & v_ac_ht_fast);
+ v_bits <<= (v_ac_bl & 63u);
+ v_n_bits -= v_ac_bl;
+ } else {
+ v_ac_code = ((uint32_t)((v_bits >> 55u)));
+ v_ac_blm1 = 8u;
+ v_bits <<= 9u;
+ v_n_bits -= 9u;
+ while (true) {
+ v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
+ if (v_ac_code < (v_ac_ht_slow >> 8u)) {
+ v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))]));
+ break;
+ }
+ v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
+ if (v_ac_blm1 == 0u) {
+ v_ac_symbol = 0u;
+ break;
+ }
+ }
+ }
+ v_ac_rrrr = (v_ac_symbol >> 4u);
+ v_z += (v_ac_rrrr + 1u);
+ v_ac_ssss = (v_ac_symbol & 15u);
+ v_ac_extend = WUFFS_JPEG__EXTEND[v_ac_ssss];
+ if (v_ac_ssss > 0u) {
+ v_ac_value = ((uint16_t)((v_bits >> (64u - v_ac_ssss))));
+ v_ac_value += (v_ac_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u));
+ v_bits <<= v_ac_ssss;
+ v_n_bits -= v_ac_ssss;
+ self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[v_z]] = ((uint16_t)(((uint16_t)(v_ac_value << self->private_impl.f_scan_al))));
+ } else if (v_ac_rrrr < 15u) {
+ self->private_impl.f_eob_run = ((uint16_t)(((((uint16_t)(1u)) << v_ac_rrrr) - 1u)));
+ if (v_ac_rrrr > 0u) {
+ self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr))));
+ v_bits <<= v_ac_rrrr;
+ v_n_bits -= v_ac_rrrr;
+ }
+ break;
+ }
+ }
+ } while (0);
+ } while (0);
+ label__goto_done__break:;
+ v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
+ if (v_pos > self->private_impl.f_bitstream_wi) {
+ v_ret = 2u;
+ } else {
+ self->private_impl.f_bitstream_ri = v_pos;
+ }
+ v_r = o_0_v_r;
+ iop_v_r = o_0_iop_v_r;
+ io0_v_r = o_0_io0_v_r;
+ io1_v_r = o_0_io1_v_r;
+ io2_v_r = o_0_io2_v_r;
+ }
+ self->private_impl.f_bitstream_bits = v_bits;
+ self->private_impl.f_bitstream_n_bits = v_n_bits;
+ return v_ret;
+}
+
+// -------- func jpeg.decoder.decode_mcu_progressive_ac_low_bit
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu_progressive_ac_low_bit(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my) {
+ uint32_t v_ret = 0;
+ uint64_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint16_t v_one_lshift_scan_al = 0;
+ wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_r = &u_r;
+ const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint32_t v_pos = 0;
+ const uint16_t* v_ac_huff_table_fast = NULL;
+ uint8_t v_ac_h = 0;
+ uint32_t v_ac_symbol = 0;
+ uint32_t v_ac_ht_fast = 0;
+ uint32_t v_ac_bl = 0;
+ uint32_t v_ac_code = 0;
+ uint32_t v_ac_blm1 = 0;
+ uint32_t v_ac_ht_slow = 0;
+ uint16_t v_ac_value = 0;
+ uint32_t v_ac_rrrr = 0;
+ uint32_t v_ac_ssss = 0;
+ uint8_t v_unzig = 0;
+ bool v_bit = false;
+
+ v_bits = self->private_impl.f_bitstream_bits;
+ v_n_bits = self->private_impl.f_bitstream_n_bits;
+ v_one_lshift_scan_al = (((uint16_t)(1u)) << self->private_impl.f_scan_al);
+ if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
+ return 2u;
+ }
+ {
+ wuffs_base__io_buffer* o_0_v_r = v_r;
+ const uint8_t *o_0_iop_v_r = iop_v_r;
+ const uint8_t *o_0_io0_v_r = io0_v_r;
+ const uint8_t *o_0_io1_v_r = io1_v_r;
+ const uint8_t *o_0_io2_v_r = io2_v_r;
+ v_r = wuffs_base__io_reader__set(
+ &u_r,
+ &iop_v_r,
+ &io0_v_r,
+ &io1_v_r,
+ &io2_v_r,
+ wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
+ self->private_impl.f_bitstream_ri,
+ self->private_impl.f_bitstream_wi),
+ ((uint64_t)(self->private_impl.f_bitstream_ri)));
+ do {
+ do {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
+ v_ret = 1u;
+ goto label__goto_done__break;
+ }
+ while (true) {
+ if (self->private_impl.f_eob_run > 0u) {
+ break;
+ }
+ v_ac_h = self->private_impl.f_mcu_blocks_ac_hselector[0u];
+ v_ac_huff_table_fast = &self->private_impl.f_huff_tables_fast[v_ac_h][0u];
+ while (true) {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
+ v_ret = 2u;
+ goto label__goto_done__break;
+ }
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ v_ac_ht_fast = ((uint32_t)(v_ac_huff_table_fast[(v_bits >> 56u)]));
+ v_ac_bl = (v_ac_ht_fast >> 8u);
+ if (v_n_bits >= v_ac_bl) {
+ v_ac_symbol = (255u & v_ac_ht_fast);
+ v_bits <<= (v_ac_bl & 63u);
+ v_n_bits -= v_ac_bl;
+ } else {
+ v_ac_code = ((uint32_t)((v_bits >> 55u)));
+ v_ac_blm1 = 8u;
+ v_bits <<= 9u;
+ v_n_bits -= 9u;
+ while (true) {
+ v_ac_ht_slow = self->private_impl.f_huff_tables_slow[v_ac_h][v_ac_blm1];
+ if (v_ac_code < (v_ac_ht_slow >> 8u)) {
+ v_ac_symbol = ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_ac_h][(255u & ((uint32_t)(v_ac_code + v_ac_ht_slow)))]));
+ break;
+ }
+ v_ac_code = (((uint32_t)(v_ac_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ v_ac_blm1 = ((v_ac_blm1 + 1u) & 15u);
+ if (v_ac_blm1 == 0u) {
+ v_ac_symbol = 0u;
+ break;
+ }
+ }
+ }
+ v_ac_rrrr = (v_ac_symbol >> 4u);
+ v_ac_ssss = (v_ac_symbol & 15u);
+ v_ac_value = 0u;
+ if (v_ac_ssss > 0u) {
+ v_ac_value = (((uint16_t)(1u)) << self->private_impl.f_scan_al);
+ if ((v_bits >> 63u) == 0u) {
+ v_ac_value = ((uint16_t)(((uint16_t)(65535u)) << self->private_impl.f_scan_al));
+ }
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ } else if (v_ac_rrrr < 15u) {
+ self->private_impl.f_eob_run = (((uint16_t)(1u)) << v_ac_rrrr);
+ if (v_ac_rrrr > 0u) {
+ self->private_impl.f_eob_run += ((uint16_t)((v_bits >> (64u - v_ac_rrrr))));
+ v_bits <<= v_ac_rrrr;
+ v_n_bits -= v_ac_rrrr;
+ }
+ goto label__goto_do_eob__break;
+ }
+ while (true) {
+ v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)];
+ if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) {
+ if (v_n_bits == 0u) {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
+ v_ret = 2u;
+ goto label__goto_done__break;
+ }
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ }
+ v_bit = ((v_bits >> 63u) > 0u);
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ if (v_bit) {
+ if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ }
+ }
+ } else if (v_ac_rrrr <= 0u) {
+ break;
+ } else {
+ v_ac_rrrr -= 1u;
+ }
+ if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
+ break;
+ }
+ self->private_impl.f_mcu_zig_index += 1u;
+ }
+ if (v_ac_value != 0u) {
+ self->private_data.f_mcu_blocks[0u][WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)]] = v_ac_value;
+ }
+ if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
+ break;
+ }
+ self->private_impl.f_mcu_zig_index += 1u;
+ }
+ goto label__block__break;
+ }
+ label__goto_do_eob__break:;
+ if (self->private_impl.f_eob_run <= 0u) {
+ v_ret = 2u;
+ goto label__goto_done__break;
+ }
+ while (true) {
+ v_unzig = WUFFS_JPEG__UNZIG[(1u + self->private_impl.f_mcu_zig_index)];
+ if (self->private_data.f_mcu_blocks[0u][v_unzig] != 0u) {
+ if (v_n_bits == 0u) {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
+ v_ret = 2u;
+ goto label__goto_done__break;
+ }
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ }
+ v_bit = ((v_bits >> 63u) > 0u);
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ if (v_bit) {
+ if (self->private_data.f_mcu_blocks[0u][v_unzig] < 32768u) {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_data.f_mcu_blocks[0u][v_unzig] += v_one_lshift_scan_al;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_data.f_mcu_blocks[0u][v_unzig] -= v_one_lshift_scan_al;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ }
+ }
+ }
+ if (self->private_impl.f_mcu_zig_index >= ((uint32_t)(self->private_impl.f_scan_se))) {
+ break;
+ }
+ self->private_impl.f_mcu_zig_index += 1u;
+ }
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_impl.f_eob_run -= 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } while (0);
+ label__block__break:;
+ } while (0);
+ label__goto_done__break:;
+ v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
+ if (v_pos > self->private_impl.f_bitstream_wi) {
+ v_ret = 2u;
+ } else {
+ self->private_impl.f_bitstream_ri = v_pos;
+ }
+ v_r = o_0_v_r;
+ iop_v_r = o_0_iop_v_r;
+ io0_v_r = o_0_io0_v_r;
+ io1_v_r = o_0_io1_v_r;
+ io2_v_r = o_0_io2_v_r;
+ }
+ self->private_impl.f_bitstream_bits = v_bits;
+ self->private_impl.f_bitstream_n_bits = v_n_bits;
+ return v_ret;
+}
+
+// -------- func jpeg.decoder.decode_mcu_progressive_dc_high_bits
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu_progressive_dc_high_bits(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my) {
+ uint32_t v_ret = 0;
+ uint64_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint8_t v_csel = 0;
+ wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_r = &u_r;
+ const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint32_t v_pos = 0;
+ uint8_t v_dc_h = 0;
+ uint32_t v_dc_symbol = 0;
+ uint32_t v_dc_ht_fast = 0;
+ uint32_t v_dc_bl = 0;
+ uint32_t v_dc_code = 0;
+ uint32_t v_dc_blm1 = 0;
+ uint32_t v_dc_ht_slow = 0;
+ uint16_t v_dc_value = 0;
+ uint16_t v_dc_extend = 0;
+
+ v_bits = self->private_impl.f_bitstream_bits;
+ v_n_bits = self->private_impl.f_bitstream_n_bits;
+ if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
+ return 2u;
+ }
+ {
+ wuffs_base__io_buffer* o_0_v_r = v_r;
+ const uint8_t *o_0_iop_v_r = iop_v_r;
+ const uint8_t *o_0_io0_v_r = io0_v_r;
+ const uint8_t *o_0_io1_v_r = io1_v_r;
+ const uint8_t *o_0_io2_v_r = io2_v_r;
+ v_r = wuffs_base__io_reader__set(
+ &u_r,
+ &iop_v_r,
+ &io0_v_r,
+ &io1_v_r,
+ &io2_v_r,
+ wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
+ self->private_impl.f_bitstream_ri,
+ self->private_impl.f_bitstream_wi),
+ ((uint64_t)(self->private_impl.f_bitstream_ri)));
+ do {
+ while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
+ v_ret = 1u;
+ goto label__goto_done__break;
+ }
+ do {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
+ v_ret = 2u;
+ goto label__goto_done__break;
+ }
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ v_dc_h = self->private_impl.f_mcu_blocks_dc_hselector[self->private_impl.f_mcu_current_block];
+ v_dc_ht_fast = ((uint32_t)(self->private_impl.f_huff_tables_fast[v_dc_h][(v_bits >> 56u)]));
+ v_dc_bl = (v_dc_ht_fast >> 8u);
+ if (v_n_bits >= v_dc_bl) {
+ v_dc_symbol = (15u & v_dc_ht_fast);
+ v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
+ v_bits <<= (v_dc_bl & 63u);
+ v_n_bits -= v_dc_bl;
+ } else {
+ v_dc_code = ((uint32_t)((v_bits >> 55u)));
+ v_dc_blm1 = 8u;
+ v_bits <<= 9u;
+ v_n_bits -= 9u;
+ while (true) {
+ v_dc_ht_slow = self->private_impl.f_huff_tables_slow[v_dc_h][v_dc_blm1];
+ if (v_dc_code < (v_dc_ht_slow >> 8u)) {
+ v_dc_symbol = (15u & ((uint32_t)(self->private_impl.f_huff_tables_symbols[v_dc_h][(255u & ((uint32_t)(v_dc_code + v_dc_ht_slow)))])));
+ v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
+ break;
+ }
+ v_dc_code = (((uint32_t)(v_dc_code << 1u)) | ((uint32_t)((v_bits >> 63u))));
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ v_dc_blm1 = ((v_dc_blm1 + 1u) & 15u);
+ if (v_dc_blm1 == 0u) {
+ v_dc_symbol = 0u;
+ v_dc_extend = WUFFS_JPEG__EXTEND[v_dc_symbol];
+ break;
+ }
+ }
+ }
+ v_dc_value = ((uint16_t)(((v_bits >> 32u) >> (32u - v_dc_symbol))));
+ v_dc_value += (v_dc_extend & (((uint16_t)(wuffs_base__utility__sign_extend_rshift_u64(v_bits, 63u))) ^ 65535u));
+ v_bits <<= v_dc_symbol;
+ v_n_bits -= v_dc_symbol;
+ v_csel = self->private_impl.f_scan_comps_cselector[self->private_impl.f_mcu_blocks_sselector[self->private_impl.f_mcu_current_block]];
+ self->private_impl.f_mcu_previous_dc_values[v_csel] += v_dc_value;
+ self->private_data.f_mcu_blocks[self->private_impl.f_mcu_current_block][0u] = ((uint16_t)(self->private_impl.f_mcu_previous_dc_values[v_csel] << self->private_impl.f_scan_al));
+ } while (0);
+ self->private_impl.f_mcu_current_block += 1u;
+ }
+ self->private_impl.f_mcu_current_block = 0u;
+ } while (0);
+ label__goto_done__break:;
+ v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
+ if (v_pos > self->private_impl.f_bitstream_wi) {
+ v_ret = 2u;
+ } else {
+ self->private_impl.f_bitstream_ri = v_pos;
+ }
+ v_r = o_0_v_r;
+ iop_v_r = o_0_iop_v_r;
+ io0_v_r = o_0_io0_v_r;
+ io1_v_r = o_0_io1_v_r;
+ io2_v_r = o_0_io2_v_r;
+ }
+ self->private_impl.f_bitstream_bits = v_bits;
+ self->private_impl.f_bitstream_n_bits = v_n_bits;
+ return v_ret;
+}
+
+// -------- func jpeg.decoder.decode_mcu_progressive_dc_low_bit
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_jpeg__decoder__decode_mcu_progressive_dc_low_bit(
+ wuffs_jpeg__decoder* self,
+ wuffs_base__slice_u8 a_workbuf,
+ uint32_t a_mx,
+ uint32_t a_my) {
+ uint32_t v_ret = 0;
+ uint64_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint16_t v_one_lshift_scan_al = 0;
+ wuffs_base__io_buffer u_r = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_r = &u_r;
+ const uint8_t* iop_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io0_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_v_r WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint32_t v_pos = 0;
+
+ v_bits = self->private_impl.f_bitstream_bits;
+ v_n_bits = self->private_impl.f_bitstream_n_bits;
+ v_one_lshift_scan_al = (((uint16_t)(1u)) << self->private_impl.f_scan_al);
+ if (self->private_impl.f_bitstream_ri > self->private_impl.f_bitstream_wi) {
+ return 2u;
+ }
+ {
+ wuffs_base__io_buffer* o_0_v_r = v_r;
+ const uint8_t *o_0_iop_v_r = iop_v_r;
+ const uint8_t *o_0_io0_v_r = io0_v_r;
+ const uint8_t *o_0_io1_v_r = io1_v_r;
+ const uint8_t *o_0_io2_v_r = io2_v_r;
+ v_r = wuffs_base__io_reader__set(
+ &u_r,
+ &iop_v_r,
+ &io0_v_r,
+ &io1_v_r,
+ &io2_v_r,
+ wuffs_base__make_slice_u8_ij(self->private_data.f_bitstream_buffer,
+ self->private_impl.f_bitstream_ri,
+ self->private_impl.f_bitstream_wi),
+ ((uint64_t)(self->private_impl.f_bitstream_ri)));
+ do {
+ while (self->private_impl.f_mcu_current_block < self->private_impl.f_mcu_num_blocks) {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 264u) {
+ v_ret = 1u;
+ goto label__goto_done__break;
+ }
+ do {
+ if (((uint64_t)(io2_v_r - iop_v_r)) < 8u) {
+ v_ret = 2u;
+ goto label__goto_done__break;
+ }
+ v_bits |= (wuffs_base__peek_u64be__no_bounds_check(iop_v_r) >> (v_n_bits & 63u));
+ iop_v_r += ((63u - (v_n_bits & 63u)) >> 3u);
+ v_n_bits |= 56u;
+ if ((v_bits >> 63u) != 0u) {
+ self->private_data.f_mcu_blocks[self->private_impl.f_mcu_current_block][0u] |= v_one_lshift_scan_al;
+ }
+ v_bits <<= 1u;
+ v_n_bits -= 1u;
+ } while (0);
+ self->private_impl.f_mcu_current_block += 1u;
+ }
+ self->private_impl.f_mcu_current_block = 0u;
+ } while (0);
+ label__goto_done__break:;
+ v_pos = ((uint32_t)(wuffs_base__u64__sat_add((v_r ? v_r->meta.pos : 0), ((uint64_t)(iop_v_r - io0_v_r)))));
+ if (v_pos > self->private_impl.f_bitstream_wi) {
+ v_ret = 2u;
+ } else {
+ self->private_impl.f_bitstream_ri = v_pos;
+ }
+ v_r = o_0_v_r;
+ iop_v_r = o_0_iop_v_r;
+ io0_v_r = o_0_io0_v_r;
+ io1_v_r = o_0_io1_v_r;
+ io2_v_r = o_0_io2_v_r;
+ }
+ self->private_impl.f_bitstream_bits = v_bits;
+ self->private_impl.f_bitstream_n_bits = v_n_bits;
+ return v_ret;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_json__error__bad_c0_control_code[] = "#json: bad C0 control code";
+const char wuffs_json__error__bad_utf_8[] = "#json: bad UTF-8";
+const char wuffs_json__error__bad_backslash_escape[] = "#json: bad backslash-escape";
+const char wuffs_json__error__bad_input[] = "#json: bad input";
+const char wuffs_json__error__bad_new_line_in_a_string[] = "#json: bad new-line in a string";
+const char wuffs_json__error__bad_quirk_combination[] = "#json: bad quirk combination";
+const char wuffs_json__error__unsupported_number_length[] = "#json: unsupported number length";
+const char wuffs_json__error__unsupported_recursion_depth[] = "#json: unsupported recursion depth";
+const char wuffs_json__error__internal_error_inconsistent_i_o[] = "#json: internal error: inconsistent I/O";
+
+// ---------------- Private Consts
+
+#define WUFFS_JSON__DECODER_NUMBER_LENGTH_MAX_INCL 99
+
+static const uint8_t
+WUFFS_JSON__LUT_BACKSLASHES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 3, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 162, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 0, 0, 0, 175,
+ 7, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 4,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 220, 0, 0, 0,
+ 0, 1, 136, 0, 0, 2, 140, 0,
+ 0, 0, 0, 0, 0, 0, 138, 0,
+ 0, 0, 141, 0, 137, 0, 6, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const uint8_t
+WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 1, 3, 4, 5, 6, 7, 10,
+};
+
+static const uint8_t
+WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 7, 27, 10, 63, 39, 11, 0,
+};
+
+static const uint8_t
+WUFFS_JSON__LUT_CHARS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 138, 139, 140, 141, 142, 143,
+ 144, 145, 146, 147, 148, 149, 150, 151,
+ 152, 153, 154, 155, 156, 157, 158, 159,
+ 0, 0, 1, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 2, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 16, 16, 16, 16, 16, 16, 16, 16,
+ 32, 32, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 5, 5, 5, 5, 5, 32, 32, 32,
+ 32, 32, 32, 32, 32, 32, 32, 32,
+};
+
+#define WUFFS_JSON__CLASS_WHITESPACE 0
+
+#define WUFFS_JSON__CLASS_STRING 1
+
+#define WUFFS_JSON__CLASS_COMMA 2
+
+#define WUFFS_JSON__CLASS_COLON 3
+
+#define WUFFS_JSON__CLASS_NUMBER 4
+
+#define WUFFS_JSON__CLASS_OPEN_CURLY_BRACE 5
+
+#define WUFFS_JSON__CLASS_CLOSE_CURLY_BRACE 6
+
+#define WUFFS_JSON__CLASS_OPEN_SQUARE_BRACKET 7
+
+#define WUFFS_JSON__CLASS_CLOSE_SQUARE_BRACKET 8
+
+#define WUFFS_JSON__CLASS_FALSE 9
+
+#define WUFFS_JSON__CLASS_TRUE 10
+
+#define WUFFS_JSON__CLASS_NULL_NAN_INF 11
+
+#define WUFFS_JSON__CLASS_COMMENT 12
+
+#define WUFFS_JSON__EXPECT_VALUE 7858
+
+#define WUFFS_JSON__EXPECT_NON_STRING_VALUE 7856
+
+#define WUFFS_JSON__EXPECT_STRING 4098
+
+#define WUFFS_JSON__EXPECT_COMMA 4100
+
+#define WUFFS_JSON__EXPECT_COLON 4104
+
+#define WUFFS_JSON__EXPECT_NUMBER 4112
+
+#define WUFFS_JSON__EXPECT_CLOSE_CURLY_BRACE 4160
+
+#define WUFFS_JSON__EXPECT_CLOSE_SQUARE_BRACKET 4352
+
+static const uint8_t
+WUFFS_JSON__LUT_CLASSES[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 0, 0, 15, 15, 0, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 0, 15, 1, 15, 15, 15, 15, 15,
+ 15, 15, 15, 11, 2, 4, 15, 12,
+ 4, 4, 4, 4, 4, 4, 4, 4,
+ 4, 4, 3, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 11, 15, 15, 15, 15, 11, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 7, 15, 8, 15, 15,
+ 15, 15, 15, 15, 15, 15, 9, 15,
+ 15, 11, 15, 15, 15, 15, 11, 15,
+ 15, 15, 15, 15, 10, 15, 15, 15,
+ 15, 15, 15, 5, 15, 6, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+ 15, 15, 15, 15, 15, 15, 15, 15,
+};
+
+static const uint8_t
+WUFFS_JSON__LUT_DECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+static const uint8_t
+WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 128, 129, 130, 131, 132, 133, 134, 135,
+ 136, 137, 0, 0, 0, 0, 0, 0,
+ 0, 138, 139, 140, 141, 142, 143, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 138, 139, 140, 141, 142, 143, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+};
+
+#define WUFFS_JSON__QUIRKS_BASE 1225364480
+
+#define WUFFS_JSON__QUIRKS_COUNT 21
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_json__decoder__decode_number(
+ wuffs_json__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_json__decoder__decode_digits(
+ wuffs_json__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ uint32_t a_n);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_json__decoder__decode_leading(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_json__decoder__decode_comment(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_json__decoder__decode_inf_nan(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_json__decoder__decode_trailer(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+// ---------------- VTables
+
+const wuffs_base__token_decoder__func_ptrs
+wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__token_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__slice_u8))(&wuffs_json__decoder__decode_tokens),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_json__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_json__decoder__history_retain_length),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_json__decoder__set_quirk),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_json__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_json__decoder__initialize(
+ wuffs_json__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__token_decoder.vtable_name =
+ wuffs_base__token_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__token_decoder.function_pointers =
+ (const void*)(&wuffs_json__decoder__func_ptrs_for__wuffs_base__token_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_json__decoder*
+wuffs_json__decoder__alloc(void) {
+ wuffs_json__decoder* x =
+ (wuffs_json__decoder*)(calloc(sizeof(wuffs_json__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_json__decoder__initialize(
+ x, sizeof(wuffs_json__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_json__decoder(void) {
+ return sizeof(wuffs_json__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func json.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_json__decoder__get_quirk(
+ const wuffs_json__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ uint32_t v_key = 0;
+
+ if (a_key >= 1225364480u) {
+ v_key = (a_key - 1225364480u);
+ if (v_key < 21u) {
+ if (self->private_impl.f_quirks[v_key]) {
+ return 1u;
+ }
+ }
+ }
+ return 0u;
+}
+
+// -------- func json.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_json__decoder__set_quirk(
+ wuffs_json__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (a_key >= 1225364480u) {
+ a_key -= 1225364480u;
+ if (a_key < 21u) {
+ self->private_impl.f_quirks[a_key] = (a_value > 0u);
+ return wuffs_base__make_status(NULL);
+ }
+ }
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func json.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_json__decoder__history_retain_length(
+ const wuffs_json__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func json.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_json__decoder__workbuf_len(
+ const wuffs_json__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__empty_range_ii_u64();
+}
+
+// -------- func json.decoder.decode_tokens
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_json__decoder__decode_tokens(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_vminor = 0;
+ uint32_t v_number_length = 0;
+ uint32_t v_number_status = 0;
+ uint32_t v_string_length = 0;
+ uint32_t v_whitespace_length = 0;
+ uint32_t v_depth = 0;
+ uint32_t v_stack_byte = 0;
+ uint32_t v_stack_bit = 0;
+ uint32_t v_match = 0;
+ uint32_t v_c4 = 0;
+ uint8_t v_c = 0;
+ uint8_t v_backslash = 0;
+ uint8_t v_char = 0;
+ uint8_t v_class = 0;
+ uint32_t v_multi_byte_utf8 = 0;
+ uint8_t v_backslash_x_ok = 0;
+ uint8_t v_backslash_x_value = 0;
+ uint32_t v_backslash_x_string = 0;
+ uint8_t v_uni4_ok = 0;
+ uint64_t v_uni4_string = 0;
+ uint32_t v_uni4_value = 0;
+ uint32_t v_uni4_high_surrogate = 0;
+ uint8_t v_uni8_ok = 0;
+ uint64_t v_uni8_string = 0;
+ uint32_t v_uni8_value = 0;
+ uint32_t v_expect = 0;
+ uint32_t v_expect_after_value = 0;
+
+ wuffs_base__token* iop_a_dst = NULL;
+ wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_tokens[0];
+ if (coro_susp_point) {
+ v_depth = self->private_data.s_decode_tokens[0].v_depth;
+ v_expect = self->private_data.s_decode_tokens[0].v_expect;
+ v_expect_after_value = self->private_data.s_decode_tokens[0].v_expect_after_value;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_end_of_data) {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (self->private_impl.f_quirks[18u]) {
+ if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u] || self->private_impl.f_quirks[17u]) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_quirk_combination);
+ goto exit;
+ }
+ }
+ if (self->private_impl.f_quirks[15u] || self->private_impl.f_quirks[16u]) {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_json__decoder__decode_leading(self, a_dst, a_src);
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ v_expect = 7858u;
+ label__outer__continue:;
+ while (true) {
+ while (true) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ goto label__outer__continue;
+ }
+ v_whitespace_length = 0u;
+ v_c = 0u;
+ v_class = 0u;
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (v_whitespace_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_whitespace_length = 0u;
+ }
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ goto label__outer__continue;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ v_class = WUFFS_JSON__LUT_CLASSES[v_c];
+ if (v_class != 0u) {
+ break;
+ }
+ iop_a_src += 1u;
+ if (v_whitespace_length >= 65534u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(65535u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_whitespace_length = 0u;
+ goto label__outer__continue;
+ }
+ v_whitespace_length += 1u;
+ }
+ if (v_whitespace_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_whitespace_length = 0u;
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ goto label__outer__continue;
+ }
+ }
+ if (0u == (v_expect & (((uint32_t)(1u)) << v_class))) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ if (v_class == 1u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 1u;
+ label__string_loop_outer__continue:;
+ while (true) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
+ continue;
+ }
+ v_string_length = 0u;
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (v_string_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ }
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
+ goto label__string_loop_outer__continue;
+ }
+ while (((uint64_t)(io2_a_src - iop_a_src)) > 4u) {
+ v_c4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ if (0u != (WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 0u))] |
+ WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 8u))] |
+ WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 16u))] |
+ WUFFS_JSON__LUT_CHARS[(255u & (v_c4 >> 24u))])) {
+ break;
+ }
+ iop_a_src += 4u;
+ if (v_string_length > 65527u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ goto label__string_loop_outer__continue;
+ }
+ v_string_length += 4u;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ v_char = WUFFS_JSON__LUT_CHARS[v_c];
+ if (v_char == 0u) {
+ iop_a_src += 1u;
+ if (v_string_length >= 65531u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(65532u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ goto label__string_loop_outer__continue;
+ }
+ v_string_length += 1u;
+ continue;
+ } else if (v_char == 1u) {
+ if (v_string_length != 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ }
+ goto label__string_loop_outer__break;
+ } else if (v_char == 2u) {
+ if (v_string_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ goto label__string_loop_outer__continue;
+ }
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
+ goto label__string_loop_outer__continue;
+ }
+ v_c = ((uint8_t)((wuffs_base__peek_u16le__no_bounds_check(iop_a_src) >> 8u)));
+ v_backslash = WUFFS_JSON__LUT_BACKSLASHES[v_c];
+ if ((v_backslash & 128u) != 0u) {
+ iop_a_src += 2u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((6291456u | ((uint32_t)((v_backslash & 127u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ } else if (v_backslash != 0u) {
+ if (self->private_impl.f_quirks[WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_QUIRKS[(v_backslash & 7u)]]) {
+ iop_a_src += 2u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((6291456u | ((uint32_t)(WUFFS_JSON__LUT_QUIRKY_BACKSLASHES_CHARS[(v_backslash & 7u)]))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ }
+ } else if (v_c == 117u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
+ goto label__string_loop_outer__continue;
+ }
+ v_uni4_string = (((uint64_t)(wuffs_base__peek_u48le__no_bounds_check(iop_a_src))) >> 16u);
+ v_uni4_value = 0u;
+ v_uni4_ok = 128u;
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))];
+ v_uni4_ok &= v_c;
+ v_uni4_value |= (((uint32_t)((v_c & 15u))) << 12u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))];
+ v_uni4_ok &= v_c;
+ v_uni4_value |= (((uint32_t)((v_c & 15u))) << 8u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))];
+ v_uni4_ok &= v_c;
+ v_uni4_value |= (((uint32_t)((v_c & 15u))) << 4u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))];
+ v_uni4_ok &= v_c;
+ v_uni4_value |= (((uint32_t)((v_c & 15u))) << 0u);
+ if (v_uni4_ok == 0u) {
+ } else if ((v_uni4_value < 55296u) || (57343u < v_uni4_value)) {
+ iop_a_src += 6u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((6291456u | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ } else if (v_uni4_value >= 56320u) {
+ } else {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 12u) {
+ if (a_src && a_src->meta.closed) {
+ if (self->private_impl.f_quirks[20u]) {
+ iop_a_src += 6u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
+ goto label__string_loop_outer__continue;
+ }
+ v_uni4_string = (wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 4u) >> 16u);
+ if (((255u & (v_uni4_string >> 0u)) != 92u) || ((255u & (v_uni4_string >> 8u)) != 117u)) {
+ v_uni4_high_surrogate = 0u;
+ v_uni4_value = 0u;
+ v_uni4_ok = 0u;
+ } else {
+ v_uni4_high_surrogate = (65536u + ((v_uni4_value - 55296u) << 10u));
+ v_uni4_value = 0u;
+ v_uni4_ok = 128u;
+ v_uni4_string >>= 16u;
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 0u))];
+ v_uni4_ok &= v_c;
+ v_uni4_value |= (((uint32_t)((v_c & 15u))) << 12u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 8u))];
+ v_uni4_ok &= v_c;
+ v_uni4_value |= (((uint32_t)((v_c & 15u))) << 8u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 16u))];
+ v_uni4_ok &= v_c;
+ v_uni4_value |= (((uint32_t)((v_c & 15u))) << 4u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni4_string >> 24u))];
+ v_uni4_ok &= v_c;
+ v_uni4_value |= (((uint32_t)((v_c & 15u))) << 0u);
+ }
+ if ((v_uni4_ok != 0u) && (56320u <= v_uni4_value) && (v_uni4_value <= 57343u)) {
+ v_uni4_value -= 56320u;
+ iop_a_src += 12u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((6291456u | v_uni4_high_surrogate | v_uni4_value))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(12u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ }
+ }
+ if (self->private_impl.f_quirks[20u]) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 6u) {
+ status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ iop_a_src += 6u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(6u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ }
+ } else if ((v_c == 85u) && self->private_impl.f_quirks[2u]) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 10u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
+ goto label__string_loop_outer__continue;
+ }
+ v_uni8_string = wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 2u);
+ v_uni8_value = 0u;
+ v_uni8_ok = 128u;
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 0u))];
+ v_uni8_ok &= v_c;
+ v_uni8_value |= (((uint32_t)((v_c & 15u))) << 28u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 8u))];
+ v_uni8_ok &= v_c;
+ v_uni8_value |= (((uint32_t)((v_c & 15u))) << 24u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 16u))];
+ v_uni8_ok &= v_c;
+ v_uni8_value |= (((uint32_t)((v_c & 15u))) << 20u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 24u))];
+ v_uni8_ok &= v_c;
+ v_uni8_value |= (((uint32_t)((v_c & 15u))) << 16u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 32u))];
+ v_uni8_ok &= v_c;
+ v_uni8_value |= (((uint32_t)((v_c & 15u))) << 12u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 40u))];
+ v_uni8_ok &= v_c;
+ v_uni8_value |= (((uint32_t)((v_c & 15u))) << 8u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 48u))];
+ v_uni8_ok &= v_c;
+ v_uni8_value |= (((uint32_t)((v_c & 15u))) << 4u);
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_uni8_string >> 56u))];
+ v_uni8_ok &= v_c;
+ v_uni8_value |= (((uint32_t)((v_c & 15u))) << 0u);
+ if (v_uni8_ok == 0u) {
+ } else if ((v_uni8_value < 55296u) || ((57343u < v_uni8_value) && (v_uni8_value <= 1114111u))) {
+ iop_a_src += 10u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((6291456u | (v_uni8_value & 2097151u)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ } else if (self->private_impl.f_quirks[20u]) {
+ iop_a_src += 10u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(10u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ }
+ } else if ((v_c == 120u) && self->private_impl.f_quirks[9u]) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
+ goto label__string_loop_outer__continue;
+ }
+ v_backslash_x_string = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ v_backslash_x_ok = 128u;
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 16u))];
+ v_backslash_x_ok &= v_c;
+ v_backslash_x_value = ((uint8_t)(((v_c & 15u) << 4u)));
+ v_c = WUFFS_JSON__LUT_HEXADECIMAL_DIGITS[(255u & (v_backslash_x_string >> 24u))];
+ v_backslash_x_ok &= v_c;
+ v_backslash_x_value = ((uint8_t)((v_backslash_x_value | (v_c & 15u))));
+ if ((v_backslash_x_ok == 0u) || ((v_backslash_x_string & 65535u) != 30812u)) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
+ goto exit;
+ }
+ iop_a_src += 4u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((6291456u | ((uint32_t)(v_backslash_x_value))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__string_loop_outer__continue;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_backslash_escape);
+ goto exit;
+ } else if (v_char == 3u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
+ if (v_string_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ goto label__string_loop_outer__continue;
+ }
+ }
+ if (a_src && a_src->meta.closed) {
+ if (self->private_impl.f_quirks[20u]) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 1u;
+ goto label__string_loop_outer__continue;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
+ goto label__string_loop_outer__continue;
+ }
+ v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ if ((v_multi_byte_utf8 & 49152u) == 32768u) {
+ v_multi_byte_utf8 = ((1984u & ((uint32_t)(v_multi_byte_utf8 << 6u))) | (63u & (v_multi_byte_utf8 >> 8u)));
+ iop_a_src += 2u;
+ if (v_string_length >= 65528u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)((v_string_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ goto label__string_loop_outer__continue;
+ }
+ v_string_length += 2u;
+ continue;
+ }
+ } else if (v_char == 4u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
+ if (v_string_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ goto label__string_loop_outer__continue;
+ }
+ }
+ if (a_src && a_src->meta.closed) {
+ if (self->private_impl.f_quirks[20u]) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 1u;
+ goto label__string_loop_outer__continue;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(12);
+ goto label__string_loop_outer__continue;
+ }
+ v_multi_byte_utf8 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
+ if ((v_multi_byte_utf8 & 12632064u) == 8421376u) {
+ v_multi_byte_utf8 = ((61440u & ((uint32_t)(v_multi_byte_utf8 << 12u))) | (4032u & (v_multi_byte_utf8 >> 2u)) | (63u & (v_multi_byte_utf8 >> 16u)));
+ if ((2047u < v_multi_byte_utf8) && ((v_multi_byte_utf8 < 55296u) || (57343u < v_multi_byte_utf8))) {
+ iop_a_src += 3u;
+ if (v_string_length >= 65528u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)((v_string_length + 3u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ goto label__string_loop_outer__continue;
+ }
+ v_string_length += 3u;
+ continue;
+ }
+ }
+ } else if (v_char == 5u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
+ if (v_string_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ goto label__string_loop_outer__continue;
+ }
+ }
+ if (a_src && a_src->meta.closed) {
+ if (self->private_impl.f_quirks[20u]) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 1u;
+ goto label__string_loop_outer__continue;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(13);
+ goto label__string_loop_outer__continue;
+ }
+ v_multi_byte_utf8 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ if ((v_multi_byte_utf8 & 3233857536u) == 2155905024u) {
+ v_multi_byte_utf8 = ((1835008u & ((uint32_t)(v_multi_byte_utf8 << 18u))) |
+ (258048u & ((uint32_t)(v_multi_byte_utf8 << 4u))) |
+ (4032u & (v_multi_byte_utf8 >> 10u)) |
+ (63u & (v_multi_byte_utf8 >> 24u)));
+ if ((65535u < v_multi_byte_utf8) && (v_multi_byte_utf8 <= 1114111u)) {
+ iop_a_src += 4u;
+ if (v_string_length >= 65528u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)((v_string_length + 4u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ goto label__string_loop_outer__continue;
+ }
+ v_string_length += 4u;
+ continue;
+ }
+ }
+ }
+ if (v_string_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194819u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_string_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_string_length = 0u;
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ goto label__string_loop_outer__continue;
+ }
+ }
+ if ((v_char & 128u) != 0u) {
+ if (self->private_impl.f_quirks[0u]) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((6291456u | ((uint32_t)((v_char & 127u)))))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 1u;
+ goto label__string_loop_outer__continue;
+ }
+ if (v_char == 138u) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_new_line_in_a_string);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_c0_control_code);
+ goto exit;
+ }
+ if (self->private_impl.f_quirks[20u]) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(6356989u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 1u;
+ goto label__string_loop_outer__continue;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_utf_8);
+ goto exit;
+ }
+ }
+ label__string_loop_outer__break:;
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(14);
+ continue;
+ }
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(15);
+ continue;
+ }
+ iop_a_src += 1u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4194579u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ break;
+ }
+ if (0u == (v_expect & (((uint32_t)(1u)) << 4u))) {
+ v_expect = 4104u;
+ goto label__outer__continue;
+ }
+ break;
+ } else if (v_class == 2u) {
+ iop_a_src += 1u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (0u == (v_expect & (((uint32_t)(1u)) << 8u))) {
+ if (self->private_impl.f_quirks[13u]) {
+ v_expect = 4162u;
+ } else {
+ v_expect = 4098u;
+ }
+ } else {
+ if (self->private_impl.f_quirks[13u]) {
+ v_expect = 8114u;
+ } else {
+ v_expect = 7858u;
+ }
+ }
+ goto label__outer__continue;
+ } else if (v_class == 3u) {
+ iop_a_src += 1u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_expect = 7858u;
+ goto label__outer__continue;
+ } else if (v_class == 4u) {
+ while (true) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_number_length = wuffs_json__decoder__decode_number(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ v_number_status = (v_number_length >> 8u);
+ v_vminor = 10486787u;
+ if ((v_number_length & 128u) != 0u) {
+ v_vminor = 10486785u;
+ }
+ v_number_length = (v_number_length & 127u);
+ if (v_number_status == 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_number_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ break;
+ }
+ while (v_number_length > 0u) {
+ v_number_length -= 1u;
+ if (iop_a_src > io1_a_src) {
+ iop_a_src--;
+ } else {
+ status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ }
+ if (v_number_status == 1u) {
+ if (self->private_impl.f_quirks[14u]) {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
+ status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ break;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ } else if (v_number_status == 2u) {
+ status = wuffs_base__make_status(wuffs_json__error__unsupported_number_length);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(17);
+ while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(18);
+ }
+ }
+ }
+ break;
+ } else if (v_class == 5u) {
+ v_vminor = 2113553u;
+ if (v_depth == 0u) {
+ } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) {
+ v_vminor = 2113601u;
+ } else {
+ v_vminor = 2113569u;
+ }
+ if (v_depth >= 1024u) {
+ status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
+ goto exit;
+ }
+ v_stack_byte = (v_depth / 32u);
+ v_stack_bit = (v_depth & 31u);
+ self->private_data.f_stack[v_stack_byte] |= (((uint32_t)(1u)) << v_stack_bit);
+ v_depth += 1u;
+ iop_a_src += 1u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_expect = 4162u;
+ v_expect_after_value = 4164u;
+ goto label__outer__continue;
+ } else if (v_class == 6u) {
+ iop_a_src += 1u;
+ if (v_depth <= 1u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2101314u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__outer__break;
+ }
+ v_depth -= 1u;
+ v_stack_byte = ((v_depth - 1u) / 32u);
+ v_stack_bit = ((v_depth - 1u) & 31u);
+ if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2105410u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_expect = 4356u;
+ v_expect_after_value = 4356u;
+ } else {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2113602u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_expect = 4164u;
+ v_expect_after_value = 4164u;
+ }
+ goto label__outer__continue;
+ } else if (v_class == 7u) {
+ v_vminor = 2105361u;
+ if (v_depth == 0u) {
+ } else if (0u != (v_expect_after_value & (((uint32_t)(1u)) << 6u))) {
+ v_vminor = 2105409u;
+ } else {
+ v_vminor = 2105377u;
+ }
+ if (v_depth >= 1024u) {
+ status = wuffs_base__make_status(wuffs_json__error__unsupported_recursion_depth);
+ goto exit;
+ }
+ v_stack_byte = (v_depth / 32u);
+ v_stack_bit = (v_depth & 31u);
+ self->private_data.f_stack[v_stack_byte] &= (4294967295u ^ (((uint32_t)(1u)) << v_stack_bit));
+ v_depth += 1u;
+ iop_a_src += 1u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(v_vminor)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_expect = 8114u;
+ v_expect_after_value = 4356u;
+ goto label__outer__continue;
+ } else if (v_class == 8u) {
+ iop_a_src += 1u;
+ if (v_depth <= 1u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2101282u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ goto label__outer__break;
+ }
+ v_depth -= 1u;
+ v_stack_byte = ((v_depth - 1u) / 32u);
+ v_stack_bit = ((v_depth - 1u) & 31u);
+ if (0u == (self->private_data.f_stack[v_stack_byte] & (((uint32_t)(1u)) << v_stack_bit))) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2105378u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_expect = 4356u;
+ v_expect_after_value = 4356u;
+ } else {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2113570u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ v_expect = 4164u;
+ v_expect_after_value = 4164u;
+ }
+ goto label__outer__continue;
+ } else if (v_class == 9u) {
+ v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 111546413966853u);
+ if (v_match == 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(8388612u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(5u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) {
+ status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ iop_a_src += 5u;
+ break;
+ } else if (v_match == 1u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(19);
+ goto label__outer__continue;
+ }
+ } else if (v_class == 10u) {
+ v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 435762131972u);
+ if (v_match == 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(8388616u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
+ status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ iop_a_src += 4u;
+ break;
+ } else if (v_match == 1u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(20);
+ goto label__outer__continue;
+ }
+ } else if (v_class == 11u) {
+ v_match = wuffs_base__io_reader__match7(iop_a_src, io2_a_src, a_src, 465676103172u);
+ if (v_match == 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(8388610u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
+ status = wuffs_base__make_status(wuffs_json__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ iop_a_src += 4u;
+ break;
+ } else if (v_match == 1u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(21);
+ goto label__outer__continue;
+ }
+ if (self->private_impl.f_quirks[14u]) {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
+ status = wuffs_json__decoder__decode_inf_nan(self, a_dst, a_src);
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ break;
+ }
+ } else if (v_class == 12u) {
+ if (self->private_impl.f_quirks[11u] || self->private_impl.f_quirks[12u]) {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(23);
+ status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ if (self->private_impl.f_comment_type > 0u) {
+ goto label__outer__continue;
+ }
+ }
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ if (v_depth == 0u) {
+ break;
+ }
+ v_expect = v_expect_after_value;
+ }
+ label__outer__break:;
+ if (self->private_impl.f_quirks[17u] || self->private_impl.f_quirks[18u]) {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(24);
+ status = wuffs_json__decoder__decode_trailer(self, a_dst, a_src);
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ self->private_impl.f_end_of_data = true;
+
+ ok:
+ self->private_impl.p_decode_tokens[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_tokens[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+ self->private_data.s_decode_tokens[0].v_depth = v_depth;
+ self->private_data.s_decode_tokens[0].v_expect = v_expect;
+ self->private_data.s_decode_tokens[0].v_expect_after_value = v_expect_after_value;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func json.decoder.decode_number
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_json__decoder__decode_number(
+ wuffs_json__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ uint8_t v_c = 0;
+ uint32_t v_n = 0;
+ uint32_t v_floating_point = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ do {
+ v_n = 0u;
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if ( ! (a_src && a_src->meta.closed)) {
+ v_n |= 768u;
+ }
+ break;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if (v_c != 45u) {
+ } else {
+ v_n += 1u;
+ iop_a_src += 1u;
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if ( ! (a_src && a_src->meta.closed)) {
+ v_n |= 768u;
+ }
+ v_n |= 256u;
+ break;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ }
+ if (v_c == 48u) {
+ v_n += 1u;
+ iop_a_src += 1u;
+ } else {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (v_n > 99u) {
+ break;
+ }
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if ( ! (a_src && a_src->meta.closed)) {
+ v_n |= 768u;
+ }
+ break;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if (v_c != 46u) {
+ } else {
+ if (v_n >= 99u) {
+ v_n |= 512u;
+ break;
+ }
+ v_n += 1u;
+ iop_a_src += 1u;
+ v_floating_point = 128u;
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (v_n > 99u) {
+ break;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if ( ! (a_src && a_src->meta.closed)) {
+ v_n |= 768u;
+ }
+ break;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ }
+ if ((v_c != 69u) && (v_c != 101u)) {
+ break;
+ }
+ if (v_n >= 99u) {
+ v_n |= 512u;
+ break;
+ }
+ v_n += 1u;
+ iop_a_src += 1u;
+ v_floating_point = 128u;
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if ( ! (a_src && a_src->meta.closed)) {
+ v_n |= 768u;
+ }
+ v_n |= 256u;
+ break;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if ((v_c != 43u) && (v_c != 45u)) {
+ } else {
+ if (v_n >= 99u) {
+ v_n |= 512u;
+ break;
+ }
+ v_n += 1u;
+ iop_a_src += 1u;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ v_n = wuffs_json__decoder__decode_digits(self, a_src, v_n);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ } while (0);
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ return (v_n | v_floating_point);
+}
+
+// -------- func json.decoder.decode_digits
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint32_t
+wuffs_json__decoder__decode_digits(
+ wuffs_json__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ uint32_t a_n) {
+ uint8_t v_c = 0;
+ uint32_t v_n = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_n = a_n;
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if ( ! (a_src && a_src->meta.closed)) {
+ v_n |= 768u;
+ }
+ break;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if (0u == WUFFS_JSON__LUT_DECIMAL_DIGITS[v_c]) {
+ break;
+ }
+ if (v_n >= 99u) {
+ v_n |= 512u;
+ break;
+ }
+ v_n += 1u;
+ iop_a_src += 1u;
+ }
+ if (v_n == a_n) {
+ v_n |= 256u;
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ return v_n;
+}
+
+// -------- func json.decoder.decode_leading
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_json__decoder__decode_leading(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_u = 0;
+
+ wuffs_base__token* iop_a_dst = NULL;
+ wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_leading[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.f_allow_leading_ars = self->private_impl.f_quirks[15u];
+ self->private_impl.f_allow_leading_ubom = self->private_impl.f_quirks[16u];
+ while (self->private_impl.f_allow_leading_ars || self->private_impl.f_allow_leading_ubom) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ continue;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ break;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ continue;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if ((v_c == 30u) && self->private_impl.f_allow_leading_ars) {
+ self->private_impl.f_allow_leading_ars = false;
+ iop_a_src += 1u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ continue;
+ } else if ((v_c == 239u) && self->private_impl.f_allow_leading_ubom) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
+ if (a_src && a_src->meta.closed) {
+ break;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ continue;
+ }
+ v_u = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
+ if (v_u == 12565487u) {
+ self->private_impl.f_allow_leading_ubom = false;
+ iop_a_src += 3u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ continue;
+ }
+ }
+ break;
+ }
+
+ ok:
+ self->private_impl.p_decode_leading[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_leading[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func json.decoder.decode_comment
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_json__decoder__decode_comment(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint16_t v_c2 = 0;
+ uint32_t v_length = 0;
+
+ wuffs_base__token* iop_a_dst = NULL;
+ wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_comment[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.f_comment_type = 0u;
+ while ((((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) || (((uint64_t)(io2_a_src - iop_a_src)) <= 1u)) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ continue;
+ }
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ }
+ v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
+ if ((v_c2 == 10799u) && self->private_impl.f_quirks[11u]) {
+ iop_a_src += 2u;
+ v_length = 2u;
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 1u) {
+ if (v_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ }
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
+ }
+ v_length = 0u;
+ continue;
+ }
+ v_c2 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
+ if (v_c2 == 12074u) {
+ iop_a_src += 2u;
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)((v_length + 2u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ self->private_impl.f_comment_type = 1u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ iop_a_src += 1u;
+ if (v_length >= 65533u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(2u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
+ }
+ v_length = 0u;
+ continue;
+ }
+ v_length += 1u;
+ }
+ } else if ((v_c2 == 12079u) && self->private_impl.f_quirks[12u]) {
+ iop_a_src += 2u;
+ v_length = 2u;
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ self->private_impl.f_comment_type = 2u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ } else if (v_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
+ while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
+ }
+ v_length = 0u;
+ continue;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if (v_c == 10u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ self->private_impl.f_comment_type = 2u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ iop_a_src += 1u;
+ if (v_length >= 65533u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(1u)) << WUFFS_BASE__TOKEN__CONTINUED__SHIFT) |
+ (((uint64_t)((v_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ while (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
+ }
+ v_length = 0u;
+ continue;
+ }
+ v_length += 1u;
+ }
+ }
+
+ ok:
+ self->private_impl.p_decode_comment[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_comment[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func json.decoder.decode_inf_nan
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_json__decoder__decode_inf_nan(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_c4 = 0;
+ uint32_t v_neg = 0;
+
+ wuffs_base__token* iop_a_dst = NULL;
+ wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_inf_nan[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ continue;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 2u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ continue;
+ }
+ v_c4 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
+ if ((v_c4 | 2105376u) == 6712937u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) > 7u) {
+ if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) | 2314885530818453536u) == 8751735898823356009u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(8u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 8u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ } else if ( ! (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ continue;
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(10485792u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 3u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ } else if ((v_c4 | 2105376u) == 7233902u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(10485888u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(3u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 3u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ } else if ((v_c4 & 255u) == 43u) {
+ v_neg = 0u;
+ } else if ((v_c4 & 255u) == 45u) {
+ v_neg = 1u;
+ } else {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 3u) {
+ if (a_src && a_src->meta.closed) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
+ continue;
+ }
+ v_c4 = (wuffs_base__peek_u32le__no_bounds_check(iop_a_src) >> 8u);
+ if ((v_c4 | 2105376u) == 6712937u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) > 8u) {
+ if ((wuffs_base__peek_u64le__no_bounds_check(iop_a_src + 1u) | 2314885530818453536u) == 8751735898823356009u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(9u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 9u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ } else if ( ! (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
+ continue;
+ }
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((10485760u | (((uint32_t)(32u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 4u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ } else if ((v_c4 | 2105376u) == 7233902u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)((10485760u | (((uint32_t)(128u)) >> v_neg)))) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(4u)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ iop_a_src += 4u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+
+ ok:
+ self->private_impl.p_decode_inf_nan[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_inf_nan[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func json.decoder.decode_trailer
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_json__decoder__decode_trailer(
+ wuffs_json__decoder* self,
+ wuffs_base__token_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_whitespace_length = 0;
+
+ wuffs_base__token* iop_a_dst = NULL;
+ wuffs_base__token* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ wuffs_base__token* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_trailer[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_quirks[18u]) {
+ self->private_impl.f_trailer_stop = 10u;
+ } else {
+ self->private_impl.f_trailer_stop = 0u;
+ }
+ label__outer__continue:;
+ while (true) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ continue;
+ }
+ v_whitespace_length = 0u;
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (v_whitespace_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ }
+ if (a_src && a_src->meta.closed) {
+ goto label__outer__break;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ goto label__outer__continue;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if (WUFFS_JSON__LUT_CLASSES[v_c] != 0u) {
+ if (v_whitespace_length > 0u) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)(v_whitespace_length)) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ }
+ if (self->private_impl.f_trailer_stop > 0u) {
+ status = wuffs_base__make_status(wuffs_json__error__bad_input);
+ goto exit;
+ }
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_json__decoder__decode_comment(self, a_dst, a_src);
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ if (self->private_impl.f_comment_type > 0u) {
+ goto label__outer__continue;
+ }
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ iop_a_src += 1u;
+ if ((v_whitespace_length >= 65534u) || (v_c == self->private_impl.f_trailer_stop)) {
+ *iop_a_dst++ = wuffs_base__make_token(
+ (((uint64_t)(0u)) << WUFFS_BASE__TOKEN__VALUE_MINOR__SHIFT) |
+ (((uint64_t)((v_whitespace_length + 1u))) << WUFFS_BASE__TOKEN__LENGTH__SHIFT));
+ if (v_c == self->private_impl.f_trailer_stop) {
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ goto label__outer__continue;
+ }
+ v_whitespace_length += 1u;
+ }
+ }
+ label__outer__break:;
+
+ ok:
+ self->private_impl.p_decode_trailer[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_trailer[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JSON)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_lzw__error__bad_code[] = "#lzw: bad code";
+const char wuffs_lzw__error__truncated_input[] = "#lzw: truncated input";
+const char wuffs_lzw__error__internal_error_inconsistent_i_o[] = "#lzw: internal error: inconsistent I/O";
+
+// ---------------- Private Consts
+
+#define WUFFS_LZW__QUIRKS_BASE 1348378624
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_lzw__decoder__read_from(
+ wuffs_lzw__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_lzw__decoder__write_to(
+ wuffs_lzw__decoder* self,
+ wuffs_base__io_buffer* a_dst);
+
+// ---------------- VTables
+
+const wuffs_base__io_transformer__func_ptrs
+wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer = {
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_lzw__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_lzw__decoder__history_retain_length),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_lzw__decoder__set_quirk),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__slice_u8))(&wuffs_lzw__decoder__transform_io),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_lzw__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+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 options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
+ wuffs_base__io_transformer__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
+ (const void*)(&wuffs_lzw__decoder__func_ptrs_for__wuffs_base__io_transformer);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_lzw__decoder*
+wuffs_lzw__decoder__alloc(void) {
+ wuffs_lzw__decoder* x =
+ (wuffs_lzw__decoder*)(calloc(sizeof(wuffs_lzw__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_lzw__decoder__initialize(
+ x, sizeof(wuffs_lzw__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_lzw__decoder(void) {
+ return sizeof(wuffs_lzw__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func lzw.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_lzw__decoder__get_quirk(
+ const wuffs_lzw__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (a_key == 1348378624u) {
+ return ((uint64_t)(self->private_impl.f_pending_literal_width_plus_one));
+ }
+ return 0u;
+}
+
+// -------- func lzw.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_lzw__decoder__set_quirk(
+ wuffs_lzw__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (a_key == 1348378624u) {
+ if (a_value > 9u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_pending_literal_width_plus_one = ((uint32_t)(a_value));
+ return wuffs_base__make_status(NULL);
+ }
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func lzw.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_lzw__decoder__history_retain_length(
+ const wuffs_lzw__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func lzw.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_lzw__decoder__workbuf_len(
+ const wuffs_lzw__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(0u, 0u);
+}
+
+// -------- func lzw.decoder.transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_lzw__decoder__transform_io(
+ wuffs_lzw__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_i = 0;
+
+ uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.f_literal_width = 8u;
+ if (self->private_impl.f_pending_literal_width_plus_one > 0u) {
+ self->private_impl.f_literal_width = (self->private_impl.f_pending_literal_width_plus_one - 1u);
+ }
+ self->private_impl.f_clear_code = (((uint32_t)(1u)) << self->private_impl.f_literal_width);
+ self->private_impl.f_end_code = (self->private_impl.f_clear_code + 1u);
+ self->private_impl.f_save_code = self->private_impl.f_end_code;
+ self->private_impl.f_prev_code = self->private_impl.f_end_code;
+ self->private_impl.f_width = (self->private_impl.f_literal_width + 1u);
+ self->private_impl.f_bits = 0u;
+ self->private_impl.f_n_bits = 0u;
+ self->private_impl.f_output_ri = 0u;
+ self->private_impl.f_output_wi = 0u;
+ v_i = 0u;
+ while (v_i < self->private_impl.f_clear_code) {
+ self->private_data.f_lm1s[v_i] = 0u;
+ self->private_data.f_suffixes[v_i][0u] = ((uint8_t)(v_i));
+ v_i += 1u;
+ }
+ while (true) {
+ wuffs_lzw__decoder__read_from(self, a_src);
+ if (self->private_impl.f_output_wi > 0u) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_lzw__decoder__write_to(self, a_dst);
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ if (self->private_impl.f_read_from_return_value == 0u) {
+ break;
+ } else if (self->private_impl.f_read_from_return_value == 1u) {
+ continue;
+ } else if (self->private_impl.f_read_from_return_value == 2u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ } else if (self->private_impl.f_read_from_return_value == 3u) {
+ status = wuffs_base__make_status(wuffs_lzw__error__truncated_input);
+ goto exit;
+ } else if (self->private_impl.f_read_from_return_value == 4u) {
+ status = wuffs_base__make_status(wuffs_lzw__error__bad_code);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ }
+
+ ok:
+ self->private_impl.p_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func lzw.decoder.read_from
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_lzw__decoder__read_from(
+ wuffs_lzw__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ uint32_t v_clear_code = 0;
+ uint32_t v_end_code = 0;
+ uint32_t v_save_code = 0;
+ uint32_t v_prev_code = 0;
+ uint32_t v_width = 0;
+ uint32_t v_bits = 0;
+ uint32_t v_n_bits = 0;
+ uint32_t v_output_wi = 0;
+ uint32_t v_code = 0;
+ uint32_t v_c = 0;
+ uint32_t v_o = 0;
+ uint32_t v_steps = 0;
+ uint8_t v_first_byte = 0;
+ uint16_t v_lm1_b = 0;
+ uint16_t v_lm1_a = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_clear_code = self->private_impl.f_clear_code;
+ v_end_code = self->private_impl.f_end_code;
+ v_save_code = self->private_impl.f_save_code;
+ v_prev_code = self->private_impl.f_prev_code;
+ v_width = self->private_impl.f_width;
+ v_bits = self->private_impl.f_bits;
+ v_n_bits = self->private_impl.f_n_bits;
+ v_output_wi = self->private_impl.f_output_wi;
+ while (true) {
+ if (v_n_bits < v_width) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= 4u) {
+ v_bits |= ((uint32_t)(wuffs_base__peek_u32le__no_bounds_check(iop_a_src) << v_n_bits));
+ iop_a_src += ((31u - v_n_bits) >> 3u);
+ v_n_bits |= 24u;
+ } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ self->private_impl.f_read_from_return_value = 3u;
+ } else {
+ self->private_impl.f_read_from_return_value = 2u;
+ }
+ break;
+ } else {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ if (v_n_bits >= v_width) {
+ } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ if (a_src && a_src->meta.closed) {
+ self->private_impl.f_read_from_return_value = 3u;
+ } else {
+ self->private_impl.f_read_from_return_value = 2u;
+ }
+ break;
+ } else {
+ v_bits |= (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) << v_n_bits);
+ iop_a_src += 1u;
+ v_n_bits += 8u;
+ if (v_n_bits < v_width) {
+ self->private_impl.f_read_from_return_value = 5u;
+ break;
+ }
+ }
+ }
+ }
+ v_code = ((v_bits) & WUFFS_BASE__LOW_BITS_MASK__U32(v_width));
+ v_bits >>= v_width;
+ v_n_bits -= v_width;
+ if (v_code < v_clear_code) {
+ self->private_data.f_output[v_output_wi] = ((uint8_t)(v_code));
+ v_output_wi = ((v_output_wi + 1u) & 8191u);
+ if (v_save_code <= 4095u) {
+ v_lm1_a = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u);
+ self->private_data.f_lm1s[v_save_code] = v_lm1_a;
+ if ((v_lm1_a % 8u) != 0u) {
+ self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
+ memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code]));
+ self->private_data.f_suffixes[v_save_code][(v_lm1_a % 8u)] = ((uint8_t)(v_code));
+ } else {
+ self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
+ self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_code));
+ }
+ v_save_code += 1u;
+ if (v_width < 12u) {
+ v_width += (1u & (v_save_code >> v_width));
+ }
+ v_prev_code = v_code;
+ }
+ } else if (v_code <= v_end_code) {
+ if (v_code == v_end_code) {
+ self->private_impl.f_read_from_return_value = 0u;
+ break;
+ }
+ v_save_code = v_end_code;
+ v_prev_code = v_end_code;
+ v_width = (self->private_impl.f_literal_width + 1u);
+ } else if (v_code <= v_save_code) {
+ v_c = v_code;
+ if (v_code == v_save_code) {
+ v_c = v_prev_code;
+ }
+ v_o = ((v_output_wi + (((uint32_t)(self->private_data.f_lm1s[v_c])) & 4294967288u)) & 8191u);
+ v_output_wi = ((v_output_wi + 1u + ((uint32_t)(self->private_data.f_lm1s[v_c]))) & 8191u);
+ v_steps = (((uint32_t)(self->private_data.f_lm1s[v_c])) >> 3u);
+ while (true) {
+ memcpy((self->private_data.f_output)+(v_o), (self->private_data.f_suffixes[v_c]), 8u);
+ if (v_steps <= 0u) {
+ break;
+ }
+ v_steps -= 1u;
+ v_o = (((uint32_t)(v_o - 8u)) & 8191u);
+ v_c = ((uint32_t)(self->private_impl.f_prefixes[v_c]));
+ }
+ v_first_byte = self->private_data.f_suffixes[v_c][0u];
+ if (v_code == v_save_code) {
+ self->private_data.f_output[v_output_wi] = v_first_byte;
+ v_output_wi = ((v_output_wi + 1u) & 8191u);
+ }
+ if (v_save_code <= 4095u) {
+ v_lm1_b = (((uint16_t)(self->private_data.f_lm1s[v_prev_code] + 1u)) & 4095u);
+ self->private_data.f_lm1s[v_save_code] = v_lm1_b;
+ if ((v_lm1_b % 8u) != 0u) {
+ self->private_impl.f_prefixes[v_save_code] = self->private_impl.f_prefixes[v_prev_code];
+ memcpy(self->private_data.f_suffixes[v_save_code],self->private_data.f_suffixes[v_prev_code], sizeof(self->private_data.f_suffixes[v_save_code]));
+ self->private_data.f_suffixes[v_save_code][(v_lm1_b % 8u)] = v_first_byte;
+ } else {
+ self->private_impl.f_prefixes[v_save_code] = ((uint16_t)(v_prev_code));
+ self->private_data.f_suffixes[v_save_code][0u] = ((uint8_t)(v_first_byte));
+ }
+ v_save_code += 1u;
+ if (v_width < 12u) {
+ v_width += (1u & (v_save_code >> v_width));
+ }
+ v_prev_code = v_code;
+ }
+ } else {
+ self->private_impl.f_read_from_return_value = 4u;
+ break;
+ }
+ if (v_output_wi > 4095u) {
+ self->private_impl.f_read_from_return_value = 1u;
+ break;
+ }
+ }
+ if (self->private_impl.f_read_from_return_value != 2u) {
+ while (v_n_bits >= 8u) {
+ v_n_bits -= 8u;
+ if (iop_a_src > io1_a_src) {
+ iop_a_src--;
+ } else {
+ self->private_impl.f_read_from_return_value = 5u;
+ break;
+ }
+ }
+ }
+ self->private_impl.f_save_code = v_save_code;
+ self->private_impl.f_prev_code = v_prev_code;
+ self->private_impl.f_width = v_width;
+ self->private_impl.f_bits = v_bits;
+ self->private_impl.f_n_bits = v_n_bits;
+ self->private_impl.f_output_wi = v_output_wi;
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func lzw.decoder.write_to
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_lzw__decoder__write_to(
+ wuffs_lzw__decoder* self,
+ wuffs_base__io_buffer* a_dst) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__slice_u8 v_s = {0};
+ uint64_t v_n = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_write_to[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (self->private_impl.f_output_wi > 0u) {
+ if (self->private_impl.f_output_ri > self->private_impl.f_output_wi) {
+ status = wuffs_base__make_status(wuffs_lzw__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ v_s = wuffs_base__make_slice_u8_ij(self->private_data.f_output,
+ self->private_impl.f_output_ri,
+ self->private_impl.f_output_wi);
+ v_n = wuffs_base__io_writer__copy_from_slice(&iop_a_dst, io2_a_dst,v_s);
+ if (v_n == ((uint64_t)(v_s.len))) {
+ self->private_impl.f_output_ri = 0u;
+ self->private_impl.f_output_wi = 0u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ self->private_impl.f_output_ri = (((uint32_t)(self->private_impl.f_output_ri + ((uint32_t)(v_n)))) & 8191u);
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_write_to[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_write_to[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func lzw.decoder.flush
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__slice_u8
+wuffs_lzw__decoder__flush(
+ wuffs_lzw__decoder* self) {
+ if (!self) {
+ return wuffs_base__make_slice_u8(NULL, 0);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_slice_u8(NULL, 0);
+ }
+
+ uint32_t v_ri = 0;
+ uint32_t v_wi = 0;
+
+ v_ri = self->private_impl.f_output_ri;
+ v_wi = self->private_impl.f_output_wi;
+ self->private_impl.f_output_ri = 0u;
+ self->private_impl.f_output_wi = 0u;
+ if (v_ri <= v_wi) {
+ return wuffs_base__make_slice_u8_ij(self->private_data.f_output, v_ri, v_wi);
+ }
+ return wuffs_base__make_slice_u8(self->private_data.f_output, 0);
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__LZW)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_netpbm__error__bad_header[] = "#netpbm: bad header";
+const char wuffs_netpbm__error__truncated_input[] = "#netpbm: truncated input";
+const char wuffs_netpbm__error__unsupported_netpbm_file[] = "#netpbm: unsupported Netpbm file";
+const char wuffs_netpbm__note__internal_note_short_read[] = "@netpbm: internal note: short read";
+
+// ---------------- Private Consts
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_netpbm__decoder__do_decode_image_config(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_netpbm__decoder__do_decode_frame_config(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_netpbm__decoder__do_decode_frame(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_netpbm__decoder__swizzle(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+// ---------------- VTables
+
+const wuffs_base__image_decoder__func_ptrs
+wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__pixel_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
+ wuffs_base__slice_u8,
+ wuffs_base__decode_frame_options*))(&wuffs_netpbm__decoder__decode_frame),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__frame_config*,
+ wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_frame_config),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__image_config*,
+ wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__decode_image_config),
+ (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_netpbm__decoder__frame_dirty_rect),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_netpbm__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__history_retain_length),
+ (uint32_t(*)(const void*))(&wuffs_netpbm__decoder__num_animation_loops),
+ (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frame_configs),
+ (uint64_t(*)(const void*))(&wuffs_netpbm__decoder__num_decoded_frames),
+ (wuffs_base__status(*)(void*,
+ uint64_t,
+ uint64_t))(&wuffs_netpbm__decoder__restart_frame),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_netpbm__decoder__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ uint32_t,
+ bool))(&wuffs_netpbm__decoder__set_report_metadata),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*))(&wuffs_netpbm__decoder__tell_me_more),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_netpbm__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_netpbm__decoder__initialize(
+ wuffs_netpbm__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
+ wuffs_base__image_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
+ (const void*)(&wuffs_netpbm__decoder__func_ptrs_for__wuffs_base__image_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_netpbm__decoder*
+wuffs_netpbm__decoder__alloc(void) {
+ wuffs_netpbm__decoder* x =
+ (wuffs_netpbm__decoder*)(calloc(sizeof(wuffs_netpbm__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_netpbm__decoder__initialize(
+ x, sizeof(wuffs_netpbm__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_netpbm__decoder(void) {
+ return sizeof(wuffs_netpbm__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func netpbm.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_netpbm__decoder__get_quirk(
+ const wuffs_netpbm__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func netpbm.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__set_quirk(
+ wuffs_netpbm__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func netpbm.decoder.decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__decode_image_config(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_image_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func netpbm.decoder.do_decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_netpbm__decoder__do_decode_image_config(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_n = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c != 80u) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ if ((v_c < 49u) || (55u < v_c)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ } else if (v_c == 53u) {
+ self->private_impl.f_pixfmt = 536870920u;
+ } else if (v_c == 54u) {
+ self->private_impl.f_pixfmt = 2684356744u;
+ } else {
+ status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_c = t_2;
+ }
+ if (v_c != 10u) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_c = t_3;
+ }
+ if ((v_c == 32u) || (v_c == 9u)) {
+ continue;
+ } else if (v_c == 35u) {
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_4 = *iop_a_src++;
+ v_c = t_4;
+ }
+ if (v_c == 10u) {
+ break;
+ }
+ }
+ continue;
+ } else if ((v_c < 48u) || (57u < v_c)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_width = ((uint32_t)((v_c - 48u)));
+ break;
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ v_c = t_5;
+ }
+ if ((v_c == 32u) || (v_c == 9u)) {
+ break;
+ } else if ((v_c < 48u) || (57u < v_c)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ }
+ v_n = ((10u * self->private_impl.f_width) + ((uint32_t)((v_c - 48u))));
+ if (v_n > 16777215u) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
+ goto exit;
+ }
+ self->private_impl.f_width = v_n;
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_6 = *iop_a_src++;
+ v_c = t_6;
+ }
+ if ((v_c == 32u) || (v_c == 9u)) {
+ continue;
+ } else if (v_c == 35u) {
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_7 = *iop_a_src++;
+ v_c = t_7;
+ }
+ if (v_c == 10u) {
+ break;
+ }
+ }
+ continue;
+ } else if ((v_c < 48u) || (57u < v_c)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_height = ((uint32_t)((v_c - 48u)));
+ break;
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_8 = *iop_a_src++;
+ v_c = t_8;
+ }
+ if ((v_c == 32u) || (v_c == 9u) || (v_c == 13u)) {
+ continue;
+ } else if (v_c == 10u) {
+ break;
+ } else if ((v_c < 48u) || (57u < v_c)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ }
+ v_n = ((10u * self->private_impl.f_height) + ((uint32_t)((v_c - 48u))));
+ if (v_n > 16777215u) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
+ goto exit;
+ }
+ self->private_impl.f_height = v_n;
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_9 = *iop_a_src++;
+ v_c = t_9;
+ }
+ if ((v_c == 32u) || (v_c == 9u)) {
+ continue;
+ } else if (v_c == 35u) {
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_10 = *iop_a_src++;
+ v_c = t_10;
+ }
+ if (v_c == 10u) {
+ break;
+ }
+ }
+ continue;
+ } else if ((v_c < 48u) || (57u < v_c)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_max_value = ((uint32_t)((v_c - 48u)));
+ break;
+ }
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_11 = *iop_a_src++;
+ v_c = t_11;
+ }
+ if ((v_c == 32u) || (v_c == 9u) || (v_c == 13u)) {
+ continue;
+ } else if (v_c == 10u) {
+ break;
+ } else if ((v_c < 48u) || (57u < v_c)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__bad_header);
+ goto exit;
+ }
+ v_n = ((10u * self->private_impl.f_max_value) + ((uint32_t)((v_c - 48u))));
+ if (v_n > 16777215u) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
+ goto exit;
+ }
+ self->private_impl.f_max_value = v_n;
+ }
+ if (self->private_impl.f_max_value != 255u) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__unsupported_netpbm_file);
+ goto exit;
+ }
+ self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ if (a_dst != NULL) {
+ wuffs_base__image_config__set(
+ a_dst,
+ self->private_impl.f_pixfmt,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ self->private_impl.f_frame_config_io_position,
+ false);
+ }
+ self->private_impl.f_call_sequence = 32u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_do_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func netpbm.decoder.decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__decode_frame_config(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 2)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func netpbm.decoder.do_decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_netpbm__decoder__do_decode_frame_config(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 32u) {
+ } else if (self->private_impl.f_call_sequence < 32u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_netpbm__decoder__do_decode_image_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (self->private_impl.f_call_sequence == 40u) {
+ if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_restart);
+ goto exit;
+ }
+ } else if (self->private_impl.f_call_sequence == 64u) {
+ self->private_impl.f_call_sequence = 96u;
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (a_dst != NULL) {
+ wuffs_base__frame_config__set(
+ a_dst,
+ wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height),
+ ((wuffs_base__flicks)(0u)),
+ 0u,
+ self->private_impl.f_frame_config_io_position,
+ 0u,
+ false,
+ false,
+ 0u);
+ }
+ self->private_impl.f_call_sequence = 64u;
+
+ ok:
+ self->private_impl.p_do_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func netpbm.decoder.decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__decode_frame(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 3)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_netpbm__decoder__do_decode_frame(self,
+ a_dst,
+ a_src,
+ a_blend,
+ a_workbuf,
+ a_opts);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_netpbm__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func netpbm.decoder.do_decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_netpbm__decoder__do_decode_frame(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 64u) {
+ } else if (self->private_impl.f_call_sequence < 64u) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_netpbm__decoder__do_decode_frame_config(self, NULL, a_src);
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ self->private_impl.f_dst_x = 0u;
+ self->private_impl.f_dst_y = 0u;
+ v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
+ wuffs_base__pixel_buffer__pixel_format(a_dst),
+ wuffs_base__pixel_buffer__palette(a_dst),
+ wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
+ wuffs_base__utility__empty_slice_u8(),
+ a_blend);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ while (true) {
+ v_status = wuffs_netpbm__decoder__swizzle(self, a_dst, a_src);
+ if (wuffs_base__status__is_ok(&v_status)) {
+ break;
+ } else if (v_status.repr != wuffs_netpbm__note__internal_note_short_read) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ }
+ self->private_impl.f_call_sequence = 96u;
+
+ ok:
+ self->private_impl.p_do_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ return status;
+}
+
+// -------- func netpbm.decoder.swizzle
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_netpbm__decoder__swizzle(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint32_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_bytes_per_row = 0;
+ uint32_t v_src_bytes_per_pixel = 0;
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint64_t v_i = 0;
+ uint64_t v_j = 0;
+ uint64_t v_n = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ goto exit;
+ }
+ v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
+ v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ while (true) {
+ if (self->private_impl.f_dst_x == self->private_impl.f_width) {
+ self->private_impl.f_dst_x = 0u;
+ self->private_impl.f_dst_y += 1u;
+ if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
+ break;
+ }
+ }
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
+ }
+ v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
+ if (v_i >= ((uint64_t)(v_dst.len))) {
+ v_src_bytes_per_pixel = 1u;
+ if (self->private_impl.f_pixfmt == 2684356744u) {
+ v_src_bytes_per_pixel = 3u;
+ }
+ v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
+ v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
+ v_j = v_n;
+ while (v_j >= 8u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
+ iop_a_src += (v_src_bytes_per_pixel * 8u);
+ }
+ v_j -= 8u;
+ }
+ while (v_j > 0u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
+ iop_a_src += (v_src_bytes_per_pixel * 1u);
+ }
+ v_j -= 1u;
+ }
+ } else {
+ v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
+ &self->private_impl.f_swizzler,
+ wuffs_base__slice_u8__subslice_i(v_dst, v_i),
+ wuffs_base__pixel_buffer__palette(a_dst),
+ &iop_a_src,
+ io2_a_src);
+ }
+ if (v_n == 0u) {
+ status = wuffs_base__make_status(wuffs_netpbm__note__internal_note_short_read);
+ goto ok;
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
+ }
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func netpbm.decoder.frame_dirty_rect
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_netpbm__decoder__frame_dirty_rect(
+ const wuffs_netpbm__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ return wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height);
+}
+
+// -------- func netpbm.decoder.num_animation_loops
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_netpbm__decoder__num_animation_loops(
+ const wuffs_netpbm__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func netpbm.decoder.num_decoded_frame_configs
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_netpbm__decoder__num_decoded_frame_configs(
+ const wuffs_netpbm__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 32u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func netpbm.decoder.num_decoded_frames
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_netpbm__decoder__num_decoded_frames(
+ const wuffs_netpbm__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 64u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func netpbm.decoder.restart_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__restart_frame(
+ wuffs_netpbm__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (self->private_impl.f_call_sequence < 32u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ }
+ if ((a_index != 0u) || (a_io_position != self->private_impl.f_frame_config_io_position)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_call_sequence = 40u;
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func netpbm.decoder.set_report_metadata
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_netpbm__decoder__set_report_metadata(
+ wuffs_netpbm__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func netpbm.decoder.tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_netpbm__decoder__tell_me_more(
+ wuffs_netpbm__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 4)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ status = wuffs_base__make_status(wuffs_base__error__no_more_information);
+ goto exit;
+
+ goto ok;
+ ok:
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func netpbm.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_netpbm__decoder__history_retain_length(
+ const wuffs_netpbm__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func netpbm.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_netpbm__decoder__workbuf_len(
+ const wuffs_netpbm__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(0u, 0u);
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_nie__error__bad_header[] = "#nie: bad header";
+const char wuffs_nie__error__truncated_input[] = "#nie: truncated input";
+const char wuffs_nie__error__unsupported_nie_file[] = "#nie: unsupported NIE file";
+const char wuffs_nie__note__internal_note_short_read[] = "@nie: internal note: short read";
+
+// ---------------- Private Consts
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_nie__decoder__do_decode_image_config(
+ wuffs_nie__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_nie__decoder__do_decode_frame_config(
+ wuffs_nie__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_nie__decoder__do_decode_frame(
+ wuffs_nie__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_nie__decoder__swizzle(
+ wuffs_nie__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+// ---------------- VTables
+
+const wuffs_base__image_decoder__func_ptrs
+wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__pixel_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
+ wuffs_base__slice_u8,
+ wuffs_base__decode_frame_options*))(&wuffs_nie__decoder__decode_frame),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__frame_config*,
+ wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_frame_config),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__image_config*,
+ wuffs_base__io_buffer*))(&wuffs_nie__decoder__decode_image_config),
+ (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_nie__decoder__frame_dirty_rect),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_nie__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_nie__decoder__history_retain_length),
+ (uint32_t(*)(const void*))(&wuffs_nie__decoder__num_animation_loops),
+ (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frame_configs),
+ (uint64_t(*)(const void*))(&wuffs_nie__decoder__num_decoded_frames),
+ (wuffs_base__status(*)(void*,
+ uint64_t,
+ uint64_t))(&wuffs_nie__decoder__restart_frame),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_nie__decoder__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ uint32_t,
+ bool))(&wuffs_nie__decoder__set_report_metadata),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*))(&wuffs_nie__decoder__tell_me_more),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_nie__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_nie__decoder__initialize(
+ wuffs_nie__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
+ wuffs_base__image_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
+ (const void*)(&wuffs_nie__decoder__func_ptrs_for__wuffs_base__image_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_nie__decoder*
+wuffs_nie__decoder__alloc(void) {
+ wuffs_nie__decoder* x =
+ (wuffs_nie__decoder*)(calloc(sizeof(wuffs_nie__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_nie__decoder__initialize(
+ x, sizeof(wuffs_nie__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_nie__decoder(void) {
+ return sizeof(wuffs_nie__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func nie.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_nie__decoder__get_quirk(
+ const wuffs_nie__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func nie.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__set_quirk(
+ wuffs_nie__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func nie.decoder.decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__decode_image_config(
+ wuffs_nie__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_image_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func nie.decoder.do_decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_nie__decoder__do_decode_image_config(
+ wuffs_nie__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_a = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0)) << 56;
+ }
+ }
+ v_a = t_0;
+ }
+ if (v_a != 1169146734u) {
+ status = wuffs_base__make_status(wuffs_nie__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1)) << 56;
+ }
+ }
+ v_a = t_1;
+ }
+ if (v_a == 879649535u) {
+ self->private_impl.f_pixfmt = 2164295816u;
+ } else if (v_a == 946758399u) {
+ self->private_impl.f_pixfmt = 2164308923u;
+ } else if (v_a == 879780607u) {
+ status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
+ goto exit;
+ } else if (v_a == 946889471u) {
+ status = wuffs_base__make_status(wuffs_nie__error__unsupported_nie_file);
+ goto exit;
+ } else {
+ status = wuffs_base__make_status(wuffs_nie__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
+ if (num_bits_2 == 24) {
+ t_2 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2)) << 56;
+ }
+ }
+ v_a = t_2;
+ }
+ if (v_a > 2147483647u) {
+ status = wuffs_base__make_status(wuffs_nie__error__bad_header);
+ goto exit;
+ } else if (v_a > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ self->private_impl.f_width = v_a;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ uint32_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_3 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
+ if (num_bits_3 == 24) {
+ t_3 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3)) << 56;
+ }
+ }
+ v_a = t_3;
+ }
+ if (v_a > 2147483647u) {
+ status = wuffs_base__make_status(wuffs_nie__error__bad_header);
+ goto exit;
+ } else if (v_a > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ self->private_impl.f_height = v_a;
+ if (a_dst != NULL) {
+ wuffs_base__image_config__set(
+ a_dst,
+ self->private_impl.f_pixfmt,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ 16u,
+ false);
+ }
+ self->private_impl.f_call_sequence = 32u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_do_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func nie.decoder.decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__decode_frame_config(
+ wuffs_nie__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 2)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func nie.decoder.do_decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_nie__decoder__do_decode_frame_config(
+ wuffs_nie__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 32u) {
+ } else if (self->private_impl.f_call_sequence < 32u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_nie__decoder__do_decode_image_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (self->private_impl.f_call_sequence == 40u) {
+ if (16u != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_restart);
+ goto exit;
+ }
+ } else if (self->private_impl.f_call_sequence == 64u) {
+ self->private_impl.f_call_sequence = 96u;
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (a_dst != NULL) {
+ wuffs_base__frame_config__set(
+ a_dst,
+ wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height),
+ ((wuffs_base__flicks)(0u)),
+ 0u,
+ 16u,
+ 0u,
+ false,
+ false,
+ 0u);
+ }
+ self->private_impl.f_call_sequence = 64u;
+
+ ok:
+ self->private_impl.p_do_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func nie.decoder.decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__decode_frame(
+ wuffs_nie__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 3)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_nie__decoder__do_decode_frame(self,
+ a_dst,
+ a_src,
+ a_blend,
+ a_workbuf,
+ a_opts);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_nie__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func nie.decoder.do_decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_nie__decoder__do_decode_frame(
+ wuffs_nie__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 64u) {
+ } else if (self->private_impl.f_call_sequence < 64u) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_nie__decoder__do_decode_frame_config(self, NULL, a_src);
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ self->private_impl.f_dst_x = 0u;
+ self->private_impl.f_dst_y = 0u;
+ v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
+ wuffs_base__pixel_buffer__pixel_format(a_dst),
+ wuffs_base__pixel_buffer__palette(a_dst),
+ wuffs_base__utility__make_pixel_format(self->private_impl.f_pixfmt),
+ wuffs_base__utility__empty_slice_u8(),
+ a_blend);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ while (true) {
+ v_status = wuffs_nie__decoder__swizzle(self, a_dst, a_src);
+ if (wuffs_base__status__is_ok(&v_status)) {
+ break;
+ } else if (v_status.repr != wuffs_nie__note__internal_note_short_read) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ }
+ self->private_impl.f_call_sequence = 96u;
+
+ ok:
+ self->private_impl.p_do_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ return status;
+}
+
+// -------- func nie.decoder.swizzle
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_nie__decoder__swizzle(
+ wuffs_nie__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint32_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_bytes_per_row = 0;
+ uint32_t v_src_bytes_per_pixel = 0;
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint64_t v_i = 0;
+ uint64_t v_j = 0;
+ uint64_t v_n = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ goto exit;
+ }
+ v_dst_bytes_per_pixel = (v_dst_bits_per_pixel / 8u);
+ v_dst_bytes_per_row = ((uint64_t)((self->private_impl.f_width * v_dst_bytes_per_pixel)));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ while (true) {
+ if (self->private_impl.f_dst_x == self->private_impl.f_width) {
+ self->private_impl.f_dst_x = 0u;
+ self->private_impl.f_dst_y += 1u;
+ if (self->private_impl.f_dst_y >= self->private_impl.f_height) {
+ break;
+ }
+ }
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, self->private_impl.f_dst_y);
+ if (v_dst_bytes_per_row < ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row);
+ }
+ v_i = (((uint64_t)(self->private_impl.f_dst_x)) * ((uint64_t)(v_dst_bytes_per_pixel)));
+ if (v_i >= ((uint64_t)(v_dst.len))) {
+ v_src_bytes_per_pixel = 4u;
+ if (self->private_impl.f_pixfmt == 2164308923u) {
+ v_src_bytes_per_pixel = 8u;
+ }
+ v_n = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(v_src_bytes_per_pixel)));
+ v_n = wuffs_base__u64__min(v_n, ((uint64_t)(((uint32_t)(self->private_impl.f_width - self->private_impl.f_dst_x)))));
+ v_j = v_n;
+ while (v_j >= 8u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 8u)))) {
+ iop_a_src += (v_src_bytes_per_pixel * 8u);
+ }
+ v_j -= 8u;
+ }
+ while (v_j > 0u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) >= ((uint64_t)((v_src_bytes_per_pixel * 1u)))) {
+ iop_a_src += (v_src_bytes_per_pixel * 1u);
+ }
+ v_j -= 1u;
+ }
+ } else {
+ v_n = wuffs_base__pixel_swizzler__swizzle_interleaved_from_reader(
+ &self->private_impl.f_swizzler,
+ wuffs_base__slice_u8__subslice_i(v_dst, v_i),
+ wuffs_base__pixel_buffer__palette(a_dst),
+ &iop_a_src,
+ io2_a_src);
+ }
+ if (v_n == 0u) {
+ status = wuffs_base__make_status(wuffs_nie__note__internal_note_short_read);
+ goto ok;
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_dst_x, ((uint32_t)(v_n)));
+ }
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func nie.decoder.frame_dirty_rect
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_nie__decoder__frame_dirty_rect(
+ const wuffs_nie__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ return wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height);
+}
+
+// -------- func nie.decoder.num_animation_loops
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_nie__decoder__num_animation_loops(
+ const wuffs_nie__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func nie.decoder.num_decoded_frame_configs
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_nie__decoder__num_decoded_frame_configs(
+ const wuffs_nie__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 32u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func nie.decoder.num_decoded_frames
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_nie__decoder__num_decoded_frames(
+ const wuffs_nie__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 64u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func nie.decoder.restart_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__restart_frame(
+ wuffs_nie__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (self->private_impl.f_call_sequence < 32u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ }
+ if ((a_index != 0u) || (a_io_position != 16u)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_call_sequence = 40u;
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func nie.decoder.set_report_metadata
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_nie__decoder__set_report_metadata(
+ wuffs_nie__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func nie.decoder.tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_nie__decoder__tell_me_more(
+ wuffs_nie__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 4)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ status = wuffs_base__make_status(wuffs_base__error__no_more_information);
+ goto exit;
+
+ goto ok;
+ ok:
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func nie.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_nie__decoder__history_retain_length(
+ const wuffs_nie__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func nie.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_nie__decoder__workbuf_len(
+ const wuffs_nie__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(0u, 0u);
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_zlib__note__dictionary_required[] = "@zlib: dictionary required";
+const char wuffs_zlib__error__bad_checksum[] = "#zlib: bad checksum";
+const char wuffs_zlib__error__bad_compression_method[] = "#zlib: bad compression method";
+const char wuffs_zlib__error__bad_compression_window_size[] = "#zlib: bad compression window size";
+const char wuffs_zlib__error__bad_parity_check[] = "#zlib: bad parity check";
+const char wuffs_zlib__error__incorrect_dictionary[] = "#zlib: incorrect dictionary";
+const char wuffs_zlib__error__truncated_input[] = "#zlib: truncated input";
+
+// ---------------- Private Consts
+
+#define WUFFS_ZLIB__QUIRKS_BASE 2113790976
+
+#define WUFFS_ZLIB__QUIRKS_COUNT 1
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_zlib__decoder__do_transform_io(
+ wuffs_zlib__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+// ---------------- VTables
+
+const wuffs_base__io_transformer__func_ptrs
+wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer = {
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_zlib__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_zlib__decoder__history_retain_length),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_zlib__decoder__set_quirk),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__slice_u8))(&wuffs_zlib__decoder__transform_io),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_zlib__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_zlib__decoder__initialize(
+ wuffs_zlib__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ {
+ wuffs_base__status z = wuffs_adler32__hasher__initialize(
+ &self->private_data.f_checksum, sizeof(self->private_data.f_checksum), WUFFS_VERSION, options);
+ if (z.repr) {
+ return z;
+ }
+ }
+ {
+ wuffs_base__status z = wuffs_adler32__hasher__initialize(
+ &self->private_data.f_dict_id_hasher, sizeof(self->private_data.f_dict_id_hasher), WUFFS_VERSION, options);
+ if (z.repr) {
+ return z;
+ }
+ }
+ {
+ wuffs_base__status z = wuffs_deflate__decoder__initialize(
+ &self->private_data.f_flate, sizeof(self->private_data.f_flate), WUFFS_VERSION, options);
+ if (z.repr) {
+ return z;
+ }
+ }
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.vtable_name =
+ wuffs_base__io_transformer__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__io_transformer.function_pointers =
+ (const void*)(&wuffs_zlib__decoder__func_ptrs_for__wuffs_base__io_transformer);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_zlib__decoder*
+wuffs_zlib__decoder__alloc(void) {
+ wuffs_zlib__decoder* x =
+ (wuffs_zlib__decoder*)(calloc(sizeof(wuffs_zlib__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_zlib__decoder__initialize(
+ x, sizeof(wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_zlib__decoder(void) {
+ return sizeof(wuffs_zlib__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func zlib.decoder.dictionary_id
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_zlib__decoder__dictionary_id(
+ const wuffs_zlib__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return self->private_impl.f_dict_id_want;
+}
+
+// -------- func zlib.decoder.add_dictionary
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_zlib__decoder__add_dictionary(
+ wuffs_zlib__decoder* self,
+ wuffs_base__slice_u8 a_dict) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ if (self->private_impl.f_header_complete) {
+ self->private_impl.f_bad_call_sequence = true;
+ } else {
+ self->private_impl.f_dict_id_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_dict_id_hasher, a_dict);
+ wuffs_deflate__decoder__add_history(&self->private_data.f_flate, a_dict);
+ }
+ self->private_impl.f_got_dictionary = true;
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func zlib.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_zlib__decoder__get_quirk(
+ const wuffs_zlib__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ uint32_t v_key = 0;
+
+ if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
+ return 1u;
+ } else if (a_key >= 2113790976u) {
+ v_key = (a_key - 2113790976u);
+ if (v_key < 1u) {
+ if (self->private_impl.f_quirks[v_key]) {
+ return 1u;
+ }
+ }
+ }
+ return 0u;
+}
+
+// -------- func zlib.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_zlib__decoder__set_quirk(
+ wuffs_zlib__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (self->private_impl.f_header_complete) {
+ self->private_impl.f_bad_call_sequence = true;
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ } else if (a_key == 1u) {
+ self->private_impl.f_ignore_checksum = (a_value > 0u);
+ return wuffs_base__make_status(NULL);
+ } else if (a_key >= 2113790976u) {
+ a_key -= 2113790976u;
+ if (a_key < 1u) {
+ self->private_impl.f_quirks[a_key] = (a_value > 0u);
+ return wuffs_base__make_status(NULL);
+ }
+ }
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func zlib.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_zlib__decoder__history_retain_length(
+ const wuffs_zlib__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func zlib.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_zlib__decoder__workbuf_len(
+ const wuffs_zlib__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(1u, 1u);
+}
+
+// -------- func zlib.decoder.transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_zlib__decoder__transform_io(
+ wuffs_zlib__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_transform_io[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_zlib__decoder__do_transform_io(self, a_dst, a_src, a_workbuf);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_zlib__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func zlib.decoder.do_transform_io
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_zlib__decoder__do_transform_io(
+ wuffs_zlib__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint16_t v_x = 0;
+ uint32_t v_checksum_got = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ uint32_t v_checksum_want = 0;
+ uint64_t v_mark = 0;
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_transform_io[0];
+ if (coro_susp_point) {
+ v_checksum_got = self->private_data.s_do_transform_io[0].v_checksum_got;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_bad_call_sequence) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ } else if (self->private_impl.f_quirks[0u]) {
+ } else if ( ! self->private_impl.f_want_dictionary) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint16_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_0 = wuffs_base__peek_u16be__no_bounds_check(iop_a_src);
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_transform_io[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 8) {
+ t_0 = ((uint16_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ v_x = t_0;
+ }
+ if (((v_x >> 8u) & 15u) != 8u) {
+ status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_method);
+ goto exit;
+ }
+ if ((v_x >> 12u) > 7u) {
+ status = wuffs_base__make_status(wuffs_zlib__error__bad_compression_window_size);
+ goto exit;
+ }
+ if ((v_x % 31u) != 0u) {
+ status = wuffs_base__make_status(wuffs_zlib__error__bad_parity_check);
+ goto exit;
+ }
+ self->private_impl.f_want_dictionary = ((v_x & 32u) != 0u);
+ if (self->private_impl.f_want_dictionary) {
+ self->private_impl.f_dict_id_got = 1u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_transform_io[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ self->private_impl.f_dict_id_want = t_1;
+ }
+ status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
+ goto ok;
+ } else if (self->private_impl.f_got_dictionary) {
+ status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
+ goto exit;
+ }
+ } else if (self->private_impl.f_dict_id_got != self->private_impl.f_dict_id_want) {
+ if (self->private_impl.f_got_dictionary) {
+ status = wuffs_base__make_status(wuffs_zlib__error__incorrect_dictionary);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_zlib__note__dictionary_required);
+ goto ok;
+ }
+ self->private_impl.f_header_complete = true;
+ while (true) {
+ v_mark = ((uint64_t)(iop_a_dst - io0_a_dst));
+ {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_2 = wuffs_deflate__decoder__transform_io(&self->private_data.f_flate, a_dst, a_src, a_workbuf);
+ v_status = t_2;
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ if ( ! self->private_impl.f_ignore_checksum && ! self->private_impl.f_quirks[0u]) {
+ v_checksum_got = wuffs_adler32__hasher__update_u32(&self->private_data.f_checksum, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_dst - io0_a_dst)), io0_a_dst));
+ }
+ if (wuffs_base__status__is_ok(&v_status)) {
+ break;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
+ }
+ if ( ! self->private_impl.f_quirks[0u]) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ uint32_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_transform_io[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_transform_io[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
+ if (num_bits_3 == 24) {
+ t_3 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3));
+ }
+ }
+ v_checksum_want = t_3;
+ }
+ if ( ! self->private_impl.f_ignore_checksum && (v_checksum_got != v_checksum_want)) {
+ status = wuffs_base__make_status(wuffs_zlib__error__bad_checksum);
+ goto exit;
+ }
+ }
+
+ ok:
+ self->private_impl.p_do_transform_io[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_transform_io[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_transform_io[0].v_checksum_got = v_checksum_got;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__ZLIB)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_png__error__bad_animation_sequence_number[] = "#png: bad animation sequence number";
+const char wuffs_png__error__bad_checksum[] = "#png: bad checksum";
+const char wuffs_png__error__bad_chunk[] = "#png: bad chunk";
+const char wuffs_png__error__bad_filter[] = "#png: bad filter";
+const char wuffs_png__error__bad_header[] = "#png: bad header";
+const char wuffs_png__error__bad_text_chunk_not_latin_1[] = "#png: bad text chunk (not Latin-1)";
+const char wuffs_png__error__missing_palette[] = "#png: missing palette";
+const char wuffs_png__error__truncated_input[] = "#png: truncated input";
+const char wuffs_png__error__unsupported_cgbi_extension[] = "#png: unsupported CgBI extension";
+const char wuffs_png__error__unsupported_png_compression_method[] = "#png: unsupported PNG compression method";
+const char wuffs_png__error__unsupported_png_file[] = "#png: unsupported PNG file";
+const char wuffs_png__error__internal_error_inconsistent_i_o[] = "#png: internal error: inconsistent I/O";
+const char wuffs_png__error__internal_error_inconsistent_chunk_type[] = "#png: internal error: inconsistent chunk type";
+const char wuffs_png__error__internal_error_inconsistent_frame_bounds[] = "#png: internal error: inconsistent frame bounds";
+const char wuffs_png__error__internal_error_inconsistent_workbuf_length[] = "#png: internal error: inconsistent workbuf length";
+const char wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input[] = "#png: internal error: zlib decoder did not exhaust its input";
+
+// ---------------- Private Consts
+
+#define WUFFS_PNG__ANCILLARY_BIT 32
+
+static const uint8_t
+WUFFS_PNG__INTERLACING[8][6] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ {
+ 0, 0, 0, 0, 0, 0,
+ }, {
+ 3, 7, 0, 3, 7, 0,
+ }, {
+ 3, 3, 4, 3, 7, 0,
+ }, {
+ 2, 3, 0, 3, 3, 4,
+ }, {
+ 2, 1, 2, 2, 3, 0,
+ }, {
+ 1, 1, 0, 2, 1, 2,
+ }, {
+ 1, 0, 1, 1, 1, 0,
+ }, {
+ 0, 0, 0, 1, 0, 1,
+ },
+};
+
+static const uint8_t
+WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 255, 85, 0, 17, 0, 0, 0,
+};
+
+static const uint8_t
+WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 8, 4, 0, 2, 0, 0, 0,
+};
+
+static const uint8_t
+WUFFS_PNG__NUM_CHANNELS[8] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 1, 0, 3, 1, 2, 0, 4, 0,
+};
+
+static const uint16_t
+WUFFS_PNG__LATIN_1[256] WUFFS_BASE__POTENTIALLY_UNUSED = {
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 32, 33, 34, 35, 36, 37, 38, 39,
+ 40, 41, 42, 43, 44, 45, 46, 47,
+ 48, 49, 50, 51, 52, 53, 54, 55,
+ 56, 57, 58, 59, 60, 61, 62, 63,
+ 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 73, 74, 75, 76, 77, 78, 79,
+ 80, 81, 82, 83, 84, 85, 86, 87,
+ 88, 89, 90, 91, 92, 93, 94, 95,
+ 96, 97, 98, 99, 100, 101, 102, 103,
+ 104, 105, 106, 107, 108, 109, 110, 111,
+ 112, 113, 114, 115, 116, 117, 118, 119,
+ 120, 121, 122, 123, 124, 125, 126, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 41410, 41666, 41922, 42178, 42434, 42690, 42946,
+ 43202, 43458, 43714, 43970, 44226, 44482, 44738, 44994,
+ 45250, 45506, 45762, 46018, 46274, 46530, 46786, 47042,
+ 47298, 47554, 47810, 48066, 48322, 48578, 48834, 49090,
+ 32963, 33219, 33475, 33731, 33987, 34243, 34499, 34755,
+ 35011, 35267, 35523, 35779, 36035, 36291, 36547, 36803,
+ 37059, 37315, 37571, 37827, 38083, 38339, 38595, 38851,
+ 39107, 39363, 39619, 39875, 40131, 40387, 40643, 40899,
+ 41155, 41411, 41667, 41923, 42179, 42435, 42691, 42947,
+ 43203, 43459, 43715, 43971, 44227, 44483, 44739, 44995,
+ 45251, 45507, 45763, 46019, 46275, 46531, 46787, 47043,
+ 47299, 47555, 47811, 48067, 48323, 48579, 48835, 49091,
+};
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1_distance_4_arm_neon(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr);
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3_distance_4_arm_neon(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_3_arm_neon(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_4_arm_neon(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1__choosy_default(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1_distance_3_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1_distance_4_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_2(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3__choosy_default(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3_distance_3_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3_distance_4_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4__choosy_default(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_3_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_4_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1_distance_4_x86_sse42(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3_distance_4_x86_sse42(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_3_x86_sse42(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_4_x86_sse42(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev);
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__do_decode_image_config(
+ wuffs_png__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_ihdr(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__assign_filter_distance(
+ wuffs_png__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint64_t
+wuffs_png__decoder__calculate_bytes_per_row(
+ const wuffs_png__decoder* self,
+ uint32_t a_width);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__choose_filter_implementations(
+ wuffs_png__decoder* self);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_other_chunk(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ bool a_framy);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_actl(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_chrm(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_exif(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_fctl(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_gama(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_iccp(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_plte(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_srgb(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_trns(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__do_decode_frame_config(
+ wuffs_png__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__skip_frame(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__do_decode_frame(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_pass(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__do_tell_me_more(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__filter_and_swizzle(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__filter_and_swizzle__choosy_default(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__filter_and_swizzle_tricky(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf);
+
+// ---------------- VTables
+
+const wuffs_base__image_decoder__func_ptrs
+wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__pixel_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
+ wuffs_base__slice_u8,
+ wuffs_base__decode_frame_options*))(&wuffs_png__decoder__decode_frame),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__frame_config*,
+ wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_frame_config),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__image_config*,
+ wuffs_base__io_buffer*))(&wuffs_png__decoder__decode_image_config),
+ (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_png__decoder__frame_dirty_rect),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_png__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_png__decoder__history_retain_length),
+ (uint32_t(*)(const void*))(&wuffs_png__decoder__num_animation_loops),
+ (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frame_configs),
+ (uint64_t(*)(const void*))(&wuffs_png__decoder__num_decoded_frames),
+ (wuffs_base__status(*)(void*,
+ uint64_t,
+ uint64_t))(&wuffs_png__decoder__restart_frame),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_png__decoder__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ uint32_t,
+ bool))(&wuffs_png__decoder__set_report_metadata),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*))(&wuffs_png__decoder__tell_me_more),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_png__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_png__decoder__initialize(
+ wuffs_png__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.choosy_filter_1 = &wuffs_png__decoder__filter_1__choosy_default;
+ self->private_impl.choosy_filter_3 = &wuffs_png__decoder__filter_3__choosy_default;
+ self->private_impl.choosy_filter_4 = &wuffs_png__decoder__filter_4__choosy_default;
+ self->private_impl.choosy_filter_and_swizzle = &wuffs_png__decoder__filter_and_swizzle__choosy_default;
+
+ {
+ wuffs_base__status z = wuffs_crc32__ieee_hasher__initialize(
+ &self->private_data.f_crc32, sizeof(self->private_data.f_crc32), WUFFS_VERSION, options);
+ if (z.repr) {
+ return z;
+ }
+ }
+ {
+ wuffs_base__status z = wuffs_zlib__decoder__initialize(
+ &self->private_data.f_zlib, sizeof(self->private_data.f_zlib), WUFFS_VERSION, options);
+ if (z.repr) {
+ return z;
+ }
+ }
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
+ wuffs_base__image_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
+ (const void*)(&wuffs_png__decoder__func_ptrs_for__wuffs_base__image_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_png__decoder*
+wuffs_png__decoder__alloc(void) {
+ wuffs_png__decoder* x =
+ (wuffs_png__decoder*)(calloc(sizeof(wuffs_png__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_png__decoder__initialize(
+ x, sizeof(wuffs_png__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_png__decoder(void) {
+ return sizeof(wuffs_png__decoder);
+}
+
+// ---------------- Function Implementations
+
+// ‼ WUFFS MULTI-FILE SECTION +arm_neon
+// -------- func png.decoder.filter_1_distance_4_arm_neon
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1_distance_4_arm_neon(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr) {
+ wuffs_base__slice_u8 v_curr = {0};
+ uint8x8_t v_fa = {0};
+ uint8x8_t v_fx = {0};
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ v_curr.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, v_fa);
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, v_fa);
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end1_curr) {
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, v_fa);
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+// ‼ WUFFS MULTI-FILE SECTION -arm_neon
+
+// ‼ WUFFS MULTI-FILE SECTION +arm_neon
+// -------- func png.decoder.filter_3_distance_4_arm_neon
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3_distance_4_arm_neon(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ uint8x8_t v_fa = {0};
+ uint8x8_t v_fb = {0};
+ uint8x8_t v_fx = {0};
+
+ if (((uint64_t)(a_prev.len)) == 0u) {
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ v_curr.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end1_curr) {
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 0;
+ }
+ } else {
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end1_curr) {
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fx = vadd_u8(v_fx, vhadd_u8(v_fa, v_fb));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ }
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+// ‼ WUFFS MULTI-FILE SECTION -arm_neon
+
+// ‼ WUFFS MULTI-FILE SECTION +arm_neon
+// -------- func png.decoder.filter_4_distance_3_arm_neon
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_3_arm_neon(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ uint8x8_t v_fa = {0};
+ uint8x8_t v_fb = {0};
+ uint8x8_t v_fc = {0};
+ uint8x8_t v_fx = {0};
+ uint16x8_t v_fafb = {0};
+ uint16x8_t v_fcfc = {0};
+ uint16x8_t v_pa = {0};
+ uint16x8_t v_pb = {0};
+ uint16x8_t v_pc = {0};
+ uint16x8_t v_cmpab = {0};
+ uint16x8_t v_cmpac = {0};
+ uint8x8_t v_picka = {0};
+ uint8x8_t v_pickb = {0};
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fafb = vaddl_u8(v_fa, v_fb);
+ v_fcfc = vaddl_u8(v_fc, v_fc);
+ v_pa = vabdl_u8(v_fb, v_fc);
+ v_pb = vabdl_u8(v_fa, v_fc);
+ v_pc = vabdq_u16(v_fafb, v_fcfc);
+ v_cmpab = vcleq_u16(v_pa, v_pb);
+ v_cmpac = vcleq_u16(v_pa, v_pc);
+ v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
+ v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
+ v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
+ wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fc = v_fb;
+ v_fa = v_fx;
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fafb = vaddl_u8(v_fa, v_fb);
+ v_fcfc = vaddl_u8(v_fc, v_fc);
+ v_pa = vabdl_u8(v_fb, v_fc);
+ v_pb = vabdl_u8(v_fa, v_fc);
+ v_pc = vabdq_u16(v_fafb, v_fcfc);
+ v_cmpab = vcleq_u16(v_pa, v_pb);
+ v_cmpac = vcleq_u16(v_pa, v_pc);
+ v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
+ v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
+ v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
+ wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fc = v_fb;
+ v_fa = v_fx;
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3);
+ while (v_curr.ptr < i_end1_curr) {
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fafb = vaddl_u8(v_fa, v_fb);
+ v_fcfc = vaddl_u8(v_fc, v_fc);
+ v_pa = vabdl_u8(v_fb, v_fc);
+ v_pb = vabdl_u8(v_fa, v_fc);
+ v_pc = vabdq_u16(v_fafb, v_fcfc);
+ v_cmpab = vcleq_u16(v_pa, v_pb);
+ v_cmpac = vcleq_u16(v_pa, v_pc);
+ v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
+ v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
+ v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
+ wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fc = v_fb;
+ v_fa = v_fx;
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 3;
+ v_prev.len = 3;
+ uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
+ while (v_curr.ptr < i_end2_curr) {
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
+ v_fafb = vaddl_u8(v_fa, v_fb);
+ v_fcfc = vaddl_u8(v_fc, v_fc);
+ v_pa = vabdl_u8(v_fb, v_fc);
+ v_pb = vabdl_u8(v_fa, v_fc);
+ v_pc = vabdq_u16(v_fafb, v_fcfc);
+ v_cmpab = vcleq_u16(v_pa, v_pb);
+ v_cmpac = vcleq_u16(v_pa, v_pc);
+ v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
+ v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
+ v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
+ wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+// ‼ WUFFS MULTI-FILE SECTION -arm_neon
+
+// ‼ WUFFS MULTI-FILE SECTION +arm_neon
+// -------- func png.decoder.filter_4_distance_4_arm_neon
+
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_4_arm_neon(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ uint8x8_t v_fa = {0};
+ uint8x8_t v_fb = {0};
+ uint8x8_t v_fc = {0};
+ uint8x8_t v_fx = {0};
+ uint16x8_t v_fafb = {0};
+ uint16x8_t v_fcfc = {0};
+ uint16x8_t v_pa = {0};
+ uint16x8_t v_pb = {0};
+ uint16x8_t v_pc = {0};
+ uint16x8_t v_cmpab = {0};
+ uint16x8_t v_cmpac = {0};
+ uint8x8_t v_picka = {0};
+ uint8x8_t v_pickb = {0};
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fafb = vaddl_u8(v_fa, v_fb);
+ v_fcfc = vaddl_u8(v_fc, v_fc);
+ v_pa = vabdl_u8(v_fb, v_fc);
+ v_pb = vabdl_u8(v_fa, v_fc);
+ v_pc = vabdq_u16(v_fafb, v_fcfc);
+ v_cmpab = vcleq_u16(v_pa, v_pb);
+ v_cmpac = vcleq_u16(v_pa, v_pc);
+ v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
+ v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
+ v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fc = v_fb;
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fafb = vaddl_u8(v_fa, v_fb);
+ v_fcfc = vaddl_u8(v_fc, v_fc);
+ v_pa = vabdl_u8(v_fb, v_fc);
+ v_pb = vabdl_u8(v_fa, v_fc);
+ v_pc = vabdq_u16(v_fafb, v_fcfc);
+ v_cmpab = vcleq_u16(v_pa, v_pb);
+ v_cmpac = vcleq_u16(v_pa, v_pc);
+ v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
+ v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
+ v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fc = v_fb;
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end1_curr) {
+ v_fb = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_fx = vreinterpret_u8_u32(vdup_n_u32(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_fafb = vaddl_u8(v_fa, v_fb);
+ v_fcfc = vaddl_u8(v_fc, v_fc);
+ v_pa = vabdl_u8(v_fb, v_fc);
+ v_pb = vabdl_u8(v_fa, v_fc);
+ v_pc = vabdq_u16(v_fafb, v_fcfc);
+ v_cmpab = vcleq_u16(v_pa, v_pb);
+ v_cmpac = vcleq_u16(v_pa, v_pc);
+ v_picka = vmovn_u16(vandq_u16(v_cmpab, v_cmpac));
+ v_pickb = vmovn_u16(vcleq_u16(v_pb, v_pc));
+ v_fx = vadd_u8(v_fx, vbsl_u8(v_picka, v_fa, vbsl_u8(v_pickb, v_fb, v_fc)));
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, vget_lane_u32(vreinterpret_u32_u8(v_fx), 0u));
+ v_fc = v_fb;
+ v_fa = v_fx;
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+// ‼ WUFFS MULTI-FILE SECTION -arm_neon
+
+// -------- func png.decoder.filter_1
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr) {
+ return (*self->private_impl.choosy_filter_1)(self, a_curr);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1__choosy_default(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr) {
+ uint64_t v_filter_distance = 0;
+ uint8_t v_fa = 0;
+ uint64_t v_i_start = 0;
+ uint64_t v_i = 0;
+
+ v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
+ v_i_start = 0u;
+ while (v_i_start < v_filter_distance) {
+ v_fa = 0u;
+ v_i = v_i_start;
+ while (v_i < ((uint64_t)(a_curr.len))) {
+ a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + v_fa));
+ v_fa = a_curr.ptr[v_i];
+ v_i += v_filter_distance;
+ }
+ v_i_start += 1u;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_1_distance_3_fallback
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1_distance_3_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr) {
+ wuffs_base__slice_u8 v_curr = {0};
+ uint8_t v_fa0 = 0;
+ uint8_t v_fa1 = 0;
+ uint8_t v_fa2 = 0;
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ v_curr.len = 3;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ }
+ v_curr.len = 3;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
+ while (v_curr.ptr < i_end1_curr) {
+ v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ }
+ v_curr.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_1_distance_4_fallback
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1_distance_4_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr) {
+ wuffs_base__slice_u8 v_curr = {0};
+ uint8_t v_fa0 = 0;
+ uint8_t v_fa1 = 0;
+ uint8_t v_fa2 = 0;
+ uint8_t v_fa3 = 0;
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ v_curr.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fa0 = ((uint8_t)(v_fa0 + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)(v_fa1 + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)(v_fa2 + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_fa3 = ((uint8_t)(v_fa3 + v_curr.ptr[3u]));
+ v_curr.ptr[3u] = v_fa3;
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_2
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_2(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ uint64_t v_n = 0;
+ uint64_t v_i = 0;
+
+ v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
+ v_i = 0u;
+ while (v_i < v_n) {
+ a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
+ v_i += 1u;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_3
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ return (*self->private_impl.choosy_filter_3)(self, a_curr, a_prev);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3__choosy_default(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ uint64_t v_filter_distance = 0;
+ uint64_t v_n = 0;
+ uint64_t v_i = 0;
+
+ v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
+ if (((uint64_t)(a_prev.len)) == 0u) {
+ v_i = v_filter_distance;
+ while (v_i < ((uint64_t)(a_curr.len))) {
+ a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_curr.ptr[(v_i - v_filter_distance)] / 2u)));
+ v_i += 1u;
+ }
+ } else {
+ v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
+ v_i = 0u;
+ while ((v_i < v_n) && (v_i < v_filter_distance)) {
+ a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + (a_prev.ptr[v_i] / 2u)));
+ v_i += 1u;
+ }
+ v_i = v_filter_distance;
+ while (v_i < v_n) {
+ a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(((((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)])) + ((uint32_t)(a_prev.ptr[v_i]))) / 2u)))));
+ v_i += 1u;
+ }
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_3_distance_3_fallback
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3_distance_3_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ uint8_t v_fa0 = 0;
+ uint8_t v_fa1 = 0;
+ uint8_t v_fa2 = 0;
+
+ if (((uint64_t)(a_prev.len)) == 0u) {
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ v_curr.len = 3;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ }
+ v_curr.len = 3;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
+ while (v_curr.ptr < i_end1_curr) {
+ v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ }
+ v_curr.len = 0;
+ }
+ } else {
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 3;
+ v_prev.len = 3;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 6) * 6);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 3;
+ v_prev.len = 3;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
+ while (v_curr.ptr < i_end1_curr) {
+ v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_3_distance_4_fallback
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3_distance_4_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ uint8_t v_fa0 = 0;
+ uint8_t v_fa1 = 0;
+ uint8_t v_fa2 = 0;
+ uint8_t v_fa3 = 0;
+
+ if (((uint64_t)(a_prev.len)) == 0u) {
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ v_curr.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fa0 = ((uint8_t)((v_fa0 / 2u) + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)((v_fa1 / 2u) + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)((v_fa2 / 2u) + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_fa3 = ((uint8_t)((v_fa3 / 2u) + v_curr.ptr[3u]));
+ v_curr.ptr[3u] = v_fa3;
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 0;
+ }
+ } else {
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fa0 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa0)) + ((uint32_t)(v_prev.ptr[0u]))) / 2u))) + v_curr.ptr[0u]));
+ v_curr.ptr[0u] = v_fa0;
+ v_fa1 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa1)) + ((uint32_t)(v_prev.ptr[1u]))) / 2u))) + v_curr.ptr[1u]));
+ v_curr.ptr[1u] = v_fa1;
+ v_fa2 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa2)) + ((uint32_t)(v_prev.ptr[2u]))) / 2u))) + v_curr.ptr[2u]));
+ v_curr.ptr[2u] = v_fa2;
+ v_fa3 = ((uint8_t)(((uint8_t)(((((uint32_t)(v_fa3)) + ((uint32_t)(v_prev.ptr[3u]))) / 2u))) + v_curr.ptr[3u]));
+ v_curr.ptr[3u] = v_fa3;
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_4
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ return (*self->private_impl.choosy_filter_4)(self, a_curr, a_prev);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4__choosy_default(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ uint64_t v_filter_distance = 0;
+ uint64_t v_n = 0;
+ uint64_t v_i = 0;
+ uint32_t v_fa = 0;
+ uint32_t v_fb = 0;
+ uint32_t v_fc = 0;
+ uint32_t v_pp = 0;
+ uint32_t v_pa = 0;
+ uint32_t v_pb = 0;
+ uint32_t v_pc = 0;
+
+ v_filter_distance = ((uint64_t)(self->private_impl.f_filter_distance));
+ v_n = wuffs_base__u64__min(((uint64_t)(a_curr.len)), ((uint64_t)(a_prev.len)));
+ v_i = 0u;
+ while ((v_i < v_n) && (v_i < v_filter_distance)) {
+ a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + a_prev.ptr[v_i]));
+ v_i += 1u;
+ }
+ v_i = v_filter_distance;
+ while (v_i < v_n) {
+ v_fa = ((uint32_t)(a_curr.ptr[(v_i - v_filter_distance)]));
+ v_fb = ((uint32_t)(a_prev.ptr[v_i]));
+ v_fc = ((uint32_t)(a_prev.ptr[(v_i - v_filter_distance)]));
+ v_pp = ((uint32_t)(((uint32_t)(v_fa + v_fb)) - v_fc));
+ v_pa = ((uint32_t)(v_pp - v_fa));
+ if (v_pa >= 2147483648u) {
+ v_pa = ((uint32_t)(0u - v_pa));
+ }
+ v_pb = ((uint32_t)(v_pp - v_fb));
+ if (v_pb >= 2147483648u) {
+ v_pb = ((uint32_t)(0u - v_pb));
+ }
+ v_pc = ((uint32_t)(v_pp - v_fc));
+ if (v_pc >= 2147483648u) {
+ v_pc = ((uint32_t)(0u - v_pc));
+ }
+ if ((v_pa <= v_pb) && (v_pa <= v_pc)) {
+ } else if (v_pb <= v_pc) {
+ v_fa = v_fb;
+ } else {
+ v_fa = v_fc;
+ }
+ a_curr.ptr[v_i] = ((uint8_t)(a_curr.ptr[v_i] + ((uint8_t)(v_fa))));
+ v_i += 1u;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_4_distance_3_fallback
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_3_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ uint32_t v_fa0 = 0;
+ uint32_t v_fa1 = 0;
+ uint32_t v_fa2 = 0;
+ uint32_t v_fb0 = 0;
+ uint32_t v_fb1 = 0;
+ uint32_t v_fb2 = 0;
+ uint32_t v_fc0 = 0;
+ uint32_t v_fc1 = 0;
+ uint32_t v_fc2 = 0;
+ uint32_t v_pp0 = 0;
+ uint32_t v_pp1 = 0;
+ uint32_t v_pp2 = 0;
+ uint32_t v_pa0 = 0;
+ uint32_t v_pa1 = 0;
+ uint32_t v_pa2 = 0;
+ uint32_t v_pb0 = 0;
+ uint32_t v_pb1 = 0;
+ uint32_t v_pb2 = 0;
+ uint32_t v_pc0 = 0;
+ uint32_t v_pc1 = 0;
+ uint32_t v_pc2 = 0;
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 3;
+ v_prev.len = 3;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fb0 = ((uint32_t)(v_prev.ptr[0u]));
+ v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
+ v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
+ if (v_pa0 >= 2147483648u) {
+ v_pa0 = ((uint32_t)(0u - v_pa0));
+ }
+ v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
+ if (v_pb0 >= 2147483648u) {
+ v_pb0 = ((uint32_t)(0u - v_pb0));
+ }
+ v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
+ if (v_pc0 >= 2147483648u) {
+ v_pc0 = ((uint32_t)(0u - v_pc0));
+ }
+ if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
+ } else if (v_pb0 <= v_pc0) {
+ v_fa0 = v_fb0;
+ } else {
+ v_fa0 = v_fc0;
+ }
+ v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0))));
+ v_fa0 = ((uint32_t)(v_curr.ptr[0u]));
+ v_fc0 = v_fb0;
+ v_fb1 = ((uint32_t)(v_prev.ptr[1u]));
+ v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
+ v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
+ if (v_pa1 >= 2147483648u) {
+ v_pa1 = ((uint32_t)(0u - v_pa1));
+ }
+ v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
+ if (v_pb1 >= 2147483648u) {
+ v_pb1 = ((uint32_t)(0u - v_pb1));
+ }
+ v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
+ if (v_pc1 >= 2147483648u) {
+ v_pc1 = ((uint32_t)(0u - v_pc1));
+ }
+ if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
+ } else if (v_pb1 <= v_pc1) {
+ v_fa1 = v_fb1;
+ } else {
+ v_fa1 = v_fc1;
+ }
+ v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1))));
+ v_fa1 = ((uint32_t)(v_curr.ptr[1u]));
+ v_fc1 = v_fb1;
+ v_fb2 = ((uint32_t)(v_prev.ptr[2u]));
+ v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
+ v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
+ if (v_pa2 >= 2147483648u) {
+ v_pa2 = ((uint32_t)(0u - v_pa2));
+ }
+ v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
+ if (v_pb2 >= 2147483648u) {
+ v_pb2 = ((uint32_t)(0u - v_pb2));
+ }
+ v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
+ if (v_pc2 >= 2147483648u) {
+ v_pc2 = ((uint32_t)(0u - v_pc2));
+ }
+ if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
+ } else if (v_pb2 <= v_pc2) {
+ v_fa2 = v_fb2;
+ } else {
+ v_fa2 = v_fc2;
+ }
+ v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2))));
+ v_fa2 = ((uint32_t)(v_curr.ptr[2u]));
+ v_fc2 = v_fb2;
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.filter_4_distance_4_fallback
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_4_fallback(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ uint32_t v_fa0 = 0;
+ uint32_t v_fa1 = 0;
+ uint32_t v_fa2 = 0;
+ uint32_t v_fa3 = 0;
+ uint32_t v_fb0 = 0;
+ uint32_t v_fb1 = 0;
+ uint32_t v_fb2 = 0;
+ uint32_t v_fb3 = 0;
+ uint32_t v_fc0 = 0;
+ uint32_t v_fc1 = 0;
+ uint32_t v_fc2 = 0;
+ uint32_t v_fc3 = 0;
+ uint32_t v_pp0 = 0;
+ uint32_t v_pp1 = 0;
+ uint32_t v_pp2 = 0;
+ uint32_t v_pp3 = 0;
+ uint32_t v_pa0 = 0;
+ uint32_t v_pa1 = 0;
+ uint32_t v_pa2 = 0;
+ uint32_t v_pa3 = 0;
+ uint32_t v_pb0 = 0;
+ uint32_t v_pb1 = 0;
+ uint32_t v_pb2 = 0;
+ uint32_t v_pb3 = 0;
+ uint32_t v_pc0 = 0;
+ uint32_t v_pc1 = 0;
+ uint32_t v_pc2 = 0;
+ uint32_t v_pc3 = 0;
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end0_curr) {
+ v_fb0 = ((uint32_t)(v_prev.ptr[0u]));
+ v_pp0 = ((uint32_t)(((uint32_t)(v_fa0 + v_fb0)) - v_fc0));
+ v_pa0 = ((uint32_t)(v_pp0 - v_fa0));
+ if (v_pa0 >= 2147483648u) {
+ v_pa0 = ((uint32_t)(0u - v_pa0));
+ }
+ v_pb0 = ((uint32_t)(v_pp0 - v_fb0));
+ if (v_pb0 >= 2147483648u) {
+ v_pb0 = ((uint32_t)(0u - v_pb0));
+ }
+ v_pc0 = ((uint32_t)(v_pp0 - v_fc0));
+ if (v_pc0 >= 2147483648u) {
+ v_pc0 = ((uint32_t)(0u - v_pc0));
+ }
+ if ((v_pa0 <= v_pb0) && (v_pa0 <= v_pc0)) {
+ } else if (v_pb0 <= v_pc0) {
+ v_fa0 = v_fb0;
+ } else {
+ v_fa0 = v_fc0;
+ }
+ v_curr.ptr[0u] = ((uint8_t)(v_curr.ptr[0u] + ((uint8_t)(v_fa0))));
+ v_fa0 = ((uint32_t)(v_curr.ptr[0u]));
+ v_fc0 = v_fb0;
+ v_fb1 = ((uint32_t)(v_prev.ptr[1u]));
+ v_pp1 = ((uint32_t)(((uint32_t)(v_fa1 + v_fb1)) - v_fc1));
+ v_pa1 = ((uint32_t)(v_pp1 - v_fa1));
+ if (v_pa1 >= 2147483648u) {
+ v_pa1 = ((uint32_t)(0u - v_pa1));
+ }
+ v_pb1 = ((uint32_t)(v_pp1 - v_fb1));
+ if (v_pb1 >= 2147483648u) {
+ v_pb1 = ((uint32_t)(0u - v_pb1));
+ }
+ v_pc1 = ((uint32_t)(v_pp1 - v_fc1));
+ if (v_pc1 >= 2147483648u) {
+ v_pc1 = ((uint32_t)(0u - v_pc1));
+ }
+ if ((v_pa1 <= v_pb1) && (v_pa1 <= v_pc1)) {
+ } else if (v_pb1 <= v_pc1) {
+ v_fa1 = v_fb1;
+ } else {
+ v_fa1 = v_fc1;
+ }
+ v_curr.ptr[1u] = ((uint8_t)(v_curr.ptr[1u] + ((uint8_t)(v_fa1))));
+ v_fa1 = ((uint32_t)(v_curr.ptr[1u]));
+ v_fc1 = v_fb1;
+ v_fb2 = ((uint32_t)(v_prev.ptr[2u]));
+ v_pp2 = ((uint32_t)(((uint32_t)(v_fa2 + v_fb2)) - v_fc2));
+ v_pa2 = ((uint32_t)(v_pp2 - v_fa2));
+ if (v_pa2 >= 2147483648u) {
+ v_pa2 = ((uint32_t)(0u - v_pa2));
+ }
+ v_pb2 = ((uint32_t)(v_pp2 - v_fb2));
+ if (v_pb2 >= 2147483648u) {
+ v_pb2 = ((uint32_t)(0u - v_pb2));
+ }
+ v_pc2 = ((uint32_t)(v_pp2 - v_fc2));
+ if (v_pc2 >= 2147483648u) {
+ v_pc2 = ((uint32_t)(0u - v_pc2));
+ }
+ if ((v_pa2 <= v_pb2) && (v_pa2 <= v_pc2)) {
+ } else if (v_pb2 <= v_pc2) {
+ v_fa2 = v_fb2;
+ } else {
+ v_fa2 = v_fc2;
+ }
+ v_curr.ptr[2u] = ((uint8_t)(v_curr.ptr[2u] + ((uint8_t)(v_fa2))));
+ v_fa2 = ((uint32_t)(v_curr.ptr[2u]));
+ v_fc2 = v_fb2;
+ v_fb3 = ((uint32_t)(v_prev.ptr[3u]));
+ v_pp3 = ((uint32_t)(((uint32_t)(v_fa3 + v_fb3)) - v_fc3));
+ v_pa3 = ((uint32_t)(v_pp3 - v_fa3));
+ if (v_pa3 >= 2147483648u) {
+ v_pa3 = ((uint32_t)(0u - v_pa3));
+ }
+ v_pb3 = ((uint32_t)(v_pp3 - v_fb3));
+ if (v_pb3 >= 2147483648u) {
+ v_pb3 = ((uint32_t)(0u - v_pb3));
+ }
+ v_pc3 = ((uint32_t)(v_pp3 - v_fc3));
+ if (v_pc3 >= 2147483648u) {
+ v_pc3 = ((uint32_t)(0u - v_pc3));
+ }
+ if ((v_pa3 <= v_pb3) && (v_pa3 <= v_pc3)) {
+ } else if (v_pb3 <= v_pc3) {
+ v_fa3 = v_fb3;
+ } else {
+ v_fa3 = v_fc3;
+ }
+ v_curr.ptr[3u] = ((uint8_t)(v_curr.ptr[3u] + ((uint8_t)(v_fa3))));
+ v_fa3 = ((uint32_t)(v_curr.ptr[3u]));
+ v_fc3 = v_fb3;
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+// -------- func png.decoder.filter_1_distance_4_x86_sse42
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_1_distance_4_x86_sse42(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr) {
+ wuffs_base__slice_u8 v_curr = {0};
+ __m128i v_x128 = {0};
+ __m128i v_a128 = {0};
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ v_curr.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
+ while (v_curr.ptr < i_end0_curr) {
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_a128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_a128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end1_curr) {
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_a128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+// -------- func png.decoder.filter_3_distance_4_x86_sse42
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_3_distance_4_x86_sse42(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ __m128i v_x128 = {0};
+ __m128i v_a128 = {0};
+ __m128i v_b128 = {0};
+ __m128i v_p128 = {0};
+ __m128i v_k128 = {0};
+
+ if (((uint64_t)(a_prev.len)) == 0u) {
+ v_k128 = _mm_set1_epi8((int8_t)(254u));
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ v_curr.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
+ while (v_curr.ptr < i_end0_curr) {
+ v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end1_curr) {
+ v_p128 = _mm_avg_epu8(_mm_and_si128(v_a128, v_k128), v_b128);
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ }
+ v_curr.len = 0;
+ }
+ } else {
+ v_k128 = _mm_set1_epi8((int8_t)(1u));
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
+ while (v_curr.ptr < i_end0_curr) {
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_p128 = _mm_avg_epu8(v_a128, v_b128);
+ v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_p128 = _mm_avg_epu8(v_a128, v_b128);
+ v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end1_curr) {
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_p128 = _mm_avg_epu8(v_a128, v_b128);
+ v_p128 = _mm_sub_epi8(v_p128, _mm_and_si128(v_k128, _mm_xor_si128(v_a128, v_b128)));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ }
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+// -------- func png.decoder.filter_4_distance_3_x86_sse42
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_3_x86_sse42(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ __m128i v_x128 = {0};
+ __m128i v_a128 = {0};
+ __m128i v_b128 = {0};
+ __m128i v_c128 = {0};
+ __m128i v_p128 = {0};
+ __m128i v_pa128 = {0};
+ __m128i v_pb128 = {0};
+ __m128i v_pc128 = {0};
+ __m128i v_smallest128 = {0};
+ __m128i v_z128 = {0};
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 7, 6);
+ while (v_curr.ptr < i_end0_curr) {
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
+ v_pa128 = _mm_sub_epi16(v_b128, v_c128);
+ v_pb128 = _mm_sub_epi16(v_a128, v_c128);
+ v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
+ v_pa128 = _mm_abs_epi16(v_pa128);
+ v_pb128 = _mm_abs_epi16(v_pb128);
+ v_pc128 = _mm_abs_epi16(v_pc128);
+ v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
+ v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ v_c128 = v_b128;
+ v_x128 = _mm_packus_epi16(v_x128, v_x128);
+ wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
+ v_pa128 = _mm_sub_epi16(v_b128, v_c128);
+ v_pb128 = _mm_sub_epi16(v_a128, v_c128);
+ v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
+ v_pa128 = _mm_abs_epi16(v_pa128);
+ v_pb128 = _mm_abs_epi16(v_pb128);
+ v_pc128 = _mm_abs_epi16(v_pc128);
+ v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
+ v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ v_c128 = v_b128;
+ v_x128 = _mm_packus_epi16(v_x128, v_x128);
+ wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + wuffs_base__iterate_total_advance((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)), 4, 3);
+ while (v_curr.ptr < i_end1_curr) {
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
+ v_pa128 = _mm_sub_epi16(v_b128, v_c128);
+ v_pb128 = _mm_sub_epi16(v_a128, v_c128);
+ v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
+ v_pa128 = _mm_abs_epi16(v_pa128);
+ v_pb128 = _mm_abs_epi16(v_pb128);
+ v_pc128 = _mm_abs_epi16(v_pc128);
+ v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
+ v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ v_c128 = v_b128;
+ v_x128 = _mm_packus_epi16(v_x128, v_x128);
+ wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 3;
+ v_prev.len = 3;
+ uint8_t* i_end2_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 3) * 3);
+ while (v_curr.ptr < i_end2_curr) {
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_prev.ptr)));
+ v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
+ v_pa128 = _mm_sub_epi16(v_b128, v_c128);
+ v_pb128 = _mm_sub_epi16(v_a128, v_c128);
+ v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
+ v_pa128 = _mm_abs_epi16(v_pa128);
+ v_pb128 = _mm_abs_epi16(v_pb128);
+ v_pc128 = _mm_abs_epi16(v_pc128);
+ v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
+ v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u24le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_x128 = _mm_packus_epi16(v_x128, v_x128);
+ wuffs_base__poke_u24le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 3;
+ v_prev.ptr += 3;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+// ‼ WUFFS MULTI-FILE SECTION +x86_sse42
+// -------- func png.decoder.filter_4_distance_4_x86_sse42
+
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+WUFFS_BASE__MAYBE_ATTRIBUTE_TARGET("pclmul,popcnt,sse4.2")
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__filter_4_distance_4_x86_sse42(
+ wuffs_png__decoder* self,
+ wuffs_base__slice_u8 a_curr,
+ wuffs_base__slice_u8 a_prev) {
+ wuffs_base__slice_u8 v_curr = {0};
+ wuffs_base__slice_u8 v_prev = {0};
+ __m128i v_x128 = {0};
+ __m128i v_a128 = {0};
+ __m128i v_b128 = {0};
+ __m128i v_c128 = {0};
+ __m128i v_p128 = {0};
+ __m128i v_pa128 = {0};
+ __m128i v_pb128 = {0};
+ __m128i v_pc128 = {0};
+ __m128i v_smallest128 = {0};
+ __m128i v_z128 = {0};
+
+ {
+ wuffs_base__slice_u8 i_slice_curr = a_curr;
+ v_curr.ptr = i_slice_curr.ptr;
+ wuffs_base__slice_u8 i_slice_prev = a_prev;
+ v_prev.ptr = i_slice_prev.ptr;
+ i_slice_curr.len = ((size_t)(wuffs_base__u64__min(i_slice_curr.len, i_slice_prev.len)));
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end0_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 8) * 8);
+ while (v_curr.ptr < i_end0_curr) {
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
+ v_pa128 = _mm_sub_epi16(v_b128, v_c128);
+ v_pb128 = _mm_sub_epi16(v_a128, v_c128);
+ v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
+ v_pa128 = _mm_abs_epi16(v_pa128);
+ v_pb128 = _mm_abs_epi16(v_pb128);
+ v_pc128 = _mm_abs_epi16(v_pc128);
+ v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
+ v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ v_c128 = v_b128;
+ v_x128 = _mm_packus_epi16(v_x128, v_x128);
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
+ v_pa128 = _mm_sub_epi16(v_b128, v_c128);
+ v_pb128 = _mm_sub_epi16(v_a128, v_c128);
+ v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
+ v_pa128 = _mm_abs_epi16(v_pa128);
+ v_pb128 = _mm_abs_epi16(v_pb128);
+ v_pc128 = _mm_abs_epi16(v_pc128);
+ v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
+ v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ v_c128 = v_b128;
+ v_x128 = _mm_packus_epi16(v_x128, v_x128);
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 4;
+ v_prev.len = 4;
+ uint8_t* i_end1_curr = v_curr.ptr + (((i_slice_curr.len - (size_t)(v_curr.ptr - i_slice_curr.ptr)) / 4) * 4);
+ while (v_curr.ptr < i_end1_curr) {
+ v_b128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_prev.ptr)));
+ v_b128 = _mm_unpacklo_epi8(v_b128, v_z128);
+ v_pa128 = _mm_sub_epi16(v_b128, v_c128);
+ v_pb128 = _mm_sub_epi16(v_a128, v_c128);
+ v_pc128 = _mm_add_epi16(v_pa128, v_pb128);
+ v_pa128 = _mm_abs_epi16(v_pa128);
+ v_pb128 = _mm_abs_epi16(v_pb128);
+ v_pc128 = _mm_abs_epi16(v_pc128);
+ v_smallest128 = _mm_min_epi16(v_pc128, _mm_min_epi16(v_pb128, v_pa128));
+ v_p128 = _mm_blendv_epi8(_mm_blendv_epi8(v_c128, v_b128, _mm_cmpeq_epi16(v_smallest128, v_pb128)), v_a128, _mm_cmpeq_epi16(v_smallest128, v_pa128));
+ v_x128 = _mm_cvtsi32_si128((int32_t)(wuffs_base__peek_u32le__no_bounds_check(v_curr.ptr)));
+ v_x128 = _mm_unpacklo_epi8(v_x128, v_z128);
+ v_x128 = _mm_add_epi8(v_x128, v_p128);
+ v_a128 = v_x128;
+ v_c128 = v_b128;
+ v_x128 = _mm_packus_epi16(v_x128, v_x128);
+ wuffs_base__poke_u32le__no_bounds_check(v_curr.ptr, ((uint32_t)(_mm_cvtsi128_si32(v_x128))));
+ v_curr.ptr += 4;
+ v_prev.ptr += 4;
+ }
+ v_curr.len = 0;
+ v_prev.len = 0;
+ }
+ return wuffs_base__make_empty_struct();
+}
+#endif // defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+// ‼ WUFFS MULTI-FILE SECTION -x86_sse42
+
+// -------- func png.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_png__decoder__get_quirk(
+ const wuffs_png__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if ((a_key == 1u) && self->private_impl.f_ignore_checksum) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func png.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__set_quirk(
+ wuffs_png__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (a_key == 1u) {
+ self->private_impl.f_ignore_checksum = (a_value > 0u);
+ wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, a_key, a_value);
+ return wuffs_base__make_status(NULL);
+ }
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func png.decoder.decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__decode_image_config(
+ wuffs_png__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_png__decoder__do_decode_image_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_png__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func png.decoder.do_decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__do_decode_image_config(
+ wuffs_png__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint64_t v_magic = 0;
+ uint64_t v_mark = 0;
+ uint32_t v_checksum_have = 0;
+ uint32_t v_checksum_want = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
+ if (coro_susp_point) {
+ v_checksum_have = self->private_data.s_do_decode_image_config[0].v_checksum_have;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ } else if ( ! self->private_impl.f_seen_ihdr) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint64_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
+ t_0 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
+ iop_a_src += 8;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_0;
+ if (num_bits_0 == 56) {
+ t_0 = ((uint64_t)(*scratch));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0)) << 56;
+ }
+ }
+ v_magic = t_0;
+ }
+ if (v_magic != 727905341920923785u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint64_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 8)) {
+ t_1 = wuffs_base__peek_u64le__no_bounds_check(iop_a_src);
+ iop_a_src += 8;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
+ if (num_bits_1 == 56) {
+ t_1 = ((uint64_t)(*scratch));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1)) << 56;
+ }
+ }
+ v_magic = t_1;
+ }
+ if (v_magic != 5927942488114331648u) {
+ if (v_magic == 5278895250759221248u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_cgbi_extension);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_chunk_type_array[0u] = 73u;
+ self->private_impl.f_chunk_type_array[1u] = 72u;
+ self->private_impl.f_chunk_type_array[2u] = 68u;
+ self->private_impl.f_chunk_type_array[3u] = 82u;
+ wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
+ sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
+ wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
+ while (true) {
+ v_mark = ((uint64_t)(iop_a_src - io0_a_src));
+ {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_2 = wuffs_png__decoder__decode_ihdr(self, a_src);
+ v_status = t_2;
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ if ( ! self->private_impl.f_ignore_checksum) {
+ v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
+ }
+ if (wuffs_base__status__is_ok(&v_status)) {
+ break;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ uint32_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
+ if (num_bits_3 == 24) {
+ t_3 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3));
+ }
+ }
+ v_checksum_want = t_3;
+ }
+ if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != v_checksum_want)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
+ goto exit;
+ }
+ self->private_impl.f_seen_ihdr = true;
+ } else if (self->private_impl.f_metadata_fourcc != 0u) {
+ self->private_impl.f_call_sequence = 16u;
+ status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
+ goto ok;
+ }
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
+ continue;
+ }
+ self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
+ if (self->private_impl.f_chunk_type == 1413563465u) {
+ if ( ! self->private_impl.f_seen_actl || self->private_impl.f_seen_fctl) {
+ break;
+ }
+ self->private_impl.f_seen_idat = true;
+ } else if (self->private_impl.f_chunk_type == 1413571686u) {
+ if (self->private_impl.f_seen_idat && self->private_impl.f_seen_fctl) {
+ break;
+ }
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ iop_a_src += 8u;
+ if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) {
+ self->private_impl.f_chunk_type_array[0u] = ((uint8_t)((self->private_impl.f_chunk_type >> 0u)));
+ self->private_impl.f_chunk_type_array[1u] = ((uint8_t)((self->private_impl.f_chunk_type >> 8u)));
+ self->private_impl.f_chunk_type_array[2u] = ((uint8_t)((self->private_impl.f_chunk_type >> 16u)));
+ self->private_impl.f_chunk_type_array[3u] = ((uint8_t)((self->private_impl.f_chunk_type >> 24u)));
+ wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
+ sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
+ wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
+ }
+ while (true) {
+ v_mark = ((uint64_t)(iop_a_src - io0_a_src));
+ {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_4 = wuffs_png__decoder__decode_other_chunk(self, a_src, false);
+ v_status = t_4;
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u)) {
+ v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
+ }
+ if (wuffs_base__status__is_ok(&v_status)) {
+ break;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
+ }
+ if (self->private_impl.f_metadata_fourcc != 0u) {
+ self->private_impl.f_call_sequence = 16u;
+ status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
+ goto ok;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ uint32_t t_5;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
+ if (num_bits_5 == 24) {
+ t_5 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_5 += 8u;
+ *scratch |= ((uint64_t)(num_bits_5));
+ }
+ }
+ v_checksum_want = t_5;
+ }
+ if ( ! self->private_impl.f_ignore_checksum && ((self->private_impl.f_chunk_type & 32u) == 0u) && (v_checksum_have != v_checksum_want)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
+ goto exit;
+ }
+ }
+ if ((self->private_impl.f_color_type == 3u) && ! self->private_impl.f_seen_plte) {
+ status = wuffs_base__make_status(wuffs_png__error__missing_palette);
+ goto exit;
+ }
+ self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ self->private_impl.f_first_config_io_position = self->private_impl.f_frame_config_io_position;
+ if (a_dst != NULL) {
+ wuffs_base__image_config__set(
+ a_dst,
+ self->private_impl.f_dst_pixfmt,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ self->private_impl.f_first_config_io_position,
+ ((self->private_impl.f_color_type <= 3u) && ! self->private_impl.f_seen_trns));
+ }
+ if ( ! self->private_impl.f_seen_actl) {
+ self->private_impl.f_num_animation_frames_value = 1u;
+ self->private_impl.f_first_rect_x0 = 0u;
+ self->private_impl.f_first_rect_y0 = 0u;
+ self->private_impl.f_first_rect_x1 = self->private_impl.f_width;
+ self->private_impl.f_first_rect_y1 = self->private_impl.f_height;
+ self->private_impl.f_first_duration = 0u;
+ self->private_impl.f_first_disposal = 0u;
+ self->private_impl.f_first_overwrite_instead_of_blend = false;
+ }
+ self->private_impl.f_call_sequence = 32u;
+
+ ok:
+ self->private_impl.p_do_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_decode_image_config[0].v_checksum_have = v_checksum_have;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_ihdr
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_ihdr(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_a32 = 0;
+ uint8_t v_a8 = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_ihdr[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_ihdr[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ v_a32 = t_0;
+ }
+ if ((v_a32 == 0u) || (v_a32 > 2147483647u)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ } else if (v_a32 > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ self->private_impl.f_width = v_a32;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_ihdr[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_ihdr[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ v_a32 = t_1;
+ }
+ if ((v_a32 == 0u) || (v_a32 > 2147483647u)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ } else if (v_a32 > 16777215u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ self->private_impl.f_height = v_a32;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ v_a8 = t_2;
+ }
+ if (v_a8 > 16u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_depth = v_a8;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_a8 = t_3;
+ }
+ if ((v_a8 == 1u) || (v_a8 == 5u) || (v_a8 > 6u)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_color_type = v_a8;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_4 = *iop_a_src++;
+ v_a8 = t_4;
+ }
+ if (v_a8 != 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ v_a8 = t_5;
+ }
+ if (v_a8 != 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_6 = *iop_a_src++;
+ v_a8 = t_6;
+ }
+ if (v_a8 == 0u) {
+ self->private_impl.f_interlace_pass = 0u;
+ } else if (v_a8 == 1u) {
+ self->private_impl.f_interlace_pass = 1u;
+ self->private_impl.choosy_filter_and_swizzle = (
+ &wuffs_png__decoder__filter_and_swizzle_tricky);
+ } else {
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_filter_distance = 0u;
+ wuffs_png__decoder__assign_filter_distance(self);
+ if (self->private_impl.f_filter_distance == 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_header);
+ goto exit;
+ }
+ self->private_impl.f_overall_workbuf_length = (((uint64_t)(self->private_impl.f_height)) * (1u + wuffs_png__decoder__calculate_bytes_per_row(self, self->private_impl.f_width)));
+ wuffs_png__decoder__choose_filter_implementations(self);
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_ihdr[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_ihdr[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.assign_filter_distance
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__assign_filter_distance(
+ wuffs_png__decoder* self) {
+ if (self->private_impl.f_depth < 8u) {
+ if ((self->private_impl.f_depth != 1u) && (self->private_impl.f_depth != 2u) && (self->private_impl.f_depth != 4u)) {
+ return wuffs_base__make_empty_struct();
+ } else if (self->private_impl.f_color_type == 0u) {
+ self->private_impl.f_dst_pixfmt = 536870920u;
+ self->private_impl.f_src_pixfmt = 536870920u;
+ } else if (self->private_impl.f_color_type == 3u) {
+ self->private_impl.f_dst_pixfmt = 2198077448u;
+ self->private_impl.f_src_pixfmt = 2198077448u;
+ } else {
+ return wuffs_base__make_empty_struct();
+ }
+ self->private_impl.f_filter_distance = 1u;
+ self->private_impl.choosy_filter_and_swizzle = (
+ &wuffs_png__decoder__filter_and_swizzle_tricky);
+ } else if (self->private_impl.f_color_type == 0u) {
+ if (self->private_impl.f_depth == 8u) {
+ self->private_impl.f_dst_pixfmt = 536870920u;
+ self->private_impl.f_src_pixfmt = 536870920u;
+ self->private_impl.f_filter_distance = 1u;
+ } else if (self->private_impl.f_depth == 16u) {
+ if (self->private_impl.f_interlace_pass == 0u) {
+ self->private_impl.f_dst_pixfmt = 536870923u;
+ self->private_impl.f_src_pixfmt = 537919499u;
+ } else {
+ self->private_impl.f_dst_pixfmt = 2164308923u;
+ self->private_impl.f_src_pixfmt = 2164308923u;
+ }
+ self->private_impl.f_filter_distance = 2u;
+ }
+ } else if (self->private_impl.f_color_type == 2u) {
+ if (self->private_impl.f_depth == 8u) {
+ self->private_impl.f_dst_pixfmt = 2147485832u;
+ self->private_impl.f_src_pixfmt = 2684356744u;
+ self->private_impl.f_filter_distance = 3u;
+ } else if (self->private_impl.f_depth == 16u) {
+ self->private_impl.f_dst_pixfmt = 2164308923u;
+ self->private_impl.f_src_pixfmt = 2164308923u;
+ self->private_impl.f_filter_distance = 6u;
+ self->private_impl.choosy_filter_and_swizzle = (
+ &wuffs_png__decoder__filter_and_swizzle_tricky);
+ }
+ } else if (self->private_impl.f_color_type == 3u) {
+ if (self->private_impl.f_depth == 8u) {
+ self->private_impl.f_dst_pixfmt = 2198077448u;
+ self->private_impl.f_src_pixfmt = 2198077448u;
+ self->private_impl.f_filter_distance = 1u;
+ }
+ } else if (self->private_impl.f_color_type == 4u) {
+ if (self->private_impl.f_depth == 8u) {
+ self->private_impl.f_dst_pixfmt = 2164295816u;
+ self->private_impl.f_src_pixfmt = 2164295816u;
+ self->private_impl.f_filter_distance = 2u;
+ self->private_impl.choosy_filter_and_swizzle = (
+ &wuffs_png__decoder__filter_and_swizzle_tricky);
+ } else if (self->private_impl.f_depth == 16u) {
+ self->private_impl.f_dst_pixfmt = 2164308923u;
+ self->private_impl.f_src_pixfmt = 2164308923u;
+ self->private_impl.f_filter_distance = 4u;
+ self->private_impl.choosy_filter_and_swizzle = (
+ &wuffs_png__decoder__filter_and_swizzle_tricky);
+ }
+ } else if (self->private_impl.f_color_type == 6u) {
+ if (self->private_impl.f_depth == 8u) {
+ self->private_impl.f_dst_pixfmt = 2164295816u;
+ self->private_impl.f_src_pixfmt = 2701166728u;
+ self->private_impl.f_filter_distance = 4u;
+ } else if (self->private_impl.f_depth == 16u) {
+ self->private_impl.f_dst_pixfmt = 2164308923u;
+ self->private_impl.f_src_pixfmt = 2164308923u;
+ self->private_impl.f_filter_distance = 8u;
+ self->private_impl.choosy_filter_and_swizzle = (
+ &wuffs_png__decoder__filter_and_swizzle_tricky);
+ }
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.calculate_bytes_per_row
+
+WUFFS_BASE__GENERATED_C_CODE
+static uint64_t
+wuffs_png__decoder__calculate_bytes_per_row(
+ const wuffs_png__decoder* self,
+ uint32_t a_width) {
+ uint64_t v_bytes_per_channel = 0;
+
+ if (self->private_impl.f_depth == 1u) {
+ return ((uint64_t)(((a_width + 7u) / 8u)));
+ } else if (self->private_impl.f_depth == 2u) {
+ return ((uint64_t)(((a_width + 3u) / 4u)));
+ } else if (self->private_impl.f_depth == 4u) {
+ return ((uint64_t)(((a_width + 1u) / 2u)));
+ }
+ v_bytes_per_channel = ((uint64_t)((self->private_impl.f_depth >> 3u)));
+ return (((uint64_t)(a_width)) * v_bytes_per_channel * ((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])));
+}
+
+// -------- func png.decoder.choose_filter_implementations
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_png__decoder__choose_filter_implementations(
+ wuffs_png__decoder* self) {
+ if (self->private_impl.f_filter_distance == 3u) {
+ self->private_impl.choosy_filter_1 = (
+ &wuffs_png__decoder__filter_1_distance_3_fallback);
+ self->private_impl.choosy_filter_3 = (
+ &wuffs_png__decoder__filter_3_distance_3_fallback);
+ self->private_impl.choosy_filter_4 = (
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+ wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_3_arm_neon :
+#endif
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_3_x86_sse42 :
+#endif
+ &wuffs_png__decoder__filter_4_distance_3_fallback);
+ } else if (self->private_impl.f_filter_distance == 4u) {
+ self->private_impl.choosy_filter_1 = (
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+ wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_1_distance_4_arm_neon :
+#endif
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_1_distance_4_x86_sse42 :
+#endif
+ &wuffs_png__decoder__filter_1_distance_4_fallback);
+ self->private_impl.choosy_filter_3 = (
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+ wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_3_distance_4_arm_neon :
+#endif
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_3_distance_4_x86_sse42 :
+#endif
+ &wuffs_png__decoder__filter_3_distance_4_fallback);
+ self->private_impl.choosy_filter_4 = (
+#if defined(WUFFS_BASE__CPU_ARCH__ARM_NEON)
+ wuffs_base__cpu_arch__have_arm_neon() ? &wuffs_png__decoder__filter_4_distance_4_arm_neon :
+#endif
+#if defined(WUFFS_BASE__CPU_ARCH__X86_FAMILY)
+ wuffs_base__cpu_arch__have_x86_sse42() ? &wuffs_png__decoder__filter_4_distance_4_x86_sse42 :
+#endif
+ &wuffs_png__decoder__filter_4_distance_4_fallback);
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.decode_other_chunk
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_other_chunk(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ bool a_framy) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_other_chunk[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_chunk_type == 1163152464u) && ! a_framy) {
+ if (self->private_impl.f_seen_plte) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ } else if (self->private_impl.f_color_type == 3u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_png__decoder__decode_plte(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if ((self->private_impl.f_color_type == 2u) || (self->private_impl.f_color_type == 6u)) {
+ } else {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_seen_plte = true;
+ } else if ((self->private_impl.f_chunk_type & 32u) == 0u) {
+ if (self->private_impl.f_chunk_type != 1413563465u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ }
+ if (self->private_impl.f_chunk_type == 1716082789u) {
+ if (self->private_impl.f_report_metadata_exif) {
+ if (self->private_impl.f_seen_exif) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ status = wuffs_png__decoder__decode_exif(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_exif = true;
+ }
+ } else if ((self->private_impl.f_chunk_type == 1951945833u) || (self->private_impl.f_chunk_type == 1951942004u) || (self->private_impl.f_chunk_type == 1951945850u)) {
+ if (self->private_impl.f_report_metadata_kvp) {
+ self->private_impl.f_metadata_flavor = 4u;
+ self->private_impl.f_metadata_fourcc = 1263947851u;
+ self->private_impl.f_metadata_x = 0u;
+ self->private_impl.f_metadata_y = 0u;
+ self->private_impl.f_metadata_z = 0u;
+ }
+ } else if ( ! a_framy) {
+ if (self->private_impl.f_chunk_type == 1280598881u) {
+ if (self->private_impl.f_seen_actl) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ status = wuffs_png__decoder__decode_actl(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_actl = true;
+ } else if (self->private_impl.f_chunk_type == 1297238115u) {
+ if (self->private_impl.f_report_metadata_chrm) {
+ if (self->private_impl.f_seen_chrm) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ status = wuffs_png__decoder__decode_chrm(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_chrm = true;
+ }
+ } else if (self->private_impl.f_chunk_type == 1280598886u) {
+ if (self->private_impl.f_seen_fctl) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ status = wuffs_png__decoder__decode_fctl(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_fctl = true;
+ } else if (self->private_impl.f_chunk_type == 1095582055u) {
+ if (self->private_impl.f_report_metadata_gama) {
+ if (self->private_impl.f_seen_gama) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ status = wuffs_png__decoder__decode_gama(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_gama = true;
+ }
+ } else if (self->private_impl.f_chunk_type == 1346585449u) {
+ if (self->private_impl.f_report_metadata_iccp) {
+ if (self->private_impl.f_seen_iccp) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ status = wuffs_png__decoder__decode_iccp(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_iccp = true;
+ }
+ } else if (self->private_impl.f_chunk_type == 1111970419u) {
+ if (self->private_impl.f_report_metadata_srgb) {
+ if (self->private_impl.f_seen_srgb) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ status = wuffs_png__decoder__decode_srgb(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_srgb = true;
+ }
+ } else if (self->private_impl.f_chunk_type == 1397641844u) {
+ if (self->private_impl.f_seen_trns || (self->private_impl.f_color_type > 3u) || ((self->private_impl.f_color_type == 3u) && ! self->private_impl.f_seen_plte)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ status = wuffs_png__decoder__decode_trns(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_impl.f_seen_trns = true;
+ }
+ }
+ if (self->private_impl.f_metadata_fourcc == 0u) {
+ self->private_data.s_decode_other_chunk[0].scratch = self->private_impl.f_chunk_length;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ if (self->private_data.s_decode_other_chunk[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_decode_other_chunk[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_decode_other_chunk[0].scratch;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_other_chunk[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_other_chunk[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_actl
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_actl(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_actl[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_chunk_length != 8u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ } else if (self->private_impl.f_interlace_pass > 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length = 0u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_actl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ self->private_impl.f_num_animation_frames_value = t_0;
+ }
+ if (self->private_impl.f_num_animation_frames_value == 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_actl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_actl[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ self->private_impl.f_num_animation_loops_value = t_1;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_actl[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_actl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_chrm
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_chrm(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint64_t v_u = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_chrm[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_chunk_length != 32u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length = 0u;
+ self->private_impl.f_metadata_flavor = 5u;
+ self->private_impl.f_metadata_fourcc = 1128813133u;
+ self->private_impl.f_metadata_x = 0u;
+ self->private_impl.f_metadata_y = 0u;
+ self->private_impl.f_metadata_z = 0u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint64_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_chrm[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 24) {
+ t_0 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ v_u = t_0;
+ }
+ self->private_impl.f_metadata_x |= ((16777215u & v_u) << 0u);
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint64_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_chrm[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 24) {
+ t_1 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ v_u = t_1;
+ }
+ self->private_impl.f_metadata_x |= ((16777215u & v_u) << 24u);
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ uint64_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_2 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_chrm[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
+ if (num_bits_2 == 24) {
+ t_2 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2));
+ }
+ }
+ v_u = t_2;
+ }
+ self->private_impl.f_metadata_x |= ((uint64_t)((16777215u & v_u) << 48u));
+ self->private_impl.f_metadata_y |= ((16777215u & v_u) >> 16u);
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ uint64_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_3 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_chrm[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
+ if (num_bits_3 == 24) {
+ t_3 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3));
+ }
+ }
+ v_u = t_3;
+ }
+ self->private_impl.f_metadata_y |= ((16777215u & v_u) << 8u);
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ uint64_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_4 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_chrm[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
+ if (num_bits_4 == 24) {
+ t_4 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4));
+ }
+ }
+ v_u = t_4;
+ }
+ self->private_impl.f_metadata_y |= ((16777215u & v_u) << 32u);
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ uint64_t t_5;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_5 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_chrm[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
+ uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
+ if (num_bits_5 == 24) {
+ t_5 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_5 += 8u;
+ *scratch |= ((uint64_t)(num_bits_5));
+ }
+ }
+ v_u = t_5;
+ }
+ self->private_impl.f_metadata_y |= ((uint64_t)((16777215u & v_u) << 56u));
+ self->private_impl.f_metadata_z |= ((16777215u & v_u) >> 8u);
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
+ uint64_t t_6;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_6 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_chrm[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
+ uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
+ if (num_bits_6 == 24) {
+ t_6 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_6 += 8u;
+ *scratch |= ((uint64_t)(num_bits_6));
+ }
+ }
+ v_u = t_6;
+ }
+ self->private_impl.f_metadata_z |= ((16777215u & v_u) << 16u);
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
+ uint64_t t_7;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_7 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_chrm[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_chrm[0].scratch;
+ uint32_t num_bits_7 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_7);
+ if (num_bits_7 == 24) {
+ t_7 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_7 += 8u;
+ *scratch |= ((uint64_t)(num_bits_7));
+ }
+ }
+ v_u = t_7;
+ }
+ self->private_impl.f_metadata_z |= ((16777215u & v_u) << 40u);
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_chrm[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_chrm[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_exif
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_exif(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ if (self->private_impl.f_chunk_length < 4u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_metadata_flavor = 3u;
+ self->private_impl.f_metadata_fourcc = 1163413830u;
+ self->private_impl.f_metadata_x = 0u;
+ self->private_impl.f_metadata_y = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ self->private_impl.f_metadata_z = wuffs_base__u64__sat_add(self->private_impl.f_metadata_y, ((uint64_t)(self->private_impl.f_chunk_length)));
+ self->private_impl.f_chunk_length = 0u;
+
+ goto ok;
+ ok:
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_fctl
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_fctl(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_x0 = 0;
+ uint32_t v_y0 = 0;
+ uint32_t v_x1 = 0;
+ uint32_t v_y1 = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_fctl[0];
+ if (coro_susp_point) {
+ v_x0 = self->private_data.s_decode_fctl[0].v_x0;
+ v_x1 = self->private_data.s_decode_fctl[0].v_x1;
+ v_y1 = self->private_data.s_decode_fctl[0].v_y1;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_chunk_length != 26u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length = 0u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_fctl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ v_x0 = t_0;
+ }
+ if (v_x0 != self->private_impl.f_next_animation_seq_num) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
+ goto exit;
+ } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
+ goto exit;
+ }
+ self->private_impl.f_next_animation_seq_num += 1u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_fctl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ v_x1 = t_1;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_fctl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
+ if (num_bits_2 == 24) {
+ t_2 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2));
+ }
+ }
+ v_y1 = t_2;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ uint32_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_fctl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
+ if (num_bits_3 == 24) {
+ t_3 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3));
+ }
+ }
+ v_x0 = t_3;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ uint32_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_4 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_fctl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_4);
+ if (num_bits_4 == 24) {
+ t_4 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4));
+ }
+ }
+ v_y0 = t_4;
+ }
+ v_x1 += v_x0;
+ v_y1 += v_y0;
+ if ((v_x0 >= v_x1) ||
+ (v_x0 > self->private_impl.f_width) ||
+ (v_x1 > self->private_impl.f_width) ||
+ (v_y0 >= v_y1) ||
+ (v_y0 > self->private_impl.f_height) ||
+ (v_y1 > self->private_impl.f_height)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_frame_rect_x0 = v_x0;
+ self->private_impl.f_frame_rect_y0 = v_y0;
+ self->private_impl.f_frame_rect_x1 = v_x1;
+ self->private_impl.f_frame_rect_y1 = v_y1;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ uint32_t t_5;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_5 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_fctl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
+ uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
+ if (num_bits_5 == 8) {
+ t_5 = ((uint32_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_5 += 8u;
+ *scratch |= ((uint64_t)(num_bits_5));
+ }
+ }
+ v_x0 = t_5;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
+ uint32_t t_6;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_6 = ((uint32_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_fctl[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_fctl[0].scratch;
+ uint32_t num_bits_6 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_6);
+ if (num_bits_6 == 8) {
+ t_6 = ((uint32_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_6 += 8u;
+ *scratch |= ((uint64_t)(num_bits_6));
+ }
+ }
+ v_x1 = t_6;
+ }
+ if (v_x1 <= 0u) {
+ self->private_impl.f_frame_duration = (((uint64_t)(v_x0)) * 7056000u);
+ } else {
+ self->private_impl.f_frame_duration = ((((uint64_t)(v_x0)) * 705600000u) / ((uint64_t)(v_x1)));
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_7 = *iop_a_src++;
+ v_x0 = t_7;
+ }
+ if (v_x0 == 0u) {
+ self->private_impl.f_frame_disposal = 0u;
+ } else if (v_x0 == 1u) {
+ self->private_impl.f_frame_disposal = 1u;
+ } else if (v_x0 == 2u) {
+ self->private_impl.f_frame_disposal = 2u;
+ } else {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint32_t t_8 = *iop_a_src++;
+ v_x0 = t_8;
+ }
+ if (v_x0 == 0u) {
+ self->private_impl.f_frame_overwrite_instead_of_blend = true;
+ } else if (v_x0 == 1u) {
+ self->private_impl.f_frame_overwrite_instead_of_blend = false;
+ } else {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if (self->private_impl.f_num_decoded_frame_configs_value == 0u) {
+ self->private_impl.f_first_rect_x0 = self->private_impl.f_frame_rect_x0;
+ self->private_impl.f_first_rect_y0 = self->private_impl.f_frame_rect_y0;
+ self->private_impl.f_first_rect_x1 = self->private_impl.f_frame_rect_x1;
+ self->private_impl.f_first_rect_y1 = self->private_impl.f_frame_rect_y1;
+ self->private_impl.f_first_duration = self->private_impl.f_frame_duration;
+ self->private_impl.f_first_disposal = self->private_impl.f_frame_disposal;
+ self->private_impl.f_first_overwrite_instead_of_blend = self->private_impl.f_frame_overwrite_instead_of_blend;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_fctl[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_fctl[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_fctl[0].v_x0 = v_x0;
+ self->private_data.s_decode_fctl[0].v_x1 = v_x1;
+ self->private_data.s_decode_fctl[0].v_y1 = v_y1;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_gama
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_gama(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_gama[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_chunk_length != 4u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length = 0u;
+ self->private_impl.f_metadata_flavor = 5u;
+ self->private_impl.f_metadata_fourcc = 1195461953u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint64_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = ((uint64_t)(wuffs_base__peek_u32be__no_bounds_check(iop_a_src)));
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_gama[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_gama[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 24) {
+ t_0 = ((uint64_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ self->private_impl.f_metadata_x = t_0;
+ }
+ self->private_impl.f_metadata_y = 0u;
+ self->private_impl.f_metadata_z = 0u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_gama[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_gama[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_iccp
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_iccp(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_iccp[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ if (self->private_impl.f_chunk_length <= 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length -= 1u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c == 0u) {
+ break;
+ }
+ }
+ if (self->private_impl.f_chunk_length <= 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length -= 1u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ if (v_c != 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
+ goto exit;
+ }
+ self->private_impl.f_metadata_is_zlib_compressed = true;
+ self->private_impl.f_metadata_flavor = 4u;
+ self->private_impl.f_metadata_fourcc = 1229144912u;
+ self->private_impl.f_metadata_x = 0u;
+ self->private_impl.f_metadata_y = 0u;
+ self->private_impl.f_metadata_z = 0u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_iccp[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_iccp[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_plte
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_plte(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_num_entries = 0;
+ uint32_t v_i = 0;
+ uint32_t v_argb = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_plte[0];
+ if (coro_susp_point) {
+ v_num_entries = self->private_data.s_decode_plte[0].v_num_entries;
+ v_i = self->private_data.s_decode_plte[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_chunk_length > 768u) || ((self->private_impl.f_chunk_length % 3u) != 0u)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ v_num_entries = (((uint32_t)(self->private_impl.f_chunk_length)) / 3u);
+ self->private_impl.f_chunk_length = 0u;
+ while (v_i < v_num_entries) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
+ t_0 = ((uint32_t)(wuffs_base__peek_u24be__no_bounds_check(iop_a_src)));
+ iop_a_src += 3;
+ } else {
+ self->private_data.s_decode_plte[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_plte[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 16) {
+ t_0 = ((uint32_t)(*scratch >> 40));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ v_argb = t_0;
+ }
+ v_argb |= 4278190080u;
+ self->private_data.f_src_palette[((4u * v_i) + 0u)] = ((uint8_t)((v_argb >> 0u)));
+ self->private_data.f_src_palette[((4u * v_i) + 1u)] = ((uint8_t)((v_argb >> 8u)));
+ self->private_data.f_src_palette[((4u * v_i) + 2u)] = ((uint8_t)((v_argb >> 16u)));
+ self->private_data.f_src_palette[((4u * v_i) + 3u)] = ((uint8_t)((v_argb >> 24u)));
+ v_i += 1u;
+ }
+ while (v_i < 256u) {
+ self->private_data.f_src_palette[((4u * v_i) + 0u)] = 0u;
+ self->private_data.f_src_palette[((4u * v_i) + 1u)] = 0u;
+ self->private_data.f_src_palette[((4u * v_i) + 2u)] = 0u;
+ self->private_data.f_src_palette[((4u * v_i) + 3u)] = 255u;
+ v_i += 1u;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_plte[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_plte[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_plte[0].v_num_entries = v_num_entries;
+ self->private_data.s_decode_plte[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_srgb
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_srgb(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_srgb[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_chunk_length != 1u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length = 0u;
+ self->private_impl.f_metadata_flavor = 5u;
+ self->private_impl.f_metadata_fourcc = 1397901122u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t t_0 = *iop_a_src++;
+ self->private_impl.f_metadata_x = t_0;
+ }
+ self->private_impl.f_metadata_y = 0u;
+ self->private_impl.f_metadata_z = 0u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_srgb[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_srgb[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_trns
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_trns(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_i = 0;
+ uint32_t v_n = 0;
+ uint64_t v_u = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_trns[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_decode_trns[0].v_i;
+ v_n = self->private_data.s_decode_trns[0].v_n;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_color_type == 0u) {
+ self->private_impl.choosy_filter_and_swizzle = (
+ &wuffs_png__decoder__filter_and_swizzle_tricky);
+ if (self->private_impl.f_depth <= 8u) {
+ self->private_impl.f_dst_pixfmt = 2164295816u;
+ self->private_impl.f_src_pixfmt = 2164295816u;
+ } else {
+ self->private_impl.f_dst_pixfmt = 2164308923u;
+ self->private_impl.f_src_pixfmt = 2164308923u;
+ }
+ if (self->private_impl.f_chunk_length != 2u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length = 0u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint64_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_0 = ((uint64_t)(wuffs_base__peek_u16be__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_decode_trns[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 8) {
+ t_0 = ((uint64_t)(*scratch >> 48));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ v_u = t_0;
+ }
+ if (self->private_impl.f_depth <= 1u) {
+ self->private_impl.f_remap_transparency = (((v_u & 1u) * 16777215u) | 4278190080u);
+ } else if (self->private_impl.f_depth <= 2u) {
+ self->private_impl.f_remap_transparency = (((v_u & 3u) * 5592405u) | 4278190080u);
+ } else if (self->private_impl.f_depth <= 4u) {
+ self->private_impl.f_remap_transparency = (((v_u & 15u) * 1118481u) | 4278190080u);
+ } else if (self->private_impl.f_depth <= 8u) {
+ self->private_impl.f_remap_transparency = (((v_u & 255u) * 65793u) | 4278190080u);
+ } else {
+ self->private_impl.f_remap_transparency = ((v_u * 4295032833u) | 18446462598732840960u);
+ }
+ } else if (self->private_impl.f_color_type == 2u) {
+ self->private_impl.choosy_filter_and_swizzle = (
+ &wuffs_png__decoder__filter_and_swizzle_tricky);
+ if (self->private_impl.f_depth <= 8u) {
+ self->private_impl.f_dst_pixfmt = 2164295816u;
+ self->private_impl.f_src_pixfmt = 2164295816u;
+ } else {
+ self->private_impl.f_dst_pixfmt = 2164308923u;
+ self->private_impl.f_src_pixfmt = 2164308923u;
+ }
+ if (self->private_impl.f_chunk_length != 6u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length = 0u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint64_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 6)) {
+ t_1 = ((uint64_t)(wuffs_base__peek_u48be__no_bounds_check(iop_a_src)));
+ iop_a_src += 6;
+ } else {
+ self->private_data.s_decode_trns[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_trns[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 40) {
+ t_1 = ((uint64_t)(*scratch >> 16));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ v_u = t_1;
+ }
+ if (self->private_impl.f_depth <= 8u) {
+ self->private_impl.f_remap_transparency = ((255u & (v_u >> 0u)) |
+ (65280u & (v_u >> 8u)) |
+ (16711680u & (v_u >> 16u)) |
+ 4278190080u);
+ } else {
+ self->private_impl.f_remap_transparency = (v_u | 18446462598732840960u);
+ }
+ } else if (self->private_impl.f_color_type == 3u) {
+ self->private_impl.f_dst_pixfmt = 2164523016u;
+ self->private_impl.f_src_pixfmt = 2164523016u;
+ if (self->private_impl.f_chunk_length > 256u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ v_n = ((uint32_t)(self->private_impl.f_chunk_length));
+ self->private_impl.f_chunk_length = 0u;
+ while (v_i < v_n) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ self->private_data.f_src_palette[((4u * v_i) + 3u)] = t_2;
+ }
+ v_i += 1u;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+
+ goto ok;
+ ok:
+ self->private_impl.p_decode_trns[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_trns[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_decode_trns[0].v_i = v_i;
+ self->private_data.s_decode_trns[0].v_n = v_n;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__decode_frame_config(
+ wuffs_png__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 2)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_png__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func png.decoder.do_decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__do_decode_frame_config(
+ wuffs_png__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_checksum_have = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_call_sequence & 16u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ } else if (self->private_impl.f_call_sequence == 32u) {
+ } else if (self->private_impl.f_call_sequence < 32u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_png__decoder__do_decode_image_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (self->private_impl.f_call_sequence == 40u) {
+ if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_restart);
+ goto exit;
+ }
+ } else if (self->private_impl.f_call_sequence == 64u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ status = wuffs_png__decoder__skip_frame(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (self->private_impl.f_metadata_fourcc != 0u) {
+ self->private_impl.f_call_sequence = 48u;
+ status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
+ goto ok;
+ }
+ if (self->private_impl.f_num_decoded_frame_configs_value == 0u) {
+ self->private_impl.f_frame_rect_x0 = self->private_impl.f_first_rect_x0;
+ self->private_impl.f_frame_rect_y0 = self->private_impl.f_first_rect_y0;
+ self->private_impl.f_frame_rect_x1 = self->private_impl.f_first_rect_x1;
+ self->private_impl.f_frame_rect_y1 = self->private_impl.f_first_rect_y1;
+ self->private_impl.f_frame_config_io_position = self->private_impl.f_first_config_io_position;
+ self->private_impl.f_frame_duration = self->private_impl.f_first_duration;
+ self->private_impl.f_frame_disposal = self->private_impl.f_first_disposal;
+ self->private_impl.f_frame_overwrite_instead_of_blend = self->private_impl.f_first_overwrite_instead_of_blend;
+ } else {
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_frame_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ self->private_impl.f_chunk_length = t_0;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_frame_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_1;
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1)) << 56;
+ }
+ }
+ self->private_impl.f_chunk_type = t_1;
+ }
+ if (self->private_impl.f_chunk_type == 1145980233u) {
+ if (self->private_impl.f_chunk_length != 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_2 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_frame_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_frame_config[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_2;
+ if (num_bits_2 == 24) {
+ t_2 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2)) << 56;
+ }
+ }
+ v_checksum_have = t_2;
+ }
+ if ( ! self->private_impl.f_ignore_checksum && (v_checksum_have != 2187346606u)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
+ goto exit;
+ }
+ self->private_impl.f_call_sequence = 96u;
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ } else if (self->private_impl.f_chunk_type == 1413571686u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ } else if (self->private_impl.f_chunk_type == 1280598886u) {
+ self->private_impl.f_frame_config_io_position = ((uint64_t)(wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) - 8u));
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ status = wuffs_png__decoder__decode_fctl(self, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ self->private_data.s_do_decode_frame_config[0].scratch = 4u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ if (self->private_data.s_do_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_frame_config[0].scratch;
+ break;
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ status = wuffs_png__decoder__decode_other_chunk(self, a_src, true);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ if (self->private_impl.f_metadata_fourcc != 0u) {
+ self->private_impl.f_call_sequence = 48u;
+ status = wuffs_base__make_status(wuffs_base__note__metadata_reported);
+ goto ok;
+ }
+ self->private_data.s_do_decode_frame_config[0].scratch = 4u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
+ if (self->private_data.s_do_decode_frame_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_frame_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_frame_config[0].scratch;
+ self->private_impl.f_chunk_length = 0u;
+ }
+ }
+ if (a_dst != NULL) {
+ wuffs_base__frame_config__set(
+ a_dst,
+ wuffs_base__utility__make_rect_ie_u32(
+ self->private_impl.f_frame_rect_x0,
+ self->private_impl.f_frame_rect_y0,
+ self->private_impl.f_frame_rect_x1,
+ self->private_impl.f_frame_rect_y1),
+ ((wuffs_base__flicks)(self->private_impl.f_frame_duration)),
+ ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value)),
+ self->private_impl.f_frame_config_io_position,
+ self->private_impl.f_frame_disposal,
+ ((self->private_impl.f_color_type <= 3u) && ! self->private_impl.f_seen_trns),
+ self->private_impl.f_frame_overwrite_instead_of_blend,
+ 0u);
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frame_configs_value, 1u);
+ self->private_impl.f_call_sequence = 64u;
+
+ ok:
+ self->private_impl.p_do_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.skip_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__skip_frame(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_seq_num = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_skip_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.f_chunk_type_array[0u] = 0u;
+ self->private_impl.f_chunk_type_array[1u] = 0u;
+ self->private_impl.f_chunk_type_array[2u] = 0u;
+ self->private_impl.f_chunk_type_array[3u] = 0u;
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ continue;
+ }
+ self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
+ if (self->private_impl.f_chunk_type == 1413563465u) {
+ if (self->private_impl.f_chunk_type_array[0u] == 102u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_type_array[0u] = 73u;
+ self->private_impl.f_chunk_type_array[1u] = 68u;
+ self->private_impl.f_chunk_type_array[2u] = 65u;
+ self->private_impl.f_chunk_type_array[3u] = 84u;
+ } else if (self->private_impl.f_chunk_type == 1413571686u) {
+ if (self->private_impl.f_chunk_type_array[0u] == 73u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_type_array[0u] = 102u;
+ self->private_impl.f_chunk_type_array[1u] = 100u;
+ self->private_impl.f_chunk_type_array[2u] = 65u;
+ self->private_impl.f_chunk_type_array[3u] = 84u;
+ if (self->private_impl.f_chunk_length < 4u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length -= 4u;
+ iop_a_src += 8u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_skip_frame[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_skip_frame[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ v_seq_num = t_0;
+ }
+ if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
+ goto exit;
+ } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
+ goto exit;
+ }
+ self->private_impl.f_next_animation_seq_num += 1u;
+ self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 4u);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_skip_frame[0].scratch;
+ self->private_impl.f_chunk_length = 0u;
+ continue;
+ } else if (self->private_impl.f_chunk_type_array[0u] != 0u) {
+ break;
+ } else if (self->private_impl.f_chunk_type == 1280598886u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_data.s_skip_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (self->private_data.s_skip_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_skip_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_skip_frame[0].scratch;
+ self->private_impl.f_chunk_length = 0u;
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
+ self->private_impl.f_call_sequence = 32u;
+
+ ok:
+ self->private_impl.p_skip_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_skip_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__decode_frame(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 3)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_png__decoder__do_decode_frame(self,
+ a_dst,
+ a_src,
+ a_blend,
+ a_workbuf,
+ a_opts);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_png__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func png.decoder.do_decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__do_decode_frame(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_seq_num = 0;
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ uint32_t v_pass_width = 0;
+ uint32_t v_pass_height = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_call_sequence & 16u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ } else if (self->private_impl.f_call_sequence >= 96u) {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ } else if (self->private_impl.f_call_sequence != 64u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_png__decoder__do_decode_frame_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ }
+ while (true) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 8u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ continue;
+ }
+ self->private_impl.f_chunk_length = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ self->private_impl.f_chunk_type = ((uint32_t)((wuffs_base__peek_u64le__no_bounds_check(iop_a_src) >> 32u)));
+ if (self->private_impl.f_chunk_type == 1413563465u) {
+ self->private_impl.f_chunk_type_array[0u] = 73u;
+ self->private_impl.f_chunk_type_array[1u] = 68u;
+ self->private_impl.f_chunk_type_array[2u] = 65u;
+ self->private_impl.f_chunk_type_array[3u] = 84u;
+ iop_a_src += 8u;
+ if ( ! self->private_impl.f_ignore_checksum) {
+ wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
+ sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
+ wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
+ }
+ break;
+ } else if (self->private_impl.f_chunk_type == 1413571686u) {
+ self->private_impl.f_chunk_type_array[0u] = 102u;
+ self->private_impl.f_chunk_type_array[1u] = 100u;
+ self->private_impl.f_chunk_type_array[2u] = 65u;
+ self->private_impl.f_chunk_type_array[3u] = 84u;
+ if (self->private_impl.f_chunk_length < 4u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length -= 4u;
+ iop_a_src += 8u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_0;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_0 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_frame[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_frame[0].scratch;
+ uint32_t num_bits_0 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_0);
+ if (num_bits_0 == 24) {
+ t_0 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_0 += 8u;
+ *scratch |= ((uint64_t)(num_bits_0));
+ }
+ }
+ v_seq_num = t_0;
+ }
+ if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
+ goto exit;
+ } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
+ goto exit;
+ }
+ self->private_impl.f_next_animation_seq_num += 1u;
+ break;
+ } else if (self->private_impl.f_chunk_type == 1280598886u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_data.s_do_decode_frame[0].scratch = (((uint64_t)(self->private_impl.f_chunk_length)) + 12u);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
+ self->private_impl.f_chunk_length = 0u;
+ }
+ if (self->private_impl.f_zlib_is_dirty) {
+ wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
+ sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
+ if (self->private_impl.f_ignore_checksum) {
+ wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u);
+ }
+ }
+ self->private_impl.f_zlib_is_dirty = true;
+ v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
+ wuffs_base__pixel_buffer__pixel_format(a_dst),
+ wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
+ wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
+ wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024),
+ a_blend);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ self->private_impl.f_workbuf_hist_pos_base = 0u;
+ while (true) {
+ if (self->private_impl.f_chunk_type_array[0u] == 73u) {
+ v_pass_width = (16777215u & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][1u])) + self->private_impl.f_width) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]));
+ v_pass_height = (16777215u & ((((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][4u])) + self->private_impl.f_height) >> WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3u]));
+ } else {
+ v_pass_width = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_x1 - self->private_impl.f_frame_rect_x0)));
+ v_pass_height = (16777215u & ((uint32_t)(self->private_impl.f_frame_rect_y1 - self->private_impl.f_frame_rect_y0)));
+ }
+ if ((v_pass_width > 0u) && (v_pass_height > 0u)) {
+ self->private_impl.f_pass_bytes_per_row = wuffs_png__decoder__calculate_bytes_per_row(self, v_pass_width);
+ self->private_impl.f_pass_workbuf_length = (((uint64_t)(v_pass_height)) * (1u + self->private_impl.f_pass_bytes_per_row));
+ while (true) {
+ {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_1 = wuffs_png__decoder__decode_pass(self, a_src, a_workbuf);
+ v_status = t_1;
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ if (wuffs_base__status__is_ok(&v_status)) {
+ break;
+ } else if (wuffs_base__status__is_error(&v_status) || ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed))) {
+ if (self->private_impl.f_workbuf_wi <= ((uint64_t)(a_workbuf.len))) {
+ wuffs_png__decoder__filter_and_swizzle(self, a_dst, wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_workbuf_wi));
+ }
+ if (v_status.repr == wuffs_base__suspension__short_read) {
+ status = wuffs_base__make_status(wuffs_png__error__truncated_input);
+ goto exit;
+ }
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
+ }
+ v_status = wuffs_png__decoder__filter_and_swizzle(self, a_dst, a_workbuf);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ self->private_impl.f_workbuf_hist_pos_base += self->private_impl.f_pass_workbuf_length;
+ }
+ if ((self->private_impl.f_interlace_pass == 0u) || (self->private_impl.f_interlace_pass >= 7u)) {
+ break;
+ }
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_impl.f_interlace_pass += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ }
+ wuffs_base__u32__sat_add_indirect(&self->private_impl.f_num_decoded_frames_value, 1u);
+ self->private_impl.f_call_sequence = 32u;
+
+ ok:
+ self->private_impl.p_do_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.decode_pass
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__decode_pass(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_w = &u_w;
+ uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint64_t v_w_mark = 0;
+ uint64_t v_r_mark = 0;
+ wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
+ uint32_t v_checksum_have = 0;
+ uint32_t v_checksum_want = 0;
+ uint32_t v_seq_num = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_pass[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ self->private_impl.f_workbuf_wi = 0u;
+ while (true) {
+ if ((self->private_impl.f_workbuf_wi > self->private_impl.f_pass_workbuf_length) || (self->private_impl.f_pass_workbuf_length > ((uint64_t)(a_workbuf.len)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_workbuf_length);
+ goto exit;
+ }
+ {
+ wuffs_base__io_buffer* o_0_v_w = v_w;
+ uint8_t *o_0_iop_v_w = iop_v_w;
+ uint8_t *o_0_io0_v_w = io0_v_w;
+ uint8_t *o_0_io1_v_w = io1_v_w;
+ uint8_t *o_0_io2_v_w = io2_v_w;
+ v_w = wuffs_base__io_writer__set(
+ &u_w,
+ &iop_v_w,
+ &io0_v_w,
+ &io1_v_w,
+ &io2_v_w,
+ wuffs_base__slice_u8__subslice_ij(a_workbuf,
+ self->private_impl.f_workbuf_wi,
+ self->private_impl.f_pass_workbuf_length),
+ ((uint64_t)(self->private_impl.f_workbuf_hist_pos_base + self->private_impl.f_workbuf_wi)));
+ {
+ const bool o_1_closed_a_src = a_src->meta.closed;
+ const uint8_t *o_1_io2_a_src = io2_a_src;
+ wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
+ ((uint64_t)(self->private_impl.f_chunk_length)));
+ if (a_src) {
+ size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
+ a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
+ a_src->meta.wi = n;
+ }
+ v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
+ v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
+ {
+ u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_0 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, v_w, a_src, wuffs_base__utility__empty_slice_u8());
+ v_zlib_status = t_0;
+ iop_v_w = u_w.data.ptr + u_w.meta.wi;
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ if ( ! self->private_impl.f_ignore_checksum) {
+ wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__io__since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
+ }
+ wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_workbuf_wi, wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w))));
+ io2_a_src = o_1_io2_a_src;
+ if (a_src) {
+ a_src->meta.closed = o_1_closed_a_src;
+ a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
+ }
+ }
+ v_w = o_0_v_w;
+ iop_v_w = o_0_iop_v_w;
+ io0_v_w = o_0_io0_v_w;
+ io1_v_w = o_0_io1_v_w;
+ io2_v_w = o_0_io2_v_w;
+ }
+ if (wuffs_base__status__is_ok(&v_zlib_status)) {
+ if (self->private_impl.f_chunk_length > 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__too_much_data);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ uint32_t t_1;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_1 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_pass[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
+ uint32_t num_bits_1 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_1);
+ if (num_bits_1 == 24) {
+ t_1 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_1 += 8u;
+ *scratch |= ((uint64_t)(num_bits_1));
+ }
+ }
+ v_checksum_want = t_1;
+ }
+ if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) {
+ v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
+ if (v_checksum_have != v_checksum_want) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
+ goto exit;
+ }
+ }
+ break;
+ } else if (v_zlib_status.repr == wuffs_base__suspension__short_write) {
+ if ((1u <= self->private_impl.f_interlace_pass) && (self->private_impl.f_interlace_pass <= 6u)) {
+ break;
+ }
+ status = wuffs_base__make_status(wuffs_base__error__too_much_data);
+ goto exit;
+ } else if (v_zlib_status.repr != wuffs_base__suspension__short_read) {
+ status = v_zlib_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ } else if (self->private_impl.f_chunk_length == 0u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ uint32_t t_2;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_2 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_pass[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
+ uint32_t num_bits_2 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_2);
+ if (num_bits_2 == 24) {
+ t_2 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_2 += 8u;
+ *scratch |= ((uint64_t)(num_bits_2));
+ }
+ }
+ v_checksum_want = t_2;
+ }
+ if ( ! self->private_impl.f_ignore_checksum && (self->private_impl.f_chunk_type_array[0u] == 73u)) {
+ v_checksum_have = wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__utility__empty_slice_u8());
+ if (v_checksum_have != v_checksum_want) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_checksum);
+ goto exit;
+ }
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ uint32_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_3 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_pass[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_3);
+ if (num_bits_3 == 24) {
+ t_3 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3));
+ }
+ }
+ self->private_impl.f_chunk_length = t_3;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ uint32_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_4 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_pass[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
+ if (num_bits_4 == 24) {
+ t_4 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4)) << 56;
+ }
+ }
+ self->private_impl.f_chunk_type = t_4;
+ }
+ if (self->private_impl.f_chunk_type_array[0u] == 73u) {
+ if (self->private_impl.f_chunk_type != 1413563465u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ if ( ! self->private_impl.f_ignore_checksum) {
+ wuffs_base__ignore_status(wuffs_crc32__ieee_hasher__initialize(&self->private_data.f_crc32,
+ sizeof (wuffs_crc32__ieee_hasher), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
+ wuffs_crc32__ieee_hasher__update_u32(&self->private_data.f_crc32, wuffs_base__make_slice_u8(self->private_impl.f_chunk_type_array, 4));
+ }
+ } else {
+ if ((self->private_impl.f_chunk_type != 1413571686u) || (self->private_impl.f_chunk_length < 4u)) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length -= 4u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ uint32_t t_5;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_5 = wuffs_base__peek_u32be__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_decode_pass[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_decode_pass[0].scratch;
+ uint32_t num_bits_5 = ((uint32_t)(*scratch & 0xFFu));
+ *scratch >>= 8;
+ *scratch <<= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << (56 - num_bits_5);
+ if (num_bits_5 == 24) {
+ t_5 = ((uint32_t)(*scratch >> 32));
+ break;
+ }
+ num_bits_5 += 8u;
+ *scratch |= ((uint64_t)(num_bits_5));
+ }
+ }
+ v_seq_num = t_5;
+ }
+ if (v_seq_num != self->private_impl.f_next_animation_seq_num) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_animation_sequence_number);
+ goto exit;
+ } else if (self->private_impl.f_next_animation_seq_num >= 4294967295u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_file);
+ goto exit;
+ }
+ self->private_impl.f_next_animation_seq_num += 1u;
+ }
+ continue;
+ } else if (((uint64_t)(io2_a_src - iop_a_src)) > 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__internal_error_zlib_decoder_did_not_exhaust_its_input);
+ goto exit;
+ }
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
+ }
+ if (self->private_impl.f_workbuf_wi != self->private_impl.f_pass_workbuf_length) {
+ status = wuffs_base__make_status(wuffs_base__error__not_enough_data);
+ goto exit;
+ } else if (0u < ((uint64_t)(a_workbuf.len))) {
+ if (a_workbuf.ptr[0u] == 4u) {
+ a_workbuf.ptr[0u] = 1u;
+ }
+ }
+
+ ok:
+ self->private_impl.p_decode_pass[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_pass[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.frame_dirty_rect
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_png__decoder__frame_dirty_rect(
+ const wuffs_png__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ return wuffs_base__utility__make_rect_ie_u32(
+ self->private_impl.f_frame_rect_x0,
+ self->private_impl.f_frame_rect_y0,
+ self->private_impl.f_frame_rect_x1,
+ self->private_impl.f_frame_rect_y1);
+}
+
+// -------- func png.decoder.num_animation_loops
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_png__decoder__num_animation_loops(
+ const wuffs_png__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return self->private_impl.f_num_animation_loops_value;
+}
+
+// -------- func png.decoder.num_decoded_frame_configs
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_png__decoder__num_decoded_frame_configs(
+ const wuffs_png__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return ((uint64_t)(self->private_impl.f_num_decoded_frame_configs_value));
+}
+
+// -------- func png.decoder.num_decoded_frames
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_png__decoder__num_decoded_frames(
+ const wuffs_png__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return ((uint64_t)(self->private_impl.f_num_decoded_frames_value));
+}
+
+// -------- func png.decoder.restart_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__restart_frame(
+ wuffs_png__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (self->private_impl.f_call_sequence < 32u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ } else if ((a_index >= ((uint64_t)(self->private_impl.f_num_animation_frames_value))) || ((a_index == 0u) && (a_io_position != self->private_impl.f_first_config_io_position))) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_call_sequence = 40u;
+ if (self->private_impl.f_interlace_pass >= 1u) {
+ self->private_impl.f_interlace_pass = 1u;
+ }
+ self->private_impl.f_frame_config_io_position = a_io_position;
+ self->private_impl.f_num_decoded_frame_configs_value = ((uint32_t)(a_index));
+ self->private_impl.f_num_decoded_frames_value = self->private_impl.f_num_decoded_frame_configs_value;
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func png.decoder.set_report_metadata
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_png__decoder__set_report_metadata(
+ wuffs_png__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ if (a_fourcc == 1128813133u) {
+ self->private_impl.f_report_metadata_chrm = a_report;
+ } else if (a_fourcc == 1163413830u) {
+ self->private_impl.f_report_metadata_exif = a_report;
+ } else if (a_fourcc == 1195461953u) {
+ self->private_impl.f_report_metadata_gama = a_report;
+ } else if (a_fourcc == 1229144912u) {
+ self->private_impl.f_report_metadata_iccp = a_report;
+ } else if (a_fourcc == 1263947808u) {
+ self->private_impl.f_report_metadata_kvp = a_report;
+ } else if (a_fourcc == 1397901122u) {
+ self->private_impl.f_report_metadata_srgb = a_report;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func png.decoder.tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_png__decoder__tell_me_more(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 4)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_tell_me_more[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_png__decoder__do_tell_me_more(self, a_dst, a_minfo, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_png__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_tell_me_more[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 4 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func png.decoder.do_tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__do_tell_me_more(
+ wuffs_png__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint16_t v_c2 = 0;
+ wuffs_base__io_buffer u_w = wuffs_base__empty_io_buffer();
+ wuffs_base__io_buffer* v_w = &u_w;
+ uint8_t* iop_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io0_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_v_w WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint64_t v_num_written = 0;
+ uint64_t v_w_mark = 0;
+ uint64_t v_r_mark = 0;
+ wuffs_base__status v_zlib_status = wuffs_base__make_status(NULL);
+
+ uint8_t* iop_a_dst = NULL;
+ uint8_t* io0_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io1_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ uint8_t* io2_a_dst WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_dst && a_dst->data.ptr) {
+ io0_a_dst = a_dst->data.ptr;
+ io1_a_dst = io0_a_dst + a_dst->meta.wi;
+ iop_a_dst = io1_a_dst;
+ io2_a_dst = io0_a_dst + a_dst->data.len;
+ if (a_dst->meta.closed) {
+ io2_a_dst = iop_a_dst;
+ }
+ }
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_tell_me_more[0];
+ if (coro_susp_point) {
+ v_zlib_status = self->private_data.s_do_tell_me_more[0].v_zlib_status;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if ((self->private_impl.f_call_sequence & 16u) == 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ }
+ if (self->private_impl.f_metadata_fourcc == 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__no_more_information);
+ goto exit;
+ }
+ do {
+ if (self->private_impl.f_metadata_flavor == 3u) {
+ while (true) {
+ if (wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src))) != self->private_impl.f_metadata_y) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_i_o_position);
+ goto exit;
+ } else if (a_minfo != NULL) {
+ wuffs_base__more_information__set(a_minfo,
+ self->private_impl.f_metadata_flavor,
+ self->private_impl.f_metadata_fourcc,
+ self->private_impl.f_metadata_x,
+ self->private_impl.f_metadata_y,
+ self->private_impl.f_metadata_z);
+ }
+ if (self->private_impl.f_metadata_y >= self->private_impl.f_metadata_z) {
+ goto label__goto_done__break;
+ }
+ self->private_impl.f_metadata_y = self->private_impl.f_metadata_z;
+ status = wuffs_base__make_status(wuffs_base__suspension__even_more_information);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+ }
+ if (self->private_impl.f_metadata_is_zlib_compressed) {
+ if (self->private_impl.f_zlib_is_dirty) {
+ wuffs_base__ignore_status(wuffs_zlib__decoder__initialize(&self->private_data.f_zlib,
+ sizeof (wuffs_zlib__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED));
+ if (self->private_impl.f_ignore_checksum) {
+ wuffs_zlib__decoder__set_quirk(&self->private_data.f_zlib, 1u, 1u);
+ }
+ }
+ self->private_impl.f_zlib_is_dirty = true;
+ self->private_impl.f_ztxt_hist_pos = 0u;
+ }
+ label__loop__continue:;
+ while (true) {
+ if (a_minfo != NULL) {
+ wuffs_base__more_information__set(a_minfo,
+ self->private_impl.f_metadata_flavor,
+ self->private_impl.f_metadata_fourcc,
+ self->private_impl.f_metadata_x,
+ self->private_impl.f_metadata_y,
+ self->private_impl.f_metadata_z);
+ }
+ if (self->private_impl.f_metadata_flavor != 4u) {
+ break;
+ }
+ if (self->private_impl.f_metadata_is_zlib_compressed) {
+ if (self->private_impl.f_chunk_type == 1346585449u) {
+ {
+ const bool o_0_closed_a_src = a_src->meta.closed;
+ const uint8_t *o_0_io2_a_src = io2_a_src;
+ wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
+ ((uint64_t)(self->private_impl.f_chunk_length)));
+ if (a_src) {
+ size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
+ a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
+ a_src->meta.wi = n;
+ }
+ v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
+ {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_0 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, a_dst, a_src, wuffs_base__utility__empty_slice_u8());
+ v_zlib_status = t_0;
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
+ io2_a_src = o_0_io2_a_src;
+ if (a_src) {
+ a_src->meta.closed = o_0_closed_a_src;
+ a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
+ }
+ }
+ if (wuffs_base__status__is_ok(&v_zlib_status)) {
+ self->private_impl.f_metadata_is_zlib_compressed = false;
+ break;
+ } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
+ status = v_zlib_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ status = v_zlib_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ } else if (self->private_impl.f_chunk_type == 1951945833u) {
+ {
+ const bool o_1_closed_a_src = a_src->meta.closed;
+ const uint8_t *o_1_io2_a_src = io2_a_src;
+ wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
+ ((uint64_t)(self->private_impl.f_chunk_length)));
+ if (a_src) {
+ size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
+ a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
+ a_src->meta.wi = n;
+ }
+ v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
+ {
+ if (a_dst) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_1 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, a_dst, a_src, wuffs_base__utility__empty_slice_u8());
+ v_zlib_status = t_1;
+ if (a_dst) {
+ iop_a_dst = a_dst->data.ptr + a_dst->meta.wi;
+ }
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
+ io2_a_src = o_1_io2_a_src;
+ if (a_src) {
+ a_src->meta.closed = o_1_closed_a_src;
+ a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
+ }
+ }
+ if (wuffs_base__status__is_ok(&v_zlib_status)) {
+ self->private_impl.f_metadata_is_zlib_compressed = false;
+ break;
+ } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
+ status = v_zlib_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ status = v_zlib_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ } else if (self->private_impl.f_chunk_type == 1951945850u) {
+ if (self->private_impl.f_ztxt_ri == self->private_impl.f_ztxt_wi) {
+ {
+ wuffs_base__io_buffer* o_2_v_w = v_w;
+ uint8_t *o_2_iop_v_w = iop_v_w;
+ uint8_t *o_2_io0_v_w = io0_v_w;
+ uint8_t *o_2_io1_v_w = io1_v_w;
+ uint8_t *o_2_io2_v_w = io2_v_w;
+ v_w = wuffs_base__io_writer__set(
+ &u_w,
+ &iop_v_w,
+ &io0_v_w,
+ &io1_v_w,
+ &io2_v_w,
+ wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024),
+ self->private_impl.f_ztxt_hist_pos);
+ {
+ const bool o_3_closed_a_src = a_src->meta.closed;
+ const uint8_t *o_3_io2_a_src = io2_a_src;
+ wuffs_base__io_reader__limit(&io2_a_src, iop_a_src,
+ ((uint64_t)(self->private_impl.f_chunk_length)));
+ if (a_src) {
+ size_t n = ((size_t)(io2_a_src - a_src->data.ptr));
+ a_src->meta.closed = a_src->meta.closed && (a_src->meta.wi <= n);
+ a_src->meta.wi = n;
+ }
+ v_w_mark = ((uint64_t)(iop_v_w - io0_v_w));
+ v_r_mark = ((uint64_t)(iop_a_src - io0_a_src));
+ {
+ u_w.meta.wi = ((size_t)(iop_v_w - u_w.data.ptr));
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ wuffs_base__status t_2 = wuffs_zlib__decoder__transform_io(&self->private_data.f_zlib, v_w, a_src, wuffs_base__utility__empty_slice_u8());
+ v_zlib_status = t_2;
+ iop_v_w = u_w.data.ptr + u_w.meta.wi;
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ }
+ wuffs_base__u32__sat_sub_indirect(&self->private_impl.f_chunk_length, ((uint32_t)(wuffs_base__io__count_since(v_r_mark, ((uint64_t)(iop_a_src - io0_a_src))))));
+ v_num_written = wuffs_base__io__count_since(v_w_mark, ((uint64_t)(iop_v_w - io0_v_w)));
+ io2_a_src = o_3_io2_a_src;
+ if (a_src) {
+ a_src->meta.closed = o_3_closed_a_src;
+ a_src->meta.wi = ((size_t)(io2_a_src - a_src->data.ptr));
+ }
+ }
+ v_w = o_2_v_w;
+ iop_v_w = o_2_iop_v_w;
+ io0_v_w = o_2_io0_v_w;
+ io1_v_w = o_2_io1_v_w;
+ io2_v_w = o_2_io2_v_w;
+ }
+ if (v_num_written > 1024u) {
+ status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_i_o);
+ goto exit;
+ }
+ self->private_impl.f_ztxt_ri = 0u;
+ self->private_impl.f_ztxt_wi = ((uint32_t)(v_num_written));
+ wuffs_base__u64__sat_add_indirect(&self->private_impl.f_ztxt_hist_pos, v_num_written);
+ }
+ while (self->private_impl.f_ztxt_ri < self->private_impl.f_ztxt_wi) {
+ v_c2 = WUFFS_PNG__LATIN_1[self->private_data.f_dst_palette[self->private_impl.f_ztxt_ri]];
+ if (v_c2 == 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
+ goto exit;
+ } else if (v_c2 <= 127u) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
+ goto label__loop__continue;
+ }
+ self->private_impl.f_ztxt_ri += 1u;
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
+ } else {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
+ goto label__loop__continue;
+ }
+ self->private_impl.f_ztxt_ri += 1u;
+ (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
+ }
+ }
+ if (wuffs_base__status__is_ok(&v_zlib_status)) {
+ self->private_impl.f_metadata_is_zlib_compressed = false;
+ break;
+ } else if ( ! wuffs_base__status__is_suspension(&v_zlib_status)) {
+ status = v_zlib_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ } else if (v_zlib_status.repr != wuffs_base__suspension__short_write) {
+ status = v_zlib_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_chunk_type);
+ goto exit;
+ }
+ } else if ((self->private_impl.f_chunk_type == 1951945833u) && (self->private_impl.f_metadata_fourcc == 1263947862u)) {
+ while (true) {
+ if (self->private_impl.f_chunk_length <= 0u) {
+ goto label__loop__break;
+ } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
+ goto label__loop__continue;
+ } else if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
+ goto label__loop__continue;
+ }
+ self->private_impl.f_chunk_length -= 1u;
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, v_c), iop_a_dst += 1);
+ }
+ } else {
+ while (true) {
+ if (self->private_impl.f_chunk_length <= 0u) {
+ if (self->private_impl.f_metadata_fourcc == 1263947851u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ goto label__loop__break;
+ } else if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
+ goto label__loop__continue;
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ if (v_c == 0u) {
+ self->private_impl.f_chunk_length -= 1u;
+ iop_a_src += 1u;
+ goto label__loop__break;
+ }
+ v_c2 = WUFFS_PNG__LATIN_1[v_c];
+ if (v_c2 == 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_text_chunk_not_latin_1);
+ goto exit;
+ } else if (v_c2 <= 127u) {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
+ goto label__loop__continue;
+ }
+ self->private_impl.f_chunk_length -= 1u;
+ iop_a_src += 1u;
+ (wuffs_base__poke_u8be__no_bounds_check(iop_a_dst, ((uint8_t)(v_c2))), iop_a_dst += 1);
+ } else {
+ if (((uint64_t)(io2_a_dst - iop_a_dst)) <= 1u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_write);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(11);
+ goto label__loop__continue;
+ }
+ self->private_impl.f_chunk_length -= 1u;
+ iop_a_src += 1u;
+ (wuffs_base__poke_u16le__no_bounds_check(iop_a_dst, v_c2), iop_a_dst += 2);
+ }
+ }
+ }
+ }
+ label__loop__break:;
+ if (self->private_impl.f_metadata_fourcc == 1263947851u) {
+ self->private_impl.f_metadata_fourcc = 1263947862u;
+ if (self->private_impl.f_chunk_type == 1951945833u) {
+ if (self->private_impl.f_chunk_length <= 1u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length -= 2u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_3 = *iop_a_src++;
+ v_c = t_3;
+ }
+ if (v_c == 0u) {
+ self->private_impl.f_metadata_is_zlib_compressed = false;
+ } else if (v_c == 1u) {
+ self->private_impl.f_metadata_is_zlib_compressed = true;
+ } else {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_4 = *iop_a_src++;
+ v_c = t_4;
+ }
+ if ((v_c != 0u) && self->private_impl.f_metadata_is_zlib_compressed) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
+ goto exit;
+ }
+ self->private_impl.f_metadata_fourcc -= 2u;
+ while (self->private_impl.f_metadata_fourcc != 1263947862u) {
+ self->private_impl.f_metadata_fourcc += 1u;
+ while (true) {
+ if (self->private_impl.f_chunk_length <= 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length -= 1u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ v_c = t_5;
+ }
+ if (v_c == 0u) {
+ break;
+ }
+ }
+ }
+ } else if (self->private_impl.f_chunk_type == 1951945850u) {
+ if (self->private_impl.f_chunk_length <= 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_impl.f_chunk_length -= 1u;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_6 = *iop_a_src++;
+ v_c = t_6;
+ }
+ if (v_c != 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__unsupported_png_compression_method);
+ goto exit;
+ }
+ self->private_impl.f_metadata_is_zlib_compressed = true;
+ }
+ self->private_impl.f_call_sequence &= 239u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+ }
+ } while (0);
+ label__goto_done__break:;
+ if (self->private_impl.f_chunk_length != 0u) {
+ status = wuffs_base__make_status(wuffs_png__error__bad_chunk);
+ goto exit;
+ }
+ self->private_data.s_do_tell_me_more[0].scratch = 4u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
+ if (self->private_data.s_do_tell_me_more[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_tell_me_more[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_tell_me_more[0].scratch;
+ self->private_impl.f_metadata_flavor = 0u;
+ self->private_impl.f_metadata_fourcc = 0u;
+ self->private_impl.f_metadata_x = 0u;
+ self->private_impl.f_metadata_y = 0u;
+ self->private_impl.f_metadata_z = 0u;
+ self->private_impl.f_call_sequence &= 239u;
+ status = wuffs_base__make_status(NULL);
+ goto ok;
+
+ ok:
+ self->private_impl.p_do_tell_me_more[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_tell_me_more[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_tell_me_more[0].v_zlib_status = v_zlib_status;
+
+ goto exit;
+ exit:
+ if (a_dst && a_dst->data.ptr) {
+ a_dst->meta.wi = ((size_t)(iop_a_dst - a_dst->data.ptr));
+ }
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func png.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_png__decoder__history_retain_length(
+ const wuffs_png__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func png.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_png__decoder__workbuf_len(
+ const wuffs_png__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(self->private_impl.f_overall_workbuf_length, self->private_impl.f_overall_workbuf_length);
+}
+
+// -------- func png.decoder.filter_and_swizzle
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__filter_and_swizzle(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf) {
+ return (*self->private_impl.choosy_filter_and_swizzle)(self, a_dst, a_workbuf);
+}
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__filter_and_swizzle__choosy_default(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint64_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_bytes_per_row0 = 0;
+ uint64_t v_dst_bytes_per_row1 = 0;
+ wuffs_base__slice_u8 v_dst_palette = {0};
+ wuffs_base__table_u8 v_tab = {0};
+ uint32_t v_y = 0;
+ wuffs_base__slice_u8 v_dst = {0};
+ uint8_t v_filter = 0;
+ wuffs_base__slice_u8 v_curr_row = {0};
+ wuffs_base__slice_u8 v_prev_row = {0};
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ }
+ v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
+ v_dst_bytes_per_row0 = (((uint64_t)(self->private_impl.f_frame_rect_x0)) * v_dst_bytes_per_pixel);
+ v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
+ v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ if (v_dst_bytes_per_row1 < ((uint64_t)(v_tab.width))) {
+ v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
+ 0u,
+ 0u,
+ v_dst_bytes_per_row1,
+ ((uint64_t)(v_tab.height)));
+ }
+ if (v_dst_bytes_per_row0 < ((uint64_t)(v_tab.width))) {
+ v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
+ v_dst_bytes_per_row0,
+ 0u,
+ ((uint64_t)(v_tab.width)),
+ ((uint64_t)(v_tab.height)));
+ } else {
+ v_tab = wuffs_base__table_u8__subtable_ij(v_tab,
+ 0u,
+ 0u,
+ 0u,
+ 0u);
+ }
+ v_y = self->private_impl.f_frame_rect_y0;
+ while (v_y < self->private_impl.f_frame_rect_y1) {
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
+ if (1u > ((uint64_t)(a_workbuf.len))) {
+ return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
+ }
+ v_filter = a_workbuf.ptr[0u];
+ a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u);
+ if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
+ return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
+ }
+ v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
+ a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
+ if (v_filter == 0u) {
+ } else if (v_filter == 1u) {
+ wuffs_png__decoder__filter_1(self, v_curr_row);
+ } else if (v_filter == 2u) {
+ wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
+ } else if (v_filter == 3u) {
+ wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
+ } else if (v_filter == 4u) {
+ wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
+ } else {
+ return wuffs_base__make_status(wuffs_png__error__bad_filter);
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, v_curr_row);
+ v_prev_row = v_curr_row;
+ v_y += 1u;
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func png.decoder.filter_and_swizzle_tricky
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_png__decoder__filter_and_swizzle_tricky(
+ wuffs_png__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__slice_u8 a_workbuf) {
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint64_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_bytes_per_row1 = 0;
+ wuffs_base__slice_u8 v_dst_palette = {0};
+ wuffs_base__table_u8 v_tab = {0};
+ uint64_t v_src_bytes_per_pixel = 0;
+ uint32_t v_x = 0;
+ uint32_t v_y = 0;
+ uint64_t v_i = 0;
+ wuffs_base__slice_u8 v_dst = {0};
+ uint8_t v_filter = 0;
+ wuffs_base__slice_u8 v_s = {0};
+ wuffs_base__slice_u8 v_curr_row = {0};
+ wuffs_base__slice_u8 v_prev_row = {0};
+ uint8_t v_bits_unpacked[8] = {0};
+ uint8_t v_bits_packed = 0;
+ uint8_t v_packs_remaining = 0;
+ uint8_t v_multiplier = 0;
+ uint8_t v_shift = 0;
+
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ }
+ v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
+ v_dst_bytes_per_row1 = (((uint64_t)(self->private_impl.f_frame_rect_x1)) * v_dst_bytes_per_pixel);
+ v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ v_src_bytes_per_pixel = 1u;
+ if (self->private_impl.f_depth >= 8u) {
+ v_src_bytes_per_pixel = (((uint64_t)(WUFFS_PNG__NUM_CHANNELS[self->private_impl.f_color_type])) * ((uint64_t)((self->private_impl.f_depth >> 3u))));
+ }
+ if (self->private_impl.f_chunk_type_array[0u] == 73u) {
+ v_y = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][5u]));
+ } else {
+ v_y = self->private_impl.f_frame_rect_y0;
+ }
+ while (v_y < self->private_impl.f_frame_rect_y1) {
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, v_y);
+ if (v_dst_bytes_per_row1 < ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_j(v_dst, v_dst_bytes_per_row1);
+ }
+ if (1u > ((uint64_t)(a_workbuf.len))) {
+ return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
+ }
+ v_filter = a_workbuf.ptr[0u];
+ a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, 1u);
+ if (self->private_impl.f_pass_bytes_per_row > ((uint64_t)(a_workbuf.len))) {
+ return wuffs_base__make_status(wuffs_png__error__internal_error_inconsistent_workbuf_length);
+ }
+ v_curr_row = wuffs_base__slice_u8__subslice_j(a_workbuf, self->private_impl.f_pass_bytes_per_row);
+ a_workbuf = wuffs_base__slice_u8__subslice_i(a_workbuf, self->private_impl.f_pass_bytes_per_row);
+ if (v_filter == 0u) {
+ } else if (v_filter == 1u) {
+ wuffs_png__decoder__filter_1(self, v_curr_row);
+ } else if (v_filter == 2u) {
+ wuffs_png__decoder__filter_2(self, v_curr_row, v_prev_row);
+ } else if (v_filter == 3u) {
+ wuffs_png__decoder__filter_3(self, v_curr_row, v_prev_row);
+ } else if (v_filter == 4u) {
+ wuffs_png__decoder__filter_4(self, v_curr_row, v_prev_row);
+ } else {
+ return wuffs_base__make_status(wuffs_png__error__bad_filter);
+ }
+ v_s = v_curr_row;
+ if (self->private_impl.f_chunk_type_array[0u] == 73u) {
+ v_x = ((uint32_t)(WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][2u]));
+ } else {
+ v_x = self->private_impl.f_frame_rect_x0;
+ }
+ if (self->private_impl.f_depth == 8u) {
+ while (v_x < self->private_impl.f_frame_rect_x1) {
+ v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
+ if (v_i <= ((uint64_t)(v_dst.len))) {
+ if (self->private_impl.f_color_type == 4u) {
+ if (2u <= ((uint64_t)(v_s.len))) {
+ v_bits_unpacked[0u] = v_s.ptr[0u];
+ v_bits_unpacked[1u] = v_s.ptr[0u];
+ v_bits_unpacked[2u] = v_s.ptr[0u];
+ v_bits_unpacked[3u] = v_s.ptr[1u];
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u);
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4));
+ }
+ } else if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) {
+ if (self->private_impl.f_color_type == 0u) {
+ if (1u <= ((uint64_t)(v_s.len))) {
+ v_bits_unpacked[0u] = v_s.ptr[0u];
+ v_bits_unpacked[1u] = v_s.ptr[0u];
+ v_bits_unpacked[2u] = v_s.ptr[0u];
+ v_bits_unpacked[3u] = 255u;
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
+ if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
+ (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
+ (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
+ (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
+ v_bits_unpacked[0u] = 0u;
+ v_bits_unpacked[1u] = 0u;
+ v_bits_unpacked[2u] = 0u;
+ v_bits_unpacked[3u] = 0u;
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4));
+ }
+ } else {
+ if (3u <= ((uint64_t)(v_s.len))) {
+ v_bits_unpacked[0u] = v_s.ptr[2u];
+ v_bits_unpacked[1u] = v_s.ptr[1u];
+ v_bits_unpacked[2u] = v_s.ptr[0u];
+ v_bits_unpacked[3u] = 255u;
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, 3u);
+ if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
+ (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
+ (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
+ (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
+ v_bits_unpacked[0u] = 0u;
+ v_bits_unpacked[1u] = 0u;
+ v_bits_unpacked[2u] = 0u;
+ v_bits_unpacked[3u] = 0u;
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4));
+ }
+ }
+ } else if (v_src_bytes_per_pixel <= ((uint64_t)(v_s.len))) {
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__slice_u8__subslice_j(v_s, v_src_bytes_per_pixel));
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, v_src_bytes_per_pixel);
+ }
+ }
+ v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
+ }
+ } else if (self->private_impl.f_depth < 8u) {
+ v_multiplier = 1u;
+ if (self->private_impl.f_color_type == 0u) {
+ v_multiplier = WUFFS_PNG__LOW_BIT_DEPTH_MULTIPLIERS[self->private_impl.f_depth];
+ }
+ v_shift = ((8u - self->private_impl.f_depth) & 7u);
+ v_packs_remaining = 0u;
+ while (v_x < self->private_impl.f_frame_rect_x1) {
+ v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
+ if (v_i <= ((uint64_t)(v_dst.len))) {
+ if ((v_packs_remaining == 0u) && (1u <= ((uint64_t)(v_s.len)))) {
+ v_packs_remaining = WUFFS_PNG__LOW_BIT_DEPTH_NUM_PACKS[self->private_impl.f_depth];
+ v_bits_packed = v_s.ptr[0u];
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, 1u);
+ }
+ v_bits_unpacked[0u] = ((uint8_t)((v_bits_packed >> v_shift) * v_multiplier));
+ v_bits_packed = ((uint8_t)(v_bits_packed << self->private_impl.f_depth));
+ v_packs_remaining = ((uint8_t)(v_packs_remaining - 1u));
+ if (((uint32_t)(self->private_impl.f_remap_transparency)) != 0u) {
+ v_bits_unpacked[1u] = v_bits_unpacked[0u];
+ v_bits_unpacked[2u] = v_bits_unpacked[0u];
+ v_bits_unpacked[3u] = 255u;
+ if (((uint32_t)(self->private_impl.f_remap_transparency)) == ((((uint32_t)(v_bits_unpacked[0u])) << 0u) |
+ (((uint32_t)(v_bits_unpacked[1u])) << 8u) |
+ (((uint32_t)(v_bits_unpacked[2u])) << 16u) |
+ (((uint32_t)(v_bits_unpacked[3u])) << 24u))) {
+ v_bits_unpacked[0u] = 0u;
+ v_bits_unpacked[1u] = 0u;
+ v_bits_unpacked[2u] = 0u;
+ v_bits_unpacked[3u] = 0u;
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 4));
+ } else {
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 1));
+ }
+ }
+ v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
+ }
+ } else {
+ while (v_x < self->private_impl.f_frame_rect_x1) {
+ v_i = (((uint64_t)(v_x)) * v_dst_bytes_per_pixel);
+ if (v_i <= ((uint64_t)(v_dst.len))) {
+ if (self->private_impl.f_color_type == 0u) {
+ if (2u <= ((uint64_t)(v_s.len))) {
+ v_bits_unpacked[0u] = v_s.ptr[1u];
+ v_bits_unpacked[1u] = v_s.ptr[0u];
+ v_bits_unpacked[2u] = v_s.ptr[1u];
+ v_bits_unpacked[3u] = v_s.ptr[0u];
+ v_bits_unpacked[4u] = v_s.ptr[1u];
+ v_bits_unpacked[5u] = v_s.ptr[0u];
+ v_bits_unpacked[6u] = 255u;
+ v_bits_unpacked[7u] = 255u;
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, 2u);
+ if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) |
+ (((uint64_t)(v_bits_unpacked[1u])) << 8u) |
+ (((uint64_t)(v_bits_unpacked[2u])) << 16u) |
+ (((uint64_t)(v_bits_unpacked[3u])) << 24u) |
+ (((uint64_t)(v_bits_unpacked[4u])) << 32u) |
+ (((uint64_t)(v_bits_unpacked[5u])) << 40u) |
+ (((uint64_t)(v_bits_unpacked[6u])) << 48u) |
+ (((uint64_t)(v_bits_unpacked[7u])) << 56u))) {
+ v_bits_unpacked[0u] = 0u;
+ v_bits_unpacked[1u] = 0u;
+ v_bits_unpacked[2u] = 0u;
+ v_bits_unpacked[3u] = 0u;
+ v_bits_unpacked[4u] = 0u;
+ v_bits_unpacked[5u] = 0u;
+ v_bits_unpacked[6u] = 0u;
+ v_bits_unpacked[7u] = 0u;
+ }
+ }
+ } else if (self->private_impl.f_color_type == 2u) {
+ if (6u <= ((uint64_t)(v_s.len))) {
+ v_bits_unpacked[0u] = v_s.ptr[5u];
+ v_bits_unpacked[1u] = v_s.ptr[4u];
+ v_bits_unpacked[2u] = v_s.ptr[3u];
+ v_bits_unpacked[3u] = v_s.ptr[2u];
+ v_bits_unpacked[4u] = v_s.ptr[1u];
+ v_bits_unpacked[5u] = v_s.ptr[0u];
+ v_bits_unpacked[6u] = 255u;
+ v_bits_unpacked[7u] = 255u;
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, 6u);
+ if (self->private_impl.f_remap_transparency == ((((uint64_t)(v_bits_unpacked[0u])) << 0u) |
+ (((uint64_t)(v_bits_unpacked[1u])) << 8u) |
+ (((uint64_t)(v_bits_unpacked[2u])) << 16u) |
+ (((uint64_t)(v_bits_unpacked[3u])) << 24u) |
+ (((uint64_t)(v_bits_unpacked[4u])) << 32u) |
+ (((uint64_t)(v_bits_unpacked[5u])) << 40u) |
+ (((uint64_t)(v_bits_unpacked[6u])) << 48u) |
+ (((uint64_t)(v_bits_unpacked[7u])) << 56u))) {
+ v_bits_unpacked[0u] = 0u;
+ v_bits_unpacked[1u] = 0u;
+ v_bits_unpacked[2u] = 0u;
+ v_bits_unpacked[3u] = 0u;
+ v_bits_unpacked[4u] = 0u;
+ v_bits_unpacked[5u] = 0u;
+ v_bits_unpacked[6u] = 0u;
+ v_bits_unpacked[7u] = 0u;
+ }
+ }
+ } else if (self->private_impl.f_color_type == 4u) {
+ if (4u <= ((uint64_t)(v_s.len))) {
+ v_bits_unpacked[0u] = v_s.ptr[1u];
+ v_bits_unpacked[1u] = v_s.ptr[0u];
+ v_bits_unpacked[2u] = v_s.ptr[1u];
+ v_bits_unpacked[3u] = v_s.ptr[0u];
+ v_bits_unpacked[4u] = v_s.ptr[1u];
+ v_bits_unpacked[5u] = v_s.ptr[0u];
+ v_bits_unpacked[6u] = v_s.ptr[3u];
+ v_bits_unpacked[7u] = v_s.ptr[2u];
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, 4u);
+ }
+ } else {
+ if (8u <= ((uint64_t)(v_s.len))) {
+ v_bits_unpacked[0u] = v_s.ptr[5u];
+ v_bits_unpacked[1u] = v_s.ptr[4u];
+ v_bits_unpacked[2u] = v_s.ptr[3u];
+ v_bits_unpacked[3u] = v_s.ptr[2u];
+ v_bits_unpacked[4u] = v_s.ptr[1u];
+ v_bits_unpacked[5u] = v_s.ptr[0u];
+ v_bits_unpacked[6u] = v_s.ptr[7u];
+ v_bits_unpacked[7u] = v_s.ptr[6u];
+ v_s = wuffs_base__slice_u8__subslice_i(v_s, 8u);
+ }
+ }
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, wuffs_base__slice_u8__subslice_i(v_dst, v_i), v_dst_palette, wuffs_base__make_slice_u8(v_bits_unpacked, 8));
+ }
+ v_x += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][0u]);
+ }
+ }
+ v_prev_row = v_curr_row;
+ v_y += (((uint32_t)(1u)) << WUFFS_PNG__INTERLACING[self->private_impl.f_interlace_pass][3u]);
+ }
+ return wuffs_base__make_status(NULL);
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_tga__error__bad_header[] = "#tga: bad header";
+const char wuffs_tga__error__bad_run_length_encoding[] = "#tga: bad run length encoding";
+const char wuffs_tga__error__truncated_input[] = "#tga: truncated input";
+const char wuffs_tga__error__unsupported_tga_file[] = "#tga: unsupported TGA file";
+
+// ---------------- Private Consts
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_tga__decoder__do_decode_image_config(
+ wuffs_tga__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_tga__decoder__do_decode_frame_config(
+ wuffs_tga__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_tga__decoder__do_decode_frame(
+ wuffs_tga__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+// ---------------- VTables
+
+const wuffs_base__image_decoder__func_ptrs
+wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__pixel_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
+ wuffs_base__slice_u8,
+ wuffs_base__decode_frame_options*))(&wuffs_tga__decoder__decode_frame),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__frame_config*,
+ wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_frame_config),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__image_config*,
+ wuffs_base__io_buffer*))(&wuffs_tga__decoder__decode_image_config),
+ (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_tga__decoder__frame_dirty_rect),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_tga__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_tga__decoder__history_retain_length),
+ (uint32_t(*)(const void*))(&wuffs_tga__decoder__num_animation_loops),
+ (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frame_configs),
+ (uint64_t(*)(const void*))(&wuffs_tga__decoder__num_decoded_frames),
+ (wuffs_base__status(*)(void*,
+ uint64_t,
+ uint64_t))(&wuffs_tga__decoder__restart_frame),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_tga__decoder__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ uint32_t,
+ bool))(&wuffs_tga__decoder__set_report_metadata),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*))(&wuffs_tga__decoder__tell_me_more),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_tga__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_tga__decoder__initialize(
+ wuffs_tga__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
+ wuffs_base__image_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
+ (const void*)(&wuffs_tga__decoder__func_ptrs_for__wuffs_base__image_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_tga__decoder*
+wuffs_tga__decoder__alloc(void) {
+ wuffs_tga__decoder* x =
+ (wuffs_tga__decoder*)(calloc(sizeof(wuffs_tga__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_tga__decoder__initialize(
+ x, sizeof(wuffs_tga__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_tga__decoder(void) {
+ return sizeof(wuffs_tga__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func tga.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_tga__decoder__get_quirk(
+ const wuffs_tga__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func tga.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__set_quirk(
+ wuffs_tga__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func tga.decoder.decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__decode_image_config(
+ wuffs_tga__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_image_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func tga.decoder.do_decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_tga__decoder__do_decode_image_config(
+ wuffs_tga__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint32_t v_c = 0;
+ uint32_t v_c5 = 0;
+ uint32_t v_i = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_do_decode_image_config[0].v_i;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ self->private_impl.f_header_id_length = t_0;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ self->private_impl.f_header_color_map_type = t_1;
+ }
+ if (self->private_impl.f_header_color_map_type > 1u) {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(3);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_2 = *iop_a_src++;
+ self->private_impl.f_header_image_type = t_2;
+ }
+ if ((self->private_impl.f_header_image_type == 1u) ||
+ (self->private_impl.f_header_image_type == 2u) ||
+ (self->private_impl.f_header_image_type == 3u) ||
+ (self->private_impl.f_header_image_type == 9u) ||
+ (self->private_impl.f_header_image_type == 10u) ||
+ (self->private_impl.f_header_image_type == 11u)) {
+ } else {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_header);
+ goto exit;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(4);
+ uint16_t t_3;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_3 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(5);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_3 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_3;
+ if (num_bits_3 == 8) {
+ t_3 = ((uint16_t)(*scratch));
+ break;
+ }
+ num_bits_3 += 8u;
+ *scratch |= ((uint64_t)(num_bits_3)) << 56;
+ }
+ }
+ self->private_impl.f_header_color_map_first_entry_index = t_3;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(6);
+ uint16_t t_4;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_4 = wuffs_base__peek_u16le__no_bounds_check(iop_a_src);
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(7);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_4 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_4;
+ if (num_bits_4 == 8) {
+ t_4 = ((uint16_t)(*scratch));
+ break;
+ }
+ num_bits_4 += 8u;
+ *scratch |= ((uint64_t)(num_bits_4)) << 56;
+ }
+ }
+ self->private_impl.f_header_color_map_length = t_4;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(8);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_5 = *iop_a_src++;
+ self->private_impl.f_header_color_map_entry_size = t_5;
+ }
+ if (self->private_impl.f_header_color_map_type != 0u) {
+ if ((self->private_impl.f_header_color_map_first_entry_index != 0u) || (self->private_impl.f_header_color_map_length > 256u)) {
+ status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
+ goto exit;
+ } else if ((self->private_impl.f_header_color_map_entry_size != 15u) &&
+ (self->private_impl.f_header_color_map_entry_size != 16u) &&
+ (self->private_impl.f_header_color_map_entry_size != 24u) &&
+ (self->private_impl.f_header_color_map_entry_size != 32u)) {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_header);
+ goto exit;
+ }
+ } else {
+ if ((self->private_impl.f_header_color_map_first_entry_index != 0u) || (self->private_impl.f_header_color_map_length != 0u) || (self->private_impl.f_header_color_map_entry_size != 0u)) {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_header);
+ goto exit;
+ }
+ }
+ self->private_data.s_do_decode_image_config[0].scratch = 4u;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(9);
+ if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(10);
+ uint32_t t_6;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_6 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(11);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_6 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_6;
+ if (num_bits_6 == 8) {
+ t_6 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_6 += 8u;
+ *scratch |= ((uint64_t)(num_bits_6)) << 56;
+ }
+ }
+ self->private_impl.f_width = t_6;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(12);
+ uint32_t t_7;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_7 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(13);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_7 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_7;
+ if (num_bits_7 == 8) {
+ t_7 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_7 += 8u;
+ *scratch |= ((uint64_t)(num_bits_7)) << 56;
+ }
+ }
+ self->private_impl.f_height = t_7;
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(14);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_8 = *iop_a_src++;
+ self->private_impl.f_header_pixel_depth = t_8;
+ }
+ if ((self->private_impl.f_header_pixel_depth != 1u) &&
+ (self->private_impl.f_header_pixel_depth != 8u) &&
+ (self->private_impl.f_header_pixel_depth != 15u) &&
+ (self->private_impl.f_header_pixel_depth != 16u) &&
+ (self->private_impl.f_header_pixel_depth != 24u) &&
+ (self->private_impl.f_header_pixel_depth != 32u)) {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_header);
+ goto exit;
+ }
+ if ((self->private_impl.f_header_image_type | 8u) == 9u) {
+ self->private_impl.f_scratch_bytes_per_pixel = 1u;
+ self->private_impl.f_src_bytes_per_pixel = 1u;
+ self->private_impl.f_src_pixfmt = 2164523016u;
+ self->private_impl.f_opaque = ((self->private_impl.f_header_color_map_entry_size == 15u) || (self->private_impl.f_header_color_map_entry_size == 24u));
+ } else if ((self->private_impl.f_header_image_type | 8u) == 10u) {
+ if ((self->private_impl.f_header_pixel_depth == 15u) || (self->private_impl.f_header_pixel_depth == 16u)) {
+ self->private_impl.f_scratch_bytes_per_pixel = 4u;
+ self->private_impl.f_src_bytes_per_pixel = 0u;
+ self->private_impl.f_src_pixfmt = 2164295816u;
+ } else if (self->private_impl.f_header_pixel_depth == 24u) {
+ self->private_impl.f_scratch_bytes_per_pixel = 3u;
+ self->private_impl.f_src_bytes_per_pixel = 3u;
+ self->private_impl.f_src_pixfmt = 2147485832u;
+ self->private_impl.f_opaque = true;
+ } else if (self->private_impl.f_header_pixel_depth == 32u) {
+ self->private_impl.f_scratch_bytes_per_pixel = 4u;
+ self->private_impl.f_src_bytes_per_pixel = 4u;
+ self->private_impl.f_src_pixfmt = 2164295816u;
+ } else {
+ status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
+ goto exit;
+ }
+ } else {
+ if (self->private_impl.f_header_pixel_depth == 8u) {
+ self->private_impl.f_scratch_bytes_per_pixel = 1u;
+ self->private_impl.f_src_bytes_per_pixel = 1u;
+ self->private_impl.f_src_pixfmt = 536870920u;
+ self->private_impl.f_opaque = true;
+ } else {
+ status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
+ goto exit;
+ }
+ }
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(15);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_9 = *iop_a_src++;
+ self->private_impl.f_header_image_descriptor = t_9;
+ }
+ if ((self->private_impl.f_header_image_descriptor & 16u) != 0u) {
+ status = wuffs_base__make_status(wuffs_tga__error__unsupported_tga_file);
+ goto exit;
+ }
+ self->private_data.s_do_decode_image_config[0].scratch = ((uint32_t)(self->private_impl.f_header_id_length));
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(16);
+ if (self->private_data.s_do_decode_image_config[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_image_config[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_image_config[0].scratch;
+ if (self->private_impl.f_header_color_map_type != 0u) {
+ while (v_i < ((uint32_t)(self->private_impl.f_header_color_map_length))) {
+ if (self->private_impl.f_header_color_map_entry_size == 24u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(17);
+ uint32_t t_10;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 3)) {
+ t_10 = ((uint32_t)(wuffs_base__peek_u24le__no_bounds_check(iop_a_src)));
+ iop_a_src += 3;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(18);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_10 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_10;
+ if (num_bits_10 == 16) {
+ t_10 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_10 += 8u;
+ *scratch |= ((uint64_t)(num_bits_10)) << 56;
+ }
+ }
+ v_c = t_10;
+ }
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c >> 0u)));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c >> 8u)));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c >> 16u)));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u;
+ } else if (self->private_impl.f_header_color_map_entry_size == 32u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(19);
+ uint32_t t_11;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 4)) {
+ t_11 = wuffs_base__peek_u32le__no_bounds_check(iop_a_src);
+ iop_a_src += 4;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(20);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_11 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_11;
+ if (num_bits_11 == 24) {
+ t_11 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_11 += 8u;
+ *scratch |= ((uint64_t)(num_bits_11)) << 56;
+ }
+ }
+ v_c = t_11;
+ }
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)((v_c >> 0u)));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)((v_c >> 8u)));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)((v_c >> 16u)));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = ((uint8_t)((v_c >> 24u)));
+ } else {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(21);
+ uint32_t t_12;
+ if (WUFFS_BASE__LIKELY(io2_a_src - iop_a_src >= 2)) {
+ t_12 = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2;
+ } else {
+ self->private_data.s_do_decode_image_config[0].scratch = 0;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(22);
+ while (true) {
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint64_t* scratch = &self->private_data.s_do_decode_image_config[0].scratch;
+ uint32_t num_bits_12 = ((uint32_t)(*scratch >> 56));
+ *scratch <<= 8;
+ *scratch >>= 8;
+ *scratch |= ((uint64_t)(*iop_a_src++)) << num_bits_12;
+ if (num_bits_12 == 8) {
+ t_12 = ((uint32_t)(*scratch));
+ break;
+ }
+ num_bits_12 += 8u;
+ *scratch |= ((uint64_t)(num_bits_12)) << 56;
+ }
+ }
+ v_c = t_12;
+ }
+ v_c5 = (31u & (v_c >> 0u));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 0u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ v_c5 = (31u & (v_c >> 5u));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 1u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ v_c5 = (31u & (v_c >> 10u));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 2u)] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ self->private_data.f_src_palette[(((v_i & 255u) * 4u) + 3u)] = 255u;
+ }
+ v_i += 1u;
+ }
+ while (v_i < 256u) {
+ self->private_data.f_src_palette[((v_i * 4u) + 0u)] = 0u;
+ self->private_data.f_src_palette[((v_i * 4u) + 1u)] = 0u;
+ self->private_data.f_src_palette[((v_i * 4u) + 2u)] = 0u;
+ self->private_data.f_src_palette[((v_i * 4u) + 3u)] = 255u;
+ v_i += 1u;
+ }
+ }
+ self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ if (a_dst != NULL) {
+ wuffs_base__image_config__set(
+ a_dst,
+ self->private_impl.f_src_pixfmt,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ self->private_impl.f_frame_config_io_position,
+ self->private_impl.f_opaque);
+ }
+ self->private_impl.f_call_sequence = 32u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_do_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_decode_image_config[0].v_i = v_i;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func tga.decoder.decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__decode_frame_config(
+ wuffs_tga__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 2)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func tga.decoder.do_decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_tga__decoder__do_decode_frame_config(
+ wuffs_tga__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 32u) {
+ } else if (self->private_impl.f_call_sequence < 32u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_tga__decoder__do_decode_image_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (self->private_impl.f_call_sequence == 40u) {
+ if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_restart);
+ goto exit;
+ }
+ } else if (self->private_impl.f_call_sequence == 64u) {
+ self->private_impl.f_call_sequence = 96u;
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (a_dst != NULL) {
+ wuffs_base__frame_config__set(
+ a_dst,
+ wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height),
+ ((wuffs_base__flicks)(0u)),
+ 0u,
+ self->private_impl.f_frame_config_io_position,
+ 0u,
+ self->private_impl.f_opaque,
+ false,
+ 4278190080u);
+ }
+ self->private_impl.f_call_sequence = 64u;
+
+ ok:
+ self->private_impl.p_do_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func tga.decoder.decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__decode_frame(
+ wuffs_tga__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 3)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_tga__decoder__do_decode_frame(self,
+ a_dst,
+ a_src,
+ a_blend,
+ a_workbuf,
+ a_opts);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_tga__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func tga.decoder.do_decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_tga__decoder__do_decode_frame(
+ wuffs_tga__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint64_t v_dst_bytes_per_pixel = 0;
+ uint32_t v_dst_x = 0;
+ uint32_t v_dst_y = 0;
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_dst_palette = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint64_t v_dst_start = 0;
+ wuffs_base__slice_u8 v_src_palette = {0};
+ uint64_t v_mark = 0;
+ uint64_t v_num_pixels64 = 0;
+ uint32_t v_num_pixels32 = 0;
+ uint32_t v_lit_length = 0;
+ uint32_t v_run_length = 0;
+ uint64_t v_num_dst_bytes = 0;
+ uint32_t v_num_src_bytes = 0;
+ uint32_t v_c = 0;
+ uint32_t v_c5 = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
+ if (coro_susp_point) {
+ v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel;
+ v_dst_x = self->private_data.s_do_decode_frame[0].v_dst_x;
+ v_dst_y = self->private_data.s_do_decode_frame[0].v_dst_y;
+ v_mark = self->private_data.s_do_decode_frame[0].v_mark;
+ v_num_pixels32 = self->private_data.s_do_decode_frame[0].v_num_pixels32;
+ v_lit_length = self->private_data.s_do_decode_frame[0].v_lit_length;
+ v_run_length = self->private_data.s_do_decode_frame[0].v_run_length;
+ v_num_dst_bytes = self->private_data.s_do_decode_frame[0].v_num_dst_bytes;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 64u) {
+ } else if (self->private_impl.f_call_sequence < 64u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_tga__decoder__do_decode_frame_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (self->private_impl.f_header_color_map_type != 0u) {
+ v_src_palette = wuffs_base__make_slice_u8(self->private_data.f_src_palette, 1024);
+ }
+ v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
+ wuffs_base__pixel_buffer__pixel_format(a_dst),
+ wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024)),
+ wuffs_base__utility__make_pixel_format(self->private_impl.f_src_pixfmt),
+ v_src_palette,
+ a_blend);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ goto exit;
+ }
+ v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
+ if ((self->private_impl.f_header_image_descriptor & 32u) == 0u) {
+ v_dst_y = ((uint32_t)(self->private_impl.f_height - 1u));
+ }
+ if ((self->private_impl.f_header_image_type & 8u) == 0u) {
+ v_lit_length = self->private_impl.f_width;
+ }
+ label__resume__continue:;
+ while (true) {
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ v_dst_palette = wuffs_base__pixel_buffer__palette_or_else(a_dst, wuffs_base__make_slice_u8(self->private_data.f_dst_palette, 1024));
+ while (v_dst_y < self->private_impl.f_height) {
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
+ v_dst_start = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
+ if (v_dst_start <= ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_start);
+ } else {
+ v_dst = wuffs_base__utility__empty_slice_u8();
+ }
+ while (v_dst_x < self->private_impl.f_width) {
+ if (self->private_impl.f_src_bytes_per_pixel > 0u) {
+ if (v_lit_length > 0u) {
+ v_mark = ((uint64_t)(iop_a_src - io0_a_src));
+ v_num_pixels64 = (((uint64_t)(io2_a_src - iop_a_src)) / ((uint64_t)(self->private_impl.f_src_bytes_per_pixel)));
+ v_num_pixels32 = ((uint32_t)(wuffs_base__u64__min(v_num_pixels64, ((uint64_t)(v_lit_length)))));
+ v_num_dst_bytes = (((uint64_t)(v_num_pixels32)) * v_dst_bytes_per_pixel);
+ v_num_src_bytes = (v_num_pixels32 * self->private_impl.f_src_bytes_per_pixel);
+ self->private_data.s_do_decode_frame[0].scratch = v_num_src_bytes;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (self->private_data.s_do_decode_frame[0].scratch > ((uint64_t)(io2_a_src - iop_a_src))) {
+ self->private_data.s_do_decode_frame[0].scratch -= ((uint64_t)(io2_a_src - iop_a_src));
+ iop_a_src = io2_a_src;
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ iop_a_src += self->private_data.s_do_decode_frame[0].scratch;
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__io__since(v_mark, ((uint64_t)(iop_a_src - io0_a_src)), io0_a_src));
+ if (v_num_dst_bytes <= ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_num_dst_bytes);
+ } else {
+ v_dst = wuffs_base__utility__empty_slice_u8();
+ }
+ v_dst_x += v_num_pixels32;
+ v_lit_length = (((uint32_t)(v_lit_length - v_num_pixels32)) & 65535u);
+ if (v_lit_length > 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(3);
+ goto label__resume__continue;
+ }
+ } else if (v_run_length > 0u) {
+ v_run_length -= 1u;
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_scratch_bytes_per_pixel));
+ if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
+ }
+ v_dst_x += 1u;
+ } else {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(4);
+ goto label__resume__continue;
+ }
+ if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) {
+ v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u);
+ iop_a_src += 1u;
+ if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
+ goto exit;
+ }
+ } else {
+ if (self->private_impl.f_src_bytes_per_pixel == 1u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(5);
+ goto label__resume__continue;
+ }
+ v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
+ iop_a_src += 1u;
+ self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ } else if (self->private_impl.f_src_bytes_per_pixel == 3u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 4u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(6);
+ goto label__resume__continue;
+ }
+ v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
+ iop_a_src += 1u;
+ self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ } else {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 5u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(7);
+ goto label__resume__continue;
+ }
+ v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
+ iop_a_src += 1u;
+ self->private_data.f_scratch[0u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ self->private_data.f_scratch[1u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ self->private_data.f_scratch[2u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ self->private_data.f_scratch[3u] = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ }
+ if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
+ goto exit;
+ }
+ }
+ }
+ } else {
+ if (v_lit_length > 0u) {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 2u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(8);
+ goto label__resume__continue;
+ }
+ v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2u;
+ v_c5 = (31u & (v_c >> 0u));
+ self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ v_c5 = (31u & (v_c >> 5u));
+ self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ v_c5 = (31u & (v_c >> 10u));
+ self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ self->private_data.f_scratch[3u] = 255u;
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, 4));
+ if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
+ }
+ v_dst_x += 1u;
+ v_lit_length -= 1u;
+ } else if (v_run_length > 0u) {
+ v_run_length -= 1u;
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, v_dst_palette, wuffs_base__make_slice_u8(self->private_data.f_scratch, self->private_impl.f_scratch_bytes_per_pixel));
+ if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
+ }
+ v_dst_x += 1u;
+ } else {
+ if (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(9);
+ goto label__resume__continue;
+ }
+ if (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) < 128u) {
+ v_lit_length = (((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) + 1u);
+ iop_a_src += 1u;
+ if ((v_lit_length + v_dst_x) > self->private_impl.f_width) {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
+ goto exit;
+ }
+ } else {
+ if (((uint64_t)(io2_a_src - iop_a_src)) < 3u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(10);
+ goto label__resume__continue;
+ }
+ v_run_length = ((((uint32_t)(wuffs_base__peek_u8be__no_bounds_check(iop_a_src))) & 127u) + 1u);
+ iop_a_src += 1u;
+ v_c = ((uint32_t)(wuffs_base__peek_u16le__no_bounds_check(iop_a_src)));
+ iop_a_src += 2u;
+ v_c5 = (31u & (v_c >> 0u));
+ self->private_data.f_scratch[0u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ v_c5 = (31u & (v_c >> 5u));
+ self->private_data.f_scratch[1u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ v_c5 = (31u & (v_c >> 10u));
+ self->private_data.f_scratch[2u] = ((uint8_t)(((v_c5 << 3u) | (v_c5 >> 2u))));
+ self->private_data.f_scratch[3u] = 255u;
+ if ((v_run_length + v_dst_x) > self->private_impl.f_width) {
+ status = wuffs_base__make_status(wuffs_tga__error__bad_run_length_encoding);
+ goto exit;
+ }
+ }
+ }
+ }
+ }
+ v_dst_x = 0u;
+ if ((self->private_impl.f_header_image_descriptor & 32u) == 0u) {
+ v_dst_y -= 1u;
+ } else {
+ v_dst_y += 1u;
+ }
+ if ((self->private_impl.f_header_image_type & 8u) == 0u) {
+ v_lit_length = self->private_impl.f_width;
+ }
+ }
+ break;
+ }
+ self->private_impl.f_call_sequence = 96u;
+
+ ok:
+ self->private_impl.p_do_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
+ self->private_data.s_do_decode_frame[0].v_dst_x = v_dst_x;
+ self->private_data.s_do_decode_frame[0].v_dst_y = v_dst_y;
+ self->private_data.s_do_decode_frame[0].v_mark = v_mark;
+ self->private_data.s_do_decode_frame[0].v_num_pixels32 = v_num_pixels32;
+ self->private_data.s_do_decode_frame[0].v_lit_length = v_lit_length;
+ self->private_data.s_do_decode_frame[0].v_run_length = v_run_length;
+ self->private_data.s_do_decode_frame[0].v_num_dst_bytes = v_num_dst_bytes;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func tga.decoder.frame_dirty_rect
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_tga__decoder__frame_dirty_rect(
+ const wuffs_tga__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ return wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height);
+}
+
+// -------- func tga.decoder.num_animation_loops
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_tga__decoder__num_animation_loops(
+ const wuffs_tga__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func tga.decoder.num_decoded_frame_configs
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_tga__decoder__num_decoded_frame_configs(
+ const wuffs_tga__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 32u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func tga.decoder.num_decoded_frames
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_tga__decoder__num_decoded_frames(
+ const wuffs_tga__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 64u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func tga.decoder.restart_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__restart_frame(
+ wuffs_tga__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (self->private_impl.f_call_sequence < 32u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ }
+ if (a_index != 0u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_call_sequence = 40u;
+ self->private_impl.f_frame_config_io_position = a_io_position;
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func tga.decoder.set_report_metadata
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_tga__decoder__set_report_metadata(
+ wuffs_tga__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func tga.decoder.tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_tga__decoder__tell_me_more(
+ wuffs_tga__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 4)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ status = wuffs_base__make_status(wuffs_base__error__no_more_information);
+ goto exit;
+
+ goto ok;
+ ok:
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func tga.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_tga__decoder__history_retain_length(
+ const wuffs_tga__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func tga.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_tga__decoder__workbuf_len(
+ const wuffs_tga__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(0u, 0u);
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
+
+// ---------------- Status Codes Implementations
+
+const char wuffs_wbmp__error__bad_header[] = "#wbmp: bad header";
+const char wuffs_wbmp__error__truncated_input[] = "#wbmp: truncated input";
+
+// ---------------- Private Consts
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_wbmp__decoder__do_decode_image_config(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_wbmp__decoder__do_decode_frame_config(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src);
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_wbmp__decoder__do_decode_frame(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts);
+
+// ---------------- VTables
+
+const wuffs_base__image_decoder__func_ptrs
+wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder = {
+ (wuffs_base__status(*)(void*,
+ wuffs_base__pixel_buffer*,
+ wuffs_base__io_buffer*,
+ wuffs_base__pixel_blend,
+ wuffs_base__slice_u8,
+ wuffs_base__decode_frame_options*))(&wuffs_wbmp__decoder__decode_frame),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__frame_config*,
+ wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_frame_config),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__image_config*,
+ wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__decode_image_config),
+ (wuffs_base__rect_ie_u32(*)(const void*))(&wuffs_wbmp__decoder__frame_dirty_rect),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_wbmp__decoder__get_quirk),
+ (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__history_retain_length),
+ (uint32_t(*)(const void*))(&wuffs_wbmp__decoder__num_animation_loops),
+ (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frame_configs),
+ (uint64_t(*)(const void*))(&wuffs_wbmp__decoder__num_decoded_frames),
+ (wuffs_base__status(*)(void*,
+ uint64_t,
+ uint64_t))(&wuffs_wbmp__decoder__restart_frame),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_wbmp__decoder__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ uint32_t,
+ bool))(&wuffs_wbmp__decoder__set_report_metadata),
+ (wuffs_base__status(*)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*))(&wuffs_wbmp__decoder__tell_me_more),
+ (wuffs_base__range_ii_u64(*)(const void*))(&wuffs_wbmp__decoder__workbuf_len),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_wbmp__decoder__initialize(
+ wuffs_wbmp__decoder* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.vtable_name =
+ wuffs_base__image_decoder__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__image_decoder.function_pointers =
+ (const void*)(&wuffs_wbmp__decoder__func_ptrs_for__wuffs_base__image_decoder);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_wbmp__decoder*
+wuffs_wbmp__decoder__alloc(void) {
+ wuffs_wbmp__decoder* x =
+ (wuffs_wbmp__decoder*)(calloc(sizeof(wuffs_wbmp__decoder), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_wbmp__decoder__initialize(
+ x, sizeof(wuffs_wbmp__decoder), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_wbmp__decoder(void) {
+ return sizeof(wuffs_wbmp__decoder);
+}
+
+// ---------------- Function Implementations
+
+// -------- func wbmp.decoder.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_wbmp__decoder__get_quirk(
+ const wuffs_wbmp__decoder* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func wbmp.decoder.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__set_quirk(
+ wuffs_wbmp__decoder* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func wbmp.decoder.decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__decode_image_config(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 1)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_image_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_image_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 1 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func wbmp.decoder.do_decode_image_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_wbmp__decoder__do_decode_image_config(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__image_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ uint8_t v_c = 0;
+ uint32_t v_i = 0;
+ uint32_t v_p = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_image_config[0];
+ if (coro_susp_point) {
+ v_i = self->private_data.s_do_decode_image_config[0].v_i;
+ v_p = self->private_data.s_do_decode_image_config[0].v_p;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ goto exit;
+ }
+ v_i = 0u;
+ while (v_i < 2u) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_0 = *iop_a_src++;
+ v_c = t_0;
+ }
+ if (v_c != 0u) {
+ status = wuffs_base__make_status(wuffs_wbmp__error__bad_header);
+ goto exit;
+ }
+ v_i += 1u;
+ }
+ v_i = 0u;
+ while (v_i < 2u) {
+ v_p = 0u;
+ while (true) {
+ {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(2);
+ if (WUFFS_BASE__UNLIKELY(iop_a_src == io2_a_src)) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ goto suspend;
+ }
+ uint8_t t_1 = *iop_a_src++;
+ v_c = t_1;
+ }
+ v_p |= ((uint32_t)((v_c & 127u)));
+ if ((v_c >> 7u) == 0u) {
+ break;
+ } else if (v_p > 131071u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_image_dimension);
+ goto exit;
+ }
+ v_p <<= 7u;
+ }
+ if (v_i == 0u) {
+ self->private_impl.f_width = v_p;
+ } else {
+ self->private_impl.f_height = v_p;
+ }
+ v_i += 1u;
+ }
+ self->private_impl.f_frame_config_io_position = wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)));
+ if (a_dst != NULL) {
+ wuffs_base__image_config__set(
+ a_dst,
+ 2198077448u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height,
+ self->private_impl.f_frame_config_io_position,
+ true);
+ }
+ self->private_impl.f_call_sequence = 32u;
+
+ goto ok;
+ ok:
+ self->private_impl.p_do_decode_image_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_image_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_decode_image_config[0].v_i = v_i;
+ self->private_data.s_do_decode_image_config[0].v_p = v_p;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func wbmp.decoder.decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__decode_frame_config(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 2)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame_config(self, a_dst, a_src);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 2 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func wbmp.decoder.do_decode_frame_config
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_wbmp__decoder__do_decode_frame_config(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__frame_config* a_dst,
+ wuffs_base__io_buffer* a_src) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame_config[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 32u) {
+ } else if (self->private_impl.f_call_sequence < 32u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_wbmp__decoder__do_decode_image_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else if (self->private_impl.f_call_sequence == 40u) {
+ if (self->private_impl.f_frame_config_io_position != wuffs_base__u64__sat_add((a_src ? a_src->meta.pos : 0), ((uint64_t)(iop_a_src - io0_a_src)))) {
+ status = wuffs_base__make_status(wuffs_base__error__bad_restart);
+ goto exit;
+ }
+ } else if (self->private_impl.f_call_sequence == 64u) {
+ self->private_impl.f_call_sequence = 96u;
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ if (a_dst != NULL) {
+ wuffs_base__frame_config__set(
+ a_dst,
+ wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height),
+ ((wuffs_base__flicks)(0u)),
+ 0u,
+ self->private_impl.f_frame_config_io_position,
+ 0u,
+ true,
+ false,
+ 4278190080u);
+ }
+ self->private_impl.f_call_sequence = 64u;
+
+ ok:
+ self->private_impl.p_do_decode_frame_config[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame_config[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func wbmp.decoder.decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__decode_frame(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 3)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+
+ uint32_t coro_susp_point = self->private_impl.p_decode_frame[0];
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ while (true) {
+ {
+ wuffs_base__status t_0 = wuffs_wbmp__decoder__do_decode_frame(self,
+ a_dst,
+ a_src,
+ a_blend,
+ a_workbuf,
+ a_opts);
+ v_status = t_0;
+ }
+ if ((v_status.repr == wuffs_base__suspension__short_read) && (a_src && a_src->meta.closed)) {
+ status = wuffs_base__make_status(wuffs_wbmp__error__truncated_input);
+ goto exit;
+ }
+ status = v_status;
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(1);
+ }
+
+ ok:
+ self->private_impl.p_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_impl.active_coroutine = wuffs_base__status__is_suspension(&status) ? 3 : 0;
+
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func wbmp.decoder.do_decode_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__status
+wuffs_wbmp__decoder__do_decode_frame(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__pixel_buffer* a_dst,
+ wuffs_base__io_buffer* a_src,
+ wuffs_base__pixel_blend a_blend,
+ wuffs_base__slice_u8 a_workbuf,
+ wuffs_base__decode_frame_options* a_opts) {
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ wuffs_base__status v_status = wuffs_base__make_status(NULL);
+ wuffs_base__pixel_format v_dst_pixfmt = {0};
+ uint32_t v_dst_bits_per_pixel = 0;
+ uint64_t v_dst_bytes_per_pixel = 0;
+ uint64_t v_dst_x_in_bytes = 0;
+ uint32_t v_dst_x = 0;
+ uint32_t v_dst_y = 0;
+ wuffs_base__table_u8 v_tab = {0};
+ wuffs_base__slice_u8 v_dst = {0};
+ uint8_t v_src[1] = {0};
+ uint8_t v_c = 0;
+
+ const uint8_t* iop_a_src = NULL;
+ const uint8_t* io0_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io1_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ const uint8_t* io2_a_src WUFFS_BASE__POTENTIALLY_UNUSED = NULL;
+ if (a_src && a_src->data.ptr) {
+ io0_a_src = a_src->data.ptr;
+ io1_a_src = io0_a_src + a_src->meta.ri;
+ iop_a_src = io1_a_src;
+ io2_a_src = io0_a_src + a_src->meta.wi;
+ }
+
+ uint32_t coro_susp_point = self->private_impl.p_do_decode_frame[0];
+ if (coro_susp_point) {
+ v_dst_bytes_per_pixel = self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel;
+ v_dst_x = self->private_data.s_do_decode_frame[0].v_dst_x;
+ v_dst_y = self->private_data.s_do_decode_frame[0].v_dst_y;
+ memcpy(v_src, self->private_data.s_do_decode_frame[0].v_src, sizeof(v_src));
+ v_c = self->private_data.s_do_decode_frame[0].v_c;
+ }
+ switch (coro_susp_point) {
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_0;
+
+ if (self->private_impl.f_call_sequence == 64u) {
+ } else if (self->private_impl.f_call_sequence < 64u) {
+ if (a_src) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT(1);
+ status = wuffs_wbmp__decoder__do_decode_frame_config(self, NULL, a_src);
+ if (a_src) {
+ iop_a_src = a_src->data.ptr + a_src->meta.ri;
+ }
+ if (status.repr) {
+ goto suspend;
+ }
+ } else {
+ status = wuffs_base__make_status(wuffs_base__note__end_of_data);
+ goto ok;
+ }
+ v_status = wuffs_base__pixel_swizzler__prepare(&self->private_impl.f_swizzler,
+ wuffs_base__pixel_buffer__pixel_format(a_dst),
+ wuffs_base__pixel_buffer__palette(a_dst),
+ wuffs_base__utility__make_pixel_format(536870920u),
+ wuffs_base__utility__empty_slice_u8(),
+ a_blend);
+ if ( ! wuffs_base__status__is_ok(&v_status)) {
+ status = v_status;
+ if (wuffs_base__status__is_error(&status)) {
+ goto exit;
+ } else if (wuffs_base__status__is_suspension(&status)) {
+ status = wuffs_base__make_status(wuffs_base__error__cannot_return_a_suspension);
+ goto exit;
+ }
+ goto ok;
+ }
+ v_dst_pixfmt = wuffs_base__pixel_buffer__pixel_format(a_dst);
+ v_dst_bits_per_pixel = wuffs_base__pixel_format__bits_per_pixel(&v_dst_pixfmt);
+ if ((v_dst_bits_per_pixel & 7u) != 0u) {
+ status = wuffs_base__make_status(wuffs_base__error__unsupported_option);
+ goto exit;
+ }
+ v_dst_bytes_per_pixel = ((uint64_t)((v_dst_bits_per_pixel / 8u)));
+ if (self->private_impl.f_width > 0u) {
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ while (v_dst_y < self->private_impl.f_height) {
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
+ v_dst_x = 0u;
+ while (v_dst_x < self->private_impl.f_width) {
+ if ((v_dst_x & 7u) == 0u) {
+ while (((uint64_t)(io2_a_src - iop_a_src)) <= 0u) {
+ status = wuffs_base__make_status(wuffs_base__suspension__short_read);
+ WUFFS_BASE__COROUTINE_SUSPENSION_POINT_MAYBE_SUSPEND(2);
+ v_tab = wuffs_base__pixel_buffer__plane(a_dst, 0u);
+ v_dst = wuffs_base__table_u8__row_u32(v_tab, v_dst_y);
+ v_dst_x_in_bytes = (((uint64_t)(v_dst_x)) * v_dst_bytes_per_pixel);
+ if (v_dst_x_in_bytes <= ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_x_in_bytes);
+ }
+ }
+ v_c = wuffs_base__peek_u8be__no_bounds_check(iop_a_src);
+ iop_a_src += 1u;
+ }
+ if ((v_c & 128u) == 0u) {
+ v_src[0u] = 0u;
+ } else {
+ v_src[0u] = 255u;
+ }
+ v_c = ((uint8_t)((((uint32_t)(v_c)) << 1u)));
+ wuffs_base__pixel_swizzler__swizzle_interleaved_from_slice(&self->private_impl.f_swizzler, v_dst, wuffs_base__utility__empty_slice_u8(), wuffs_base__make_slice_u8(v_src, 1));
+ if (v_dst_bytes_per_pixel <= ((uint64_t)(v_dst.len))) {
+ v_dst = wuffs_base__slice_u8__subslice_i(v_dst, v_dst_bytes_per_pixel);
+ }
+ v_dst_x += 1u;
+ }
+ v_dst_y += 1u;
+ }
+ }
+ self->private_impl.f_call_sequence = 96u;
+
+ ok:
+ self->private_impl.p_do_decode_frame[0] = 0;
+ goto exit;
+ }
+
+ goto suspend;
+ suspend:
+ self->private_impl.p_do_decode_frame[0] = wuffs_base__status__is_suspension(&status) ? coro_susp_point : 0;
+ self->private_data.s_do_decode_frame[0].v_dst_bytes_per_pixel = v_dst_bytes_per_pixel;
+ self->private_data.s_do_decode_frame[0].v_dst_x = v_dst_x;
+ self->private_data.s_do_decode_frame[0].v_dst_y = v_dst_y;
+ memcpy(self->private_data.s_do_decode_frame[0].v_src, v_src, sizeof(v_src));
+ self->private_data.s_do_decode_frame[0].v_c = v_c;
+
+ goto exit;
+ exit:
+ if (a_src && a_src->data.ptr) {
+ a_src->meta.ri = ((size_t)(iop_a_src - a_src->data.ptr));
+ }
+
+ return status;
+}
+
+// -------- func wbmp.decoder.frame_dirty_rect
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__rect_ie_u32
+wuffs_wbmp__decoder__frame_dirty_rect(
+ const wuffs_wbmp__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_rect_ie_u32();
+ }
+
+ return wuffs_base__utility__make_rect_ie_u32(
+ 0u,
+ 0u,
+ self->private_impl.f_width,
+ self->private_impl.f_height);
+}
+
+// -------- func wbmp.decoder.num_animation_loops
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_wbmp__decoder__num_animation_loops(
+ const wuffs_wbmp__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func wbmp.decoder.num_decoded_frame_configs
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_wbmp__decoder__num_decoded_frame_configs(
+ const wuffs_wbmp__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 32u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func wbmp.decoder.num_decoded_frames
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_wbmp__decoder__num_decoded_frames(
+ const wuffs_wbmp__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ if (self->private_impl.f_call_sequence > 64u) {
+ return 1u;
+ }
+ return 0u;
+}
+
+// -------- func wbmp.decoder.restart_frame
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__restart_frame(
+ wuffs_wbmp__decoder* self,
+ uint64_t a_index,
+ uint64_t a_io_position) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ if (self->private_impl.f_call_sequence < 32u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_call_sequence);
+ }
+ if (a_index != 0u) {
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ self->private_impl.f_call_sequence = 40u;
+ self->private_impl.f_frame_config_io_position = a_io_position;
+ return wuffs_base__make_status(NULL);
+}
+
+// -------- func wbmp.decoder.set_report_metadata
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_wbmp__decoder__set_report_metadata(
+ wuffs_wbmp__decoder* self,
+ uint32_t a_fourcc,
+ bool a_report) {
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func wbmp.decoder.tell_me_more
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_wbmp__decoder__tell_me_more(
+ wuffs_wbmp__decoder* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+ if (!a_dst || !a_src) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__bad_argument);
+ }
+ if ((self->private_impl.active_coroutine != 0) &&
+ (self->private_impl.active_coroutine != 4)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ return wuffs_base__make_status(wuffs_base__error__interleaved_coroutine_calls);
+ }
+ self->private_impl.active_coroutine = 0;
+ wuffs_base__status status = wuffs_base__make_status(NULL);
+
+ status = wuffs_base__make_status(wuffs_base__error__no_more_information);
+ goto exit;
+
+ goto ok;
+ ok:
+ goto exit;
+ exit:
+ if (wuffs_base__status__is_error(&status)) {
+ self->private_impl.magic = WUFFS_BASE__DISABLED;
+ }
+ return status;
+}
+
+// -------- func wbmp.decoder.history_retain_length
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_wbmp__decoder__history_retain_length(
+ const wuffs_wbmp__decoder* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func wbmp.decoder.workbuf_len
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__range_ii_u64
+wuffs_wbmp__decoder__workbuf_len(
+ const wuffs_wbmp__decoder* self) {
+ if (!self) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return wuffs_base__utility__empty_range_ii_u64();
+ }
+
+ return wuffs_base__utility__make_range_ii_u64(0u, 0u);
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32)
+
+// ---------------- Status Codes Implementations
+
+// ---------------- Private Consts
+
+#define WUFFS_XXHASH32__XXH_PRIME32_1 2654435761
+
+#define WUFFS_XXHASH32__XXH_PRIME32_2 2246822519
+
+#define WUFFS_XXHASH32__XXH_PRIME32_3 3266489917
+
+#define WUFFS_XXHASH32__XXH_PRIME32_4 668265263
+
+#define WUFFS_XXHASH32__XXH_PRIME32_5 374761393
+
+#define WUFFS_XXHASH32__INITIAL_V0 606290984
+
+#define WUFFS_XXHASH32__INITIAL_V1 2246822519
+
+#define WUFFS_XXHASH32__INITIAL_V2 0
+
+#define WUFFS_XXHASH32__INITIAL_V3 1640531535
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_xxhash32__hasher__up(
+ wuffs_xxhash32__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+// ---------------- VTables
+
+const wuffs_base__hasher_u32__func_ptrs
+wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32 = {
+ (uint32_t(*)(const void*))(&wuffs_xxhash32__hasher__checksum_u32),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_xxhash32__hasher__get_quirk),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_xxhash32__hasher__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update),
+ (uint32_t(*)(void*,
+ wuffs_base__slice_u8))(&wuffs_xxhash32__hasher__update_u32),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_xxhash32__hasher__initialize(
+ wuffs_xxhash32__hasher* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__hasher_u32.vtable_name =
+ wuffs_base__hasher_u32__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__hasher_u32.function_pointers =
+ (const void*)(&wuffs_xxhash32__hasher__func_ptrs_for__wuffs_base__hasher_u32);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_xxhash32__hasher*
+wuffs_xxhash32__hasher__alloc(void) {
+ wuffs_xxhash32__hasher* x =
+ (wuffs_xxhash32__hasher*)(calloc(sizeof(wuffs_xxhash32__hasher), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_xxhash32__hasher__initialize(
+ x, sizeof(wuffs_xxhash32__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_xxhash32__hasher(void) {
+ return sizeof(wuffs_xxhash32__hasher);
+}
+
+// ---------------- Function Implementations
+
+// -------- func xxhash32.hasher.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_xxhash32__hasher__get_quirk(
+ const wuffs_xxhash32__hasher* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func xxhash32.hasher.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_xxhash32__hasher__set_quirk(
+ wuffs_xxhash32__hasher* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func xxhash32.hasher.update
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_xxhash32__hasher__update(
+ wuffs_xxhash32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ wuffs_base__slice_u8 v_remaining = {0};
+
+ if ((self->private_impl.f_length_modulo_u32 == 0u) && ! self->private_impl.f_length_overflows_u32) {
+ self->private_impl.f_v0 = 606290984u;
+ self->private_impl.f_v1 = 2246822519u;
+ self->private_impl.f_v2 = 0u;
+ self->private_impl.f_v3 = 1640531535u;
+ }
+ while (((uint64_t)(a_x.len)) > 0u) {
+ v_remaining = wuffs_base__slice_u8__subslice_j(a_x, 0u);
+ if (((uint64_t)(a_x.len)) > 16777216u) {
+ v_remaining = wuffs_base__slice_u8__subslice_i(a_x, 16777216u);
+ a_x = wuffs_base__slice_u8__subslice_j(a_x, 16777216u);
+ }
+ wuffs_xxhash32__hasher__up(self, a_x);
+ a_x = v_remaining;
+ }
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func xxhash32.hasher.update_u32
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_xxhash32__hasher__update_u32(
+ wuffs_xxhash32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return 0;
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return 0;
+ }
+
+ wuffs_xxhash32__hasher__update(self, a_x);
+ return wuffs_xxhash32__hasher__checksum_u32(self);
+}
+
+// -------- func xxhash32.hasher.up
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_xxhash32__hasher__up(
+ wuffs_xxhash32__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ uint32_t v_new_lmu = 0;
+ uint32_t v_buf_u32 = 0;
+ uint32_t v_buf_len = 0;
+ uint32_t v_v0 = 0;
+ uint32_t v_v1 = 0;
+ uint32_t v_v2 = 0;
+ uint32_t v_v3 = 0;
+ wuffs_base__slice_u8 v_p = {0};
+
+ v_new_lmu = ((uint32_t)(self->private_impl.f_length_modulo_u32 + ((uint32_t)(((uint64_t)(a_x.len))))));
+ self->private_impl.f_length_overflows_u32 = ((v_new_lmu < self->private_impl.f_length_modulo_u32) || self->private_impl.f_length_overflows_u32);
+ self->private_impl.f_length_modulo_u32 = v_new_lmu;
+ while (true) {
+ if (self->private_impl.f_buf_len >= 16u) {
+ v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) |
+ (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) |
+ (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) |
+ (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u));
+ v_v0 = ((uint32_t)(self->private_impl.f_v0 + ((uint32_t)(v_buf_u32 * 2246822519u))));
+ v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u));
+ self->private_impl.f_v0 = ((uint32_t)(v_v0 * 2654435761u));
+ v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) |
+ (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) |
+ (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) |
+ (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u));
+ v_v1 = ((uint32_t)(self->private_impl.f_v1 + ((uint32_t)(v_buf_u32 * 2246822519u))));
+ v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u));
+ self->private_impl.f_v1 = ((uint32_t)(v_v1 * 2654435761u));
+ v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) |
+ (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) |
+ (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) |
+ (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u));
+ v_v2 = ((uint32_t)(self->private_impl.f_v2 + ((uint32_t)(v_buf_u32 * 2246822519u))));
+ v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u));
+ self->private_impl.f_v2 = ((uint32_t)(v_v2 * 2654435761u));
+ v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[12u])) |
+ (((uint32_t)(self->private_impl.f_buf_data[13u])) << 8u) |
+ (((uint32_t)(self->private_impl.f_buf_data[14u])) << 16u) |
+ (((uint32_t)(self->private_impl.f_buf_data[15u])) << 24u));
+ v_v3 = ((uint32_t)(self->private_impl.f_v3 + ((uint32_t)(v_buf_u32 * 2246822519u))));
+ v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u));
+ self->private_impl.f_v3 = ((uint32_t)(v_v3 * 2654435761u));
+ self->private_impl.f_buf_len = 0u;
+ break;
+ }
+ if (((uint64_t)(a_x.len)) <= 0u) {
+ return wuffs_base__make_empty_struct();
+ }
+ self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u];
+#if defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wconversion"
+#endif
+ self->private_impl.f_buf_len += 1u;
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
+ }
+ v_buf_len = ((uint32_t)((self->private_impl.f_buf_len & 15u)));
+ v_v0 = self->private_impl.f_v0;
+ v_v1 = self->private_impl.f_v1;
+ v_v2 = self->private_impl.f_v2;
+ v_v3 = self->private_impl.f_v3;
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 16;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 16) * 16);
+ while (v_p.ptr < i_end0_p) {
+ v_buf_u32 = (((uint32_t)(v_p.ptr[0u])) |
+ (((uint32_t)(v_p.ptr[1u])) << 8u) |
+ (((uint32_t)(v_p.ptr[2u])) << 16u) |
+ (((uint32_t)(v_p.ptr[3u])) << 24u));
+ v_v0 = ((uint32_t)(v_v0 + ((uint32_t)(v_buf_u32 * 2246822519u))));
+ v_v0 = (((uint32_t)(v_v0 << 13u)) | (v_v0 >> 19u));
+ v_v0 = ((uint32_t)(v_v0 * 2654435761u));
+ v_buf_u32 = (((uint32_t)(v_p.ptr[4u])) |
+ (((uint32_t)(v_p.ptr[5u])) << 8u) |
+ (((uint32_t)(v_p.ptr[6u])) << 16u) |
+ (((uint32_t)(v_p.ptr[7u])) << 24u));
+ v_v1 = ((uint32_t)(v_v1 + ((uint32_t)(v_buf_u32 * 2246822519u))));
+ v_v1 = (((uint32_t)(v_v1 << 13u)) | (v_v1 >> 19u));
+ v_v1 = ((uint32_t)(v_v1 * 2654435761u));
+ v_buf_u32 = (((uint32_t)(v_p.ptr[8u])) |
+ (((uint32_t)(v_p.ptr[9u])) << 8u) |
+ (((uint32_t)(v_p.ptr[10u])) << 16u) |
+ (((uint32_t)(v_p.ptr[11u])) << 24u));
+ v_v2 = ((uint32_t)(v_v2 + ((uint32_t)(v_buf_u32 * 2246822519u))));
+ v_v2 = (((uint32_t)(v_v2 << 13u)) | (v_v2 >> 19u));
+ v_v2 = ((uint32_t)(v_v2 * 2654435761u));
+ v_buf_u32 = (((uint32_t)(v_p.ptr[12u])) |
+ (((uint32_t)(v_p.ptr[13u])) << 8u) |
+ (((uint32_t)(v_p.ptr[14u])) << 16u) |
+ (((uint32_t)(v_p.ptr[15u])) << 24u));
+ v_v3 = ((uint32_t)(v_v3 + ((uint32_t)(v_buf_u32 * 2246822519u))));
+ v_v3 = (((uint32_t)(v_v3 << 13u)) | (v_v3 >> 19u));
+ v_v3 = ((uint32_t)(v_v3 * 2654435761u));
+ v_p.ptr += 16;
+ }
+ v_p.len = 1;
+ uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end1_p) {
+ self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u];
+ v_buf_len = ((v_buf_len + 1u) & 15u);
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ self->private_impl.f_buf_len = ((uint8_t)(v_buf_len));
+ self->private_impl.f_v0 = v_v0;
+ self->private_impl.f_v1 = v_v1;
+ self->private_impl.f_v2 = v_v2;
+ self->private_impl.f_v3 = v_v3;
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func xxhash32.hasher.checksum_u32
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint32_t
+wuffs_xxhash32__hasher__checksum_u32(
+ const wuffs_xxhash32__hasher* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ uint32_t v_ret = 0;
+ uint32_t v_i = 0;
+ uint32_t v_n = 0;
+ uint32_t v_buf_u32 = 0;
+
+ if ((self->private_impl.f_length_modulo_u32 >= 16u) || self->private_impl.f_length_overflows_u32) {
+ v_ret += (((uint32_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 31u));
+ v_ret += (((uint32_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 25u));
+ v_ret += (((uint32_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 20u));
+ v_ret += (((uint32_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 14u));
+ v_ret += self->private_impl.f_length_modulo_u32;
+ } else {
+ v_ret += 374761393u;
+ v_ret += self->private_impl.f_length_modulo_u32;
+ }
+ v_n = 16u;
+ v_n = wuffs_base__u32__min(v_n, ((uint32_t)(self->private_impl.f_buf_len)));
+ if (4u <= v_n) {
+ v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[0u])) |
+ (((uint32_t)(self->private_impl.f_buf_data[1u])) << 8u) |
+ (((uint32_t)(self->private_impl.f_buf_data[2u])) << 16u) |
+ (((uint32_t)(self->private_impl.f_buf_data[3u])) << 24u));
+ v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
+ v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
+ v_ret *= 668265263u;
+ v_i = 4u;
+ }
+ if (8u <= v_n) {
+ v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[4u])) |
+ (((uint32_t)(self->private_impl.f_buf_data[5u])) << 8u) |
+ (((uint32_t)(self->private_impl.f_buf_data[6u])) << 16u) |
+ (((uint32_t)(self->private_impl.f_buf_data[7u])) << 24u));
+ v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
+ v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
+ v_ret *= 668265263u;
+ v_i = 8u;
+ }
+ if (12u <= v_n) {
+ v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[8u])) |
+ (((uint32_t)(self->private_impl.f_buf_data[9u])) << 8u) |
+ (((uint32_t)(self->private_impl.f_buf_data[10u])) << 16u) |
+ (((uint32_t)(self->private_impl.f_buf_data[11u])) << 24u));
+ v_ret += ((uint32_t)(v_buf_u32 * 3266489917u));
+ v_ret = (((uint32_t)(v_ret << 17u)) | (v_ret >> 15u));
+ v_ret *= 668265263u;
+ v_i = 12u;
+ }
+ while (v_i < v_n) {
+ v_ret += ((uint32_t)(((uint32_t)(self->private_impl.f_buf_data[v_i])) * 374761393u));
+ v_ret = (((uint32_t)(v_ret << 11u)) | (v_ret >> 21u));
+ v_ret *= 2654435761u;
+ v_i += 1u;
+ }
+ v_ret ^= (v_ret >> 15u);
+ v_ret *= 2246822519u;
+ v_ret ^= (v_ret >> 13u);
+ v_ret *= 3266489917u;
+ v_ret ^= (v_ret >> 16u);
+ return v_ret;
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH32)
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64)
+
+// ---------------- Status Codes Implementations
+
+// ---------------- Private Consts
+
+#define WUFFS_XXHASH64__XXH_PRIME64_1 11400714785074694791
+
+#define WUFFS_XXHASH64__XXH_PRIME64_2 14029467366897019727
+
+#define WUFFS_XXHASH64__XXH_PRIME64_3 1609587929392839161
+
+#define WUFFS_XXHASH64__XXH_PRIME64_4 9650029242287828579
+
+#define WUFFS_XXHASH64__XXH_PRIME64_5 2870177450012600261
+
+#define WUFFS_XXHASH64__INITIAL_V0 6983438078262162902
+
+#define WUFFS_XXHASH64__INITIAL_V1 14029467366897019727
+
+#define WUFFS_XXHASH64__INITIAL_V2 0
+
+#define WUFFS_XXHASH64__INITIAL_V3 7046029288634856825
+
+// ---------------- Private Initializer Prototypes
+
+// ---------------- Private Function Prototypes
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_xxhash64__hasher__up(
+ wuffs_xxhash64__hasher* self,
+ wuffs_base__slice_u8 a_x);
+
+// ---------------- VTables
+
+const wuffs_base__hasher_u64__func_ptrs
+wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64 = {
+ (uint64_t(*)(const void*))(&wuffs_xxhash64__hasher__checksum_u64),
+ (uint64_t(*)(const void*,
+ uint32_t))(&wuffs_xxhash64__hasher__get_quirk),
+ (wuffs_base__status(*)(void*,
+ uint32_t,
+ uint64_t))(&wuffs_xxhash64__hasher__set_quirk),
+ (wuffs_base__empty_struct(*)(void*,
+ wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update),
+ (uint64_t(*)(void*,
+ wuffs_base__slice_u8))(&wuffs_xxhash64__hasher__update_u64),
+};
+
+// ---------------- Initializer Implementations
+
+wuffs_base__status WUFFS_BASE__WARN_UNUSED_RESULT
+wuffs_xxhash64__hasher__initialize(
+ wuffs_xxhash64__hasher* self,
+ size_t sizeof_star_self,
+ uint64_t wuffs_version,
+ uint32_t options){
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (sizeof(*self) != sizeof_star_self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_sizeof_receiver);
+ }
+ if (((wuffs_version >> 32) != WUFFS_VERSION_MAJOR) ||
+ (((wuffs_version >> 16) & 0xFFFF) > WUFFS_VERSION_MINOR)) {
+ return wuffs_base__make_status(wuffs_base__error__bad_wuffs_version);
+ }
+
+ if ((options & WUFFS_INITIALIZE__ALREADY_ZEROED) != 0) {
+ // The whole point of this if-check is to detect an uninitialized *self.
+ // We disable the warning on GCC. Clang-5.0 does not have this warning.
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
+#endif
+ if (self->private_impl.magic != 0) {
+ return wuffs_base__make_status(wuffs_base__error__initialize_falsely_claimed_already_zeroed);
+ }
+#if !defined(__clang__) && defined(__GNUC__)
+#pragma GCC diagnostic pop
+#endif
+ } else {
+ if ((options & WUFFS_INITIALIZE__LEAVE_INTERNAL_BUFFERS_UNINITIALIZED) == 0) {
+ memset(self, 0, sizeof(*self));
+ options |= WUFFS_INITIALIZE__ALREADY_ZEROED;
+ } else {
+ memset(&(self->private_impl), 0, sizeof(self->private_impl));
+ }
+ }
+
+ self->private_impl.magic = WUFFS_BASE__MAGIC;
+ self->private_impl.vtable_for__wuffs_base__hasher_u64.vtable_name =
+ wuffs_base__hasher_u64__vtable_name;
+ self->private_impl.vtable_for__wuffs_base__hasher_u64.function_pointers =
+ (const void*)(&wuffs_xxhash64__hasher__func_ptrs_for__wuffs_base__hasher_u64);
+ return wuffs_base__make_status(NULL);
+}
+
+wuffs_xxhash64__hasher*
+wuffs_xxhash64__hasher__alloc(void) {
+ wuffs_xxhash64__hasher* x =
+ (wuffs_xxhash64__hasher*)(calloc(sizeof(wuffs_xxhash64__hasher), 1));
+ if (!x) {
+ return NULL;
+ }
+ if (wuffs_xxhash64__hasher__initialize(
+ x, sizeof(wuffs_xxhash64__hasher), WUFFS_VERSION, WUFFS_INITIALIZE__ALREADY_ZEROED).repr) {
+ free(x);
+ return NULL;
+ }
+ return x;
+}
+
+size_t
+sizeof__wuffs_xxhash64__hasher(void) {
+ return sizeof(wuffs_xxhash64__hasher);
+}
+
+// ---------------- Function Implementations
+
+// -------- func xxhash64.hasher.get_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_xxhash64__hasher__get_quirk(
+ const wuffs_xxhash64__hasher* self,
+ uint32_t a_key) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ return 0u;
+}
+
+// -------- func xxhash64.hasher.set_quirk
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__status
+wuffs_xxhash64__hasher__set_quirk(
+ wuffs_xxhash64__hasher* self,
+ uint32_t a_key,
+ uint64_t a_value) {
+ if (!self) {
+ return wuffs_base__make_status(wuffs_base__error__bad_receiver);
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_status(
+ (self->private_impl.magic == WUFFS_BASE__DISABLED)
+ ? wuffs_base__error__disabled_by_previous_error
+ : wuffs_base__error__initialize_not_called);
+ }
+
+ return wuffs_base__make_status(wuffs_base__error__unsupported_option);
+}
+
+// -------- func xxhash64.hasher.update
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC wuffs_base__empty_struct
+wuffs_xxhash64__hasher__update(
+ wuffs_xxhash64__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return wuffs_base__make_empty_struct();
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return wuffs_base__make_empty_struct();
+ }
+
+ if ((self->private_impl.f_length_modulo_u64 == 0u) && ! self->private_impl.f_length_overflows_u64) {
+ self->private_impl.f_v0 = 6983438078262162902u;
+ self->private_impl.f_v1 = 14029467366897019727u;
+ self->private_impl.f_v2 = 0u;
+ self->private_impl.f_v3 = 7046029288634856825u;
+ }
+ wuffs_xxhash64__hasher__up(self, a_x);
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func xxhash64.hasher.update_u64
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_xxhash64__hasher__update_u64(
+ wuffs_xxhash64__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ if (!self) {
+ return 0;
+ }
+ if (self->private_impl.magic != WUFFS_BASE__MAGIC) {
+ return 0;
+ }
+
+ wuffs_xxhash64__hasher__update(self, a_x);
+ return wuffs_xxhash64__hasher__checksum_u64(self);
+}
+
+// -------- func xxhash64.hasher.up
+
+WUFFS_BASE__GENERATED_C_CODE
+static wuffs_base__empty_struct
+wuffs_xxhash64__hasher__up(
+ wuffs_xxhash64__hasher* self,
+ wuffs_base__slice_u8 a_x) {
+ uint64_t v_new_lmu = 0;
+ uint64_t v_buf_u64 = 0;
+ uint32_t v_buf_len = 0;
+ uint64_t v_v0 = 0;
+ uint64_t v_v1 = 0;
+ uint64_t v_v2 = 0;
+ uint64_t v_v3 = 0;
+ wuffs_base__slice_u8 v_p = {0};
+
+ v_new_lmu = ((uint64_t)(self->private_impl.f_length_modulo_u64 + ((uint64_t)(a_x.len))));
+ self->private_impl.f_length_overflows_u64 = ((v_new_lmu < self->private_impl.f_length_modulo_u64) || self->private_impl.f_length_overflows_u64);
+ self->private_impl.f_length_modulo_u64 = v_new_lmu;
+ while (true) {
+ if (self->private_impl.f_buf_len >= 32u) {
+ v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) |
+ (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) |
+ (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) |
+ (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) |
+ (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) |
+ (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) |
+ (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) |
+ (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u));
+ v_v0 = ((uint64_t)(self->private_impl.f_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
+ v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
+ self->private_impl.f_v0 = ((uint64_t)(v_v0 * 11400714785074694791u));
+ v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) |
+ (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) |
+ (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) |
+ (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) |
+ (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) |
+ (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) |
+ (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) |
+ (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u));
+ v_v1 = ((uint64_t)(self->private_impl.f_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
+ v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
+ self->private_impl.f_v1 = ((uint64_t)(v_v1 * 11400714785074694791u));
+ v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) |
+ (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) |
+ (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) |
+ (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) |
+ (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) |
+ (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) |
+ (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) |
+ (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u));
+ v_v2 = ((uint64_t)(self->private_impl.f_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
+ v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
+ self->private_impl.f_v2 = ((uint64_t)(v_v2 * 11400714785074694791u));
+ v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[24u])) |
+ (((uint64_t)(self->private_impl.f_buf_data[25u])) << 8u) |
+ (((uint64_t)(self->private_impl.f_buf_data[26u])) << 16u) |
+ (((uint64_t)(self->private_impl.f_buf_data[27u])) << 24u) |
+ (((uint64_t)(self->private_impl.f_buf_data[28u])) << 32u) |
+ (((uint64_t)(self->private_impl.f_buf_data[29u])) << 40u) |
+ (((uint64_t)(self->private_impl.f_buf_data[30u])) << 48u) |
+ (((uint64_t)(self->private_impl.f_buf_data[31u])) << 56u));
+ v_v3 = ((uint64_t)(self->private_impl.f_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
+ v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
+ self->private_impl.f_v3 = ((uint64_t)(v_v3 * 11400714785074694791u));
+ self->private_impl.f_buf_len = 0u;
+ break;
+ }
+ if (((uint64_t)(a_x.len)) <= 0u) {
+ return wuffs_base__make_empty_struct();
+ }
+ self->private_impl.f_buf_data[self->private_impl.f_buf_len] = a_x.ptr[0u];
+ self->private_impl.f_buf_len += 1u;
+ a_x = wuffs_base__slice_u8__subslice_i(a_x, 1u);
+ }
+ v_buf_len = (self->private_impl.f_buf_len & 31u);
+ v_v0 = self->private_impl.f_v0;
+ v_v1 = self->private_impl.f_v1;
+ v_v2 = self->private_impl.f_v2;
+ v_v3 = self->private_impl.f_v3;
+ {
+ wuffs_base__slice_u8 i_slice_p = a_x;
+ v_p.ptr = i_slice_p.ptr;
+ v_p.len = 32;
+ uint8_t* i_end0_p = v_p.ptr + (((i_slice_p.len - (size_t)(v_p.ptr - i_slice_p.ptr)) / 32) * 32);
+ while (v_p.ptr < i_end0_p) {
+ v_buf_u64 = (((uint64_t)(v_p.ptr[0u])) |
+ (((uint64_t)(v_p.ptr[1u])) << 8u) |
+ (((uint64_t)(v_p.ptr[2u])) << 16u) |
+ (((uint64_t)(v_p.ptr[3u])) << 24u) |
+ (((uint64_t)(v_p.ptr[4u])) << 32u) |
+ (((uint64_t)(v_p.ptr[5u])) << 40u) |
+ (((uint64_t)(v_p.ptr[6u])) << 48u) |
+ (((uint64_t)(v_p.ptr[7u])) << 56u));
+ v_v0 = ((uint64_t)(v_v0 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
+ v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
+ v_v0 = ((uint64_t)(v_v0 * 11400714785074694791u));
+ v_buf_u64 = (((uint64_t)(v_p.ptr[8u])) |
+ (((uint64_t)(v_p.ptr[9u])) << 8u) |
+ (((uint64_t)(v_p.ptr[10u])) << 16u) |
+ (((uint64_t)(v_p.ptr[11u])) << 24u) |
+ (((uint64_t)(v_p.ptr[12u])) << 32u) |
+ (((uint64_t)(v_p.ptr[13u])) << 40u) |
+ (((uint64_t)(v_p.ptr[14u])) << 48u) |
+ (((uint64_t)(v_p.ptr[15u])) << 56u));
+ v_v1 = ((uint64_t)(v_v1 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
+ v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
+ v_v1 = ((uint64_t)(v_v1 * 11400714785074694791u));
+ v_buf_u64 = (((uint64_t)(v_p.ptr[16u])) |
+ (((uint64_t)(v_p.ptr[17u])) << 8u) |
+ (((uint64_t)(v_p.ptr[18u])) << 16u) |
+ (((uint64_t)(v_p.ptr[19u])) << 24u) |
+ (((uint64_t)(v_p.ptr[20u])) << 32u) |
+ (((uint64_t)(v_p.ptr[21u])) << 40u) |
+ (((uint64_t)(v_p.ptr[22u])) << 48u) |
+ (((uint64_t)(v_p.ptr[23u])) << 56u));
+ v_v2 = ((uint64_t)(v_v2 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
+ v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
+ v_v2 = ((uint64_t)(v_v2 * 11400714785074694791u));
+ v_buf_u64 = (((uint64_t)(v_p.ptr[24u])) |
+ (((uint64_t)(v_p.ptr[25u])) << 8u) |
+ (((uint64_t)(v_p.ptr[26u])) << 16u) |
+ (((uint64_t)(v_p.ptr[27u])) << 24u) |
+ (((uint64_t)(v_p.ptr[28u])) << 32u) |
+ (((uint64_t)(v_p.ptr[29u])) << 40u) |
+ (((uint64_t)(v_p.ptr[30u])) << 48u) |
+ (((uint64_t)(v_p.ptr[31u])) << 56u));
+ v_v3 = ((uint64_t)(v_v3 + ((uint64_t)(v_buf_u64 * 14029467366897019727u))));
+ v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
+ v_v3 = ((uint64_t)(v_v3 * 11400714785074694791u));
+ v_p.ptr += 32;
+ }
+ v_p.len = 1;
+ uint8_t* i_end1_p = i_slice_p.ptr + i_slice_p.len;
+ while (v_p.ptr < i_end1_p) {
+ self->private_impl.f_buf_data[v_buf_len] = v_p.ptr[0u];
+ v_buf_len = ((v_buf_len + 1u) & 31u);
+ v_p.ptr += 1;
+ }
+ v_p.len = 0;
+ }
+ self->private_impl.f_buf_len = v_buf_len;
+ self->private_impl.f_v0 = v_v0;
+ self->private_impl.f_v1 = v_v1;
+ self->private_impl.f_v2 = v_v2;
+ self->private_impl.f_v3 = v_v3;
+ return wuffs_base__make_empty_struct();
+}
+
+// -------- func xxhash64.hasher.checksum_u64
+
+WUFFS_BASE__GENERATED_C_CODE
+WUFFS_BASE__MAYBE_STATIC uint64_t
+wuffs_xxhash64__hasher__checksum_u64(
+ const wuffs_xxhash64__hasher* self) {
+ if (!self) {
+ return 0;
+ }
+ if ((self->private_impl.magic != WUFFS_BASE__MAGIC) &&
+ (self->private_impl.magic != WUFFS_BASE__DISABLED)) {
+ return 0;
+ }
+
+ uint64_t v_ret = 0;
+ uint64_t v_v0 = 0;
+ uint64_t v_v1 = 0;
+ uint64_t v_v2 = 0;
+ uint64_t v_v3 = 0;
+ uint32_t v_i = 0;
+ uint32_t v_i8 = 0;
+ uint32_t v_n = 0;
+ uint32_t v_buf_u32 = 0;
+ uint64_t v_buf_u64 = 0;
+
+ if ((self->private_impl.f_length_modulo_u64 >= 32u) || self->private_impl.f_length_overflows_u64) {
+ v_ret += (((uint64_t)(self->private_impl.f_v0 << 1u)) | (self->private_impl.f_v0 >> 63u));
+ v_ret += (((uint64_t)(self->private_impl.f_v1 << 7u)) | (self->private_impl.f_v1 >> 57u));
+ v_ret += (((uint64_t)(self->private_impl.f_v2 << 12u)) | (self->private_impl.f_v2 >> 52u));
+ v_ret += (((uint64_t)(self->private_impl.f_v3 << 18u)) | (self->private_impl.f_v3 >> 46u));
+ v_v0 = ((uint64_t)(self->private_impl.f_v0 * 14029467366897019727u));
+ v_v0 = (((uint64_t)(v_v0 << 31u)) | (v_v0 >> 33u));
+ v_v0 *= 11400714785074694791u;
+ v_v1 = ((uint64_t)(self->private_impl.f_v1 * 14029467366897019727u));
+ v_v1 = (((uint64_t)(v_v1 << 31u)) | (v_v1 >> 33u));
+ v_v1 *= 11400714785074694791u;
+ v_v2 = ((uint64_t)(self->private_impl.f_v2 * 14029467366897019727u));
+ v_v2 = (((uint64_t)(v_v2 << 31u)) | (v_v2 >> 33u));
+ v_v2 *= 11400714785074694791u;
+ v_v3 = ((uint64_t)(self->private_impl.f_v3 * 14029467366897019727u));
+ v_v3 = (((uint64_t)(v_v3 << 31u)) | (v_v3 >> 33u));
+ v_v3 *= 11400714785074694791u;
+ v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v0) * 11400714785074694791u)) + 9650029242287828579u));
+ v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v1) * 11400714785074694791u)) + 9650029242287828579u));
+ v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v2) * 11400714785074694791u)) + 9650029242287828579u));
+ v_ret = ((uint64_t)(((uint64_t)((v_ret ^ v_v3) * 11400714785074694791u)) + 9650029242287828579u));
+ v_ret += self->private_impl.f_length_modulo_u64;
+ } else {
+ v_ret += 2870177450012600261u;
+ v_ret += self->private_impl.f_length_modulo_u64;
+ }
+ v_n = 32u;
+ v_n = wuffs_base__u32__min(v_n, self->private_impl.f_buf_len);
+ if (8u <= v_n) {
+ v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[0u])) |
+ (((uint64_t)(self->private_impl.f_buf_data[1u])) << 8u) |
+ (((uint64_t)(self->private_impl.f_buf_data[2u])) << 16u) |
+ (((uint64_t)(self->private_impl.f_buf_data[3u])) << 24u) |
+ (((uint64_t)(self->private_impl.f_buf_data[4u])) << 32u) |
+ (((uint64_t)(self->private_impl.f_buf_data[5u])) << 40u) |
+ (((uint64_t)(self->private_impl.f_buf_data[6u])) << 48u) |
+ (((uint64_t)(self->private_impl.f_buf_data[7u])) << 56u));
+ v_buf_u64 *= 14029467366897019727u;
+ v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
+ v_buf_u64 *= 11400714785074694791u;
+ v_ret ^= v_buf_u64;
+ v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
+ v_ret *= 11400714785074694791u;
+ v_ret += 9650029242287828579u;
+ v_i = 8u;
+ }
+ if (16u <= v_n) {
+ v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[8u])) |
+ (((uint64_t)(self->private_impl.f_buf_data[9u])) << 8u) |
+ (((uint64_t)(self->private_impl.f_buf_data[10u])) << 16u) |
+ (((uint64_t)(self->private_impl.f_buf_data[11u])) << 24u) |
+ (((uint64_t)(self->private_impl.f_buf_data[12u])) << 32u) |
+ (((uint64_t)(self->private_impl.f_buf_data[13u])) << 40u) |
+ (((uint64_t)(self->private_impl.f_buf_data[14u])) << 48u) |
+ (((uint64_t)(self->private_impl.f_buf_data[15u])) << 56u));
+ v_buf_u64 *= 14029467366897019727u;
+ v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
+ v_buf_u64 *= 11400714785074694791u;
+ v_ret ^= v_buf_u64;
+ v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
+ v_ret *= 11400714785074694791u;
+ v_ret += 9650029242287828579u;
+ v_i = 16u;
+ }
+ if (24u <= v_n) {
+ v_buf_u64 = (((uint64_t)(self->private_impl.f_buf_data[16u])) |
+ (((uint64_t)(self->private_impl.f_buf_data[17u])) << 8u) |
+ (((uint64_t)(self->private_impl.f_buf_data[18u])) << 16u) |
+ (((uint64_t)(self->private_impl.f_buf_data[19u])) << 24u) |
+ (((uint64_t)(self->private_impl.f_buf_data[20u])) << 32u) |
+ (((uint64_t)(self->private_impl.f_buf_data[21u])) << 40u) |
+ (((uint64_t)(self->private_impl.f_buf_data[22u])) << 48u) |
+ (((uint64_t)(self->private_impl.f_buf_data[23u])) << 56u));
+ v_buf_u64 *= 14029467366897019727u;
+ v_buf_u64 = (((uint64_t)(v_buf_u64 << 31u)) | (v_buf_u64 >> 33u));
+ v_buf_u64 *= 11400714785074694791u;
+ v_ret ^= v_buf_u64;
+ v_ret = (((uint64_t)(v_ret << 27u)) | (v_ret >> 37u));
+ v_ret *= 11400714785074694791u;
+ v_ret += 9650029242287828579u;
+ v_i = 24u;
+ }
+ if ((v_n & 4u) != 0u) {
+ v_i8 = (v_i & 24u);
+ v_buf_u32 = (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 0u)])) |
+ (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 1u)])) << 8u) |
+ (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 2u)])) << 16u) |
+ (((uint32_t)(self->private_impl.f_buf_data[(v_i8 + 3u)])) << 24u));
+ v_ret ^= ((uint64_t)(((uint64_t)(v_buf_u32)) * 11400714785074694791u));
+ v_ret = (((uint64_t)(v_ret << 23u)) | (v_ret >> 41u));
+ v_ret *= 14029467366897019727u;
+ v_ret += 1609587929392839161u;
+ v_i = (v_i8 + 4u);
+ }
+ while (v_i < v_n) {
+ v_ret ^= ((uint64_t)(((uint64_t)(self->private_impl.f_buf_data[v_i])) * 2870177450012600261u));
+ v_ret = (((uint64_t)(v_ret << 11u)) | (v_ret >> 53u));
+ v_ret *= 11400714785074694791u;
+ v_i += 1u;
+ }
+ v_ret ^= (v_ret >> 33u);
+ v_ret *= 14029467366897019727u;
+ v_ret ^= (v_ret >> 29u);
+ v_ret *= 1609587929392839161u;
+ v_ret ^= (v_ret >> 32u);
+ return ((uint64_t)(v_ret));
+}
+
+#endif // !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__XXHASH64)
+
+#if defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+// ---------------- Auxiliary - Base
+
+// Auxiliary code is discussed at
+// https://github.com/google/wuffs/blob/main/doc/note/auxiliary-code.md
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__BASE)
+
+namespace wuffs_aux {
+
+namespace sync_io {
+
+// --------
+
+DynIOBuffer::DynIOBuffer(uint64_t max_incl)
+ : m_buf(wuffs_base__empty_io_buffer()), m_max_incl(max_incl) {}
+
+DynIOBuffer::~DynIOBuffer() {
+ if (m_buf.data.ptr) {
+ free(m_buf.data.ptr);
+ }
+}
+
+void //
+DynIOBuffer::drop() {
+ if (m_buf.data.ptr) {
+ free(m_buf.data.ptr);
+ }
+ m_buf = wuffs_base__empty_io_buffer();
+}
+
+DynIOBuffer::GrowResult //
+DynIOBuffer::grow(uint64_t min_incl) {
+ uint64_t n = round_up(min_incl, m_max_incl);
+ if (n == 0) {
+ return ((min_incl == 0) && (m_max_incl == 0))
+ ? DynIOBuffer::GrowResult::OK
+ : DynIOBuffer::GrowResult::FailedMaxInclExceeded;
+ } else if (n > m_buf.data.len) {
+ uint8_t* ptr = static_cast<uint8_t*>(realloc(m_buf.data.ptr, n));
+ if (!ptr) {
+ return DynIOBuffer::GrowResult::FailedOutOfMemory;
+ }
+ m_buf.data.ptr = ptr;
+ m_buf.data.len = n;
+ }
+ return DynIOBuffer::GrowResult::OK;
+}
+
+// round_up rounds min_incl up, returning the smallest value x satisfying
+// (min_incl <= x) and (x <= max_incl) and some other constraints. It returns 0
+// if there is no such x.
+//
+// When max_incl <= 4096, the other constraints are:
+// - (x == max_incl)
+//
+// When max_incl > 4096, the other constraints are:
+// - (x == max_incl) or (x is a power of 2)
+// - (x >= 4096)
+uint64_t //
+DynIOBuffer::round_up(uint64_t min_incl, uint64_t max_incl) {
+ if (min_incl > max_incl) {
+ return 0;
+ }
+ uint64_t n = 4096;
+ if (n >= max_incl) {
+ return max_incl;
+ }
+ while (n < min_incl) {
+ if (n >= (max_incl / 2)) {
+ return max_incl;
+ }
+ n *= 2;
+ }
+ return n;
+}
+
+// --------
+
+Input::~Input() {}
+
+IOBuffer* //
+Input::BringsItsOwnIOBuffer() {
+ return nullptr;
+}
+
+// --------
+
+FileInput::FileInput(FILE* f) : m_f(f) {}
+
+std::string //
+FileInput::CopyIn(IOBuffer* dst, uint64_t history_retain_length) {
+ if (!m_f) {
+ return "wuffs_aux::sync_io::FileInput: nullptr file";
+ } else if (!dst) {
+ return "wuffs_aux::sync_io::FileInput: nullptr IOBuffer";
+ } else if (dst->meta.closed) {
+ return "wuffs_aux::sync_io::FileInput: end of file";
+ } else {
+ dst->compact_retaining(history_retain_length);
+ size_t n = fread(dst->writer_pointer(), 1, dst->writer_length(), m_f);
+ dst->meta.wi += n;
+ dst->meta.closed = feof(m_f);
+ if (ferror(m_f)) {
+ return "wuffs_aux::sync_io::FileInput: error reading file";
+ }
+ }
+ return "";
+}
+
+// --------
+
+MemoryInput::MemoryInput(const char* ptr, size_t len)
+ : m_io(wuffs_base__ptr_u8__reader(
+ static_cast<uint8_t*>(static_cast<void*>(const_cast<char*>(ptr))),
+ len,
+ true)) {}
+
+MemoryInput::MemoryInput(const uint8_t* ptr, size_t len)
+ : m_io(wuffs_base__ptr_u8__reader(const_cast<uint8_t*>(ptr), len, true)) {}
+
+IOBuffer* //
+MemoryInput::BringsItsOwnIOBuffer() {
+ return &m_io;
+}
+
+std::string //
+MemoryInput::CopyIn(IOBuffer* dst, uint64_t history_retain_length) {
+ if (!dst) {
+ return "wuffs_aux::sync_io::MemoryInput: nullptr IOBuffer";
+ } else if (dst->meta.closed) {
+ return "wuffs_aux::sync_io::MemoryInput: end of file";
+ } else if (wuffs_base__slice_u8__overlaps(dst->data, m_io.data)) {
+ // Treat m_io's data as immutable, so don't compact dst or otherwise write
+ // to it.
+ return "wuffs_aux::sync_io::MemoryInput: overlapping buffers";
+ } else {
+ dst->compact_retaining(history_retain_length);
+ size_t nd = dst->writer_length();
+ size_t ns = m_io.reader_length();
+ size_t n = (nd < ns) ? nd : ns;
+ memcpy(dst->writer_pointer(), m_io.reader_pointer(), n);
+ m_io.meta.ri += n;
+ dst->meta.wi += n;
+ dst->meta.closed = m_io.reader_length() == 0;
+ }
+ return "";
+}
+
+// --------
+
+} // namespace sync_io
+
+namespace private_impl {
+
+struct ErrorMessages {
+ const char* max_incl_metadata_length_exceeded;
+ const char* out_of_memory;
+ const char* unexpected_end_of_file;
+ const char* unsupported_metadata;
+ const char* unsupported_negative_advance;
+
+ // If adding new "const char*" typed fields to this struct, either add them
+ // after existing fields or, if re-ordering fields, make sure that you update
+ // all of the "const private_impl::ErrorMessages FooBarErrorMessages" values
+ // in all of the sibling *.cc files.
+
+ static inline const char* resolve(const char* s) {
+ return s ? s : "wuffs_aux::private_impl: unknown error";
+ };
+};
+
+std::string //
+AdvanceIOBufferTo(const ErrorMessages& error_messages,
+ sync_io::Input& input,
+ IOBuffer& io_buf,
+ uint64_t absolute_position) {
+ if (absolute_position < io_buf.reader_position()) {
+ return error_messages.resolve(error_messages.unsupported_negative_advance);
+ }
+ while (true) {
+ uint64_t relative_position = absolute_position - io_buf.reader_position();
+ if (relative_position <= io_buf.reader_length()) {
+ io_buf.meta.ri += (size_t)relative_position;
+ break;
+ } else if (io_buf.meta.closed) {
+ return error_messages.resolve(error_messages.unexpected_end_of_file);
+ }
+ io_buf.meta.ri = io_buf.meta.wi;
+ if (!input.BringsItsOwnIOBuffer()) {
+ io_buf.compact();
+ }
+ std::string error_message = input.CopyIn(&io_buf, 0);
+ if (!error_message.empty()) {
+ return error_message;
+ }
+ }
+ return "";
+}
+
+std::string //
+HandleMetadata(
+ const ErrorMessages& error_messages,
+ sync_io::Input& input,
+ wuffs_base__io_buffer& io_buf,
+ sync_io::DynIOBuffer& raw,
+ wuffs_base__status (*tell_me_more_func)(void*,
+ wuffs_base__io_buffer*,
+ wuffs_base__more_information*,
+ wuffs_base__io_buffer*),
+ void* tell_me_more_receiver,
+ std::string (*handle_metadata_func)(void*,
+ const wuffs_base__more_information*,
+ wuffs_base__slice_u8),
+ void* handle_metadata_receiver) {
+ wuffs_base__more_information minfo = wuffs_base__empty_more_information();
+ // Reset raw but keep its backing array (the raw.m_buf.data slice).
+ raw.m_buf.meta = wuffs_base__empty_io_buffer_meta();
+
+ while (true) {
+ minfo = wuffs_base__empty_more_information();
+ wuffs_base__status status = (*tell_me_more_func)(
+ tell_me_more_receiver, &raw.m_buf, &minfo, &io_buf);
+ switch (minfo.flavor) {
+ case 0:
+ case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_TRANSFORM:
+ case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_PARSED:
+ break;
+
+ case WUFFS_BASE__MORE_INFORMATION__FLAVOR__METADATA_RAW_PASSTHROUGH: {
+ wuffs_base__range_ie_u64 r = minfo.metadata_raw_passthrough__range();
+ if (r.is_empty()) {
+ break;
+ }
+ uint64_t num_to_copy = r.length();
+ if (num_to_copy > (raw.m_max_incl - raw.m_buf.meta.wi)) {
+ return error_messages.resolve(
+ error_messages.max_incl_metadata_length_exceeded);
+ } else if (num_to_copy > (raw.m_buf.data.len - raw.m_buf.meta.wi)) {
+ switch (raw.grow(num_to_copy + raw.m_buf.meta.wi)) {
+ case sync_io::DynIOBuffer::GrowResult::OK:
+ break;
+ case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
+ return error_messages.resolve(
+ error_messages.max_incl_metadata_length_exceeded);
+ case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
+ return error_messages.resolve(error_messages.out_of_memory);
+ }
+ }
+
+ if (io_buf.reader_position() > r.min_incl) {
+ return error_messages.resolve(error_messages.unsupported_metadata);
+ } else {
+ std::string error_message =
+ AdvanceIOBufferTo(error_messages, input, io_buf, r.min_incl);
+ if (!error_message.empty()) {
+ return error_message;
+ }
+ }
+
+ while (true) {
+ uint64_t n =
+ wuffs_base__u64__min(num_to_copy, io_buf.reader_length());
+ memcpy(raw.m_buf.writer_pointer(), io_buf.reader_pointer(), n);
+ raw.m_buf.meta.wi += n;
+ io_buf.meta.ri += n;
+ num_to_copy -= n;
+ if (num_to_copy == 0) {
+ break;
+ } else if (io_buf.meta.closed) {
+ return error_messages.resolve(
+ error_messages.unexpected_end_of_file);
+ } else if (!input.BringsItsOwnIOBuffer()) {
+ io_buf.compact();
+ }
+ std::string error_message = input.CopyIn(&io_buf, 0);
+ if (!error_message.empty()) {
+ return error_message;
+ }
+ }
+ break;
+ }
+
+ default:
+ return error_messages.resolve(error_messages.unsupported_metadata);
+ }
+
+ if (status.repr == nullptr) {
+ break;
+ } else if (status.repr != wuffs_base__suspension__even_more_information) {
+ if (status.repr != wuffs_base__suspension__short_write) {
+ return status.message();
+ }
+ switch (raw.grow(wuffs_base__u64__sat_add(raw.m_buf.data.len, 1))) {
+ case sync_io::DynIOBuffer::GrowResult::OK:
+ break;
+ case sync_io::DynIOBuffer::GrowResult::FailedMaxInclExceeded:
+ return error_messages.resolve(
+ error_messages.max_incl_metadata_length_exceeded);
+ case sync_io::DynIOBuffer::GrowResult::FailedOutOfMemory:
+ return error_messages.resolve(error_messages.out_of_memory);
+ }
+ }
+ }
+
+ return (*handle_metadata_func)(handle_metadata_receiver, &minfo,
+ raw.m_buf.reader_slice());
+}
+
+} // namespace private_impl
+
+} // namespace wuffs_aux
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__AUX__BASE)
+
+// ---------------- Auxiliary - CBOR
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
+
+#include <utility>
+
+namespace wuffs_aux {
+
+DecodeCborResult::DecodeCborResult(std::string&& error_message0,
+ uint64_t cursor_position0)
+ : error_message(std::move(error_message0)),
+ cursor_position(cursor_position0) {}
+
+DecodeCborCallbacks::~DecodeCborCallbacks() {}
+
+void //
+DecodeCborCallbacks::Done(DecodeCborResult& result,
+ sync_io::Input& input,
+ IOBuffer& buffer) {}
+
+DecodeCborArgQuirks::DecodeCborArgQuirks(wuffs_base__slice_u32 repr0)
+ : repr(repr0) {}
+
+DecodeCborArgQuirks::DecodeCborArgQuirks(uint32_t* ptr0, size_t len0)
+ : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
+
+DecodeCborArgQuirks //
+DecodeCborArgQuirks::DefaultValue() {
+ return DecodeCborArgQuirks(wuffs_base__empty_slice_u32());
+}
+
+DecodeCborResult //
+DecodeCbor(DecodeCborCallbacks& callbacks,
+ sync_io::Input& input,
+ DecodeCborArgQuirks quirks) {
+ // Prepare the wuffs_base__io_buffer and the resultant error_message.
+ wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
+ wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
+ std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
+ if (!io_buf) {
+ fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
+ fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
+ io_buf = &fallback_io_buf;
+ }
+ // cursor_index is discussed at
+ // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
+ size_t cursor_index = 0;
+ std::string ret_error_message;
+ std::string io_error_message;
+
+ do {
+ // Prepare the low-level CBOR decoder.
+ wuffs_cbor__decoder::unique_ptr dec = wuffs_cbor__decoder::alloc();
+ if (!dec) {
+ ret_error_message = "wuffs_aux::DecodeCbor: out of memory";
+ goto done;
+ }
+ for (size_t i = 0; i < quirks.repr.len; i++) {
+ dec->set_quirk(quirks.repr.ptr[i], 1);
+ }
+
+ // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
+ wuffs_base__token tok_array[256];
+ wuffs_base__token_buffer tok_buf =
+ wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
+ &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
+ wuffs_base__status tok_status = wuffs_base__make_status(nullptr);
+
+ // Prepare other state.
+ int32_t depth = 0;
+ std::string str;
+ int64_t extension_category = 0;
+ uint64_t extension_detail = 0;
+
+ // Valid token's VBCs range in 0 ..= 15. Values over that are for tokens
+ // from outside of the base package, such as the CBOR package.
+ constexpr int64_t EXT_CAT__CBOR_TAG = 16;
+
+ // Loop, doing these two things:
+ // 1. Get the next token.
+ // 2. Process that token.
+ while (true) {
+ // 1. Get the next token.
+
+ while (tok_buf.meta.ri >= tok_buf.meta.wi) {
+ if (tok_status.repr == nullptr) {
+ // No-op.
+ } else if (tok_status.repr == wuffs_base__suspension__short_write) {
+ tok_buf.compact();
+ } else if (tok_status.repr == wuffs_base__suspension__short_read) {
+ // Read from input to io_buf.
+ if (!io_error_message.empty()) {
+ ret_error_message = std::move(io_error_message);
+ goto done;
+ } else if (cursor_index != io_buf->meta.ri) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad cursor_index";
+ goto done;
+ } else if (io_buf->meta.closed) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: io_buf is closed";
+ goto done;
+ }
+ io_buf->compact_retaining(dec->history_retain_length());
+ if (io_buf->meta.wi >= io_buf->data.len) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: io_buf is full";
+ goto done;
+ }
+ cursor_index = io_buf->meta.ri;
+ io_error_message = input.CopyIn(io_buf, dec->history_retain_length());
+ } else {
+ ret_error_message = tok_status.message();
+ goto done;
+ }
+
+ if (WUFFS_CBOR__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad WORKBUF_LEN";
+ goto done;
+ }
+ wuffs_base__slice_u8 work_buf = wuffs_base__empty_slice_u8();
+ tok_status = dec->decode_tokens(&tok_buf, io_buf, work_buf);
+ if ((tok_buf.meta.ri > tok_buf.meta.wi) ||
+ (tok_buf.meta.wi > tok_buf.data.len) ||
+ (io_buf->meta.ri > io_buf->meta.wi) ||
+ (io_buf->meta.wi > io_buf->data.len)) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad buffer indexes";
+ goto done;
+ }
+ }
+
+ wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++];
+ uint64_t token_len = token.length();
+ if ((io_buf->meta.ri < cursor_index) ||
+ ((io_buf->meta.ri - cursor_index) < token_len)) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad token indexes";
+ goto done;
+ }
+ uint8_t* token_ptr = io_buf->data.ptr + cursor_index;
+ cursor_index += static_cast<size_t>(token_len);
+
+ // 2. Process that token.
+
+ uint64_t vbd = token.value_base_detail();
+
+ if (extension_category != 0) {
+ int64_t ext = token.value_extension();
+ if ((ext >= 0) && !token.continued()) {
+ extension_detail = (extension_detail
+ << WUFFS_BASE__TOKEN__VALUE_EXTENSION__NUM_BITS) |
+ static_cast<uint64_t>(ext);
+ switch (extension_category) {
+ case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED:
+ extension_category = 0;
+ ret_error_message =
+ callbacks.AppendI64(static_cast<int64_t>(extension_detail));
+ goto parsed_a_value;
+ case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED:
+ extension_category = 0;
+ ret_error_message = callbacks.AppendU64(extension_detail);
+ goto parsed_a_value;
+ case EXT_CAT__CBOR_TAG:
+ extension_category = 0;
+ ret_error_message = callbacks.AppendCborTag(extension_detail);
+ if (!ret_error_message.empty()) {
+ goto done;
+ }
+ continue;
+ }
+ }
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad extended token";
+ goto done;
+ }
+
+ switch (token.value_base_category()) {
+ case WUFFS_BASE__TOKEN__VBC__FILLER:
+ continue;
+
+ case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
+ ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
+ if (!ret_error_message.empty()) {
+ goto done;
+ }
+ depth++;
+ if (depth > WUFFS_CBOR__DECODER_DEPTH_MAX_INCL) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad depth";
+ goto done;
+ }
+ continue;
+ }
+ ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
+ depth--;
+ if (depth < 0) {
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: bad depth";
+ goto done;
+ }
+ goto parsed_a_value;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__STRING: {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
+ // No-op.
+ } else if (vbd &
+ WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
+ const char* ptr = // Convert from (uint8_t*).
+ static_cast<const char*>(static_cast<void*>(token_ptr));
+ str.append(ptr, static_cast<size_t>(token_len));
+ } else {
+ goto fail;
+ }
+ if (token.continued()) {
+ continue;
+ }
+ ret_error_message =
+ (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CHAIN_MUST_BE_UTF_8)
+ ? callbacks.AppendTextString(std::move(str))
+ : callbacks.AppendByteString(std::move(str));
+ str.clear();
+ goto parsed_a_value;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
+ uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
+ size_t n = wuffs_base__utf_8__encode(
+ wuffs_base__make_slice_u8(
+ &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
+ static_cast<uint32_t>(vbd));
+ const char* ptr = // Convert from (uint8_t*).
+ static_cast<const char*>(static_cast<void*>(&u[0]));
+ str.append(ptr, n);
+ if (token.continued()) {
+ continue;
+ }
+ goto fail;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__LITERAL: {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL) {
+ ret_error_message = callbacks.AppendNull();
+ } else if (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__UNDEFINED) {
+ ret_error_message = callbacks.AppendUndefined();
+ } else {
+ ret_error_message = callbacks.AppendBool(
+ vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
+ }
+ goto parsed_a_value;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__NUMBER: {
+ const uint64_t cfp_fbbe_fifb =
+ WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT |
+ WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_BINARY_BIG_ENDIAN |
+ WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_IGNORE_FIRST_BYTE;
+ if ((vbd & cfp_fbbe_fifb) == cfp_fbbe_fifb) {
+ double f;
+ switch (token_len) {
+ case 3:
+ f = wuffs_base__ieee_754_bit_representation__from_u16_to_f64(
+ wuffs_base__peek_u16be__no_bounds_check(token_ptr + 1));
+ break;
+ case 5:
+ f = wuffs_base__ieee_754_bit_representation__from_u32_to_f64(
+ wuffs_base__peek_u32be__no_bounds_check(token_ptr + 1));
+ break;
+ case 9:
+ f = wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
+ wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
+ break;
+ default:
+ goto fail;
+ }
+ ret_error_message = callbacks.AppendF64(f);
+ goto parsed_a_value;
+ }
+ goto fail;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED: {
+ if (token.continued()) {
+ extension_category = WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_SIGNED;
+ extension_detail =
+ static_cast<uint64_t>(token.value_base_detail__sign_extended());
+ continue;
+ }
+ ret_error_message =
+ callbacks.AppendI64(token.value_base_detail__sign_extended());
+ goto parsed_a_value;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED: {
+ if (token.continued()) {
+ extension_category =
+ WUFFS_BASE__TOKEN__VBC__INLINE_INTEGER_UNSIGNED;
+ extension_detail = vbd;
+ continue;
+ }
+ ret_error_message = callbacks.AppendU64(vbd);
+ goto parsed_a_value;
+ }
+ }
+
+ if (token.value_major() == WUFFS_CBOR__TOKEN_VALUE_MAJOR) {
+ uint64_t value_minor = token.value_minor();
+ if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__MINUS_1_MINUS_X) {
+ if (token_len == 9) {
+ ret_error_message = callbacks.AppendMinus1MinusX(
+ wuffs_base__peek_u64be__no_bounds_check(token_ptr + 1));
+ goto parsed_a_value;
+ }
+ } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__SIMPLE_VALUE) {
+ ret_error_message =
+ callbacks.AppendCborSimpleValue(static_cast<uint8_t>(
+ value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK));
+ goto parsed_a_value;
+ } else if (value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__TAG) {
+ if (token.continued()) {
+ extension_category = EXT_CAT__CBOR_TAG;
+ extension_detail =
+ value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK;
+ continue;
+ }
+ ret_error_message = callbacks.AppendCborTag(
+ value_minor & WUFFS_CBOR__TOKEN_VALUE_MINOR__DETAIL_MASK);
+ if (!ret_error_message.empty()) {
+ goto done;
+ }
+ continue;
+ }
+ }
+
+ fail:
+ ret_error_message =
+ "wuffs_aux::DecodeCbor: internal error: unexpected token";
+ goto done;
+
+ parsed_a_value:
+ if (!ret_error_message.empty() || (depth == 0)) {
+ goto done;
+ }
+ }
+ } while (false);
+
+done:
+ DecodeCborResult result(
+ std::move(ret_error_message),
+ wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
+ callbacks.Done(result, input, *io_buf);
+ return result;
+}
+
+} // namespace wuffs_aux
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__AUX__CBOR)
+
+// ---------------- Auxiliary - Image
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
+
+#include <utility>
+
+namespace wuffs_aux {
+
+DecodeImageResult::DecodeImageResult(MemOwner&& pixbuf_mem_owner0,
+ wuffs_base__pixel_buffer pixbuf0,
+ std::string&& error_message0)
+ : pixbuf_mem_owner(std::move(pixbuf_mem_owner0)),
+ pixbuf(pixbuf0),
+ error_message(std::move(error_message0)) {}
+
+DecodeImageResult::DecodeImageResult(std::string&& error_message0)
+ : pixbuf_mem_owner(nullptr, &free),
+ pixbuf(wuffs_base__null_pixel_buffer()),
+ error_message(std::move(error_message0)) {}
+
+DecodeImageCallbacks::~DecodeImageCallbacks() {}
+
+DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
+ MemOwner&& mem_owner0,
+ wuffs_base__pixel_buffer pixbuf0)
+ : mem_owner(std::move(mem_owner0)), pixbuf(pixbuf0), error_message("") {}
+
+DecodeImageCallbacks::AllocPixbufResult::AllocPixbufResult(
+ std::string&& error_message0)
+ : mem_owner(nullptr, &free),
+ pixbuf(wuffs_base__null_pixel_buffer()),
+ error_message(std::move(error_message0)) {}
+
+DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
+ MemOwner&& mem_owner0,
+ wuffs_base__slice_u8 workbuf0)
+ : mem_owner(std::move(mem_owner0)), workbuf(workbuf0), error_message("") {}
+
+DecodeImageCallbacks::AllocWorkbufResult::AllocWorkbufResult(
+ std::string&& error_message0)
+ : mem_owner(nullptr, &free),
+ workbuf(wuffs_base__empty_slice_u8()),
+ error_message(std::move(error_message0)) {}
+
+wuffs_base__image_decoder::unique_ptr //
+DecodeImageCallbacks::SelectDecoder(uint32_t fourcc,
+ wuffs_base__slice_u8 prefix_data,
+ bool prefix_closed) {
+ switch (fourcc) {
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__BMP)
+ case WUFFS_BASE__FOURCC__BMP:
+ return wuffs_bmp__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__GIF)
+ case WUFFS_BASE__FOURCC__GIF:
+ return wuffs_gif__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__JPEG)
+ case WUFFS_BASE__FOURCC__JPEG:
+ return wuffs_jpeg__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NIE)
+ case WUFFS_BASE__FOURCC__NIE:
+ return wuffs_nie__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__NETPBM)
+ case WUFFS_BASE__FOURCC__NPBM:
+ return wuffs_netpbm__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__PNG)
+ case WUFFS_BASE__FOURCC__PNG: {
+ auto dec = wuffs_png__decoder::alloc_as__wuffs_base__image_decoder();
+ // Favor faster decodes over rejecting invalid checksums.
+ dec->set_quirk(WUFFS_BASE__QUIRK_IGNORE_CHECKSUM, 1);
+ return dec;
+ }
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__TGA)
+ case WUFFS_BASE__FOURCC__TGA:
+ return wuffs_tga__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__WBMP)
+ case WUFFS_BASE__FOURCC__WBMP:
+ return wuffs_wbmp__decoder::alloc_as__wuffs_base__image_decoder();
+#endif
+ }
+
+ return wuffs_base__image_decoder::unique_ptr(nullptr);
+}
+
+std::string //
+DecodeImageCallbacks::HandleMetadata(const wuffs_base__more_information& minfo,
+ wuffs_base__slice_u8 raw) {
+ return "";
+}
+
+wuffs_base__pixel_format //
+DecodeImageCallbacks::SelectPixfmt(
+ const wuffs_base__image_config& image_config) {
+ return wuffs_base__make_pixel_format(WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL);
+}
+
+DecodeImageCallbacks::AllocPixbufResult //
+DecodeImageCallbacks::AllocPixbuf(const wuffs_base__image_config& image_config,
+ bool allow_uninitialized_memory) {
+ uint32_t w = image_config.pixcfg.width();
+ uint32_t h = image_config.pixcfg.height();
+ if ((w == 0) || (h == 0)) {
+ return AllocPixbufResult("");
+ }
+ uint64_t len = image_config.pixcfg.pixbuf_len();
+ if ((len == 0) || (SIZE_MAX < len)) {
+ return AllocPixbufResult(DecodeImage_UnsupportedPixelConfiguration);
+ }
+ void* ptr =
+ allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
+ if (!ptr) {
+ return AllocPixbufResult(DecodeImage_OutOfMemory);
+ }
+ wuffs_base__pixel_buffer pixbuf;
+ wuffs_base__status status = pixbuf.set_from_slice(
+ &image_config.pixcfg,
+ wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
+ if (!status.is_ok()) {
+ free(ptr);
+ return AllocPixbufResult(status.message());
+ }
+ return AllocPixbufResult(MemOwner(ptr, &free), pixbuf);
+}
+
+DecodeImageCallbacks::AllocWorkbufResult //
+DecodeImageCallbacks::AllocWorkbuf(wuffs_base__range_ii_u64 len_range,
+ bool allow_uninitialized_memory) {
+ uint64_t len = len_range.max_incl;
+ if (len == 0) {
+ return AllocWorkbufResult("");
+ } else if (SIZE_MAX < len) {
+ return AllocWorkbufResult(DecodeImage_OutOfMemory);
+ }
+ void* ptr =
+ allow_uninitialized_memory ? malloc((size_t)len) : calloc((size_t)len, 1);
+ if (!ptr) {
+ return AllocWorkbufResult(DecodeImage_OutOfMemory);
+ }
+ return AllocWorkbufResult(
+ MemOwner(ptr, &free),
+ wuffs_base__make_slice_u8((uint8_t*)ptr, (size_t)len));
+}
+
+void //
+DecodeImageCallbacks::Done(
+ DecodeImageResult& result,
+ sync_io::Input& input,
+ IOBuffer& buffer,
+ wuffs_base__image_decoder::unique_ptr image_decoder) {}
+
+const char DecodeImage_BufferIsTooShort[] = //
+ "wuffs_aux::DecodeImage: buffer is too short";
+const char DecodeImage_MaxInclDimensionExceeded[] = //
+ "wuffs_aux::DecodeImage: max_incl_dimension exceeded";
+const char DecodeImage_MaxInclMetadataLengthExceeded[] = //
+ "wuffs_aux::DecodeImage: max_incl_metadata_length exceeded";
+const char DecodeImage_OutOfMemory[] = //
+ "wuffs_aux::DecodeImage: out of memory";
+const char DecodeImage_UnexpectedEndOfFile[] = //
+ "wuffs_aux::DecodeImage: unexpected end of file";
+const char DecodeImage_UnsupportedImageFormat[] = //
+ "wuffs_aux::DecodeImage: unsupported image format";
+const char DecodeImage_UnsupportedMetadata[] = //
+ "wuffs_aux::DecodeImage: unsupported metadata";
+const char DecodeImage_UnsupportedPixelBlend[] = //
+ "wuffs_aux::DecodeImage: unsupported pixel blend";
+const char DecodeImage_UnsupportedPixelConfiguration[] = //
+ "wuffs_aux::DecodeImage: unsupported pixel configuration";
+const char DecodeImage_UnsupportedPixelFormat[] = //
+ "wuffs_aux::DecodeImage: unsupported pixel format";
+
+DecodeImageArgQuirks::DecodeImageArgQuirks(wuffs_base__slice_u32 repr0)
+ : repr(repr0) {}
+
+DecodeImageArgQuirks::DecodeImageArgQuirks(uint32_t* ptr0, size_t len0)
+ : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
+
+DecodeImageArgQuirks //
+DecodeImageArgQuirks::DefaultValue() {
+ return DecodeImageArgQuirks(wuffs_base__empty_slice_u32());
+}
+
+DecodeImageArgFlags::DecodeImageArgFlags(uint64_t repr0) : repr(repr0) {}
+
+DecodeImageArgFlags //
+DecodeImageArgFlags::DefaultValue() {
+ return DecodeImageArgFlags(0);
+}
+
+DecodeImageArgPixelBlend::DecodeImageArgPixelBlend(
+ wuffs_base__pixel_blend repr0)
+ : repr(repr0) {}
+
+DecodeImageArgPixelBlend //
+DecodeImageArgPixelBlend::DefaultValue() {
+ return DecodeImageArgPixelBlend(WUFFS_BASE__PIXEL_BLEND__SRC);
+}
+
+DecodeImageArgBackgroundColor::DecodeImageArgBackgroundColor(
+ wuffs_base__color_u32_argb_premul repr0)
+ : repr(repr0) {}
+
+DecodeImageArgBackgroundColor //
+DecodeImageArgBackgroundColor::DefaultValue() {
+ return DecodeImageArgBackgroundColor(1);
+}
+
+DecodeImageArgMaxInclDimension::DecodeImageArgMaxInclDimension(uint32_t repr0)
+ : repr(repr0) {}
+
+DecodeImageArgMaxInclDimension //
+DecodeImageArgMaxInclDimension::DefaultValue() {
+ return DecodeImageArgMaxInclDimension(1048575);
+}
+
+DecodeImageArgMaxInclMetadataLength::DecodeImageArgMaxInclMetadataLength(
+ uint64_t repr0)
+ : repr(repr0) {}
+
+DecodeImageArgMaxInclMetadataLength //
+DecodeImageArgMaxInclMetadataLength::DefaultValue() {
+ return DecodeImageArgMaxInclMetadataLength(16777215);
+}
+
+// --------
+
+namespace {
+
+const private_impl::ErrorMessages DecodeImageErrorMessages = {
+ DecodeImage_MaxInclMetadataLengthExceeded, //
+ DecodeImage_OutOfMemory, //
+ DecodeImage_UnexpectedEndOfFile, //
+ DecodeImage_UnsupportedMetadata, //
+ DecodeImage_UnsupportedImageFormat, //
+};
+
+std::string //
+DecodeImageAdvanceIOBufferTo(sync_io::Input& input,
+ wuffs_base__io_buffer& io_buf,
+ uint64_t absolute_position) {
+ return private_impl::AdvanceIOBufferTo(DecodeImageErrorMessages, input,
+ io_buf, absolute_position);
+}
+
+wuffs_base__status //
+DIHM0(void* self,
+ wuffs_base__io_buffer* a_dst,
+ wuffs_base__more_information* a_minfo,
+ wuffs_base__io_buffer* a_src) {
+ return wuffs_base__image_decoder__tell_me_more(
+ static_cast<wuffs_base__image_decoder*>(self), a_dst, a_minfo, a_src);
+}
+
+std::string //
+DIHM1(void* self,
+ const wuffs_base__more_information* minfo,
+ wuffs_base__slice_u8 raw) {
+ return static_cast<DecodeImageCallbacks*>(self)->HandleMetadata(*minfo, raw);
+}
+
+std::string //
+DecodeImageHandleMetadata(wuffs_base__image_decoder::unique_ptr& image_decoder,
+ DecodeImageCallbacks& callbacks,
+ sync_io::Input& input,
+ wuffs_base__io_buffer& io_buf,
+ sync_io::DynIOBuffer& raw_metadata_buf) {
+ return private_impl::HandleMetadata(DecodeImageErrorMessages, input, io_buf,
+ raw_metadata_buf, DIHM0,
+ static_cast<void*>(image_decoder.get()),
+ DIHM1, static_cast<void*>(&callbacks));
+}
+
+DecodeImageResult //
+DecodeImage0(wuffs_base__image_decoder::unique_ptr& image_decoder,
+ DecodeImageCallbacks& callbacks,
+ sync_io::Input& input,
+ wuffs_base__io_buffer& io_buf,
+ wuffs_base__slice_u32 quirks,
+ uint64_t flags,
+ wuffs_base__pixel_blend pixel_blend,
+ wuffs_base__color_u32_argb_premul background_color,
+ uint32_t max_incl_dimension,
+ uint64_t max_incl_metadata_length) {
+ // Check args.
+ switch (pixel_blend) {
+ case WUFFS_BASE__PIXEL_BLEND__SRC:
+ case WUFFS_BASE__PIXEL_BLEND__SRC_OVER:
+ break;
+ default:
+ return DecodeImageResult(DecodeImage_UnsupportedPixelBlend);
+ }
+
+ wuffs_base__image_config image_config = wuffs_base__null_image_config();
+ sync_io::DynIOBuffer raw_metadata_buf(max_incl_metadata_length);
+ uint64_t start_pos = io_buf.reader_position();
+ bool interested_in_metadata_after_the_frame = false;
+ bool redirected = false;
+ int32_t fourcc = 0;
+redirect:
+ do {
+ // Determine the image format.
+ if (!redirected) {
+ while (true) {
+ fourcc = wuffs_base__magic_number_guess_fourcc(io_buf.reader_slice(),
+ io_buf.meta.closed);
+ if (fourcc > 0) {
+ break;
+ } else if ((fourcc == 0) && (io_buf.reader_length() >= 64)) {
+ // Having (fourcc == 0) means that Wuffs' built in MIME sniffer
+ // didn't recognize the image format. Nonetheless, custom callbacks
+ // may still be able to do their own MIME sniffing, for exotic image
+ // types. We try to give them at least 64 bytes of prefix data when
+ // one-shot-calling callbacks.SelectDecoder. There is no mechanism
+ // for the callbacks to request a longer prefix.
+ break;
+ } else if (io_buf.meta.closed || (io_buf.writer_length() == 0)) {
+ fourcc = 0;
+ break;
+ }
+ std::string error_message = input.CopyIn(&io_buf, 0);
+ if (!error_message.empty()) {
+ return DecodeImageResult(std::move(error_message));
+ }
+ }
+ } else {
+ wuffs_base__io_buffer empty = wuffs_base__empty_io_buffer();
+ wuffs_base__more_information minfo = wuffs_base__empty_more_information();
+ wuffs_base__status tmm_status =
+ image_decoder->tell_me_more(&empty, &minfo, &io_buf);
+ if (tmm_status.repr != nullptr) {
+ return DecodeImageResult(tmm_status.message());
+ }
+ if (minfo.flavor != WUFFS_BASE__MORE_INFORMATION__FLAVOR__IO_REDIRECT) {
+ return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
+ }
+ uint64_t pos = minfo.io_redirect__range().min_incl;
+ if (pos <= start_pos) {
+ // Redirects must go forward.
+ return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
+ }
+ std::string error_message =
+ DecodeImageAdvanceIOBufferTo(input, io_buf, pos);
+ if (!error_message.empty()) {
+ return DecodeImageResult(std::move(error_message));
+ }
+ fourcc = (int32_t)(minfo.io_redirect__fourcc());
+ if (fourcc == 0) {
+ return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
+ }
+ image_decoder.reset();
+ }
+
+ // Select the image decoder.
+ image_decoder = callbacks.SelectDecoder(
+ (uint32_t)fourcc, io_buf.reader_slice(), io_buf.meta.closed);
+ if (!image_decoder) {
+ return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
+ }
+
+ // Apply quirks.
+ for (size_t i = 0; i < quirks.len; i++) {
+ image_decoder->set_quirk(quirks.ptr[i], 1);
+ }
+
+ // Apply flags.
+ if (flags != 0) {
+ if (flags & DecodeImageArgFlags::REPORT_METADATA_CHRM) {
+ image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__CHRM, true);
+ }
+ if (flags & DecodeImageArgFlags::REPORT_METADATA_EXIF) {
+ interested_in_metadata_after_the_frame = true;
+ image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__EXIF, true);
+ }
+ if (flags & DecodeImageArgFlags::REPORT_METADATA_GAMA) {
+ image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__GAMA, true);
+ }
+ if (flags & DecodeImageArgFlags::REPORT_METADATA_ICCP) {
+ image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__ICCP, true);
+ }
+ if (flags & DecodeImageArgFlags::REPORT_METADATA_KVP) {
+ interested_in_metadata_after_the_frame = true;
+ image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__KVP, true);
+ }
+ if (flags & DecodeImageArgFlags::REPORT_METADATA_SRGB) {
+ image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__SRGB, true);
+ }
+ if (flags & DecodeImageArgFlags::REPORT_METADATA_XMP) {
+ interested_in_metadata_after_the_frame = true;
+ image_decoder->set_report_metadata(WUFFS_BASE__FOURCC__XMP, true);
+ }
+ }
+
+ // Decode the image config.
+ while (true) {
+ wuffs_base__status id_dic_status =
+ image_decoder->decode_image_config(&image_config, &io_buf);
+ if (id_dic_status.repr == nullptr) {
+ break;
+ } else if (id_dic_status.repr == wuffs_base__note__i_o_redirect) {
+ if (redirected) {
+ return DecodeImageResult(DecodeImage_UnsupportedImageFormat);
+ }
+ redirected = true;
+ goto redirect;
+ } else if (id_dic_status.repr == wuffs_base__note__metadata_reported) {
+ std::string error_message = DecodeImageHandleMetadata(
+ image_decoder, callbacks, input, io_buf, raw_metadata_buf);
+ if (!error_message.empty()) {
+ return DecodeImageResult(std::move(error_message));
+ }
+ } else if (id_dic_status.repr != wuffs_base__suspension__short_read) {
+ return DecodeImageResult(id_dic_status.message());
+ } else if (io_buf.meta.closed) {
+ return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
+ } else {
+ std::string error_message =
+ input.CopyIn(&io_buf, image_decoder->history_retain_length());
+ if (!error_message.empty()) {
+ return DecodeImageResult(std::move(error_message));
+ }
+ }
+ }
+ } while (false);
+ if (!interested_in_metadata_after_the_frame) {
+ raw_metadata_buf.drop();
+ }
+
+ // Select the pixel format.
+ uint32_t w = image_config.pixcfg.width();
+ uint32_t h = image_config.pixcfg.height();
+ if ((w > max_incl_dimension) || (h > max_incl_dimension)) {
+ return DecodeImageResult(DecodeImage_MaxInclDimensionExceeded);
+ }
+ wuffs_base__pixel_format pixel_format = callbacks.SelectPixfmt(image_config);
+ if (pixel_format.repr != image_config.pixcfg.pixel_format().repr) {
+ switch (pixel_format.repr) {
+ case WUFFS_BASE__PIXEL_FORMAT__BGR_565:
+ case WUFFS_BASE__PIXEL_FORMAT__BGR:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_NONPREMUL_4X16LE:
+ case WUFFS_BASE__PIXEL_FORMAT__BGRA_PREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGB:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_NONPREMUL:
+ case WUFFS_BASE__PIXEL_FORMAT__RGBA_PREMUL:
+ break;
+ default:
+ return DecodeImageResult(DecodeImage_UnsupportedPixelFormat);
+ }
+ image_config.pixcfg.set(pixel_format.repr,
+ WUFFS_BASE__PIXEL_SUBSAMPLING__NONE, w, h);
+ }
+
+ // Allocate the pixel buffer.
+ bool valid_background_color =
+ wuffs_base__color_u32_argb_premul__is_valid(background_color);
+ DecodeImageCallbacks::AllocPixbufResult alloc_pixbuf_result =
+ callbacks.AllocPixbuf(image_config, valid_background_color);
+ if (!alloc_pixbuf_result.error_message.empty()) {
+ return DecodeImageResult(std::move(alloc_pixbuf_result.error_message));
+ }
+ wuffs_base__pixel_buffer pixel_buffer = alloc_pixbuf_result.pixbuf;
+ if (valid_background_color) {
+ wuffs_base__status pb_scufr_status = pixel_buffer.set_color_u32_fill_rect(
+ pixel_buffer.pixcfg.bounds(), background_color);
+ if (pb_scufr_status.repr != nullptr) {
+ return DecodeImageResult(pb_scufr_status.message());
+ }
+ }
+
+ // Allocate the work buffer. Wuffs' decoders conventionally assume that this
+ // can be uninitialized memory.
+ wuffs_base__range_ii_u64 workbuf_len = image_decoder->workbuf_len();
+ DecodeImageCallbacks::AllocWorkbufResult alloc_workbuf_result =
+ callbacks.AllocWorkbuf(workbuf_len, true);
+ if (!alloc_workbuf_result.error_message.empty()) {
+ return DecodeImageResult(std::move(alloc_workbuf_result.error_message));
+ } else if (alloc_workbuf_result.workbuf.len < workbuf_len.min_incl) {
+ return DecodeImageResult(DecodeImage_BufferIsTooShort);
+ }
+
+ // Decode the frame config.
+ wuffs_base__frame_config frame_config = wuffs_base__null_frame_config();
+ while (true) {
+ wuffs_base__status id_dfc_status =
+ image_decoder->decode_frame_config(&frame_config, &io_buf);
+ if (id_dfc_status.repr == nullptr) {
+ break;
+ } else if (id_dfc_status.repr == wuffs_base__note__metadata_reported) {
+ std::string error_message = DecodeImageHandleMetadata(
+ image_decoder, callbacks, input, io_buf, raw_metadata_buf);
+ if (!error_message.empty()) {
+ return DecodeImageResult(std::move(error_message));
+ }
+ } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
+ return DecodeImageResult(id_dfc_status.message());
+ } else if (io_buf.meta.closed) {
+ return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
+ } else {
+ std::string error_message =
+ input.CopyIn(&io_buf, image_decoder->history_retain_length());
+ if (!error_message.empty()) {
+ return DecodeImageResult(std::move(error_message));
+ }
+ }
+ }
+
+ // Decode the frame (the pixels).
+ //
+ // From here on, always returns the pixel_buffer. If we get this far, we can
+ // still display a partial image, even if we encounter an error.
+ std::string message("");
+ if ((pixel_blend == WUFFS_BASE__PIXEL_BLEND__SRC_OVER) &&
+ frame_config.overwrite_instead_of_blend()) {
+ pixel_blend = WUFFS_BASE__PIXEL_BLEND__SRC;
+ }
+ while (true) {
+ wuffs_base__status id_df_status =
+ image_decoder->decode_frame(&pixel_buffer, &io_buf, pixel_blend,
+ alloc_workbuf_result.workbuf, nullptr);
+ if (id_df_status.repr == nullptr) {
+ break;
+ } else if (id_df_status.repr != wuffs_base__suspension__short_read) {
+ message = id_df_status.message();
+ break;
+ } else if (io_buf.meta.closed) {
+ message = DecodeImage_UnexpectedEndOfFile;
+ break;
+ } else {
+ std::string error_message =
+ input.CopyIn(&io_buf, image_decoder->history_retain_length());
+ if (!error_message.empty()) {
+ message = std::move(error_message);
+ break;
+ }
+ }
+ }
+
+ // Decode any metadata after the frame.
+ if (interested_in_metadata_after_the_frame) {
+ while (true) {
+ wuffs_base__status id_dfc_status =
+ image_decoder->decode_frame_config(NULL, &io_buf);
+ if (id_dfc_status.repr == wuffs_base__note__end_of_data) {
+ break;
+ } else if (id_dfc_status.repr == nullptr) {
+ continue;
+ } else if (id_dfc_status.repr == wuffs_base__note__metadata_reported) {
+ std::string error_message = DecodeImageHandleMetadata(
+ image_decoder, callbacks, input, io_buf, raw_metadata_buf);
+ if (!error_message.empty()) {
+ return DecodeImageResult(std::move(error_message));
+ }
+ } else if (id_dfc_status.repr != wuffs_base__suspension__short_read) {
+ return DecodeImageResult(id_dfc_status.message());
+ } else if (io_buf.meta.closed) {
+ return DecodeImageResult(DecodeImage_UnexpectedEndOfFile);
+ } else {
+ std::string error_message =
+ input.CopyIn(&io_buf, image_decoder->history_retain_length());
+ if (!error_message.empty()) {
+ return DecodeImageResult(std::move(error_message));
+ }
+ }
+ }
+ }
+
+ return DecodeImageResult(std::move(alloc_pixbuf_result.mem_owner),
+ pixel_buffer, std::move(message));
+}
+
+} // namespace
+
+DecodeImageResult //
+DecodeImage(DecodeImageCallbacks& callbacks,
+ sync_io::Input& input,
+ DecodeImageArgQuirks quirks,
+ DecodeImageArgFlags flags,
+ DecodeImageArgPixelBlend pixel_blend,
+ DecodeImageArgBackgroundColor background_color,
+ DecodeImageArgMaxInclDimension max_incl_dimension,
+ DecodeImageArgMaxInclMetadataLength max_incl_metadata_length) {
+ wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
+ wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
+ std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
+ if (!io_buf) {
+ fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[32768]);
+ fallback_io_buf =
+ wuffs_base__ptr_u8__writer(fallback_io_array.get(), 32768);
+ io_buf = &fallback_io_buf;
+ }
+
+ wuffs_base__image_decoder::unique_ptr image_decoder(nullptr);
+ DecodeImageResult result =
+ DecodeImage0(image_decoder, callbacks, input, *io_buf, quirks.repr,
+ flags.repr, pixel_blend.repr, background_color.repr,
+ max_incl_dimension.repr, max_incl_metadata_length.repr);
+ callbacks.Done(result, input, *io_buf, std::move(image_decoder));
+ return result;
+}
+
+} // namespace wuffs_aux
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__AUX__IMAGE)
+
+// ---------------- Auxiliary - JSON
+
+#if !defined(WUFFS_CONFIG__MODULES) || defined(WUFFS_CONFIG__MODULE__AUX__JSON)
+
+#include <utility>
+
+namespace wuffs_aux {
+
+DecodeJsonResult::DecodeJsonResult(std::string&& error_message0,
+ uint64_t cursor_position0)
+ : error_message(std::move(error_message0)),
+ cursor_position(cursor_position0) {}
+
+DecodeJsonCallbacks::~DecodeJsonCallbacks() {}
+
+void //
+DecodeJsonCallbacks::Done(DecodeJsonResult& result,
+ sync_io::Input& input,
+ IOBuffer& buffer) {}
+
+const char DecodeJson_BadJsonPointer[] = //
+ "wuffs_aux::DecodeJson: bad JSON Pointer";
+const char DecodeJson_NoMatch[] = //
+ "wuffs_aux::DecodeJson: no match";
+
+DecodeJsonArgQuirks::DecodeJsonArgQuirks(wuffs_base__slice_u32 repr0)
+ : repr(repr0) {}
+
+DecodeJsonArgQuirks::DecodeJsonArgQuirks(uint32_t* ptr0, size_t len0)
+ : repr(wuffs_base__make_slice_u32(ptr0, len0)) {}
+
+DecodeJsonArgQuirks //
+DecodeJsonArgQuirks::DefaultValue() {
+ return DecodeJsonArgQuirks(wuffs_base__empty_slice_u32());
+}
+
+DecodeJsonArgJsonPointer::DecodeJsonArgJsonPointer(std::string repr0)
+ : repr(repr0) {}
+
+DecodeJsonArgJsonPointer //
+DecodeJsonArgJsonPointer::DefaultValue() {
+ return DecodeJsonArgJsonPointer(std::string());
+}
+
+// --------
+
+#define WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN \
+ while (tok_buf.meta.ri >= tok_buf.meta.wi) { \
+ if (tok_status.repr == nullptr) { \
+ goto done; \
+ } else if (tok_status.repr == wuffs_base__suspension__short_write) { \
+ tok_buf.compact(); \
+ } else if (tok_status.repr == wuffs_base__suspension__short_read) { \
+ if (!io_error_message.empty()) { \
+ ret_error_message = std::move(io_error_message); \
+ goto done; \
+ } else if (cursor_index != io_buf->meta.ri) { \
+ ret_error_message = \
+ "wuffs_aux::DecodeJson: internal error: bad cursor_index"; \
+ goto done; \
+ } else if (io_buf->meta.closed) { \
+ ret_error_message = \
+ "wuffs_aux::DecodeJson: internal error: io_buf is closed"; \
+ goto done; \
+ } \
+ io_buf->compact_retaining(dec->history_retain_length()); \
+ if (io_buf->meta.wi >= io_buf->data.len) { \
+ ret_error_message = \
+ "wuffs_aux::DecodeJson: internal error: io_buf is full"; \
+ goto done; \
+ } \
+ cursor_index = io_buf->meta.ri; \
+ io_error_message = input.CopyIn(io_buf, dec->history_retain_length()); \
+ } else { \
+ ret_error_message = tok_status.message(); \
+ goto done; \
+ } \
+ tok_status = \
+ dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8()); \
+ if ((tok_buf.meta.ri > tok_buf.meta.wi) || \
+ (tok_buf.meta.wi > tok_buf.data.len) || \
+ (io_buf->meta.ri > io_buf->meta.wi) || \
+ (io_buf->meta.wi > io_buf->data.len)) { \
+ ret_error_message = \
+ "wuffs_aux::DecodeJson: internal error: bad buffer indexes"; \
+ goto done; \
+ } \
+ } \
+ wuffs_base__token token = tok_buf.data.ptr[tok_buf.meta.ri++]; \
+ uint64_t token_len = token.length(); \
+ if ((io_buf->meta.ri < cursor_index) || \
+ ((io_buf->meta.ri - cursor_index) < token_len)) { \
+ ret_error_message = \
+ "wuffs_aux::DecodeJson: internal error: bad token indexes"; \
+ goto done; \
+ } \
+ uint8_t* token_ptr = io_buf->data.ptr + cursor_index; \
+ (void)(token_ptr); \
+ cursor_index += static_cast<size_t>(token_len)
+
+// --------
+
+namespace {
+
+// DecodeJson_SplitJsonPointer returns ("bar", 8) for ("/foo/bar/b~1z/qux", 5,
+// etc). It returns a 0 size_t when s has invalid JSON Pointer syntax or i is
+// out of bounds.
+//
+// The string returned is unescaped. If calling it again, this time with i=8,
+// the "b~1z" substring would be returned as "b/z".
+std::pair<std::string, size_t> //
+DecodeJson_SplitJsonPointer(std::string& s,
+ size_t i,
+ bool allow_tilde_n_tilde_r_tilde_t) {
+ std::string fragment;
+ if (i > s.size()) {
+ return std::make_pair(std::string(), 0);
+ }
+ while (i < s.size()) {
+ char c = s[i];
+ if (c == '/') {
+ break;
+ } else if (c != '~') {
+ fragment.push_back(c);
+ i++;
+ continue;
+ }
+ i++;
+ if (i >= s.size()) {
+ return std::make_pair(std::string(), 0);
+ }
+ c = s[i];
+ if (c == '0') {
+ fragment.push_back('~');
+ i++;
+ continue;
+ } else if (c == '1') {
+ fragment.push_back('/');
+ i++;
+ continue;
+ } else if (allow_tilde_n_tilde_r_tilde_t) {
+ if (c == 'n') {
+ fragment.push_back('\n');
+ i++;
+ continue;
+ } else if (c == 'r') {
+ fragment.push_back('\r');
+ i++;
+ continue;
+ } else if (c == 't') {
+ fragment.push_back('\t');
+ i++;
+ continue;
+ }
+ }
+ return std::make_pair(std::string(), 0);
+ }
+ return std::make_pair(std::move(fragment), i);
+}
+
+// --------
+
+std::string //
+DecodeJson_WalkJsonPointerFragment(wuffs_base__token_buffer& tok_buf,
+ wuffs_base__status& tok_status,
+ wuffs_json__decoder::unique_ptr& dec,
+ wuffs_base__io_buffer* io_buf,
+ std::string& io_error_message,
+ size_t& cursor_index,
+ sync_io::Input& input,
+ std::string& json_pointer_fragment) {
+ std::string ret_error_message;
+ while (true) {
+ WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
+
+ int64_t vbc = token.value_base_category();
+ uint64_t vbd = token.value_base_detail();
+ if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
+ continue;
+ } else if ((vbc != WUFFS_BASE__TOKEN__VBC__STRUCTURE) ||
+ !(vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH)) {
+ return DecodeJson_NoMatch;
+ } else if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__TO_LIST) {
+ goto do_list;
+ }
+ goto do_dict;
+ }
+
+do_dict:
+ // Alternate between these two things:
+ // 1. Decode the next dict key (a string). If it matches the fragment, we're
+ // done (success). If we've reached the dict's end (VBD__STRUCTURE__POP)
+ // so that there was no next dict key, we're done (failure).
+ // 2. Otherwise, skip the next dict value.
+ while (true) {
+ for (std::string str; true;) {
+ WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
+
+ int64_t vbc = token.value_base_category();
+ uint64_t vbd = token.value_base_detail();
+ switch (vbc) {
+ case WUFFS_BASE__TOKEN__VBC__FILLER:
+ continue;
+
+ case WUFFS_BASE__TOKEN__VBC__STRUCTURE:
+ if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
+ goto fail;
+ }
+ return DecodeJson_NoMatch;
+
+ case WUFFS_BASE__TOKEN__VBC__STRING: {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
+ // No-op.
+ } else if (vbd &
+ WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
+ const char* ptr = // Convert from (uint8_t*).
+ static_cast<const char*>(static_cast<void*>(token_ptr));
+ str.append(ptr, static_cast<size_t>(token_len));
+ } else {
+ goto fail;
+ }
+ break;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
+ uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
+ size_t n = wuffs_base__utf_8__encode(
+ wuffs_base__make_slice_u8(
+ &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
+ static_cast<uint32_t>(vbd));
+ const char* ptr = // Convert from (uint8_t*).
+ static_cast<const char*>(static_cast<void*>(&u[0]));
+ str.append(ptr, n);
+ break;
+ }
+
+ default:
+ goto fail;
+ }
+
+ if (token.continued()) {
+ continue;
+ }
+ if (str == json_pointer_fragment) {
+ return "";
+ }
+ goto skip_the_next_dict_value;
+ }
+
+ skip_the_next_dict_value:
+ for (uint32_t skip_depth = 0; true;) {
+ WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
+
+ int64_t vbc = token.value_base_category();
+ uint64_t vbd = token.value_base_detail();
+ if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
+ continue;
+ } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
+ skip_depth++;
+ continue;
+ }
+ skip_depth--;
+ }
+
+ if (skip_depth == 0) {
+ break;
+ }
+ } // skip_the_next_dict_value
+ } // do_dict
+
+do_list:
+ do {
+ wuffs_base__result_u64 result_u64 = wuffs_base__parse_number_u64(
+ wuffs_base__make_slice_u8(
+ static_cast<uint8_t*>(static_cast<void*>(
+ const_cast<char*>(json_pointer_fragment.data()))),
+ json_pointer_fragment.size()),
+ WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
+ if (!result_u64.status.is_ok()) {
+ return DecodeJson_NoMatch;
+ }
+ uint64_t remaining = result_u64.value;
+ if (remaining == 0) {
+ goto check_that_a_value_follows;
+ }
+ for (uint32_t skip_depth = 0; true;) {
+ WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
+
+ int64_t vbc = token.value_base_category();
+ uint64_t vbd = token.value_base_detail();
+ if (token.continued() || (vbc == WUFFS_BASE__TOKEN__VBC__FILLER)) {
+ continue;
+ } else if (vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
+ skip_depth++;
+ continue;
+ }
+ if (skip_depth == 0) {
+ return DecodeJson_NoMatch;
+ }
+ skip_depth--;
+ }
+
+ if (skip_depth > 0) {
+ continue;
+ }
+ remaining--;
+ if (remaining == 0) {
+ goto check_that_a_value_follows;
+ }
+ }
+ } while (false); // do_list
+
+check_that_a_value_follows:
+ while (true) {
+ WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
+
+ int64_t vbc = token.value_base_category();
+ uint64_t vbd = token.value_base_detail();
+ if (vbc == WUFFS_BASE__TOKEN__VBC__FILLER) {
+ continue;
+ }
+
+ // Undo the last part of WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN, so
+ // that we're only peeking at the next token.
+ tok_buf.meta.ri--;
+ cursor_index -= static_cast<size_t>(token_len);
+
+ if ((vbc == WUFFS_BASE__TOKEN__VBC__STRUCTURE) &&
+ (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__POP)) {
+ return DecodeJson_NoMatch;
+ }
+ return "";
+ } // check_that_a_value_follows
+
+fail:
+ return "wuffs_aux::DecodeJson: internal error: unexpected token";
+done:
+ return ret_error_message;
+}
+
+} // namespace
+
+// --------
+
+DecodeJsonResult //
+DecodeJson(DecodeJsonCallbacks& callbacks,
+ sync_io::Input& input,
+ DecodeJsonArgQuirks quirks,
+ DecodeJsonArgJsonPointer json_pointer) {
+ // Prepare the wuffs_base__io_buffer and the resultant error_message.
+ wuffs_base__io_buffer* io_buf = input.BringsItsOwnIOBuffer();
+ wuffs_base__io_buffer fallback_io_buf = wuffs_base__empty_io_buffer();
+ std::unique_ptr<uint8_t[]> fallback_io_array(nullptr);
+ if (!io_buf) {
+ fallback_io_array = std::unique_ptr<uint8_t[]>(new uint8_t[4096]);
+ fallback_io_buf = wuffs_base__ptr_u8__writer(fallback_io_array.get(), 4096);
+ io_buf = &fallback_io_buf;
+ }
+ // cursor_index is discussed at
+ // https://nigeltao.github.io/blog/2020/jsonptr.html#the-cursor-index
+ size_t cursor_index = 0;
+ std::string ret_error_message;
+ std::string io_error_message;
+
+ do {
+ // Prepare the low-level JSON decoder.
+ wuffs_json__decoder::unique_ptr dec = wuffs_json__decoder::alloc();
+ if (!dec) {
+ ret_error_message = "wuffs_aux::DecodeJson: out of memory";
+ goto done;
+ } else if (WUFFS_JSON__DECODER_WORKBUF_LEN_MAX_INCL_WORST_CASE != 0) {
+ ret_error_message =
+ "wuffs_aux::DecodeJson: internal error: bad WORKBUF_LEN";
+ goto done;
+ }
+ bool allow_tilde_n_tilde_r_tilde_t = false;
+ for (size_t i = 0; i < quirks.repr.len; i++) {
+ dec->set_quirk(quirks.repr.ptr[i], 1);
+ if (quirks.repr.ptr[i] ==
+ WUFFS_JSON__QUIRK_JSON_POINTER_ALLOW_TILDE_N_TILDE_R_TILDE_T) {
+ allow_tilde_n_tilde_r_tilde_t = true;
+ }
+ }
+
+ // Prepare the wuffs_base__tok_buffer. 256 tokens is 2KiB.
+ wuffs_base__token tok_array[256];
+ wuffs_base__token_buffer tok_buf =
+ wuffs_base__slice_token__writer(wuffs_base__make_slice_token(
+ &tok_array[0], (sizeof(tok_array) / sizeof(tok_array[0]))));
+ wuffs_base__status tok_status =
+ dec->decode_tokens(&tok_buf, io_buf, wuffs_base__empty_slice_u8());
+
+ // Prepare other state.
+ int32_t depth = 0;
+ std::string str;
+
+ // Walk the (optional) JSON Pointer.
+ for (size_t i = 0; i < json_pointer.repr.size();) {
+ if (json_pointer.repr[i] != '/') {
+ ret_error_message = DecodeJson_BadJsonPointer;
+ goto done;
+ }
+ std::pair<std::string, size_t> split = DecodeJson_SplitJsonPointer(
+ json_pointer.repr, i + 1, allow_tilde_n_tilde_r_tilde_t);
+ i = split.second;
+ if (i == 0) {
+ ret_error_message = DecodeJson_BadJsonPointer;
+ goto done;
+ }
+ ret_error_message = DecodeJson_WalkJsonPointerFragment(
+ tok_buf, tok_status, dec, io_buf, io_error_message, cursor_index,
+ input, split.first);
+ if (!ret_error_message.empty()) {
+ goto done;
+ }
+ }
+
+ // Loop, doing these two things:
+ // 1. Get the next token.
+ // 2. Process that token.
+ while (true) {
+ WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN;
+
+ int64_t vbc = token.value_base_category();
+ uint64_t vbd = token.value_base_detail();
+ switch (vbc) {
+ case WUFFS_BASE__TOKEN__VBC__FILLER:
+ continue;
+
+ case WUFFS_BASE__TOKEN__VBC__STRUCTURE: {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__STRUCTURE__PUSH) {
+ ret_error_message = callbacks.Push(static_cast<uint32_t>(vbd));
+ if (!ret_error_message.empty()) {
+ goto done;
+ }
+ depth++;
+ if (depth > WUFFS_JSON__DECODER_DEPTH_MAX_INCL) {
+ ret_error_message =
+ "wuffs_aux::DecodeJson: internal error: bad depth";
+ goto done;
+ }
+ continue;
+ }
+ ret_error_message = callbacks.Pop(static_cast<uint32_t>(vbd));
+ depth--;
+ if (depth < 0) {
+ ret_error_message =
+ "wuffs_aux::DecodeJson: internal error: bad depth";
+ goto done;
+ }
+ goto parsed_a_value;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__STRING: {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_0_DST_1_SRC_DROP) {
+ // No-op.
+ } else if (vbd &
+ WUFFS_BASE__TOKEN__VBD__STRING__CONVERT_1_DST_1_SRC_COPY) {
+ const char* ptr = // Convert from (uint8_t*).
+ static_cast<const char*>(static_cast<void*>(token_ptr));
+ str.append(ptr, static_cast<size_t>(token_len));
+ } else {
+ goto fail;
+ }
+ if (token.continued()) {
+ continue;
+ }
+ ret_error_message = callbacks.AppendTextString(std::move(str));
+ str.clear();
+ goto parsed_a_value;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__UNICODE_CODE_POINT: {
+ uint8_t u[WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL];
+ size_t n = wuffs_base__utf_8__encode(
+ wuffs_base__make_slice_u8(
+ &u[0], WUFFS_BASE__UTF_8__BYTE_LENGTH__MAX_INCL),
+ static_cast<uint32_t>(vbd));
+ const char* ptr = // Convert from (uint8_t*).
+ static_cast<const char*>(static_cast<void*>(&u[0]));
+ str.append(ptr, n);
+ if (token.continued()) {
+ continue;
+ }
+ goto fail;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__LITERAL: {
+ ret_error_message =
+ (vbd & WUFFS_BASE__TOKEN__VBD__LITERAL__NULL)
+ ? callbacks.AppendNull()
+ : callbacks.AppendBool(vbd &
+ WUFFS_BASE__TOKEN__VBD__LITERAL__TRUE);
+ goto parsed_a_value;
+ }
+
+ case WUFFS_BASE__TOKEN__VBC__NUMBER: {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__FORMAT_TEXT) {
+ if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_INTEGER_SIGNED) {
+ wuffs_base__result_i64 r = wuffs_base__parse_number_i64(
+ wuffs_base__make_slice_u8(token_ptr,
+ static_cast<size_t>(token_len)),
+ WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
+ if (r.status.is_ok()) {
+ ret_error_message = callbacks.AppendI64(r.value);
+ goto parsed_a_value;
+ }
+ }
+ if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_FLOATING_POINT) {
+ wuffs_base__result_f64 r = wuffs_base__parse_number_f64(
+ wuffs_base__make_slice_u8(token_ptr,
+ static_cast<size_t>(token_len)),
+ WUFFS_BASE__PARSE_NUMBER_XXX__DEFAULT_OPTIONS);
+ if (r.status.is_ok()) {
+ ret_error_message = callbacks.AppendF64(r.value);
+ goto parsed_a_value;
+ }
+ }
+ } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_INF) {
+ ret_error_message = callbacks.AppendF64(
+ wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
+ 0xFFF0000000000000ul));
+ goto parsed_a_value;
+ } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_INF) {
+ ret_error_message = callbacks.AppendF64(
+ wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
+ 0x7FF0000000000000ul));
+ goto parsed_a_value;
+ } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_NEG_NAN) {
+ ret_error_message = callbacks.AppendF64(
+ wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
+ 0xFFFFFFFFFFFFFFFFul));
+ goto parsed_a_value;
+ } else if (vbd & WUFFS_BASE__TOKEN__VBD__NUMBER__CONTENT_POS_NAN) {
+ ret_error_message = callbacks.AppendF64(
+ wuffs_base__ieee_754_bit_representation__from_u64_to_f64(
+ 0x7FFFFFFFFFFFFFFFul));
+ goto parsed_a_value;
+ }
+ goto fail;
+ }
+ }
+
+ fail:
+ ret_error_message =
+ "wuffs_aux::DecodeJson: internal error: unexpected token";
+ goto done;
+
+ parsed_a_value:
+ // If an error was encountered, we are done. Otherwise, (depth == 0)
+ // after parsing a value is equivalent to having decoded the entire JSON
+ // value (for an empty json_pointer query) or having decoded the
+ // pointed-to JSON value (for a non-empty json_pointer query). In the
+ // latter case, we are also done.
+ //
+ // However, if quirks like WUFFS_JSON__QUIRK_ALLOW_TRAILING_FILLER or
+ // WUFFS_JSON__QUIRK_EXPECT_TRAILING_NEW_LINE_OR_EOF are passed, decoding
+ // the entire JSON value should also consume any trailing filler, in case
+ // the DecodeJson caller wants to subsequently check that the input is
+ // completely exhausted (and otherwise raise "valid JSON followed by
+ // further (unexpected) data"). We aren't done yet. Instead, keep the
+ // loop running until WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN's
+ // decode_tokens returns an ok status.
+ if (!ret_error_message.empty() ||
+ ((depth == 0) && !json_pointer.repr.empty())) {
+ goto done;
+ }
+ }
+ } while (false);
+
+done:
+ DecodeJsonResult result(
+ std::move(ret_error_message),
+ wuffs_base__u64__sat_add(io_buf->meta.pos, cursor_index));
+ callbacks.Done(result, input, *io_buf);
+ return result;
+}
+
+#undef WUFFS_AUX__DECODE_JSON__GET_THE_NEXT_TOKEN
+
+} // namespace wuffs_aux
+
+#endif // !defined(WUFFS_CONFIG__MODULES) ||
+ // defined(WUFFS_CONFIG__MODULE__AUX__JSON)
+
+#endif // defined(__cplusplus) && defined(WUFFS_BASE__HAVE_UNIQUE_PTR)
+
+#endif // WUFFS_IMPLEMENTATION
+
+#if defined(__GNUC__)
+#pragma GCC diagnostic pop
+#elif defined(__clang__)
+#pragma clang diagnostic pop
+#endif
+
+#endif // WUFFS_INCLUDE_GUARD